diff options
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r-- | src/backend/parser/parse_relation.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 93aeab8d16f..82e088a38ba 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -48,6 +48,7 @@ static void expandTupleDesc(TupleDesc tupdesc, Alias *eref, int location, bool include_dropped, List **colnames, List **colvars); static int specialAttNum(const char *attname); +static bool isQueryUsingTempRelation_walker(Node *node, void *context); /* @@ -2615,3 +2616,51 @@ errorMissingColumn(ParseState *pstate, colname, rte->eref->aliasname) : 0, parser_errposition(pstate, location))); } + + +/* + * Examine a fully-parsed query, and return TRUE iff any relation underlying + * the query is a temporary relation (table, view, or materialized view). + */ +bool +isQueryUsingTempRelation(Query *query) +{ + return isQueryUsingTempRelation_walker((Node *) query, NULL); +} + +static bool +isQueryUsingTempRelation_walker(Node *node, void *context) +{ + if (node == NULL) + return false; + + if (IsA(node, Query)) + { + Query *query = (Query *) node; + ListCell *rtable; + + foreach(rtable, query->rtable) + { + RangeTblEntry *rte = lfirst(rtable); + + if (rte->rtekind == RTE_RELATION) + { + Relation rel = heap_open(rte->relid, AccessShareLock); + char relpersistence = rel->rd_rel->relpersistence; + + heap_close(rel, AccessShareLock); + if (relpersistence == RELPERSISTENCE_TEMP) + return true; + } + } + + return query_tree_walker(query, + isQueryUsingTempRelation_walker, + context, + QTW_IGNORE_JOINALIASES); + } + + return expression_tree_walker(node, + isQueryUsingTempRelation_walker, + context); +} |