From: Teodor Sigaev Date: Mon, 10 Apr 2017 16:25:59 +0000 (+0300) Subject: add working with fasttruncate X-Git-Url: http://sigaev.ru/git/gitweb.cgi?a=commitdiff_plain;h=e44c627e72af54acdb09ec0c6175da4c302191a9;p=online_analyze.git add working with fasttruncate --- diff --git a/online_analyze.c b/online_analyze.c index dba4226..2ef4193 100644 --- a/online_analyze.c +++ b/online_analyze.c @@ -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 ||