PostgreSQL Source Code  git master
queryenvironment.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * queryenvironment.c
4  * Query environment, to store context-specific values like ephemeral named
5  * relations. Initial use is for named tuplestores for delta information
6  * from "normal" relations.
7  *
8  * The initial implementation uses a list because the number of such relations
9  * in any one context is expected to be very small. If that becomes a
10  * performance problem, the implementation can be changed with no other impact
11  * on callers, since this is an opaque structure. This is the reason to
12  * require a create function.
13  *
14  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
15  * Portions Copyright (c) 1994, Regents of the University of California
16  *
17  *
18  * IDENTIFICATION
19  * src/backend/utils/misc/queryenvironment.c
20  *
21  *-------------------------------------------------------------------------
22  */
23 #include "postgres.h"
24 
25 #include "access/table.h"
26 #include "utils/queryenvironment.h"
27 #include "utils/rel.h"
28 
29 /*
30  * Private state of a query environment.
31  */
33 {
35 };
36 
37 
40 {
41  return (QueryEnvironment *) palloc0(sizeof(QueryEnvironment));
42 }
43 
45 get_visible_ENR_metadata(QueryEnvironment *queryEnv, const char *refname)
46 {
48 
49  Assert(refname != NULL);
50 
51  if (queryEnv == NULL)
52  return NULL;
53 
54  enr = get_ENR(queryEnv, refname);
55 
56  if (enr)
57  return &(enr->md);
58 
59  return NULL;
60 }
61 
62 /*
63  * Register a named relation for use in the given environment.
64  *
65  * If this is intended exclusively for planning purposes, the tstate field can
66  * be left NULL;
67  */
68 void
70 {
71  Assert(enr != NULL);
72  Assert(get_ENR(queryEnv, enr->md.name) == NULL);
73 
74  queryEnv->namedRelList = lappend(queryEnv->namedRelList, enr);
75 }
76 
77 /*
78  * Unregister an ephemeral relation by name. This will probably be a rarely
79  * used function, but seems like it should be provided "just in case".
80  */
81 void
82 unregister_ENR(QueryEnvironment *queryEnv, const char *name)
83 {
85 
86  match = get_ENR(queryEnv, name);
87  if (match)
88  queryEnv->namedRelList = list_delete(queryEnv->namedRelList, match);
89 }
90 
91 /*
92  * This returns an ENR if there is a name match in the given collection. It
93  * must quietly return NULL if no match is found.
94  */
96 get_ENR(QueryEnvironment *queryEnv, const char *name)
97 {
98  ListCell *lc;
99 
100  Assert(name != NULL);
101 
102  if (queryEnv == NULL)
103  return NULL;
104 
105  foreach(lc, queryEnv->namedRelList)
106  {
108 
109  if (strcmp(enr->md.name, name) == 0)
110  return enr;
111  }
112 
113  return NULL;
114 }
115 
116 /*
117  * Gets the TupleDesc for a Ephemeral Named Relation, based on which field was
118  * filled.
119  *
120  * When the TupleDesc is based on a relation from the catalogs, we count on
121  * that relation being used at the same time, so that appropriate locks will
122  * already be held. Locking here would be too late anyway.
123  */
124 TupleDesc
126 {
127  TupleDesc tupdesc;
128 
129  /* One, and only one, of these fields must be filled. */
130  Assert((enrmd->reliddesc == InvalidOid) != (enrmd->tupdesc == NULL));
131 
132  if (enrmd->tupdesc != NULL)
133  tupdesc = enrmd->tupdesc;
134  else
135  {
136  Relation relation;
137 
138  relation = table_open(enrmd->reliddesc, NoLock);
139  tupdesc = relation->rd_att;
140  table_close(relation, NoLock);
141  }
142 
143  return tupdesc;
144 }
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:339
List * list_delete(List *list, void *datum)
Definition: list.c:853
#define NoLock
Definition: lockdefs.h:34
void * palloc0(Size size)
Definition: mcxt.c:1334
#define lfirst(lc)
Definition: pg_list.h:172
#define InvalidOid
Definition: postgres_ext.h:36
TupleDesc ENRMetadataGetTupDesc(EphemeralNamedRelationMetadata enrmd)
EphemeralNamedRelation get_ENR(QueryEnvironment *queryEnv, const char *name)
EphemeralNamedRelationMetadata get_visible_ENR_metadata(QueryEnvironment *queryEnv, const char *refname)
void unregister_ENR(QueryEnvironment *queryEnv, const char *name)
QueryEnvironment * create_queryEnv(void)
void register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr)
EphemeralNamedRelationData * EphemeralNamedRelation
EphemeralNamedRelationMetadataData md
Definition: pg_list.h:54
TupleDesc rd_att
Definition: rel.h:112
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
const char * name