Support for v14
[online_analyze.git] / online_analyze.c
index 3051283..1a50250 100644 (file)
@@ -55,6 +55,9 @@
 #if PG_VERSION_NUM >= 100000
 #include "utils/varlena.h"
 #include "utils/regproc.h"
+#if PG_VERSION_NUM >= 130000
+#include "common/hashfn.h"
+#endif
 #endif
 #endif
 #endif
@@ -77,6 +80,10 @@ static ExecutorEnd_hook_type oldExecutorEndHook = NULL;
 static ProcessUtility_hook_type        oldProcessUtilityHook = NULL;
 #endif
 
+#if PG_VERSION_NUM >= 120000
+#define VACOPT_NOWAIT VACOPT_SKIP_LOCKED
+#endif
+
 typedef enum CmdKind
 {
        CK_SELECT = CMD_SELECT,
@@ -446,9 +453,10 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                rstat->tableid = relOid;
                newTable = true;
        }
-       else if (operation == CK_VACUUM)
+
+       if (operation == CK_VACUUM)
        {
-               /* force reread becouse vacuum could change n_tuples */
+               /* force reread because vacuum could change n_tuples */
                rstat->rereadStat = true;
                return;
        }
@@ -457,6 +465,8 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                /* only analyze */
                rstat->changes_since_analyze = 0;
                rstat->analyze_timestamp = now;
+               if (newTable)
+                       rstat->rereadStat = true;
                return;
        }
 
@@ -510,6 +520,7 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                VacuumParams                    vacstmt;
 #endif
                TimestampTz                             startStamp, endStamp;
+               int                                             flags;
 
 
                memset(&startStamp, 0, sizeof(startStamp)); /* keep compiler quiet */
@@ -538,9 +549,16 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                vacstmt.log_min_duration = -1;
 #endif
 
+
                if (online_analyze_verbose)
                        startStamp = GetCurrentTimestamp();
 
+               flags = VACOPT_ANALYZE | VACOPT_NOWAIT |
+                                       ((online_analyze_verbose) ?  VACOPT_VERBOSE : 0);
+
+#if PG_VERSION_NUM >= 120000
+               vacstmt.options = flags;
+#endif
                analyze_rel(relOid,
 #if PG_VERSION_NUM < 90500
                        &vacstmt
@@ -553,7 +571,9 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
 #endif
 #else
                        makeRangeVarFromOid(relOid),
-                       VACOPT_ANALYZE | ((online_analyze_verbose) ? VACOPT_VERBOSE : 0),
+#if PG_VERSION_NUM < 120000
+                       flags,
+#endif
                        &vacstmt, NULL, true, GetAccessStrategy(BAS_VACUUM)
 #endif
                );
@@ -582,6 +602,7 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                        case CK_INSERT:
                        case CK_UPDATE:
                                rstat->n_tuples += naffected;
+                               /* FALLTHROUGH */
                        case CK_DELETE:
                                rstat->rereadStat = (reltype == OATT_PERSISTENT);
                                break;
@@ -622,6 +643,7 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                        case CK_UPDATE:
                                rstat->changes_since_analyze += 2 * naffected;
                                rstat->n_tuples += naffected;
+                               break;
                        case CK_DELETE:
                                rstat->changes_since_analyze += naffected;
                                break;
@@ -783,6 +805,36 @@ removeTable(XactEvent event, void *arg)
        toremove = NIL;
 }
 
+#if PG_VERSION_NUM >= 120000
+static int
+parse_vacuum_opt(VacuumStmt *vacstmt)
+{
+       int                     options = vacstmt->is_vacuumcmd ? VACOPT_VACUUM : VACOPT_ANALYZE;
+       ListCell        *lc;
+
+       foreach(lc, vacstmt->options)
+       {
+               DefElem *opt = (DefElem *) lfirst(lc);
+
+               /* Parse common options for VACUUM and ANALYZE */
+               if (strcmp(opt->defname, "verbose") == 0)
+                       options |= VACOPT_VERBOSE;
+               else if (strcmp(opt->defname, "skip_locked") == 0)
+                       options |= VACOPT_SKIP_LOCKED;
+               else if (strcmp(opt->defname, "analyze") == 0)
+                       options |= VACOPT_ANALYZE;
+               else if (strcmp(opt->defname, "freeze") == 0)
+                       options |= VACOPT_FREEZE;
+               else if (strcmp(opt->defname, "full") == 0)
+                       options |= VACOPT_FULL;
+               else if (strcmp(opt->defname, "disable_page_skipping") == 0)
+                       options |= VACOPT_DISABLE_PAGE_SKIPPING;
+       }
+
+       return options;
+}
+#endif
+
 
 #if PG_VERSION_NUM >= 90200
 static void
