fix accounting of n tpules after truncate, athough it should not affect anything
authorTeodor Sigaev <teodor@sigaev.ru>
Mon, 10 Apr 2017 16:25:59 +0000 (19:25 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Mon, 10 Apr 2017 16:25:59 +0000 (19:25 +0300)
online_analyze.c

index dba4226..2ef4193 100644 (file)
@@ -30,6 +30,7 @@
 #include "postgres.h"
 
 #include "pgstat.h"
+#include "access/transam.h"
 #include "catalog/namespace.h"
 #include "commands/vacuum.h"
 #include "executor/executor.h"
@@ -602,7 +603,7 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                                rstat->changes_since_analyze += naffected;
                                break;
                        case CK_TRUNCATE:
-                               rstat->changes_since_analyze = rstat->n_tuples;
+                               rstat->changes_since_analyze = 0;
                                rstat->n_tuples = 0;
                                break;
                        default:
@@ -615,15 +616,81 @@ makeAnalyze(Oid relOid, CmdKind operation, int64 naffected)
                relstatsInit();
 }
 
+static Const*
+isFastTruncateCall(QueryDesc *queryDesc)
+{
+       TargetEntry     *te;
+       FuncExpr        *fe;
+       Const           *constval;
+
+       if (!(
+                 queryDesc->plannedstmt &&
+                 queryDesc->operation == CMD_SELECT &&
+                 queryDesc->plannedstmt->planTree &&
+                 queryDesc->plannedstmt->planTree->targetlist &&
+                 list_length(queryDesc->plannedstmt->planTree->targetlist) == 1 &&
+                 IsA(linitial(queryDesc->plannedstmt->planTree->targetlist), TargetEntry)
+                ))
+               return NULL;
+
+       te = linitial(queryDesc->plannedstmt->planTree->targetlist);
+
+       if (!IsA(te, TargetEntry))
+               return NULL;
+
+       fe = (FuncExpr*)te->expr;
+
+       if (!(
+                 fe && IsA(fe, FuncExpr) &&
+                 fe->funcid >= FirstNormalObjectId &&
+                 fe->funcretset == false &&
+                 fe->funcresulttype == VOIDOID &&
+                 fe->funcvariadic == false &&
+                 list_length(fe->args) == 1 &&
+                 IsA(linitial(fe->args), Const)
+                ))
+               return NULL;
+
+       constval = linitial(fe->args);
+
+       if (!(
+                 IsA(constval,Const) &&
+                 constval->consttype == TEXTOID &&
+                 strcmp(get_func_name(fe->funcid), "fasttruncate") == 0
+                ))
+               return NULL;
+
+       return constval;
+}
+
+
+
 extern PGDLLIMPORT void onlineAnalyzeHooker(QueryDesc *queryDesc);
 void
 onlineAnalyzeHooker(QueryDesc *queryDesc)
 {
        int64   naffected = -1;
+       Const   *constval;
 
        if (queryDesc->estate)
                naffected = queryDesc->estate->es_processed;
 
+       if (online_analyze_enable &&
+               (constval = isFastTruncateCall(queryDesc)) != NULL)
+       {
+               Datum           tblnamed = constval->constvalue;
+               char            *tblname = text_to_cstring(DatumGetTextP(tblnamed));
+               RangeVar        *tblvar =
+                       makeRangeVarFromNameList(stringToQualifiedNameList(tblname));
+
+               makeAnalyze(RangeVarGetRelid(tblvar,
+#if PG_VERSION_NUM >= 90200
+                                                                        NoLock,
+#endif
+                                                                        false),
+                                       CK_TRUNCATE, -1);
+       }
+
        if (online_analyze_enable && queryDesc->plannedstmt &&
                        (queryDesc->operation == CMD_INSERT ||
                         queryDesc->operation == CMD_UPDATE ||