summaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_relation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r--src/backend/parser/parse_relation.c49
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);
+}