diff --git a/createas.c b/createas.c index a26bad1..21ca067 100644 --- a/createas.c +++ b/createas.c @@ -11,6 +11,7 @@ */ #include "postgres.h" +#include "access/xact.h" #include "access/genam.h" #include "access/heapam.h" #include "catalog/dependency.h" @@ -70,6 +71,10 @@ static Bitmapset *get_primary_key_attnos_from_query(Query *query, List **constra static void StoreImmvQuery(Oid viewOid, Query *viewQuery); +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM < 140000) +static bool CreateTableAsRelExists(CreateTableAsStmt *ctas); +#endif + /* * ExecCreateImmv -- execute a create_immv() function * @@ -286,7 +291,11 @@ rewriteQueryForIMMV(Query *query, List *colNames) { rewritten->groupClause = transformDistinctClause(NULL, &rewritten->targetList, rewritten->sortClause, false); +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) fn = makeFuncCall(list_make1(makeString("count")), NIL, COERCE_EXPLICIT_CALL, -1); +#else + fn = makeFuncCall(list_make1(makeString("count")), NIL, -1); +#endif fn->agg_star = true; node = ParseFuncOrColumn(pstate, fn->funcname, NIL, NULL, fn, false, -1); @@ -869,8 +878,9 @@ get_primary_key_attnos_from_query(Query *query, List **constraintList, bool is_c int i; Bitmapset *keys = NULL; Relids rels_in_from; +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) PlannerInfo root; - +#endif /* * Collect primary key attributes from all tables used in query. The key attributes @@ -939,8 +949,11 @@ get_primary_key_attnos_from_query(Query *query, List **constraintList, bool is_c } /* Collect relations appearing in the FROM clause */ +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) rels_in_from = pull_varnos_of_level(&root, (Node *)query->jointree, 0); - +#else + rels_in_from = pull_varnos_of_level((Node *)query->jointree, 0); +#endif /* * Check if all key attributes of relations in FROM are appearing in the target * list. If an attribute remains in key_attnos_list in spite of the table is used @@ -997,3 +1010,39 @@ StoreImmvQuery(Oid viewOid, Query *viewQuery) CommandCounterIncrement(); } +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM < 140000) +/* + * CreateTableAsRelExists --- check existence of relation for CreateTableAsStmt + * + * Utility wrapper checking if the relation pending for creation in this + * CreateTableAsStmt query already exists or not. Returns true if the + * relation exists, otherwise false. + */ +static bool +CreateTableAsRelExists(CreateTableAsStmt *ctas) +{ + Oid nspid; + IntoClause *into = ctas->into; + + nspid = RangeVarGetCreationNamespace(into->rel); + + if (get_relname_relid(into->rel->relname, nspid)) + { + if (!ctas->if_not_exists) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_TABLE), + errmsg("relation \"%s\" already exists", + into->rel->relname))); + + /* The relation exists and IF NOT EXISTS has been specified */ + ereport(NOTICE, + (errcode(ERRCODE_DUPLICATE_TABLE), + errmsg("relation \"%s\" already exists, skipping", + into->rel->relname))); + return true; + } + + /* Relation does not exist, it can be created */ + return false; +} +#endif diff --git a/matview.c b/matview.c index 9905ec2..cf6f4c3 100644 --- a/matview.c +++ b/matview.c @@ -25,6 +25,7 @@ #include "parser/parse_clause.h" #include "parser/parse_func.h" #include "parser/parse_relation.h" +#include "parser/parser.h" #include "rewrite/rewriteHandler.h" #include "rewrite/rowsecurity.h" #include "storage/lmgr.h" @@ -566,13 +567,19 @@ IVM_immediate_maintenance(PG_FUNCTION_ARGS) old_tuplestore = tuplestore_begin_heap(false, false, work_mem); dest_old = CreateDestReceiver(DestTuplestore); +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) SetTuplestoreDestReceiverParams(dest_old, old_tuplestore, TopTransactionContext, false, NULL, NULL); - +#else + SetTuplestoreDestReceiverParams(dest_old, + old_tuplestore, + TopTransactionContext, + false); +#endif MemoryContextSwitchTo(oldcxt); } if (entry->has_new) @@ -581,12 +588,19 @@ IVM_immediate_maintenance(PG_FUNCTION_ARGS) new_tuplestore = tuplestore_begin_heap(false, false, work_mem); dest_new = CreateDestReceiver(DestTuplestore); +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) SetTuplestoreDestReceiverParams(dest_new, new_tuplestore, TopTransactionContext, false, NULL, NULL); +#else + SetTuplestoreDestReceiverParams(dest_new, + new_tuplestore, + TopTransactionContext, + false); +#endif MemoryContextSwitchTo(oldcxt); } @@ -843,7 +857,12 @@ get_prestate_rte(RangeTblEntry *rte, MV_TriggerTable *table, make_delta_enr_name("old", table->table_id, i)); } + +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) raw = (RawStmt*)linitial(raw_parser(str.data, RAW_PARSE_DEFAULT)); +#else + raw = (RawStmt*)linitial(raw_parser(str.data)); +#endif sub = transformStmt(pstate, raw->stmt); /* If this query has setOperations, RTEs in rtables has a subquery which contains ENR */ @@ -942,7 +961,11 @@ union_ENRs(RangeTblEntry *rte, Oid relid, List *enr_rtes, const char *prefix, make_delta_enr_name(prefix, relid, i)); } +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) raw = (RawStmt*)linitial(raw_parser(str.data, RAW_PARSE_DEFAULT)); +#else + raw = (RawStmt*)linitial(raw_parser(str.data)); +#endif sub = transformStmt(pstate, raw->stmt); rte->rtekind = RTE_SUBQUERY; @@ -982,7 +1005,11 @@ rewrite_query_for_distinct(Query *query, ParseState *pstate) Node *node; /* Add count(*) for counting distinct tuples in views */ +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) fn = makeFuncCall(list_make1(makeString("count")), NIL, COERCE_EXPLICIT_CALL, -1); +#else + fn = makeFuncCall(list_make1(makeString("count")), NIL, -1); +#endif fn->agg_star = true; if (!query->groupClause && !query->hasAggs) query->groupClause = transformDistinctClause(NULL, &query->targetList, query->sortClause, false); diff --git a/pg_ivm.c b/pg_ivm.c index 638c9de..ae00655 100644 --- a/pg_ivm.c +++ b/pg_ivm.c @@ -185,7 +185,11 @@ create_immv(PG_FUNCTION_ARGS) ctas = makeNode(CreateTableAsStmt); ctas->query = parsetree->stmt; +#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) ctas->objtype = OBJECT_MATVIEW; +#else + ctas->relkind = OBJECT_MATVIEW; +#endif ctas->is_select_into = false; ctas->into = makeNode(IntoClause); ctas->into->rel = makeRangeVarFromNameList(names);