#include "utils/guc.h"
#if PG_VERSION_NUM >= 90200
#include "catalog/pg_class.h"
+#include "nodes/primnodes.h"
+#include "tcop/utility.h"
#include "utils/rel.h"
#include "utils/relcache.h"
#include "utils/timestamp.h"
static int online_analyze_threshold = 50;
static double online_analyze_min_interval = 10000;
+static ExecutorEnd_hook_type oldExecutorEndHook = NULL;
+#if PG_VERSION_NUM >= 90200
+static ProcessUtility_hook_type oldProcessUtilityHook = NULL;
+#endif
+
typedef enum
{
OATT_ALL = 0x03,
foreach(l, namelist)
{
char *curname = (char *) lfirst(l);
- Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)),
#if PG_VERSION_NUM >= 90200
- NoLock,
-#endif
+ Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)),
+ NoLock, true);
+#else
+ Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)),
true);
+#endif
if (relOid == InvalidOid)
{
return false;
}
-static ExecutorEnd_hook_type oldhook = NULL;
-
static void
makeAnalyze(Oid relOid, CmdType operation, uint32 naffected)
{
if (relOid == InvalidOid)
return;
+ if (get_rel_relkind(relOid) != RELKIND_RELATION)
+ return;
+
tabentry = pgstat_fetch_stat_tabentry(relOid);
#if PG_VERSION_NUM >= 90000
VacuumStmt vacstmt;
TimestampTz startStamp, endStamp;
+ memset(&startStamp, 0, sizeof(startStamp)); /* keep compiler quiet */
+
/*
* includeTables overwrites excludeTables
*/
if (online_analyze_verbose)
startStamp = GetCurrentTimestamp();
- analyze_rel(relOid, &vacstmt, GetAccessStrategy(BAS_VACUUM)
-#if (PG_VERSION_NUM < 90004) && (PG_VERSION_NUM >= 90000)
+ analyze_rel(relOid, &vacstmt
+#if PG_VERSION_NUM >= 90018
+ , true
+#endif
+ , GetAccessStrategy(BAS_VACUUM)
+#if (PG_VERSION_NUM >= 90000) && (PG_VERSION_NUM < 90004)
, true
#endif
);
if (online_analyze_enable && queryDesc->plannedstmt &&
(queryDesc->operation == CMD_INSERT ||
queryDesc->operation == CMD_UPDATE ||
- queryDesc->operation == CMD_DELETE ||
-#if PG_VERSION_NUM >= 90200
- 0 /* (queryDesc->operation == CMD_SELECT && queryDesc->dest && queryDesc->dest == DestIntoRel) */
-#else
- (queryDesc->operation == CMD_SELECT && queryDesc->plannedstmt->intoClause)
+ queryDesc->operation == CMD_DELETE
+#if PG_VERSION_NUM < 90200
+ || (queryDesc->operation == CMD_SELECT && queryDesc->plannedstmt->intoClause)
#endif
))
{
}
}
- if (oldhook)
- (*oldhook)(queryDesc);
+ if (oldExecutorEndHook)
+ oldExecutorEndHook(queryDesc);
else
standard_ExecutorEnd(queryDesc);
}
+#if PG_VERSION_NUM >= 90200
+static void
+onlineAnalyzeHookerUtility(Node *parsetree, const char *queryString,
+#if PG_VERSION_NUM >= 90300
+ ProcessUtilityContext context, ParamListInfo params,
+#else
+ ParamListInfo params, bool isTopLevel,
+#endif
+ DestReceiver *dest, char *completionTag) {
+ RangeVar *tblname = NULL;
+
+ if (IsA(parsetree, CreateTableAsStmt) && ((CreateTableAsStmt*)parsetree)->into)
+ tblname = (RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel);
+
+ if (oldProcessUtilityHook)
+ oldProcessUtilityHook(parsetree, queryString,
+#if PG_VERSION_NUM >= 90300
+ context, params,
+#else
+ params, isTopLevel,
+#endif
+ dest, completionTag);
+ else
+ standard_ProcessUtility(parsetree, queryString,
+#if PG_VERSION_NUM >= 90300
+ context, params,
+#else
+ params, isTopLevel,
+#endif
+ dest, completionTag);
+
+ if (tblname) {
+ Oid tblOid = RangeVarGetRelid(tblname, NoLock, true);
+
+ makeAnalyze(tblOid, CMD_INSERT, 0);
+ }
+}
+#endif
+
void _PG_init(void);
void
_PG_init(void)
{
- oldhook = ExecutorEnd_hook;
+ oldExecutorEndHook = ExecutorEnd_hook;
ExecutorEnd_hook = onlineAnalyzeHooker;
+#if PG_VERSION_NUM >= 90200
+ oldProcessUtilityHook = ProcessUtility_hook;
+
+ ProcessUtility_hook = onlineAnalyzeHookerUtility;
+#endif
+
+
DefineCustomBoolVariable(
"online_analyze.enable",
"Enable on-line analyze",
"online_analyze.min_interval",
"minimum time interval between analyze call (in milliseconds)",
"minimum time interval between analyze call (in milliseconds)",
- &online_analyze_scale_factor,
+ &online_analyze_min_interval,
#if PG_VERSION_NUM >= 80400
online_analyze_min_interval,
#endif
NULL
);
-DefineCustomEnumVariable(
+ DefineCustomEnumVariable(
"online_analyze.table_type",
"Type(s) of table for online analyze: all(default), persistent, temporary, none",
NULL,
void
_PG_fini(void)
{
- ExecutorEnd_hook = oldhook;
+ ExecutorEnd_hook = oldExecutorEndHook;
+#if PG_VERSION_NUM >= 90200
+ ProcessUtility_hook = oldProcessUtilityHook;
+#endif
if (excludeTables.tables)
free(excludeTables.tables);