/*
|
* 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.
|
*/
|
|
#include "postgres.h"
|
|
#include "lib/stringinfo.h"
|
#include "nodes/extensible.h"
|
#include "nodes/nodes.h"
|
|
#include "nodes/cypher_nodes.h"
|
#include "nodes/cypher_outfuncs.h"
|
|
static void outChar(StringInfo str, char c);
|
|
#define DEFINE_AG_NODE(type) \
|
type *_node = (type *)node
|
|
#define WRITE_NODE_FIELD(field_name) \
|
do \
|
{ \
|
appendStringInfoString(str, " :" CppAsString(field_name) " "); \
|
outNode(str, _node->field_name); \
|
} while (0)
|
|
#define WRITE_STRING_FIELD(field_name) \
|
do \
|
{ \
|
appendStringInfoString(str, " :" CppAsString(field_name) " "); \
|
outToken(str, _node->field_name); \
|
} while (0)
|
|
// Write a char field (ie, one ascii character)
|
#define WRITE_CHAR_FIELD(fldname) \
|
do { \
|
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
|
outChar(str, _node->fldname)); \
|
} while (0)
|
|
#define WRITE_BOOL_FIELD(field_name) \
|
do \
|
{ \
|
appendStringInfo(str, " :" CppAsString(field_name) " %s", \
|
_node->field_name ? "true" : "false"); \
|
} while (0)
|
|
// write an enumerated-type field as an integer code
|
#define WRITE_ENUM_FIELD(field_name, enum_type) \
|
do \
|
{ \
|
appendStringInfo(str, " :" CppAsString(field_name) " %d", \
|
(int)_node->field_name); \
|
} while (0)
|
|
#define WRITE_LOCATION_FIELD(field_name) \
|
do \
|
{ \
|
appendStringInfo(str, " :" CppAsString(field_name) " %d", \
|
_node->field_name); \
|
} while (0)
|
|
#define WRITE_INT64_FIELD(field_name) \
|
do \
|
{ \
|
appendStringInfo(str, " :" CppAsString(field_name) " %ld", \
|
_node->field_name); \
|
} while (0)
|
|
// Write an integer field (anything written as ":fldname %d")
|
#define WRITE_INT32_FIELD(field_name) \
|
do { \
|
appendStringInfo(str, " :" CppAsString(field_name) " %d", \
|
_node->field_name); \
|
} while (0)
|
|
// Write an OID field (don't hard-wire assumption that OID is same as uint)
|
#define WRITE_OID_FIELD(fldname) \
|
do { \
|
appendStringInfo(str, " :" CppAsString(fldname) " %u", \
|
_node->fldname); \
|
} while(0);
|
|
|
|
// serialization function for the cypher_return ExtensibleNode.
|
void out_cypher_return(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_return);
|
|
WRITE_BOOL_FIELD(distinct);
|
WRITE_NODE_FIELD(items);
|
WRITE_NODE_FIELD(order_by);
|
WRITE_NODE_FIELD(skip);
|
WRITE_NODE_FIELD(limit);
|
|
WRITE_BOOL_FIELD(all_or_distinct);
|
WRITE_ENUM_FIELD(op, SetOperation);
|
WRITE_NODE_FIELD(larg);
|
WRITE_NODE_FIELD(rarg);
|
}
|
|
// serialization function for the cypher_with ExtensibleNode.
|
void out_cypher_with(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_with);
|
|
WRITE_BOOL_FIELD(distinct);
|
WRITE_NODE_FIELD(items);
|
WRITE_NODE_FIELD(order_by);
|
WRITE_NODE_FIELD(skip);
|
WRITE_NODE_FIELD(limit);
|
WRITE_NODE_FIELD(where);
|
}
|
|
// serialization function for the cypher_match ExtensibleNode.
|
void out_cypher_match(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_match);
|
|
WRITE_NODE_FIELD(pattern);
|
WRITE_NODE_FIELD(where);
|
WRITE_BOOL_FIELD(optional);
|
}
|
|
// serialization function for the cypher_create ExtensibleNode.
|
void out_cypher_create(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_create);
|
|
WRITE_NODE_FIELD(pattern);
|
}
|
|
// serialization function for the cypher_set ExtensibleNode.
|
void out_cypher_set(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_set);
|
|
WRITE_NODE_FIELD(items);
|
WRITE_BOOL_FIELD(is_remove);
|
}
|
|
// serialization function for the cypher_set_item ExtensibleNode.
|
void out_cypher_set_item(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_set_item);
|
|
WRITE_NODE_FIELD(prop);
|
WRITE_NODE_FIELD(expr);
|
WRITE_BOOL_FIELD(is_add);
|
}
|
|
// serialization function for the cypher_delete ExtensibleNode.
|
void out_cypher_delete(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_delete);
|
|
WRITE_BOOL_FIELD(detach);
|
WRITE_NODE_FIELD(exprs);
|
}
|
|
void out_cypher_unwind(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_unwind);
|
|
WRITE_NODE_FIELD(target);
|
}
|
|
// serialization function for the cypher_delete ExtensibleNode.
|
void out_cypher_merge(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_merge);
|
|
WRITE_NODE_FIELD(path);
|
}
|
|
// serialization function for the cypher_path ExtensibleNode.
|
void out_cypher_path(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_path);
|
|
WRITE_NODE_FIELD(path);
|
WRITE_STRING_FIELD(var_name);
|
WRITE_STRING_FIELD(parsed_var_name);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_node ExtensibleNode.
|
void out_cypher_node(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_node);
|
|
WRITE_STRING_FIELD(name);
|
WRITE_STRING_FIELD(parsed_name);
|
WRITE_STRING_FIELD(label);
|
WRITE_STRING_FIELD(parsed_label);
|
WRITE_NODE_FIELD(props);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_relationship ExtensibleNode.
|
void out_cypher_relationship(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_relationship);
|
|
WRITE_STRING_FIELD(name);
|
WRITE_STRING_FIELD(parsed_name);
|
WRITE_STRING_FIELD(label);
|
WRITE_STRING_FIELD(parsed_label);
|
WRITE_NODE_FIELD(props);
|
WRITE_NODE_FIELD(varlen);
|
WRITE_ENUM_FIELD(dir, cypher_rel_dir);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_bool_const ExtensibleNode.
|
void out_cypher_bool_const(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_bool_const);
|
|
WRITE_BOOL_FIELD(boolean);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_param ExtensibleNode.
|
void out_cypher_param(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_param);
|
|
WRITE_STRING_FIELD(name);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_map ExtensibleNode.
|
void out_cypher_map(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_map);
|
|
WRITE_NODE_FIELD(keyvals);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_list ExtensibleNode.
|
void out_cypher_list(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_list);
|
|
WRITE_NODE_FIELD(elems);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_comparison_aexpr ExtensibleNode.
|
void out_cypher_comparison_aexpr(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_comparison_aexpr);
|
|
WRITE_ENUM_FIELD(kind, A_Expr_Kind);
|
WRITE_NODE_FIELD(name);
|
WRITE_NODE_FIELD(lexpr);
|
WRITE_NODE_FIELD(rexpr);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_comparison_boolexpr ExtensibleNode.
|
void out_cypher_comparison_boolexpr(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_comparison_boolexpr);
|
|
WRITE_ENUM_FIELD(boolop, BoolExprType);
|
WRITE_NODE_FIELD(args);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_string_match ExtensibleNode.
|
void out_cypher_string_match(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_string_match);
|
|
WRITE_ENUM_FIELD(operation, cypher_string_match_op);
|
WRITE_NODE_FIELD(lhs);
|
WRITE_NODE_FIELD(rhs);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_typecast ExtensibleNode.
|
void out_cypher_typecast(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_typecast);
|
|
WRITE_NODE_FIELD(expr);
|
WRITE_STRING_FIELD(typecast);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_integer_const ExtensibleNode.
|
void out_cypher_integer_const(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_integer_const);
|
|
WRITE_INT64_FIELD(integer);
|
WRITE_LOCATION_FIELD(location);
|
}
|
|
// serialization function for the cypher_sub_pattern ExtensibleNode.
|
void out_cypher_sub_pattern(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_sub_pattern);
|
|
WRITE_ENUM_FIELD(kind, csp_kind);
|
WRITE_NODE_FIELD(pattern);
|
}
|
|
// serialization function for the cypher_call ExtensibleNode.
|
void out_cypher_call(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_call);
|
|
WRITE_NODE_FIELD(funccall);
|
WRITE_NODE_FIELD(funcexpr);
|
WRITE_NODE_FIELD(where);
|
WRITE_NODE_FIELD(yield_items);
|
}
|
|
// serialization function for the cypher_create_target_nodes ExtensibleNode.
|
void out_cypher_create_target_nodes(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_create_target_nodes);
|
|
WRITE_NODE_FIELD(paths);
|
WRITE_INT32_FIELD(flags);
|
WRITE_INT32_FIELD(graph_oid);
|
}
|
|
// serialization function for the cypher_create_path ExtensibleNode.
|
void out_cypher_create_path(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_create_path);
|
|
WRITE_NODE_FIELD(target_nodes);
|
WRITE_INT32_FIELD(path_attr_num);
|
WRITE_STRING_FIELD(var_name);
|
}
|
|
// serialization function for the cypher_target_node ExtensibleNode.
|
void out_cypher_target_node(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_target_node);
|
|
WRITE_CHAR_FIELD(type);
|
WRITE_INT32_FIELD(flags);
|
WRITE_ENUM_FIELD(dir, cypher_rel_dir);
|
WRITE_NODE_FIELD(id_expr);
|
WRITE_NODE_FIELD(id_expr_state);
|
WRITE_NODE_FIELD(prop_expr);
|
WRITE_NODE_FIELD(prop_expr_state);
|
WRITE_INT32_FIELD(prop_attr_num);
|
WRITE_NODE_FIELD(resultRelInfo);
|
WRITE_NODE_FIELD(elemTupleSlot);
|
WRITE_OID_FIELD(relid);
|
WRITE_STRING_FIELD(label_name);
|
WRITE_STRING_FIELD(variable_name);
|
WRITE_INT32_FIELD(tuple_position);
|
}
|
|
// serialization function for the cypher_update_information ExtensibleNode.
|
void out_cypher_update_information(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_update_information);
|
|
WRITE_NODE_FIELD(set_items);
|
WRITE_INT32_FIELD(flags);
|
WRITE_INT32_FIELD(tuple_position);
|
WRITE_STRING_FIELD(graph_name);
|
WRITE_STRING_FIELD(clause_name);
|
}
|
|
// serialization function for the cypher_update_item ExtensibleNode.
|
void out_cypher_update_item(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_update_item);
|
|
WRITE_INT32_FIELD(prop_position);
|
WRITE_INT32_FIELD(entity_position);
|
WRITE_STRING_FIELD(var_name);
|
WRITE_STRING_FIELD(prop_name);
|
WRITE_NODE_FIELD(qualified_name);
|
WRITE_BOOL_FIELD(remove_item);
|
WRITE_BOOL_FIELD(is_add);
|
}
|
|
// serialization function for the cypher_delete_information ExtensibleNode.
|
void out_cypher_delete_information(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_delete_information);
|
|
WRITE_NODE_FIELD(delete_items);
|
WRITE_INT32_FIELD(flags);
|
WRITE_STRING_FIELD(graph_name);
|
WRITE_INT32_FIELD(graph_oid);
|
WRITE_BOOL_FIELD(detach);
|
}
|
|
// serialization function for the cypher_delete_item ExtensibleNode.
|
void out_cypher_delete_item(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_delete_item);
|
|
WRITE_NODE_FIELD(entity_position);
|
WRITE_STRING_FIELD(var_name);
|
}
|
|
// serialization function for the cypher_merge_information ExtensibleNode.
|
void out_cypher_merge_information(StringInfo str, const ExtensibleNode *node)
|
{
|
DEFINE_AG_NODE(cypher_merge_information);
|
|
WRITE_INT32_FIELD(flags);
|
WRITE_INT32_FIELD(graph_oid);
|
WRITE_INT32_FIELD(merge_function_attr);
|
WRITE_NODE_FIELD(path);
|
}
|
|
/*
|
* Copied from Postgres
|
*
|
* Convert one char. Goes through outToken() so that special characters are
|
* escaped.
|
*/
|
static void
|
outChar(StringInfo str, char c)
|
{
|
char in[2];
|
|
in[0] = c;
|
in[1] = '\0';
|
|
outToken(str, in);
|
}
|