1
秦芳睿
8 天以前 e70a362606b78a822e93d5117a9013e8f9086faf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
 
#ifndef AG_CYPHER_NODE_H
#define AG_CYPHER_NODE_H
 
#include "postgres.h"
 
#include "nodes/extensible.h"
#include "nodes/parsenodes.h"
#include "nodes/pg_list.h"
 
#include "nodes/ag_nodes.h"
 
/* cypher sub patterns */
typedef enum csp_kind
{
        CSP_EXISTS,
        CSP_SIZE,
        CSP_FINDPATH /* shortestpath, allshortestpaths, dijkstra */
} csp_kind;
 
typedef struct cypher_sub_pattern
{
        ExtensibleNode extensible;
        csp_kind kind;
        List *pattern;
} cypher_sub_pattern;
 
/*
 * clauses
 */
 
typedef struct cypher_return
{
    ExtensibleNode extensible;
    bool distinct;
    List *items; // a list of ResTarget's
    List *order_by;
    Node *skip;
    Node *limit;
 
    bool all_or_distinct;
    SetOperation op;
    List *larg; /* lefthand argument of the unions */
    List *rarg; /*righthand argument of the unions */
} cypher_return;
 
typedef struct cypher_with
{
    ExtensibleNode extensible;
    bool distinct;
    List *items; // a list of ResTarget's
    List *order_by;
    Node *skip;
    Node *limit;
    Node *where;
} cypher_with;
 
typedef struct cypher_match
{
    ExtensibleNode extensible;
    List *pattern; // a list of cypher_paths
    Node *where; // optional WHERE subclause (expression)
    bool optional; // OPTIONAL MATCH
} cypher_match;
 
typedef struct cypher_create
{
    ExtensibleNode extensible;
    List *pattern; // a list of cypher_paths
} cypher_create;
 
typedef struct cypher_set
{
    ExtensibleNode extensible;
    List *items; // a list of cypher_set_items
    bool is_remove; // true if this is REMOVE clause
    int location;
} cypher_set;
 
typedef struct cypher_set_item
{
    ExtensibleNode extensible;
    Node *prop; // LHS
    Node *expr; // RHS
    bool is_add; // true if this is +=
    int location;
} cypher_set_item;
 
typedef struct cypher_delete
{
    ExtensibleNode extensible;
    bool detach; // true if DETACH is specified
    List *exprs; // targets of this deletion
    int location;
} cypher_delete;
 
typedef struct cypher_unwind
{
    ExtensibleNode extensible;
    ResTarget *target;
} cypher_unwind;
 
typedef struct cypher_merge
{
    ExtensibleNode extensible;
    Node *path;
} cypher_merge;
 
/*
 * pattern
 */
 
typedef struct cypher_path
{
    ExtensibleNode extensible;
    List *path; // [ node ( , relationship , node , ... ) ]
    char *var_name;
    char *parsed_var_name;
    int location;
} cypher_path;
 
// ( name :label props )
typedef struct cypher_node
{
    ExtensibleNode extensible;
    char *name;
    char *parsed_name;
    char *label;
    char *parsed_label;
    Node *props; // map or parameter
    int location;
} cypher_node;
 
typedef enum
{
    CYPHER_REL_DIR_NONE = 0,
    CYPHER_REL_DIR_LEFT = -1,
    CYPHER_REL_DIR_RIGHT = 1
} cypher_rel_dir;
 
// -[ name :label props ]-
typedef struct cypher_relationship
{
    ExtensibleNode extensible;
    char *name;
    char *parsed_name;
    char *label;
    char *parsed_label;
    Node *props; // map or parameter
    Node *varlen; // variable length relationships (A_Indices)
    cypher_rel_dir dir;
    int location;
} cypher_relationship;
 
/*
 * expression
 */
 
typedef struct cypher_bool_const
{
    ExtensibleNode extensible;
    bool boolean;
    int location;
} cypher_bool_const;
 
typedef struct cypher_integer_const
{
    ExtensibleNode extensible;
    int64 integer;
    int location;
} cypher_integer_const;
 
typedef struct cypher_param
{
    ExtensibleNode extensible;
    char *name;
    int location;
} cypher_param;
 
typedef struct cypher_map
{
    ExtensibleNode extensible;
    List *keyvals;
    int location;
    bool keep_null; // if false, keyvals with null value are removed
} cypher_map;
 
typedef struct cypher_list
{
    ExtensibleNode extensible;
    List *elems;
    int location;
} cypher_list;
 
enum cypher_string_match_op
{
    CSMO_STARTS_WITH,
    CSMO_ENDS_WITH,
    CSMO_CONTAINS
};
 
typedef struct cypher_string_match
{
    ExtensibleNode extensible;
    enum cypher_string_match_op operation;
    Node *lhs;
    Node *rhs;
    int location;
} cypher_string_match;
 
typedef struct cypher_create_target_nodes
{
    ExtensibleNode extensible;
    List *paths;
    uint32 flags;
    uint32 graph_oid;
} cypher_create_target_nodes;
 
typedef struct cypher_create_path
{
    ExtensibleNode extensible;
    List *target_nodes;
    AttrNumber path_attr_num;
    char *var_name;
} cypher_create_path;
 
/*
 * comparison expressions
 */
 
typedef struct cypher_comparison_aexpr
{
    ExtensibleNode extensible;
    A_Expr_Kind kind; /* see above */
    List *name; /* possibly-qualified name of operator */
    Node *lexpr; /* left argument, or NULL if none */
    Node *rexpr; /* right argument, or NULL if none */
    int location; /* token location, or -1 if unknown */
} cypher_comparison_aexpr;
 
typedef struct cypher_comparison_boolexpr
{
    ExtensibleNode extensible;
    BoolExprType boolop;
    List       *args;           /* arguments to this expression */
    int         location;       /* token location, or -1 if unknown */
} cypher_comparison_boolexpr;
 
 
/*
 * procedure call
 */
 
typedef struct cypher_call
{
    ExtensibleNode extensible;
    FuncCall *funccall; /*from the parser */
    FuncExpr *funcexpr; /*transformed */
 
    Node *where;
    List *yield_items; // optional yield subclause
} cypher_call;
 
#define CYPHER_CLAUSE_FLAG_NONE 0x0000
#define CYPHER_CLAUSE_FLAG_TERMINAL 0x0001
#define CYPHER_CLAUSE_FLAG_PREVIOUS_CLAUSE 0x0002
 
#define CYPHER_CLAUSE_IS_TERMINAL(flags) \
    (flags & CYPHER_CLAUSE_FLAG_TERMINAL)
 
#define CYPHER_CLAUSE_HAS_PREVIOUS_CLAUSE(flags) \
    (flags & CYPHER_CLAUSE_FLAG_PREVIOUS_CLAUSE)
 
/*
 * Structure that contains all information to create
 * a new entity in the create clause, or where to access
 * this information if it doesn't need to be created.
 *
 * NOTE: This structure may be used for the MERGE clause as
 * well
 */
typedef struct cypher_target_node
{
    ExtensibleNode extensible;
    // 'v' for vertex or 'e' for edge
    char type;
    // flags defined below, prefaced with CYPHER_TARGET_NODE_FLAG_*
    uint32 flags;
    // if an edge, denotes direction
    cypher_rel_dir dir;
    /*
     * Used to create the id for the vertex/edge,
     * if the CYPHER_TARGET_NODE_FLAG_INSERT flag
     * is set. Doing it this way will protect us when
     * rescan gets implemented. By calling the function
     * that creates the id ourselves, we won't have an
     * issue where the id could be created then not used.
     * Since there is a limited number of ids available, we
     * don't want to waste them.
     */
    Expr *id_expr;
    ExprState *id_expr_state;
 
    Expr *prop_expr;
    ExprState *prop_expr_state;
    /*
     * Attribute Number that this entity's properties
     * are stored in the CustomScanState's child TupleTableSlot
     */
    AttrNumber prop_attr_num;
    // RelInfo for the table this entity will be stored in
    ResultRelInfo *resultRelInfo;
    // elemTupleSlot used to insert the entity into its table
    TupleTableSlot *elemTupleSlot;
    // relid that the label stores its entity
    Oid relid;
    // label this entity belongs to.
    char *label_name;
    // variable name for this entity
    char *variable_name;
    /*
     * Attribute number this entity needs to be stored in
     * for parent execution nodes to reference it. If the
     * entity is a variable (CYPHER_TARGET_NODE_IS_VAR).
     */
    AttrNumber tuple_position;
} cypher_target_node;
 
#define CYPHER_TARGET_NODE_FLAG_NONE 0x0000
// node must insert data
#define CYPHER_TARGET_NODE_FLAG_INSERT 0x0001
/*
 * Flag that denotes if this target node is referencing
 * a variable that was already created AND created in the
 * same clause.
 */
#define EXISTING_VARIABLE_DECLARED_SAME_CLAUSE 0x0002
 
//node is the first instance of a declared variable
#define CYPHER_TARGET_NODE_IS_VAR 0x0004
// node is an element in a path variable
#define CYPHER_TARGET_NODE_IN_PATH_VAR 0x0008
 
#define CYPHER_TARGET_NODE_MERGE_EXISTS 0x0010
 
#define CYPHER_TARGET_NODE_OUTPUT(flags) \
    (flags & (CYPHER_TARGET_NODE_IS_VAR | CYPHER_TARGET_NODE_IN_PATH_VAR))
 
#define CYPHER_TARGET_NODE_IN_PATH(flags) \
    (flags & CYPHER_TARGET_NODE_IN_PATH_VAR)
 
#define CYPHER_TARGET_NODE_IS_VARIABLE(flags) \
    (flags & CYPHER_TARGET_NODE_IS_VAR)
 
/*
 * When a vertex is created and is reference in the same clause
 * later. We don't need to check to see if the vertex still exists.
 */
#define SAFE_TO_SKIP_EXISTENCE_CHECK(flags) \
    (flags & EXISTING_VARIABLE_DECLARED_SAME_CLAUSE)
 
#define CYPHER_TARGET_NODE_INSERT_ENTITY(flags) \
    (flags & CYPHER_TARGET_NODE_FLAG_INSERT)
 
#define UPDATE_CLAUSE_SET "SET"
#define UPDATE_CLAUSE_REMOVE "REMOVE"
 
/* Data Structures that contain information about a vertices and edges the need to be updated */
typedef struct cypher_update_information
{
    ExtensibleNode extensible;
    List *set_items;
    uint32 flags;
    AttrNumber tuple_position;
    char *graph_name;
    char *clause_name;
} cypher_update_information;
 
typedef struct cypher_update_item
{
    ExtensibleNode extensible;
    AttrNumber prop_position;
    AttrNumber entity_position;
    char *var_name;
    char *prop_name;
    List *qualified_name;
    bool remove_item;
    bool is_add;
} cypher_update_item;
 
typedef struct cypher_delete_information
{
    ExtensibleNode extensible;
    List *delete_items;
    uint32 flags;
    char *graph_name;
    uint32 graph_oid;
    bool detach;
} cypher_delete_information;
 
typedef struct cypher_delete_item
{
    ExtensibleNode extensible;
    Value *entity_position;
    char *var_name;
} cypher_delete_item;
 
typedef struct cypher_merge_information
{
    ExtensibleNode extensible;
    uint32 flags;
    uint32 graph_oid;
    AttrNumber merge_function_attr;
    cypher_create_path *path;
} cypher_merge_information;
 
/* grammar node for typecasts */
typedef struct cypher_typecast
{
    ExtensibleNode extensible;
    Node *expr;
    char *typecast;
    int location;
} cypher_typecast;
 
#endif