support 9.4
[online_analyze.git] / online_analyze.c
index 78077e8..299ae57 100644 (file)
 #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;
@@ -50,13 +58,18 @@ static double online_analyze_scale_factor = 0.1;
 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[] = 
 {
@@ -112,7 +125,13 @@ tableListAssign(const char * newval, bool doit, TableList *tbl)
        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)
                {
@@ -282,8 +301,6 @@ matchOid(TableList *tbl, Oid oid)
        return false;
 }
 
-static ExecutorEnd_hook_type oldhook = NULL;
-
 static void
 makeAnalyze(Oid relOid, CmdType operation, uint32 naffected)
 {
@@ -293,6 +310,9 @@ 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
@@ -317,6 +337,8 @@ makeAnalyze(Oid relOid, CmdType operation, uint32 naffected)
                VacuumStmt                              vacstmt;
                TimestampTz                             startStamp, endStamp;
 
+               memset(&startStamp, 0, sizeof(startStamp)); /* keep compiler quiet */
+
                /*
                 * includeTables overwrites excludeTables
                 */
@@ -335,10 +357,16 @@ makeAnalyze(Oid relOid, CmdType operation, uint32 naffected)
                        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);
 
                                        /*
@@ -372,8 +400,12 @@ makeAnalyze(Oid relOid, CmdType operation, uint32 naffected)
                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
                );
@@ -421,16 +453,22 @@ onlineAnalyzeHooker(QueryDesc *queryDesc)
        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;
@@ -446,20 +484,66 @@ onlineAnalyzeHooker(QueryDesc *queryDesc)
                }
        }
 
-       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",
@@ -544,7 +628,7 @@ _PG_init(void)
                "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
@@ -561,9 +645,9 @@ _PG_init(void)
                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
@@ -624,7 +708,10 @@ void _PG_fini(void);
 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);