@@ -84,6 +84,9 @@ static Node *transform_clause_for_join(cypher_parsestate *cpstate, cypher_clause
8484static cypher_clause * convert_merge_to_match (cypher_merge * merge );
8585static void transform_cypher_merge_mark_tuple_position (cypher_parsestate * cpstate , List * target_list , cypher_create_path * path );
8686
87+ // load csv
88+ static Query * transform_cypher_load_csv (cypher_parsestate * cpstate , cypher_clause * clause );
89+
8790// transform
8891#define PREV_CYPHER_CLAUSE_ALIAS "_"
8992#define CYPHER_OPT_RIGHT_ALIAS "_R"
@@ -145,6 +148,8 @@ Query *transform_cypher_clause(cypher_parsestate *cpstate, cypher_clause *clause
145148 result = transform_cypher_create (cpstate , clause );
146149 } else if (is_ag_node (self , cypher_merge )) {
147150 result = transform_cypher_merge (cpstate , clause );
151+ } else if (is_ag_node (self , cypher_load_csv )) {
152+ result = transform_cypher_load_csv (cpstate , clause );
148153 } else {
149154 ereport (ERROR , (errmsg_internal ("unexpected Node for cypher_clause" )));
150155 }
@@ -156,6 +161,74 @@ Query *transform_cypher_clause(cypher_parsestate *cpstate, cypher_clause *clause
156161}
157162
158163
164+ static FuncExpr * make_load_csv_clause_function (char * file_name ) {
165+
166+ return makeFuncExpr (
167+ get_ag_func_oid ("load_csv" , 1 , TEXTOID ),
168+ GTYPEOID ,
169+ list_make1 (makeConst (TEXTOID , -1 , InvalidOid , strlen (file_name ), PointerGetDatum (file_name ), false, false)),
170+ InvalidOid ,
171+ InvalidOid ,
172+ COERCE_EXPLICIT_CALL );
173+ }
174+
175+ static Query * transform_cypher_load_csv (cypher_parsestate * cpstate , cypher_clause * clause ) {
176+ ParseState * pstate = (ParseState * )cpstate ;
177+ cypher_load_csv * self = (cypher_create * )clause -> self ;
178+
179+ Query * query = makeNode (Query );
180+ query -> commandType = CMD_SELECT ;
181+ query -> targetList = NIL ;
182+
183+ if (clause -> prev ) {
184+ query -> targetList = list_concat (query -> targetList ,
185+ expandNSItemAttrs (get_parse_state (cpstate ),
186+ transform_prev_cypher_clause (cpstate , clause -> prev , true),
187+ 0 ,
188+ -1 ));
189+ }
190+
191+
192+
193+ ParseNamespaceItem * pnsi = add_srf_to_query (
194+ cpstate ,
195+ makeFuncCall (
196+ list_make2 (makeString ("postgraph" ), makeString ("load_csv" )),
197+ list_make1 (makeString (self -> file )),
198+ COERCE_EXPLICIT_CALL , -1 ),
199+ self -> alias ,
200+ list_make1 (makeString ("val" )));
201+
202+ query -> targetList = lappend (query -> targetList ,
203+ makeTargetEntry (
204+ scanNSItemForColumn (pstate , pnsi , 0 , "val" , -1 ),
205+ pstate -> p_next_resno ++ ,
206+ self -> alias ,
207+ false));
208+
209+ query -> rtable = pstate -> p_rtable ;
210+ query -> jointree = makeFromExpr (pstate -> p_joinlist , NULL );
211+
212+ if (clause -> next )
213+ return query ;
214+
215+
216+ {
217+ cypher_parsestate * new_cpstate = make_cypher_parsestate (cpstate );
218+ Query * topquery = makeNode (Query );
219+ topquery -> commandType = CMD_SELECT ;
220+ topquery -> targetList = NIL ;
221+
222+ transform_cypher_clause_as_subquery_2 (new_cpstate , query );
223+
224+ topquery -> rtable = new_cpstate -> pstate .p_rtable ;
225+ topquery -> jointree = makeFromExpr (new_cpstate -> pstate .p_joinlist , NULL );
226+
227+ return topquery ;
228+ }
229+ }
230+
231+
159232/*
160233 * This function is similar to transformFromClause() that is called with a
161234 * single RangeSubselect.
@@ -2541,23 +2614,15 @@ static cypher_target_node *transform_merge_cypher_edge(cypher_parsestate *cpstat
25412614 table_close (rel , NoLock );
25422615
25432616 // props
2544- if (edge -> props ) {
2545- /* query->targetList = lappend(query->targetList,
2546- makeTargetEntry(//BlackPink
2547- add_volatile_wrapper(transform_cypher_expr(cpstate, edge->props, EXPR_KIND_INSERT_TARGET)),
2617+ if (edge -> props )
2618+ query -> targetList = lappend (query -> targetList ,
2619+ makeTargetEntry (
2620+ add_volatile_wrapper (target_node -> prop_expr = transform_cypher_expr (cpstate , edge -> props , EXPR_KIND_INSERT_TARGET )),
25482621 target_node -> prop_attr_num = get_parse_state (cpstate )-> p_next_resno ++ ,
25492622 make_property_alias (edge -> name ),
25502623 false));
2551- */
2552- query -> targetList = lappend (query -> targetList ,
2553- makeTargetEntry (
2554- add_volatile_wrapper (scanNSItemForColumn (pstate , edge -> pnsi , 0 , AG_EDGE_COLNAME_PROPERTIES , -1 )),
2555- target_node -> prop_attr_num = get_parse_state (cpstate )-> p_next_resno ++ ,
2556- make_property_alias (edge -> name ),
2557- false));
2558- } else {
2624+ else
25592625 target_node -> prop_attr_num = InvalidAttrNumber ;
2560- }
25612626
25622627 return target_node ;
25632628}
@@ -2570,11 +2635,6 @@ static cypher_target_node *transform_merge_cypher_node(cypher_parsestate *cpstat
25702635
25712636
25722637 if (node -> name ) {
2573- /* ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2574- errmsg("MERGE does not support variables"),
2575- parser_errposition(get_parse_state(cpstate), node->location)));
2576- */
2577- // /ereport(ERROR, (errmsg_internal("nodes in CREATE cannot be a variable")));
25782638 Var * var = NULL ;
25792639 if ((var = colNameToVar (cpstate , node -> name , false, -1 )) ||
25802640 (target_node -> id_attr_num = get_target_entry_resno (cpstate , query -> targetList , make_id_alias (node -> name ))) != -1 ) {
@@ -2608,7 +2668,6 @@ static cypher_target_node *transform_merge_cypher_node(cypher_parsestate *cpstat
26082668 target_node -> label_name = node -> label ;
26092669 } else {
26102670 target_node -> label_name = "" ;
2611- //node->label = AG_DEFAULT_LABEL_VERTEX;
26122671 }
26132672
26142673 target_node -> flags |= CYPHER_TARGET_NODE_FLAG_INSERT ;
@@ -2621,35 +2680,15 @@ static cypher_target_node *transform_merge_cypher_node(cypher_parsestate *cpstat
26212680 table_close (rel , NoLock );
26222681 target_node -> adj_relid = lcd -> vertex_adjlist ;
26232682 // props
2624- if (node -> props ) {
2625- target_node -> prop_expr = transform_cypher_expr (cpstate , node -> props , EXPR_KIND_INSERT_TARGET );
2683+ if (node -> props )
26262684 query -> targetList = lappend (query -> targetList ,
26272685 makeTargetEntry (
2628- add_volatile_wrapper (transform_cypher_expr (cpstate , node -> props , EXPR_KIND_INSERT_TARGET )),
2686+ add_volatile_wrapper (target_node -> prop_expr = transform_cypher_expr (cpstate , node -> props , EXPR_KIND_INSERT_TARGET )),
26292687 target_node -> prop_attr_num = get_parse_state (cpstate )-> p_next_resno ++ ,
26302688 make_property_alias (node -> name ),
26312689 false));
2632- /*query->targetList = lappend(query->targetList,
2633- makeTargetEntry(
2634- colNameToVar(cpstate, make_property_alias(node->name), false, -1),
2635- target_node->prop_attr_num = get_parse_state(cpstate)->p_next_resno++,
2636- make_property_alias(node->name),
2637- false));*/
2638- /*
2639- query->targetList = lappend(query->targetList,
2640- makeTargetEntry(
2641- add_volatile_wrapper(scanNSItemForColumn(get_parse_state(cpstate), refnameNamespaceItem(cpstate, NULL, node->name, -1, NULL), 0, AG_VERTEX_COLNAME_PROPERTIES, -1)),
2642- target_node->prop_attr_num = get_parse_state(cpstate)->p_next_resno++,
2643- make_property_alias(node->name),
2644- false));
2645-
2646- colNameToVar(cpstate, node->name, false, -1))
2647- */
2648-
2649-
2650- } else {
2690+ else
26512691 target_node -> prop_attr_num = InvalidAttrNumber ;
2652- }
26532692
26542693 return target_node ;
26552694}
0 commit comments