@@ -793,6 +845,9 @@ onlineAnalyzeHookerUtility(
                                                   Node *parsetree,
 #endif
                                                   const char *queryString,
+#if PG_VERSION_NUM >= 140000
+                                                  bool readOnlyTree,
+#endif
 #if PG_VERSION_NUM >= 90300
                                                        ProcessUtilityContext context, ParamListInfo params,
 #if PG_VERSION_NUM >= 100000
@@ -801,7 +856,13 @@ onlineAnalyzeHookerUtility(
 #else
                                                        ParamListInfo params, bool isTopLevel,
 #endif
-                                                       DestReceiver *dest, char *completionTag) {
+                                                       DestReceiver *dest,
+#if  PG_VERSION_NUM >= 130000
+                                                       QueryCompletion *completionTag
+#else
+                                                       char *completionTag
+#endif
+) {
        List            *tblnames = NIL;
        CmdKind         op = CK_INSERT;
 #if PG_VERSION_NUM >= 100000
@@ -849,11 +910,23 @@ onlineAnalyzeHookerUtility(
                else if (IsA(parsetree, VacuumStmt))
                {
                        VacuumStmt      *vac = (VacuumStmt*)parsetree;
+                       int                     options =
+#if PG_VERSION_NUM >= 120000
+                                                       parse_vacuum_opt(vac)
+#else
+                                                       vac->options
+#endif
+                                                       ;
 
+
+#if PG_VERSION_NUM >= 110000
+                       tblnames = vac->rels;
+#else
                        if (vac->relation)
                                tblnames = list_make1(vac->relation);
+#endif
 
-                       if (vac->options & (VACOPT_VACUUM | VACOPT_FULL | VACOPT_FREEZE))
+                       if (options & (VACOPT_VACUUM | VACOPT_FULL | VACOPT_FREEZE))
                        {
                                /* optionally with analyze */
                                op = CK_VACUUM;
@@ -862,7 +935,7 @@ onlineAnalyzeHookerUtility(
                                if (tblnames == NIL)
                                        relstatsInit();
                        }
-                       else if (vac->options & VACOPT_ANALYZE)
+                       else if (options & VACOPT_ANALYZE)
                        {
                                op = CK_ANALYZE;
 
@@ -893,6 +966,9 @@ onlineAnalyzeHookerUtility(
 
        if (oldProcessUtilityHook)
                oldProcessUtilityHook(parsetree, queryString,
+#if PG_VERSION_NUM >= 140000
+                                                         readOnlyTree,
+#endif
 #if PG_VERSION_NUM >= 90300
                                                          context, params,
 #if PG_VERSION_NUM >= 100000
@@ -904,6 +980,9 @@ onlineAnalyzeHookerUtility(
                                                          dest, completionTag);
        else
                standard_ProcessUtility(parsetree, queryString,
+#if PG_VERSION_NUM >= 140000
+                                                               readOnlyTree,
+#endif
 #if PG_VERSION_NUM >= 90300
                                                                context, params,
 #if PG_VERSION_NUM >= 100000
@@ -923,15 +1002,24 @@ onlineAnalyzeHookerUtility(
 
                foreach(l, tblnames)
                {
-                       RangeVar        *tblname = (RangeVar*)lfirst(l);
-                       Oid     tblOid = RangeVarGetRelid(tblname, NoLock, true);
+                       RangeVar        *tblname =
+#if PG_VERSION_NUM >= 110000
+                               (IsA(lfirst(l), VacuumRelation)) ?
+                                       ((VacuumRelation*)lfirst(l))->relation :
+#endif
+                                       (RangeVar*)lfirst(l);
+                       Oid     tblOid;
+
+                       Assert(IsA(tblname, RangeVar));
 
+                       tblOid = RangeVarGetRelid(tblname, NoLock, true);
                        makeAnalyze(tblOid, op, -1);
                }
        }
 }
 #endif
 
+
 static void
 relstatsInit(void)
 {
@@ -951,17 +1039,20 @@ relstatsInit(void)
        else
        {
                Assert(relstats == NULL);
+
+#if PG_VERSION_NUM < 90600
                onlineAnalyzeMemoryContext =
                        AllocSetContextCreate(CacheMemoryContext,
-                                                                 "online_analyze storage context",
-#if PG_VERSION_NUM < 90600
-                                                                 ALLOCSET_DEFAULT_MINSIZE,
-                                                                 ALLOCSET_DEFAULT_INITSIZE,
-                                                                 ALLOCSET_DEFAULT_MAXSIZE
+                       "online_analyze storage context",
+                       ALLOCSET_DEFAULT_MINSIZE,
+                       ALLOCSET_DEFAULT_INITSIZE,
+                       ALLOCSET_DEFAULT_MAXSIZE
+                       );
 #else
-                                                                 ALLOCSET_DEFAULT_SIZES
+               onlineAnalyzeMemoryContext =
+                       AllocSetContextCreate(CacheMemoryContext,
+                       "online_analyze storage context", ALLOCSET_DEFAULT_SIZES);
 #endif
-                                                                );
        }
 
        hash_ctl.hcxt = onlineAnalyzeMemoryContext;