/*
|
* 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
|