From e889d9ab8dfbaba04ac2c180fb873bca86675473 Mon Sep 17 00:00:00 2001 From: Leo-XM-Zeng Date: Mon, 30 Sep 2024 21:42:49 +0200 Subject: [PATCH] Add PG15 support This applies changes to pg_ruleutils_15.c that are identical to the ones that we already made to the PG16 and PG17 versions of these files. It also notably removes tests involving the psql \bind meta-command, because those meta-commands are unsupported by PG15 its psql. This is acceptable because we Other than that this mainly adds a bunch of #if PG_VERSION_NUM >= 160000 preprocessor statements in places where APIs diverge between versions. --- .github/workflows/build_and_test.yaml | 2 +- src/pgduckdb_detoast.cpp | 2 ++ src/pgduckdb_hooks.cpp | 12 +++++++++++ src/pgduckdb_planner.cpp | 4 ++++ src/utility/copy.cpp | 25 ++++++++++++++++++++++- src/vendor/pg_ruleutils_15.c | 23 ++++++++++++++------- test/regression/expected/basic.out | 22 -------------------- test/regression/expected/type_support.out | 2 +- test/regression/sql/basic.sql | 3 --- test/regression/sql/type_support.sql | 2 +- 10 files changed, 61 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index f3c4673e..126184a6 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -34,7 +34,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - version: [REL_16_STABLE, REL_17_STABLE] + version: [REL_15_STABLE, REL_16_STABLE, REL_17_STABLE] runs-on: ${{ matrix.os }} steps: diff --git a/src/pgduckdb_detoast.cpp b/src/pgduckdb_detoast.cpp index d6440760..665b7640 100644 --- a/src/pgduckdb_detoast.cpp +++ b/src/pgduckdb_detoast.cpp @@ -3,7 +3,9 @@ extern "C" { #include "postgres.h" #include "pg_config.h" +#if PG_VERSION_NUM >= 160000 #include "varatt.h" +#endif #ifdef USE_LZ4 #include diff --git a/src/pgduckdb_hooks.cpp b/src/pgduckdb_hooks.cpp index aa92a764..486c58af 100644 --- a/src/pgduckdb_hooks.cpp +++ b/src/pgduckdb_hooks.cpp @@ -52,7 +52,11 @@ ContainsDuckdbFunctions(Node *node, void *context) { if (IsA(node, Query)) { Query *query = (Query *)node; + #if PG_VERSION_NUM >= 160000 return query_tree_walker(query, ContainsDuckdbFunctions, context, 0); + #else + return query_tree_walker(query, (bool (*)()) ((void *) ContainsDuckdbFunctions), context, 0); + #endif } if (IsA(node, FuncExpr)) { @@ -62,12 +66,20 @@ ContainsDuckdbFunctions(Node *node, void *context) { } } +#if PG_VERSION_NUM >= 160000 return expression_tree_walker(node, ContainsDuckdbFunctions, context); +#else + return expression_tree_walker(node, (bool (*)()) ((void *) ContainsDuckdbFunctions), context); +#endif } static bool NeedsDuckdbExecution(Query *query) { +#if PG_VERSION_NUM >= 160000 return query_tree_walker(query, ContainsDuckdbFunctions, NULL, 0); +#else + return query_tree_walker(query, (bool (*)()) ((void *) ContainsDuckdbFunctions), NULL, 0); +#endif } static bool diff --git a/src/pgduckdb_planner.cpp b/src/pgduckdb_planner.cpp index 03df8aab..d01d9798 100644 --- a/src/pgduckdb_planner.cpp +++ b/src/pgduckdb_planner.cpp @@ -33,7 +33,9 @@ PlanQuery(Query *parse, ParamListInfo bound_params) { glob->subroots = NIL; glob->rewindPlanIDs = NULL; glob->finalrtable = NIL; +#if PG_VERSION_NUM >= 160000 glob->finalrteperminfos = NIL; +#endif glob->finalrowmarks = NIL; glob->resultRelations = NIL; glob->appendRelations = NIL; @@ -171,7 +173,9 @@ DuckdbPlanNode(Query *parse, int cursor_options, ParamListInfo bound_params) { result->parallelModeNeeded = false; result->planTree = duckdb_plan; result->rtable = NULL; +#if PG_VERSION_NUM >= 160000 result->permInfos = NULL; +#endif result->resultRelations = NULL; result->appendRelations = NULL; result->subplans = NIL; diff --git a/src/utility/copy.cpp b/src/utility/copy.cpp index 6bb480c7..836827d4 100644 --- a/src/utility/copy.cpp +++ b/src/utility/copy.cpp @@ -30,7 +30,11 @@ static constexpr char r2_filename_prefix[] = "r2://"; static bool CreateRelationCopyParseState(ParseState *pstate, const CopyStmt *stmt, List **vars, int stmt_location, int stmt_len) { ParseNamespaceItem *nsitem; +#if PG_VERSION_NUM >= 160000 RTEPermissionInfo *perminfo; +#else + RangeTblEntry *rte; +#endif TupleDesc tuple_desc; List *attnums; Relation rel; @@ -43,12 +47,18 @@ CreateRelationCopyParseState(ParseState *pstate, const CopyStmt *stmt, List **va nsitem = addRangeTableEntryForRelation(pstate, rel, AccessShareLock, NULL, false, false); +#if PG_VERSION_NUM >= 160000 perminfo = nsitem->p_perminfo; perminfo->requiredPerms = ACL_SELECT; +#else + rte = nsitem->p_rte; + rte->requiredPerms = ACL_SELECT; +#endif tuple_desc = RelationGetDescr(rel); attnums = CopyGetAttnums(tuple_desc, rel, stmt->attlist); +#if PG_VERSION_NUM >= 160000 foreach_int(cur, attnums) { int attno; Bitmapset **bms; @@ -59,12 +69,25 @@ CreateRelationCopyParseState(ParseState *pstate, const CopyStmt *stmt, List **va lappend(*vars, makeVar(1, cur, tuple_desc->attrs[cur - 1].atttypid, tuple_desc->attrs[cur - 1].atttypmod, tuple_desc->attrs[cur - 1].attcollation, 0)); } +#else + foreach_int(cur, attnums) + { + int attno = cur - FirstLowInvalidHeapAttributeNumber; + rte->selectedCols = bms_add_member(rte->selectedCols, attno); + } +#endif +#if PG_VERSION_NUM >= 160000 if (!ExecCheckPermissions(pstate->p_rtable, list_make1(perminfo), false)) { ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("(Duckdb) Failed Permission \"%s\"", RelationGetRelationName(rel)))); } - +#else + if (!ExecCheckRTPerms(pstate->p_rtable, true)) { + ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("(Duckdb) Failed Permission \"%s\"", RelationGetRelationName(rel)))); + } +#endif table_close(rel, AccessShareLock); /* diff --git a/src/vendor/pg_ruleutils_15.c b/src/vendor/pg_ruleutils_15.c index 361bf09d..da080362 100644 --- a/src/vendor/pg_ruleutils_15.c +++ b/src/vendor/pg_ruleutils_15.c @@ -1,20 +1,18 @@ /*------------------------------------------------------------------------- * - * ruleutils.c + * pg_ruleutils_15.c * Functions to convert stored expressions/querytrees back to * source text * * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * - * IDENTIFICATION - * src/backend/utils/adt/ruleutils.c - * *------------------------------------------------------------------------- */ #include "postgres.h" +#if PG_VERSION_NUM >= 150000 && PG_VERSION_NUM < 160000 + #include #include #include @@ -67,13 +65,18 @@ #include "utils/lsyscache.h" #include "utils/partcache.h" #include "utils/rel.h" -#include "utils/ruleutils.h" +#include "pgduckdb/vendor/pg_ruleutils.h" #include "utils/snapmgr.h" #include "utils/syscache.h" #include "utils/typcache.h" #include "utils/varlena.h" #include "utils/xml.h" +#include "pgduckdb/pgduckdb_ruleutils.h" + +#include "pgduckdb/utility/rename_ruleutils.h" + + /* ---------- * Pretty formatting constants * ---------- @@ -94,7 +97,7 @@ /* Standard conversion of a "bool pretty" option to detailed flags */ #define GET_PRETTY_FLAGS(pretty) \ ((pretty) ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) \ - : PRETTYFLAG_INDENT) + : 0) /* Default line length for pretty-print wrapping: 0 means wrap always */ #define WRAP_COLUMN_DEFAULT 0 @@ -11994,6 +11997,10 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes, Oid *p_true_typeids; bool force_qualify = false; + result = pgduckdb_function_name(funcid); + if (result) + return result; + proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); if (!HeapTupleIsValid(proctup)) elog(ERROR, "cache lookup failed for function %u", funcid); @@ -12429,3 +12436,5 @@ get_range_partbound_string(List *bound_datums) return buf->data; } + +#endif diff --git a/test/regression/expected/basic.out b/test/regression/expected/basic.out index ed181bea..fc407602 100644 --- a/test/regression/expected/basic.out +++ b/test/regression/expected/basic.out @@ -16,28 +16,6 @@ SELECT a, COUNT(*) FROM t WHERE a > 5 GROUP BY a ORDER BY a; 9 | 100 (4 rows) -select COUNT(*) from t \bind \g - count -------- - 1000 -(1 row) - -select a, COUNT(*) from t WHERE a > $1 GROUP BY a ORDER BY a \bind 5 \g - a | count ----+------- - 6 | 100 - 7 | 100 - 8 | 100 - 9 | 100 -(4 rows) - -\bind 7 \g - a | count ----+------- - 8 | 100 - 9 | 100 -(2 rows) - SET duckdb.max_threads_per_query to 4; SELECT COUNT(*) FROM t; count diff --git a/test/regression/expected/type_support.out b/test/regression/expected/type_support.out index 55fd1251..bdd60c93 100644 --- a/test/regression/expected/type_support.out +++ b/test/regression/expected/type_support.out @@ -254,7 +254,7 @@ SELECT * FROM json_tbl; -- REGCLASSOID CREATE TABLE regclass_tbl (a REGCLASS); -INSERT INTO regclass_tbl VALUES (42), (3_000_000_000); +INSERT INTO regclass_tbl VALUES (42), (3000000000); SELECT * FROM regclass_tbl; a ------------ diff --git a/test/regression/sql/basic.sql b/test/regression/sql/basic.sql index b9b3f5e9..d32d3f0a 100644 --- a/test/regression/sql/basic.sql +++ b/test/regression/sql/basic.sql @@ -6,9 +6,6 @@ SET client_min_messages to 'DEBUG1'; SELECT COUNT(*) FROM t; SELECT a, COUNT(*) FROM t WHERE a > 5 GROUP BY a ORDER BY a; -select COUNT(*) from t \bind \g -select a, COUNT(*) from t WHERE a > $1 GROUP BY a ORDER BY a \bind 5 \g -\bind 7 \g SET duckdb.max_threads_per_query to 4; diff --git a/test/regression/sql/type_support.sql b/test/regression/sql/type_support.sql index 983b813e..9e56e616 100644 --- a/test/regression/sql/type_support.sql +++ b/test/regression/sql/type_support.sql @@ -133,7 +133,7 @@ SELECT * FROM json_tbl; -- REGCLASSOID CREATE TABLE regclass_tbl (a REGCLASS); -INSERT INTO regclass_tbl VALUES (42), (3_000_000_000); +INSERT INTO regclass_tbl VALUES (42), (3000000000); SELECT * FROM regclass_tbl; DROP TABLE chr;