PostgreSQL Source Code git master
Loading...
Searching...
No Matches
parse_graphtable.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "catalog/pg_propgraph_label.h"
#include "catalog/pg_propgraph_property.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_collate.h"
#include "parser/parse_expr.h"
#include "parser/parse_graphtable.h"
#include "parser/parse_node.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/relcache.h"
#include "utils/syscache.h"
Include dependency graph for parse_graphtable.c:

Go to the source code of this file.

Functions

static const charget_gep_kind_name (GraphElementPatternKind gepkind)
 
NodetransformGraphTablePropertyRef (ParseState *pstate, ColumnRef *cref)
 
static NodetransformLabelExpr (GraphTableParseState *gpstate, Node *labelexpr)
 
static NodetransformGraphElementPattern (ParseState *pstate, GraphElementPattern *gep)
 
static NodetransformPathTerm (ParseState *pstate, List *path_term)
 
static NodetransformPathPatternList (ParseState *pstate, List *path_pattern)
 
NodetransformGraphPattern (ParseState *pstate, GraphPattern *graph_pattern)
 

Function Documentation

◆ get_gep_kind_name()

static const char * get_gep_kind_name ( GraphElementPatternKind  gepkind)
static

Definition at line 40 of file parse_graphtable.c.

41{
42 switch (gepkind)
43 {
44 case VERTEX_PATTERN:
45 return "vertex";
47 return "edge pointing left";
49 return "edge pointing right";
51 return "edge pointing any direction";
52 case PAREN_EXPR:
53 return "nested path pattern";
54 }
55
56 /*
57 * When a GraphElementPattern is constructed by the parser, it will set a
58 * value from the GraphElementPatternKind enum. But we may get here if the
59 * GraphElementPatternKind value stored in a catalog is corrupted.
60 */
61 return "unknown";
62}
@ EDGE_PATTERN_RIGHT
@ VERTEX_PATTERN
@ EDGE_PATTERN_LEFT
@ PAREN_EXPR
@ EDGE_PATTERN_ANY
static int fb(int x)

References EDGE_PATTERN_ANY, EDGE_PATTERN_LEFT, EDGE_PATTERN_RIGHT, fb(), PAREN_EXPR, and VERTEX_PATTERN.

Referenced by transformPathTerm().

◆ transformGraphElementPattern()

static Node * transformGraphElementPattern ( ParseState pstate,
GraphElementPattern gep 
)
static

Definition at line 239 of file parse_graphtable.c.

240{
242
243 if (gep->quantifier)
246 errmsg("element pattern quantifier is not supported")));
247
248 Assert(!gpstate->cur_gep);
249
250 gpstate->cur_gep = gep;
251
252 gep->labelexpr = transformLabelExpr(gpstate, gep->labelexpr);
253
254 gep->whereClause = transformExpr(pstate, gep->whereClause, EXPR_KIND_WHERE);
255 assign_expr_collations(pstate, gep->whereClause);
256
257 gpstate->cur_gep = NULL;
258
259 return (Node *) gep;
260}
#define Assert(condition)
Definition c.h:943
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:151
static char * errmsg
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition parse_expr.c:121
static Node * transformLabelExpr(GraphTableParseState *gpstate, Node *labelexpr)
@ EXPR_KIND_WHERE
Definition parse_node.h:46
Definition nodes.h:135
GraphTableParseState * p_graph_table_pstate
Definition parse_node.h:242

References Assert, assign_expr_collations(), ereport, errcode(), errmsg, ERROR, EXPR_KIND_WHERE, fb(), ParseState::p_graph_table_pstate, transformExpr(), and transformLabelExpr().

Referenced by transformPathTerm().

◆ transformGraphPattern()

Node * transformGraphPattern ( ParseState pstate,
GraphPattern graph_pattern 
)

Definition at line 374 of file parse_graphtable.c.

375{
376 List *path_pattern_list = castNode(List,
377 transformPathPatternList(pstate, graph_pattern->path_pattern_list));
378
379 graph_pattern->path_pattern_list = path_pattern_list;
380 graph_pattern->whereClause = transformExpr(pstate, graph_pattern->whereClause, EXPR_KIND_WHERE);
381 assign_expr_collations(pstate, graph_pattern->whereClause);
382
383 return (Node *) graph_pattern;
384}
#define castNode(_type_, nodeptr)
Definition nodes.h:182
static Node * transformPathPatternList(ParseState *pstate, List *path_pattern)
Node * whereClause
List * path_pattern_list
Definition pg_list.h:54

References assign_expr_collations(), castNode, EXPR_KIND_WHERE, GraphPattern::path_pattern_list, transformExpr(), transformPathPatternList(), and GraphPattern::whereClause.

Referenced by transformRangeGraphTable().

◆ transformGraphTablePropertyRef()

Node * transformGraphTablePropertyRef ( ParseState pstate,
ColumnRef cref 
)

Definition at line 79 of file parse_graphtable.c.

80{
82
83 if (!gpstate)
84 return NULL;
85
86 if (list_length(cref->fields) == 2)
87 {
88 Node *field1 = linitial(cref->fields);
89 Node *field2 = lsecond(cref->fields);
90 char *elvarname;
91 char *propname;
92
93 if (IsA(field1, A_Star) || IsA(field2, A_Star))
94 {
98 errmsg("\"*\" is not supported here"),
99 parser_errposition(pstate, cref->location));
100 else
103 errmsg("\"*\" not allowed here"),
104 parser_errposition(pstate, cref->location));
105 }
106
107 elvarname = strVal(field1);
109
110 if (list_member(gpstate->variables, field1))
111 {
115
116 /*
117 * If we are transforming expression in an element pattern,
118 * property references containing only that variable are allowed.
119 */
120 if (gpstate->cur_gep)
121 {
122 if (!gpstate->cur_gep->variable ||
123 strcmp(elvarname, gpstate->cur_gep->variable) != 0)
126 errmsg("non-local element variable reference is not supported"),
127 parser_errposition(pstate, cref->location));
128 }
129
135 errmsg("property \"%s\" does not exist", propname));
137
138 gpr->location = cref->location;
139 gpr->elvarname = elvarname;
140 gpr->propid = pgpform->oid;
141 gpr->typeId = pgpform->pgptypid;
142 gpr->typmod = pgpform->pgptypmod;
143 gpr->collation = pgpform->pgpcollation;
144
146
147 return (Node *) gpr;
148 }
149 }
150
151 return NULL;
152}
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
bool list_member(const List *list, const void *datum)
Definition list.c:661
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define makeNode(_type_)
Definition nodes.h:161
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
@ EXPR_KIND_SELECT_TARGET
Definition parse_node.h:54
static int list_length(const List *l)
Definition pg_list.h:152
#define linitial(l)
Definition pg_list.h:178
#define lsecond(l)
Definition pg_list.h:183
END_CATALOG_STRUCT typedef FormData_pg_propgraph_property * Form_pg_propgraph_property
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
ParseExprKind p_expr_kind
Definition parse_node.h:232
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231
#define strVal(v)
Definition value.h:82

References CStringGetDatum(), ereport, errcode(), errmsg, ERROR, EXPR_KIND_SELECT_TARGET, fb(), Form_pg_propgraph_property, GETSTRUCT(), HeapTupleIsValid, IsA, linitial, list_length(), list_member(), lsecond, makeNode, ObjectIdGetDatum(), ParseState::p_expr_kind, ParseState::p_graph_table_pstate, parser_errposition(), ReleaseSysCache(), SearchSysCache2(), and strVal.

Referenced by transformColumnRef().

◆ transformLabelExpr()

static Node * transformLabelExpr ( GraphTableParseState gpstate,
Node labelexpr 
)
static

Definition at line 166 of file parse_graphtable.c.

167{
168 Node *result;
169
170 if (labelexpr == NULL)
171 return NULL;
172
174
175 switch (nodeTag(labelexpr))
176 {
177 case T_ColumnRef:
178 {
179 ColumnRef *cref = (ColumnRef *) labelexpr;
180 const char *labelname;
181 Oid labelid;
183
184 Assert(list_length(cref->fields) == 1);
185 labelname = strVal(linitial(cref->fields));
186
188 if (!labelid)
191 errmsg("label \"%s\" does not exist in property graph \"%s\"", labelname, get_rel_name(gpstate->graphid)));
192
194 lref->labelid = labelid;
195 lref->location = cref->location;
196
197 result = (Node *) lref;
198 break;
199 }
200
201 case T_BoolExpr:
202 {
203 BoolExpr *be = (BoolExpr *) labelexpr;
204 ListCell *lc;
205 List *args = NIL;
206
207 foreach(lc, be->args)
208 {
209 Node *arg = (Node *) lfirst(lc);
210
212 args = lappend(args, arg);
213 }
214
215 result = (Node *) makeBoolExpr(be->boolop, args, be->location);
216 break;
217 }
218
219 default:
220 /* should not reach here */
221 elog(ERROR, "unsupported label expression node: %d", (int) nodeTag(labelexpr));
222 result = NULL; /* keep compiler quiet */
223 break;
224 }
225
226 return result;
227}
uint32 result
Datum arg
Definition elog.c:1322
#define elog(elevel,...)
Definition elog.h:227
List * lappend(List *list, void *datum)
Definition list.c:339
char * get_rel_name(Oid relid)
Definition lsyscache.c:2148
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition makefuncs.c:420
#define nodeTag(nodeptr)
Definition nodes.h:139
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
unsigned int Oid
void check_stack_depth(void)
Definition stack_depth.c:95
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition syscache.h:111

References arg, Assert, check_stack_depth(), CStringGetDatum(), elog, ereport, errcode(), errmsg, ERROR, fb(), get_rel_name(), GetSysCacheOid2, lappend(), lfirst, linitial, list_length(), makeBoolExpr(), makeNode, NIL, nodeTag, ObjectIdGetDatum(), result, strVal, and transformLabelExpr().

Referenced by transformGraphElementPattern(), and transformLabelExpr().

◆ transformPathPatternList()

static Node * transformPathPatternList ( ParseState pstate,
List path_pattern 
)
static

Definition at line 324 of file parse_graphtable.c.

325{
326 List *result = NIL;
328
330
331 /* Grammar doesn't allow empty path pattern list */
333
334 /*
335 * We do not support multiple path patterns in one GRAPH_TABLE clause
336 * right now. But we may do so in future.
337 */
338 if (list_length(path_pattern) != 1)
341 errmsg("multiple path patterns in one GRAPH_TABLE clause not supported")));
342
343 /*
344 * Collect all the variables in the path pattern into the
345 * GraphTableParseState so that we can detect any non-local element
346 * variable references. We need to do this before transforming the path
347 * pattern so as to detect forward references to element variables in the
348 * WHERE clause of an element pattern.
349 */
351 {
353 {
354 if (gep->variable)
355 gpstate->variables = list_append_unique(gpstate->variables, makeString(pstrdup(gep->variable)));
356 }
357 }
358
361
362 return (Node *) result;
363}
List * list_append_unique(List *list, void *datum)
Definition list.c:1343
char * pstrdup(const char *in)
Definition mcxt.c:1781
static Node * transformPathTerm(ParseState *pstate, List *path_term)
#define foreach_node(type, var, lst)
Definition pg_list.h:528
String * makeString(char *str)
Definition value.c:63

References Assert, ereport, errcode(), errmsg, ERROR, fb(), foreach_node, lappend(), list_append_unique(), list_length(), makeString(), NIL, ParseState::p_graph_table_pstate, pstrdup(), result, and transformPathTerm().

Referenced by transformGraphPattern().

◆ transformPathTerm()

static Node * transformPathTerm ( ParseState pstate,
List path_term 
)
static

Definition at line 266 of file parse_graphtable.c.

267{
268 List *result = NIL;
270
272 {
273 if (gep->kind != VERTEX_PATTERN && !IS_EDGE_PATTERN(gep->kind))
276 errmsg("unsupported element pattern kind: \"%s\"", get_gep_kind_name(gep->kind)),
277 parser_errposition(pstate, gep->location)));
278
279 if (IS_EDGE_PATTERN(gep->kind))
280 {
281 if (!prev_gep)
284 errmsg("path pattern cannot start with an edge pattern"),
285 parser_errposition(pstate, gep->location)));
286 else if (prev_gep->kind != VERTEX_PATTERN)
289 errmsg("edge pattern must be preceded by a vertex pattern"),
290 parser_errposition(pstate, gep->location)));
291 }
292 else
293 {
294 if (prev_gep && !IS_EDGE_PATTERN(prev_gep->kind))
297 errmsg("adjacent vertex patterns are not supported"),
298 parser_errposition(pstate, gep->location)));
299 }
300
303 prev_gep = gep;
304 }
305
306 /* Path pattern should have at least one element pattern. */
308
309 if (IS_EDGE_PATTERN(prev_gep->kind))
310 {
313 errmsg("path pattern cannot end with an edge pattern"),
314 parser_errposition(pstate, prev_gep->location)));
315 }
316
317 return (Node *) result;
318}
static const char * get_gep_kind_name(GraphElementPatternKind gepkind)
static Node * transformGraphElementPattern(ParseState *pstate, GraphElementPattern *gep)
#define IS_EDGE_PATTERN(kind)

References Assert, ereport, errcode(), errmsg, ERROR, fb(), foreach_node, get_gep_kind_name(), IS_EDGE_PATTERN, lappend(), NIL, parser_errposition(), result, transformGraphElementPattern(), and VERTEX_PATTERN.

Referenced by transformPathPatternList().