From 82858ca8fe9986e7da76de9151d81a263f4e8350 Mon Sep 17 00:00:00 2001 From: Halil Ozan Akgul Date: Fri, 13 Aug 2021 19:48:50 +0300 Subject: [PATCH] Introduces ProcessUtility macros for readOnlyTree parameter New macros: standard_ProcessUtility_compat, ProcessUtility_compat, ColumnarProcessUtility_compat, PrevProcessUtilityHook_compat The functions now have a new bool parameter: readOnlyTree These new macros give us the ability to use this new parameter for PG14 and it doesn't give the parameter for previous versions In multi_ProcessUtility and ColumnarProcessUtility, before doing anything else, we check if readOnlyTree parameter is true and create a copy of pstmt Existing readOnlyTree parameters are set to false since we already handle the read only case at multi_ProcessUtility and ColumnarProcessUtility Relevant PG commit: 7c337b6b527b7052e6a751f966d5734c56f668b5 --- src/backend/columnar/columnar_tableam.c | 18 ++++++++- .../distributed/commands/utility_hook.c | 38 ++++++++++++------- .../columnar/columnar_version_compat.h | 8 ++++ .../distributed/commands/utility_hook.h | 3 ++ src/include/distributed/version_compat.h | 7 ++++ 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/backend/columnar/columnar_tableam.c b/src/backend/columnar/columnar_tableam.c index 9c7c42bf4..7577deb05 100644 --- a/src/backend/columnar/columnar_tableam.c +++ b/src/backend/columnar/columnar_tableam.c @@ -118,6 +118,9 @@ static void ColumnarTableAMObjectAccessHook(ObjectAccessType access, Oid classId void *arg); static void ColumnarProcessUtility(PlannedStmt *pstmt, const char *queryString, +#if PG_VERSION_NUM >= PG_VERSION_14 + bool readOnlyTree, +#endif ProcessUtilityContext context, ParamListInfo params, struct QueryEnvironment *queryEnv, @@ -2006,12 +2009,23 @@ ColumnarTableAMObjectAccessHook(ObjectAccessType access, Oid classId, Oid object static void ColumnarProcessUtility(PlannedStmt *pstmt, const char *queryString, +#if PG_VERSION_NUM >= PG_VERSION_14 + bool readOnlyTree, +#endif ProcessUtilityContext context, ParamListInfo params, struct QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletionCompat *completionTag) { + +#if PG_VERSION_NUM >= PG_VERSION_14 + if (readOnlyTree) + { + pstmt = copyObject(pstmt); + } +#endif + Node *parsetree = pstmt->utilityStmt; if (IsA(parsetree, IndexStmt)) @@ -2034,8 +2048,8 @@ ColumnarProcessUtility(PlannedStmt *pstmt, RelationClose(rel); } - PrevProcessUtilityHook(pstmt, queryString, context, - params, queryEnv, dest, completionTag); + PrevProcessUtilityHook_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); } diff --git a/src/backend/distributed/commands/utility_hook.c b/src/backend/distributed/commands/utility_hook.c index 26b162cd1..82837ba59 100644 --- a/src/backend/distributed/commands/utility_hook.c +++ b/src/backend/distributed/commands/utility_hook.c @@ -111,8 +111,8 @@ ProcessUtilityParseTree(Node *node, const char *queryString, ProcessUtilityConte plannedStmt->commandType = CMD_UTILITY; plannedStmt->utilityStmt = node; - ProcessUtility(plannedStmt, queryString, context, params, NULL, dest, - completionTag); + ProcessUtility_compat(plannedStmt, queryString, false, context, params, NULL, dest, + completionTag); } @@ -128,13 +128,25 @@ ProcessUtilityParseTree(Node *node, const char *queryString, ProcessUtilityConte void multi_ProcessUtility(PlannedStmt *pstmt, const char *queryString, +#if PG_VERSION_NUM >= PG_VERSION_14 + bool readOnlyTree, +#endif ProcessUtilityContext context, ParamListInfo params, struct QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletionCompat *completionTag) { - Node *parsetree = pstmt->utilityStmt; + Node *parsetree; + +#if PG_VERSION_NUM >= PG_VERSION_14 + if (readOnlyTree) + { + pstmt = copyObject(pstmt); + } +#endif + + parsetree = pstmt->utilityStmt; if (IsA(parsetree, TransactionStmt) || IsA(parsetree, LockStmt) || @@ -154,8 +166,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, * that state. Since we never need to intercept transaction statements, * skip our checks and immediately fall into standard_ProcessUtility. */ - standard_ProcessUtility(pstmt, queryString, context, - params, queryEnv, dest, completionTag); + standard_ProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); return; } @@ -173,8 +185,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, * Ensure that utility commands do not behave any differently until CREATE * EXTENSION is invoked. */ - standard_ProcessUtility(pstmt, queryString, context, - params, queryEnv, dest, completionTag); + standard_ProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); return; } @@ -205,8 +217,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, PG_TRY(); { - standard_ProcessUtility(pstmt, queryString, context, - params, queryEnv, dest, completionTag); + standard_ProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); StoredProcedureLevel -= 1; } @@ -229,8 +241,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, PG_TRY(); { - standard_ProcessUtility(pstmt, queryString, context, - params, queryEnv, dest, completionTag); + standard_ProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); DoBlockLevel -= 1; } @@ -566,8 +578,8 @@ ProcessUtilityInternal(PlannedStmt *pstmt, citusCanBeUpdatedToAvailableVersion = !InstalledAndAvailableVersionsSame(); } - standard_ProcessUtility(pstmt, queryString, context, - params, queryEnv, dest, completionTag); + standard_ProcessUtility_compat(pstmt, queryString, false, context, + params, queryEnv, dest, completionTag); /* * if we are running ALTER EXTENSION citus UPDATE (to "") command, we may need diff --git a/src/include/columnar/columnar_version_compat.h b/src/include/columnar/columnar_version_compat.h index 29a0a42d5..36b7f5068 100644 --- a/src/include/columnar/columnar_version_compat.h +++ b/src/include/columnar/columnar_version_compat.h @@ -13,7 +13,15 @@ #define COLUMNAR_COMPAT_H #if PG_VERSION_NUM >= PG_VERSION_14 +#define ColumnarProcessUtility_compat(a, b, c, d, e, f, g, h) \ + ColumnarProcessUtility(a, b, c, d, e, f, g, h) +#define PrevProcessUtilityHook_compat(a, b, c, d, e, f, g, h) \ + PrevProcessUtilityHook(a, b, c, d, e, f, g, h) #else +#define ColumnarProcessUtility_compat(a, b, c, d, e, f, g, h) \ + ColumnarProcessUtility(a, b, d, e, f, g, h) +#define PrevProcessUtilityHook_compat(a, b, c, d, e, f, g, h) \ + PrevProcessUtilityHook(a, b, d, e, f, g, h) #endif #define ACLCHECK_OBJECT_TABLE OBJECT_TABLE diff --git a/src/include/distributed/commands/utility_hook.h b/src/include/distributed/commands/utility_hook.h index 24717986e..22f8a8cf1 100644 --- a/src/include/distributed/commands/utility_hook.h +++ b/src/include/distributed/commands/utility_hook.h @@ -64,6 +64,9 @@ typedef struct DDLJob extern void multi_ProcessUtility(PlannedStmt *pstmt, const char *queryString, +#if PG_VERSION_NUM >= PG_VERSION_14 + bool readOnlyTree, +#endif ProcessUtilityContext context, ParamListInfo params, struct QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletionCompat *completionTag diff --git a/src/include/distributed/version_compat.h b/src/include/distributed/version_compat.h index 588676929..1f97ff901 100644 --- a/src/include/distributed/version_compat.h +++ b/src/include/distributed/version_compat.h @@ -50,6 +50,10 @@ #define IsReindexWithParam_compat(reindex, param) IsReindexWithParam(reindex, param) #define CopyFromState_compat CopyFromState #define BeginCopyFrom_compat(a, b, c, d, e, f, g, h) BeginCopyFrom(a, b, c, d, e, f, g, h) +#define standard_ProcessUtility_compat(a, b, c, d, e, f, g, h) \ + standard_ProcessUtility(a, b, c, d, e, f, g, h) +#define ProcessUtility_compat(a, b, c, d, e, f, g, h) \ + ProcessUtility(a, b, c, d, e, f, g, h) #else #define AlterTableStmtObjType(a) ((a)->relkind) #define F_NEXTVAL_COMPAT F_NEXTVAL_OID @@ -73,6 +77,9 @@ false)) #define CopyFromState_compat CopyState #define BeginCopyFrom_compat(a, b, c, d, e, f, g, h) BeginCopyFrom(a, b, d, e, f, g, h) +#define standard_ProcessUtility_compat(a, b, c, d, e, f, g, h) \ + standard_ProcessUtility(a, b, d, e, f, g, h) +#define ProcessUtility_compat(a, b, c, d, e, f, g, h) ProcessUtility(a, b, d, e, f, g, h) #endif #if PG_VERSION_NUM >= PG_VERSION_13