Merge pull request #10 from tatsuo-ishii/rel13
Allow to build pg_ivm on PostgreSQL 13.
This commit is contained in:
commit
9719ed644d
3 changed files with 83 additions and 3 deletions
53
createas.c
53
createas.c
|
|
@ -11,6 +11,7 @@
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/xact.h"
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/dependency.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);
|
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
|
* ExecCreateImmv -- execute a create_immv() function
|
||||||
*
|
*
|
||||||
|
|
@ -286,7 +291,11 @@ rewriteQueryForIMMV(Query *query, List *colNames)
|
||||||
{
|
{
|
||||||
rewritten->groupClause = transformDistinctClause(NULL, &rewritten->targetList, rewritten->sortClause, false);
|
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);
|
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;
|
fn->agg_star = true;
|
||||||
|
|
||||||
node = ParseFuncOrColumn(pstate, fn->funcname, NIL, NULL, fn, false, -1);
|
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;
|
int i;
|
||||||
Bitmapset *keys = NULL;
|
Bitmapset *keys = NULL;
|
||||||
Relids rels_in_from;
|
Relids rels_in_from;
|
||||||
|
#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000)
|
||||||
PlannerInfo root;
|
PlannerInfo root;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Collect primary key attributes from all tables used in query. The key attributes
|
* 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 */
|
/* 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);
|
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
|
* 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
|
* 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();
|
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
|
||||||
|
|
|
||||||
29
matview.c
29
matview.c
|
|
@ -25,6 +25,7 @@
|
||||||
#include "parser/parse_clause.h"
|
#include "parser/parse_clause.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
|
#include "parser/parser.h"
|
||||||
#include "rewrite/rewriteHandler.h"
|
#include "rewrite/rewriteHandler.h"
|
||||||
#include "rewrite/rowsecurity.h"
|
#include "rewrite/rowsecurity.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
|
|
@ -566,13 +567,19 @@ IVM_immediate_maintenance(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
old_tuplestore = tuplestore_begin_heap(false, false, work_mem);
|
old_tuplestore = tuplestore_begin_heap(false, false, work_mem);
|
||||||
dest_old = CreateDestReceiver(DestTuplestore);
|
dest_old = CreateDestReceiver(DestTuplestore);
|
||||||
|
#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000)
|
||||||
SetTuplestoreDestReceiverParams(dest_old,
|
SetTuplestoreDestReceiverParams(dest_old,
|
||||||
old_tuplestore,
|
old_tuplestore,
|
||||||
TopTransactionContext,
|
TopTransactionContext,
|
||||||
false,
|
false,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
#else
|
||||||
|
SetTuplestoreDestReceiverParams(dest_old,
|
||||||
|
old_tuplestore,
|
||||||
|
TopTransactionContext,
|
||||||
|
false);
|
||||||
|
#endif
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
}
|
}
|
||||||
if (entry->has_new)
|
if (entry->has_new)
|
||||||
|
|
@ -581,12 +588,19 @@ IVM_immediate_maintenance(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
new_tuplestore = tuplestore_begin_heap(false, false, work_mem);
|
new_tuplestore = tuplestore_begin_heap(false, false, work_mem);
|
||||||
dest_new = CreateDestReceiver(DestTuplestore);
|
dest_new = CreateDestReceiver(DestTuplestore);
|
||||||
|
#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000)
|
||||||
SetTuplestoreDestReceiverParams(dest_new,
|
SetTuplestoreDestReceiverParams(dest_new,
|
||||||
new_tuplestore,
|
new_tuplestore,
|
||||||
TopTransactionContext,
|
TopTransactionContext,
|
||||||
false,
|
false,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
#else
|
||||||
|
SetTuplestoreDestReceiverParams(dest_new,
|
||||||
|
new_tuplestore,
|
||||||
|
TopTransactionContext,
|
||||||
|
false);
|
||||||
|
#endif
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -843,7 +857,12 @@ get_prestate_rte(RangeTblEntry *rte, MV_TriggerTable *table,
|
||||||
make_delta_enr_name("old", table->table_id, i));
|
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));
|
raw = (RawStmt*)linitial(raw_parser(str.data, RAW_PARSE_DEFAULT));
|
||||||
|
#else
|
||||||
|
raw = (RawStmt*)linitial(raw_parser(str.data));
|
||||||
|
#endif
|
||||||
sub = transformStmt(pstate, raw->stmt);
|
sub = transformStmt(pstate, raw->stmt);
|
||||||
|
|
||||||
/* If this query has setOperations, RTEs in rtables has a subquery which contains ENR */
|
/* 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));
|
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));
|
raw = (RawStmt*)linitial(raw_parser(str.data, RAW_PARSE_DEFAULT));
|
||||||
|
#else
|
||||||
|
raw = (RawStmt*)linitial(raw_parser(str.data));
|
||||||
|
#endif
|
||||||
sub = transformStmt(pstate, raw->stmt);
|
sub = transformStmt(pstate, raw->stmt);
|
||||||
|
|
||||||
rte->rtekind = RTE_SUBQUERY;
|
rte->rtekind = RTE_SUBQUERY;
|
||||||
|
|
@ -982,7 +1005,11 @@ rewrite_query_for_distinct(Query *query, ParseState *pstate)
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
/* Add count(*) for counting distinct tuples in views */
|
/* 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);
|
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;
|
fn->agg_star = true;
|
||||||
if (!query->groupClause && !query->hasAggs)
|
if (!query->groupClause && !query->hasAggs)
|
||||||
query->groupClause = transformDistinctClause(NULL, &query->targetList, query->sortClause, false);
|
query->groupClause = transformDistinctClause(NULL, &query->targetList, query->sortClause, false);
|
||||||
|
|
|
||||||
4
pg_ivm.c
4
pg_ivm.c
|
|
@ -185,7 +185,11 @@ create_immv(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
ctas = makeNode(CreateTableAsStmt);
|
ctas = makeNode(CreateTableAsStmt);
|
||||||
ctas->query = parsetree->stmt;
|
ctas->query = parsetree->stmt;
|
||||||
|
#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000)
|
||||||
ctas->objtype = OBJECT_MATVIEW;
|
ctas->objtype = OBJECT_MATVIEW;
|
||||||
|
#else
|
||||||
|
ctas->relkind = OBJECT_MATVIEW;
|
||||||
|
#endif
|
||||||
ctas->is_select_into = false;
|
ctas->is_select_into = false;
|
||||||
ctas->into = makeNode(IntoClause);
|
ctas->into = makeNode(IntoClause);
|
||||||
ctas->into->rel = makeRangeVarFromNameList(names);
|
ctas->into->rel = makeRangeVarFromNameList(names);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue