79 #define PGSS_DUMP_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "/pg_stat_statements.stat"
84 #define PGSS_TEXT_FILE PG_STAT_TMP_DIR "/pgss_query_texts.stat"
93 #define USAGE_EXEC(duration) (1.0)
94 #define USAGE_INIT (1.0)
95 #define ASSUMED_MEDIAN_INIT (10.0)
96 #define ASSUMED_LENGTH_INIT 1024
97 #define USAGE_DECREASE_FACTOR (0.99)
98 #define STICKY_DECREASE_FACTOR (0.50)
99 #define USAGE_DEALLOC_PERCENT 5
100 #define IS_STICKY(c) ((c.calls[PGSS_PLAN] + c.calls[PGSS_EXEC]) == 0)
106 #define PGSS_HANDLED_UTILITY(n) (!IsA(n, ExecuteStmt) && \
107 !IsA(n, PrepareStmt))
298 #define pgss_enabled(level) \
299 (!IsParallelWorker() && \
300 (pgss_track == PGSS_TRACK_ALL || \
301 (pgss_track == PGSS_TRACK_TOP && (level) == 0)))
303 #define record_gc_qtexts() \
305 volatile pgssSharedState *s = (volatile pgssSharedState *) pgss; \
306 SpinLockAcquire(&s->mutex); \
308 SpinLockRelease(&s->mutex); \
330 const char *query_string,
336 uint64 count,
bool execute_once);
344 static void pgss_store(
const char *query, uint64 queryId,
345 int query_location,
int query_len,
347 double total_time, uint64 rows,
359 static bool qtext_store(
const char *query,
int query_len,
360 Size *query_offset,
int *gc_count);
363 char *buffer,
Size buffer_size);
368 int query_loc,
int *query_len_p);
401 "Sets the maximum number of statements tracked by pg_stat_statements.",
414 "Selects which statements are tracked by pg_stat_statements.",
426 "Selects whether utility commands are tracked by pg_stat_statements.",
437 "Selects whether planning duration is tracked by pg_stat_statements.",
448 "Save pg_stat_statements statistics across server shutdowns.",
607 buffer = (
char *)
palloc(buffer_size);
609 if (fread(&header,
sizeof(
uint32), 1, file) != 1 ||
610 fread(&pgver,
sizeof(
uint32), 1, file) != 1 ||
611 fread(&num,
sizeof(
int32), 1, file) != 1)
618 for (
i = 0;
i < num;
i++)
624 if (fread(&temp,
sizeof(
pgssEntry), 1, file) != 1)
635 buffer =
repalloc(buffer, buffer_size);
691 errmsg(
"could not read file \"%s\": %m",
696 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
697 errmsg(
"ignoring invalid data in file \"%s\"",
703 errmsg(
"could not write file \"%s\": %m",
731 char *qbuffer = NULL;
732 Size qbuffer_size = 0;
758 if (fwrite(&num_entries,
sizeof(
int32), 1, file) != 1)
774 qbuffer, qbuffer_size);
779 if (fwrite(entry,
sizeof(
pgssEntry), 1, file) != 1 ||
780 fwrite(qstr, 1,
len + 1, file) !=
len + 1)
814 errmsg(
"could not write file \"%s\": %m",
844 query->queryId = UINT64CONST(0);
876 const char *query_string,
896 &&
parse->queryId != UINT64CONST(0))
939 memset(&walusage, 0,
sizeof(
WalUsage));
944 parse->stmt_location,
1052 if (queryId != UINT64CONST(0) && queryDesc->
totaltime &&
1091 uint64 saved_queryId = pstmt->
queryId;
1093 int saved_stmt_len = pstmt->
stmt_len;
1110 pstmt->
queryId = UINT64CONST(0);
1144 context, params, queryEnv,
1148 context, params, queryEnv,
1175 rows = (qc && (qc->
commandTag == CMDTAG_COPY ||
1178 qc->
commandTag == CMDTAG_REFRESH_MATERIALIZED_VIEW)) ?
1186 memset(&walusage, 0,
sizeof(
WalUsage));
1191 saved_stmt_location,
1205 context, params, queryEnv,
1209 context, params, queryEnv,
1227 int query_location,
int query_len,
1229 double total_time, uint64 rows,
1237 char *norm_query = NULL;
1250 if (queryId == UINT64CONST(0))
1267 key.queryid = queryId;
1300 stored =
qtext_store(norm_query ? norm_query : query, query_len,
1301 &query_offset, &gc_count);
1322 stored =
qtext_store(norm_query ? norm_query : query, query_len,
1323 &query_offset, NULL);
1355 e->counters.calls[kind] += 1;
1356 e->counters.total_time[kind] += total_time;
1358 if (
e->counters.calls[kind] == 1)
1360 e->counters.min_time[kind] = total_time;
1361 e->counters.max_time[kind] = total_time;
1362 e->counters.mean_time[kind] = total_time;
1370 double old_mean =
e->counters.mean_time[kind];
1372 e->counters.mean_time[kind] +=
1373 (total_time - old_mean) /
e->counters.calls[kind];
1374 e->counters.sum_var_time[kind] +=
1375 (total_time - old_mean) * (total_time -
e->counters.mean_time[kind]);
1378 if (
e->counters.min_time[kind] > total_time)
1379 e->counters.min_time[kind] = total_time;
1380 if (
e->counters.max_time[kind] < total_time)
1381 e->counters.max_time[kind] = total_time;
1383 e->counters.rows += rows;
1400 e->counters.wal_fpi += walusage->
wal_fpi;
1401 e->counters.wal_bytes += walusage->
wal_bytes;
1408 e->counters.jit_deform_count++;
1412 e->counters.jit_inlining_count++;
1416 e->counters.jit_optimization_count++;
1420 e->counters.jit_emission_count++;
1466 #define PG_STAT_STATEMENTS_COLS_V1_0 14
1467 #define PG_STAT_STATEMENTS_COLS_V1_1 18
1468 #define PG_STAT_STATEMENTS_COLS_V1_2 19
1469 #define PG_STAT_STATEMENTS_COLS_V1_3 23
1470 #define PG_STAT_STATEMENTS_COLS_V1_8 32
1471 #define PG_STAT_STATEMENTS_COLS_V1_9 33
1472 #define PG_STAT_STATEMENTS_COLS_V1_10 43
1473 #define PG_STAT_STATEMENTS_COLS_V1_11 45
1474 #define PG_STAT_STATEMENTS_COLS 45
1567 bool is_allowed_role =
false;
1568 char *qbuffer = NULL;
1569 Size qbuffer_size = 0;
1584 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1585 errmsg(
"pg_stat_statements must be loaded via shared_preload_libraries")));
1598 elog(
ERROR,
"incorrect number of output arguments");
1603 elog(
ERROR,
"incorrect number of output arguments");
1608 elog(
ERROR,
"incorrect number of output arguments");
1612 elog(
ERROR,
"incorrect number of output arguments");
1616 elog(
ERROR,
"incorrect number of output arguments");
1620 elog(
ERROR,
"incorrect number of output arguments");
1624 elog(
ERROR,
"incorrect number of output arguments");
1628 elog(
ERROR,
"incorrect number of output arguments");
1631 elog(
ERROR,
"incorrect number of output arguments");
1689 if (qbuffer == NULL ||
1709 memset(nulls, 0,
sizeof(nulls));
1716 if (is_allowed_role || entry->
key.
userid == userid)
1804 if (tmp.
calls[kind] > 1)
1887 #define PG_STAT_STATEMENTS_INFO_COLS 2
1902 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1903 errmsg(
"pg_stat_statements must be loaded via shared_preload_libraries")));
1907 elog(
ERROR,
"return type must be a row type");
1995 double l_usage = (*(
pgssEntry *
const *) lhs)->counters.usage;
1996 double r_usage = (*(
pgssEntry *
const *) rhs)->counters.usage;
1998 if (l_usage < r_usage)
2000 else if (l_usage > r_usage)
2043 entries[
i++] = entry;
2064 if (nvalidtexts > 0)
2071 nvictims =
Min(nvictims,
i);
2073 for (
i = 0;
i < nvictims;
i++)
2108 Size *query_offset,
int *gc_count)
2122 s->
extent += query_len + 1;
2129 *query_offset = off;
2148 if (
pg_pwrite(
fd, query, query_len, off) != query_len)
2169 errmsg(
"could not write file \"%s\": %m",
2209 if (errno != ENOENT)
2212 errmsg(
"could not read file \"%s\": %m",
2222 errmsg(
"could not stat file \"%s\": %m",
2236 (
errcode(ERRCODE_OUT_OF_MEMORY),
2238 errdetail(
"Could not allocate enough memory to read file \"%s\".",
2262 if (
read(
fd,
buf + nread, toread) != toread)
2267 errmsg(
"could not read file \"%s\": %m",
2281 *buffer_size = nread;
2293 char *buffer,
Size buffer_size)
2299 if (query_len < 0 ||
2300 query_offset + query_len >= buffer_size)
2303 if (buffer[query_offset + query_len] !=
'\0')
2306 return buffer + query_offset;
2335 if ((uint64) extent < (uint64) 512 *
pgss_max)
2394 if (qbuffer == NULL)
2408 errmsg(
"could not write file \"%s\": %m",
2434 if (fwrite(qry, 1, query_len + 1, qfile) != query_len + 1)
2438 errmsg(
"could not write file \"%s\": %m",
2445 extent += query_len + 1;
2453 if (
ftruncate(fileno(qfile), extent) != 0)
2456 errmsg(
"could not truncate file \"%s\": %m",
2463 errmsg(
"could not write file \"%s\": %m",
2469 elog(
DEBUG1,
"pgss gc of queries file shrunk size from %zu to %zu",
2522 errmsg(
"could not recreate file \"%s\": %m",
2557 long num_remove = 0;
2562 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2563 errmsg(
"pg_stat_statements must be loaded via shared_preload_libraries")));
2568 if (userid != 0 && dbid != 0 && queryid != UINT64CONST(0))
2572 key.userid = userid;
2574 key.queryid = queryid;
2579 key.toplevel =
false;
2585 key.toplevel =
true;
2590 else if (userid != 0 || dbid != 0 || queryid != UINT64CONST(0))
2596 if ((!userid || entry->
key.
userid == userid) &&
2597 (!dbid || entry->
key.
dbid == dbid) &&
2617 if (num_entries != num_remove)
2643 errmsg(
"could not create file \"%s\": %m",
2652 errmsg(
"could not truncate file \"%s\": %m",
2687 int query_loc,
int *query_len_p)
2690 int query_len = *query_len_p;
2715 norm_query =
palloc(norm_query_buflen + 1);
2732 len_to_wrt = off - last_off;
2733 len_to_wrt -= last_tok_len;
2736 memcpy(norm_query + n_quer_loc, query + quer_loc, len_to_wrt);
2737 n_quer_loc += len_to_wrt;
2740 n_quer_loc +=
sprintf(norm_query + n_quer_loc,
"$%d",
2743 quer_loc = off + tok_len;
2745 last_tok_len = tok_len;
2752 len_to_wrt = query_len - quer_loc;
2755 memcpy(norm_query + n_quer_loc, query + quer_loc, len_to_wrt);
2756 n_quer_loc += len_to_wrt;
2758 Assert(n_quer_loc <= norm_query_buflen);
2759 norm_query[n_quer_loc] =
'\0';
2761 *query_len_p = n_quer_loc;
2833 if (loc <= last_loc)
2851 if (query[loc] ==
'-')
bool has_privs_of_role(Oid member, Oid role)
void(* post_parse_analyze_hook_type)(ParseState *pstate, Query *query, JumbleState *jstate)
Datum numeric_in(PG_FUNCTION_ARGS)
TimestampTz GetCurrentTimestamp(void)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
elog(ERROR, "%s: %s", p2, msg)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void hash_seq_term(HASH_SEQ_STATUS *status)
long hash_get_num_entries(HTAB *hashp)
Size hash_estimate_size(long num_entries, Size entrysize)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errcode_for_file_access(void)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
ExecutorEnd_hook_type ExecutorEnd_hook
ExecutorFinish_hook_type ExecutorFinish_hook
ExecutorStart_hook_type ExecutorStart_hook
void standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
void standard_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
ExecutorRun_hook_type ExecutorRun_hook
void standard_ExecutorEnd(QueryDesc *queryDesc)
void standard_ExecutorFinish(QueryDesc *queryDesc)
void(* ExecutorRun_hook_type)(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
void(* ExecutorFinish_hook_type)(QueryDesc *queryDesc)
void(* ExecutorStart_hook_type)(QueryDesc *queryDesc, int eflags)
void(* ExecutorEnd_hook_type)(QueryDesc *queryDesc)
FILE * AllocateFile(const char *name, const char *mode)
int durable_rename(const char *oldfile, const char *newfile, int elevel)
int CloseTransientFile(int fd)
int OpenTransientFile(const char *fileName, int fileFlags)
Datum Int64GetDatum(int64 X)
#define PG_GETARG_INT64(n)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_DATUM(x)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
void DefineCustomEnumVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, const struct config_enum_entry *options, GucContext context, int flags, GucEnumCheckHook check_hook, GucEnumAssignHook assign_hook, GucShowHook show_hook)
void DefineCustomBoolVariable(const char *name, const char *short_desc, const char *long_desc, bool *valueAddr, bool bootValue, GucContext context, int flags, GucBoolCheckHook check_hook, GucBoolAssignHook assign_hook, GucShowHook show_hook)
void MarkGUCPrefixReserved(const char *className)
void DefineCustomIntVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, int minValue, int maxValue, GucContext context, int flags, GucIntCheckHook check_hook, GucIntAssignHook assign_hook, GucShowHook show_hook)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_SUBTRACT(x, y)
#define INSTR_TIME_GET_MILLISEC(t)
void InstrEndLoop(Instrumentation *instr)
Instrumentation * InstrAlloc(int n, int instrument_options, bool async_mode)
void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, const WalUsage *sub)
BufferUsage pgBufferUsage
void BufferUsageAccumDiff(BufferUsage *dst, const BufferUsage *add, const BufferUsage *sub)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
void(* shmem_startup_hook_type)(void)
shmem_startup_hook_type shmem_startup_hook
void RequestAddinShmemSpace(Size size)
PGDLLIMPORT const ScanKeywordList ScanKeywords
Assert(fmt[strlen(fmt) - 1] !='\n')
LWLockPadded * GetNamedLWLockTranche(const char *tranche_name)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
void LWLockRelease(LWLock *lock)
char * pg_any_to_server(const char *s, int len, int encoding)
int GetDatabaseEncoding(void)
void pfree(void *pointer)
void * repalloc(void *pointer, Size size)
void(* shmem_request_hook_type)(void)
shmem_request_hook_type shmem_request_hook
bool process_shared_preload_libraries_in_progress
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
post_parse_analyze_hook_type post_parse_analyze_hook
static int entry_cmp(const void *lhs, const void *rhs)
#define PG_STAT_STATEMENTS_COLS_V1_0
static planner_hook_type prev_planner_hook
static bool pgss_track_planning
#define ASSUMED_MEDIAN_INIT
#define PG_STAT_STATEMENTS_INFO_COLS
PG_FUNCTION_INFO_V1(pg_stat_statements_reset)
static ExecutorRun_hook_type prev_ExecutorRun
struct pgssSharedState pgssSharedState
static void pgss_store(const char *query, uint64 queryId, int query_location, int query_len, pgssStoreKind kind, double total_time, uint64 rows, const BufferUsage *bufusage, const WalUsage *walusage, const struct JitInstrumentation *jitusage, JumbleState *jstate)
static void pg_stat_statements_internal(FunctionCallInfo fcinfo, pgssVersion api_version, bool showtext)
#define record_gc_qtexts()
Datum pg_stat_statements_reset_1_7(PG_FUNCTION_ARGS)
static PlannedStmt * pgss_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams)
static int exec_nested_level
static void gc_qtexts(void)
#define PG_STAT_STATEMENTS_COLS_V1_8
static int comp_location(const void *a, const void *b)
Datum pg_stat_statements_1_11(PG_FUNCTION_ARGS)
#define PG_STAT_STATEMENTS_COLS
Datum pg_stat_statements_1_9(PG_FUNCTION_ARGS)
static int plan_nested_level
static char * qtext_fetch(Size query_offset, int query_len, char *buffer, Size buffer_size)
#define USAGE_DEALLOC_PERCENT
static bool qtext_store(const char *query, int query_len, Size *query_offset, int *gc_count)
Datum pg_stat_statements_1_10(PG_FUNCTION_ARGS)
#define USAGE_EXEC(duration)
#define PG_STAT_STATEMENTS_COLS_V1_11
#define STICKY_DECREASE_FACTOR
static const struct config_enum_entry track_options[]
#define PG_STAT_STATEMENTS_COLS_V1_2
Datum pg_stat_statements_reset(PG_FUNCTION_ARGS)
static void pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
static char * qtext_load_file(Size *buffer_size)
static post_parse_analyze_hook_type prev_post_parse_analyze_hook
static bool need_gc_qtexts(void)
#define pgss_enabled(level)
static shmem_startup_hook_type prev_shmem_startup_hook
static shmem_request_hook_type prev_shmem_request_hook
static void entry_reset(Oid userid, Oid dbid, uint64 queryid)
static void pgss_shmem_request(void)
static void pgss_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
#define ASSUMED_LENGTH_INIT
#define PG_STAT_STATEMENTS_COLS_V1_3
static Size pgss_memsize(void)
static void pgss_shmem_startup(void)
struct pgssGlobalStats pgssGlobalStats
static const uint32 PGSS_PG_MAJOR_VERSION
Datum pg_stat_statements_1_2(PG_FUNCTION_ARGS)
struct pgssEntry pgssEntry
#define USAGE_DECREASE_FACTOR
static ExecutorStart_hook_type prev_ExecutorStart
Datum pg_stat_statements(PG_FUNCTION_ARGS)
Datum pg_stat_statements_info(PG_FUNCTION_ARGS)
static void entry_dealloc(void)
#define PG_STAT_STATEMENTS_COLS_V1_10
static pgssSharedState * pgss
Datum pg_stat_statements_1_3(PG_FUNCTION_ARGS)
static void pgss_ExecutorFinish(QueryDesc *queryDesc)
static ProcessUtility_hook_type prev_ProcessUtility
#define PG_STAT_STATEMENTS_COLS_V1_1
Datum pg_stat_statements_1_8(PG_FUNCTION_ARGS)
static void pgss_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate)
struct pgssHashKey pgssHashKey
static pgssEntry * entry_alloc(pgssHashKey *key, Size query_offset, int query_len, int encoding, bool sticky)
static void fill_in_constant_lengths(JumbleState *jstate, const char *query, int query_loc)
static bool pgss_track_utility
static ExecutorEnd_hook_type prev_ExecutorEnd
#define PG_STAT_STATEMENTS_COLS_V1_9
#define PGSS_HANDLED_UTILITY(n)
static void pgss_ExecutorEnd(QueryDesc *queryDesc)
static char * generate_normalized_query(JumbleState *jstate, const char *query, int query_loc, int *query_len_p)
static void pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
static const uint32 PGSS_FILE_HEADER
static void pgss_shmem_shutdown(int code, Datum arg)
static ExecutorFinish_hook_type prev_ExecutorFinish
#define PG_VALID_BE_ENCODING(_enc)
static core_yyscan_t yyscanner
planner_hook_type planner_hook
PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams)
PlannedStmt *(* planner_hook_type)(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams)
#define qsort(a, b, c, d)
#define Int64GetDatumFast(X)
#define Float8GetDatumFast(X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
static int fd(const char *x, int i)
const char * CleanQuerytext(const char *query, int *location, int *len)
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, const ScanKeywordList *keywordlist, const uint16 *keyword_tokens)
void scanner_finish(core_yyscan_t yyscanner)
PGDLLIMPORT const uint16 ScanKeywordTokens[]
int core_yylex(core_YYSTYPE *yylval_param, YYLTYPE *yylloc_param, core_yyscan_t yyscanner)
Size add_size(Size s1, Size s2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
HTAB * ShmemInitHash(const char *name, long init_size, long max_size, HASHCTL *infoP, int hash_flags)
#define SpinLockInit(lock)
#define SpinLockRelease(lock)
#define SpinLockAcquire(lock)
int64 shared_blks_dirtied
instr_time temp_blk_write_time
instr_time blk_write_time
instr_time temp_blk_read_time
int64 shared_blks_written
int64 calls[PGSS_NUMKIND]
int64 shared_blks_written
double jit_generation_time
double min_time[PGSS_NUMKIND]
double sum_var_time[PGSS_NUMKIND]
double temp_blk_read_time
double jit_optimization_time
int64 jit_optimization_count
double total_time[PGSS_NUMKIND]
double max_time[PGSS_NUMKIND]
int64 shared_blks_dirtied
double mean_time[PGSS_NUMKIND]
double temp_blk_write_time
struct JitContext * es_jit
uint64 es_total_processed
MemoryContext es_query_cxt
instr_time generation_counter
instr_time optimization_counter
instr_time deform_counter
instr_time emission_counter
instr_time inlining_counter
int highest_extern_param_id
const char * p_sourcetext
PlannedStmt * plannedstmt
struct Instrumentation * totaltime
Tuplestorestate * setResult
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
void standard_ProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
ProcessUtility_hook_type ProcessUtility_hook
void(* ProcessUtility_hook_type)(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
static Datum TimestampTzGetDatum(TimestampTz X)