static ProcessUtility_hook_type oldProcessUtilityHook = NULL;
#endif
+typedef enum CmdKind
+{
+ CK_SELECT = CMD_SELECT,
+ CK_UPDATE = CMD_UPDATE,
+ CK_INSERT = CMD_INSERT,
+ CK_DELETE = CMD_DELETE,
+ CK_TRUNCATE,
+ CK_CREATE
+} CmdKind;
+
typedef enum
{
OATT_ALL = 0x03,
#endif
static void
-makeAnalyze(Oid relOid, CmdType operation, int32 naffected)
+makeAnalyze(Oid relOid, CmdKind operation, int32 naffected)
{
TimestampTz now = GetCurrentTimestamp();
Relation rel;
else
rstat = &dummyrstat; /* found == false for following if */
- if (found == false || rstat->rereadStat == true || naffected == 0)
+ if (!found)
{
+ MemSet(rstat, 0, sizeof(*rstat));
+ rstat->tableid = relOid;
+ newTable = true;
+ }
- if (!found)
- {
- MemSet(rstat, 0, sizeof(*rstat));
- rstat->tableid = relOid;
- }
- Assert(rstat->tableid == relOid);
+ Assert(rstat->tableid == relOid);
+
+ if (operation != CK_TRUNCATE &&
+ (found == false || rstat->rereadStat == true))
+ {
+
+ rstat->rereadStat = false;
tabentry = pgstat_fetch_stat_tabentry(relOid);
rstat->autovac_analyze_timestamp =
tabentry->autovac_analyze_timestamp;
rstat->analyze_timestamp = tabentry->analyze_timestamp;
- rstat->rereadStat = false;
- }
- else
- {
- newTable = true;
- rstat->rereadStat = true;
}
}
- if (newTable || (
+ if (naffected == 0)
+ rstat->rereadStat = true;
+
+ if (newTable ||
+ /* force analyze from after truncate */
+ operation == CK_TRUNCATE || (
/* do not analyze too often, if both stamps are exceeded the go */
TimestampDifferenceExceeds(rstat->analyze_timestamp, now, online_analyze_min_interval) &&
TimestampDifferenceExceeds(rstat->autovac_analyze_timestamp, now, online_analyze_min_interval) &&
rstat->autovac_analyze_timestamp = now;
rstat->changes_since_analyze = 0;
- rstat->rereadStat = true;
+
+ switch(operation)
+ {
+ case CK_INSERT:
+ rstat->n_tuples += naffected;
+ break;
+ case CK_UPDATE:
+ rstat->n_tuples += naffected;
+ rstat->rereadStat = true;
+ break;
+ case CK_DELETE:
+ rstat->rereadStat = true;
+ break;
+ case CK_TRUNCATE:
+ rstat->n_tuples = 0;
+ break;
+ default:
+ break;
+ }
/* update last analyze timestamp in local memory of backend */
if (tabentry)
if (tabentry)
tabentry->changes_since_analyze += naffected;
#endif
- rstat->changes_since_analyze += naffected;
+ switch(operation)
+ {
+ case CK_INSERT:
+ rstat->changes_since_analyze += naffected;
+ rstat->n_tuples += naffected;
+ break;
+ case CK_UPDATE:
+ rstat->changes_since_analyze += 2 * naffected;
+ rstat->n_tuples += naffected;
+ case CK_DELETE:
+ rstat->changes_since_analyze += naffected;
+ break;
+ case CK_TRUNCATE:
+ rstat->changes_since_analyze = rstat->n_tuples;
+ rstat->n_tuples = 0;
+ break;
+ default:
+ break;
+ }
}
/* Reset local cache if we are over limit */
RangeTblEntry *rte = list_nth(queryDesc->plannedstmt->rtable, n-1);
if (rte->rtekind == RTE_RELATION)
- makeAnalyze(rte->relid, queryDesc->operation, naffected);
+ makeAnalyze(rte->relid, (CmdKind)queryDesc->operation, naffected);
}
}
}
ParamListInfo params, bool isTopLevel,
#endif
DestReceiver *dest, char *completionTag) {
- RangeVar *tblname = NULL;
+ List *tblnames = NIL;
+ CmdKind op = CK_INSERT;
#if PG_VERSION_NUM >= 100000
Node *parsetree = NULL;
parsetree = pstmt->utilityStmt;
#endif
- if (parsetree && IsA(parsetree, CreateTableAsStmt) &&
- ((CreateTableAsStmt*)parsetree)->into &&
- online_analyze_enable)
- tblname = (RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel);
+ if (parsetree && online_analyze_enable)
+ {
+ if (IsA(parsetree, CreateTableAsStmt) &&
+ ((CreateTableAsStmt*)parsetree)->into)
+ {
+ tblnames =
+ list_make1((RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel));
+ op = CK_CREATE;
+ }
+ else if (IsA(parsetree, TruncateStmt))
+ {
+ tblnames = list_copy(((TruncateStmt*)parsetree)->relations);
+ op = CK_TRUNCATE;
+ }
+ }
#if PG_VERSION_NUM >= 100000
#define parsetree pstmt
#undef parsetree
#endif
- if (tblname) {
- Oid tblOid = RangeVarGetRelid(tblname, NoLock, true);
+ if (tblnames) {
+ ListCell *l;
- makeAnalyze(tblOid, CMD_INSERT, -1);
+ foreach(l, tblnames)
+ {
+ RangeVar *tblname = (RangeVar*)lfirst(l);
+ Oid tblOid = RangeVarGetRelid(tblname, NoLock, true);
+
+ makeAnalyze(tblOid, op, -1);
+ }
}
}
#endif