#include "utils/builtins.h"
#include "utils/lsyscache.h"
#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"
+#endif
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
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,
OATT_PERSISTENT = 0x01,
OATT_TEMPORARY = 0x02,
OATT_NONE = 0x00
-} OnlyneAnalyzeTableType;
+} OnlineAnalyzeTableType;
static const struct config_enum_entry online_analyze_table_type_options[] =
{
foreach(l, namelist)
{
char *curname = (char *) lfirst(l);
- Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), true);
+#if PG_VERSION_NUM >= 90200
+ 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
*/
default:
{
Relation rel;
- OnlyneAnalyzeTableType reltype;
+ OnlineAnalyzeTableType reltype;
rel = RelationIdGetRelation(relOid);
- reltype = (rel->rd_istemp || rel->rd_islocaltemp) ? OATT_TEMPORARY : OATT_PERSISTENT;
+ reltype =
+#if PG_VERSION_NUM >= 90100
+ (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
+#else
+ (rel->rd_istemp || rel->rd_islocaltemp)
+#endif
+ ? OATT_TEMPORARY : OATT_PERSISTENT;
RelationClose(rel);
/*
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 ||
- (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 (queryDesc->plannedstmt->intoClause)
+#if PG_VERSION_NUM < 90200
+ if (queryDesc->operation == CMD_SELECT)
{
Oid relOid = RangeVarGetRelid(queryDesc->plannedstmt->intoClause->rel, true);
makeAnalyze(relOid, queryDesc->operation, naffected);
}
- else if (queryDesc->plannedstmt->resultRelations &&
+ else
+#endif
+ if (queryDesc->plannedstmt->resultRelations &&
queryDesc->plannedstmt->rtable)
{
ListCell *l;
}
}
- 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 onlyne analyze: all(default), persistent, temporary, none",
+ "Type(s) of table for online analyze: all(default), persistent, temporary, none",
NULL,
&online_analyze_table_type,
#if PG_VERSION_NUM >= 80400
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);