@@ -133,13 +133,13 @@ static void begin_cypher_create(CustomScanState *node, EState *estate, int eflag
133133 ExecGetResultType (node -> ss .ps .lefttree ),
134134 & TTSOpsHeapTuple );
135135
136- /*
136+
137137 if (!CYPHER_CLAUSE_IS_TERMINAL (css -> flags )) {
138138 TupleDesc tupdesc = node -> ss .ss_ScanTupleSlot -> tts_tupleDescriptor ;
139139
140140 ExecAssignProjectionInfo (& node -> ss .ps , tupdesc );
141141 }
142- */
142+
143143
144144 if (list_length (css -> pattern ) != 1 )
145145 ereport (ERROR , (errmsg_internal ("executor create found a multi pattern" )));
@@ -203,111 +203,141 @@ static TupleTableSlot *exec_cypher_create(CustomScanState *csnode)
203203 EState * estate = css -> css .ss .ps .state ;
204204 ExprContext * econtext = css -> css .ss .ps .ps_ExprContext ;
205205
206+ while (true) {
207+ RollbackCmdId (estate );
208+ TupleTableSlot * return_slot = ExecProcNode (csnode -> ss .ps .lefttree );
209+ AdvanceCmdId (estate );
210+
211+ if (TupIsNull (return_slot ))
212+ return return_slot ;
213+ // if ((return_slot->tts_flags = return_slot & TTS_FLAG_EMPTY))
214+ // return NULL;
215+ econtext -> ecxt_scantuple =
216+ csnode -> ss .ps .lefttree -> ps_ProjInfo -> pi_exprContext -> ecxt_scantuple ;
217+ TupleTableSlot * slot = econtext -> ecxt_scantuple ;//csnode->ss.ps.lefttree->ps_ProjInfo->pi_exprContext->ecxt_scantuple;
218+ //slot->tts_ops->materialize(slot);
219+
220+ if (list_length (css -> pattern ) != 1 )
221+ ereport (ERROR , (errmsg_internal ("executor create found a multi pattern" )));
222+
223+ cypher_create_path * path = linitial (css -> pattern );
224+
225+ ListCell * lc ;
226+ int i = 1 ;
227+ foreach (lc , path -> target_nodes ) {
228+ cypher_target_node * node = (cypher_target_node * )lfirst (lc );
229+ bool isNull ;
230+ if (i % 2 == 1 )
231+ css -> vertex_ids [0 ][i /2 ] = ExecEvalExpr (node -> id_expr_state , econtext , & isNull );
232+ else {
233+ css -> edge_ids [0 ][(i - 1 )/2 ] = ExecEvalExpr (node -> id_expr_state , econtext , & isNull );
234+
235+ }
236+ i ++ ;
237+ }
206238
207- RollbackCmdId (estate );
208- TupleTableSlot * slot = ExecProcNode (csnode -> ss .ps .lefttree );
209- AdvanceCmdId (estate );
239+ for (int i = 0 ; i < list_length (path -> target_nodes )/2 + 1 ; i ++ ) {
240+ cypher_target_node * node = (cypher_target_node * )list_nth (path -> target_nodes , i * 2 );
241+
242+ ResultRelInfo * resultRelInfo = node -> resultRelInfo ;
243+ TupleTableSlot * elemTupleSlot = node -> elemTupleSlot ;
210244
211- slot = csnode -> ss .ps .lefttree -> ps_ProjInfo -> pi_exprContext -> ecxt_scantuple ;
212- slot -> tts_ops -> materialize (slot );
213- if (list_length (css -> pattern ) != 1 )
214- ereport (ERROR , (errmsg_internal ("executor create found a multi pattern" )));
245+ ResultRelInfo * * old_estate_es_result_relations_info = NULL ;
215246
216- cypher_create_path * path = linitial (css -> pattern );
247+ /* save the old result relation info */
248+ old_estate_es_result_relations_info = estate -> es_result_relations ;
217249
218- ListCell * lc ;
219- int i = 1 ;
220- foreach (lc , path -> target_nodes ) {
221- cypher_target_node * node = (cypher_target_node * )lfirst (lc );
222- bool isNull ;
223- if (i % 2 == 1 )
224- css -> vertex_ids [0 ][i /2 ] = ExecEvalExpr (node -> id_expr_state , econtext , & isNull );
225- else {
226- css -> edge_ids [0 ][(i - 1 )/2 ] = ExecEvalExpr (node -> id_expr_state , econtext , & isNull );
227-
228- }
229- i ++ ;
230-
231- }
250+ estate -> es_result_relations = & resultRelInfo ;
232251
233- for (int i = 0 ; i < list_length (path -> target_nodes )/2 + 1 ; i ++ ) {
234- cypher_target_node * node = (cypher_target_node * )list_nth (path -> target_nodes , i * 2 );
235-
236- ResultRelInfo * resultRelInfo = node -> resultRelInfo ;
237- TupleTableSlot * elemTupleSlot = node -> elemTupleSlot ;
252+ ExecClearTuple (elemTupleSlot );
253+
254+ // get the next graphid for this vertex.
255+ elemTupleSlot -> tts_values [0 ] = css -> vertex_ids [0 ][i ];
256+ elemTupleSlot -> tts_isnull [0 ] = false;
257+ if (node -> id_attr_num != InvalidAttrNumber ) {
258+ slot -> tts_values [node -> id_attr_num - 1 ] = GRAPHID_GET_DATUM (css -> vertex_ids [0 ][i ]);
259+ slot -> tts_isnull [node -> id_attr_num - 1 ] = false;
260+ }
238261
239- ResultRelInfo * * old_estate_es_result_relations_info = NULL ;
262+ // get the properties for this vertex
263+ if (node -> prop_attr_num == InvalidAttrNumber ) {
264+ elemTupleSlot -> tts_values [1 ] = NULL ;
265+ elemTupleSlot -> tts_isnull [1 ] = true;
266+ } else {
267+ elemTupleSlot -> tts_values [1 ] = slot -> tts_values [node -> prop_attr_num - 1 ];
268+ elemTupleSlot -> tts_isnull [1 ] = slot -> tts_isnull [node -> prop_attr_num - 1 ];
269+ }
240270
241- /* save the old result relation info */
242- old_estate_es_result_relations_info = estate -> es_result_relations ;
271+ if (node -> tuple_position != InvalidAttrNumber ) {
272+ slot -> tts_values [node -> tuple_position - 1 ] = VERTEX_GET_DATUM (create_vertex (
273+ slot -> tts_values [node -> id_attr_num - 1 ],
274+ css -> graph_oid ,
275+ elemTupleSlot -> tts_isnull [1 ] ? NULL : DATUM_GET_GTYPE_P (elemTupleSlot -> tts_values [1 ])));
276+ slot -> tts_isnull [node -> tuple_position - 1 ] = false;
277+ }
243278
244- estate -> es_result_relations = & resultRelInfo ;
279+ // Insert the new vertex
280+ insert_entity_tuple (resultRelInfo , elemTupleSlot , estate );
245281
246- ExecClearTuple (elemTupleSlot );
247282
248- // get the next graphid for this vertex.
249- elemTupleSlot -> tts_values [0 ] = css -> vertex_ids [0 ][i ];
250- elemTupleSlot -> tts_isnull [0 ] = false;
251- if (node -> id_attr_num != InvalidAttrNumber ) {
252- slot -> tts_values [node -> id_attr_num - 1 ] = GRAPHID_GET_DATUM (css -> vertex_ids [0 ][i ]);
253- slot -> tts_isnull [node -> id_attr_num - 1 ] = false;
254- }
283+ if (list_length (path -> target_nodes ) > 1 && i < (list_length (path -> target_nodes )/2 )) {
255284
256- // get the properties for this vertex
257- if (node -> prop_attr_num == InvalidAttrNumber ) {
258- elemTupleSlot -> tts_values [1 ] = NULL ;
259- elemTupleSlot -> tts_isnull [1 ] = true;
260- } else {
261- elemTupleSlot -> tts_values [1 ] = slot -> tts_values [node -> prop_attr_num - 1 ];
262- elemTupleSlot -> tts_isnull [1 ] = slot -> tts_isnull [node -> prop_attr_num - 1 ];
263- }
285+
286+ resultRelInfo = node -> adj_resultRelInfo ;
287+ elemTupleSlot = node -> adj_elemTupleSlot ;
264288
265- if (node -> tuple_position != InvalidAttrNumber ) {
266- create_vertex (
267- GRAPHID_GET_DATUM (slot -> tts_values [node -> id_attr_num - 1 ]),
268- css -> graph_oid ,
269- node -> prop_attr_num == InvalidAttrNumber ? NULL : DATUM_GET_GTYPE_P (slot -> tts_values [node -> prop_attr_num - 1 ]));
270- }
289+ estate -> es_result_relations = & resultRelInfo ;
271290
272- // Insert the new vertex
273- insert_entity_tuple (resultRelInfo , elemTupleSlot , estate );
291+ ExecClearTuple (elemTupleSlot );
292+ cypher_target_node * node = (cypher_target_node * )list_nth (path -> target_nodes , (i * 2 ) + 1 );
293+ // get the next graphid for this vertex.
294+ elemTupleSlot -> tts_values [0 ] = css -> edge_ids [0 ][i ];
295+ elemTupleSlot -> tts_isnull [0 ] = false;
296+
297+ elemTupleSlot -> tts_values [1 ] = css -> vertex_ids [0 ][node -> dir == CYPHER_REL_DIR_RIGHT ? i : i + 1 ];
298+ elemTupleSlot -> tts_isnull [1 ] = false;
299+
300+ elemTupleSlot -> tts_values [2 ] = css -> vertex_ids [0 ][node -> dir == CYPHER_REL_DIR_RIGHT ? i + 1 : i ];
301+ elemTupleSlot -> tts_isnull [2 ] = false;
274302
275- if (list_length (path -> target_nodes ) > 1 && i < (list_length (path -> target_nodes )/2 )) {
276- resultRelInfo = node -> adj_resultRelInfo ;
277- elemTupleSlot = node -> adj_elemTupleSlot ;
278303
279- estate -> es_result_relations = & resultRelInfo ;
304+ if (node -> prop_attr_num == InvalidAttrNumber ) {
305+ elemTupleSlot -> tts_values [3 ] = NULL ;
306+ elemTupleSlot -> tts_isnull [3 ] = true;
307+ } else {
308+ //TupleTableSlot *scanTupleSlot = econtext->ecxt_scantuple;
309+ elemTupleSlot -> tts_values [3 ] = slot -> tts_values [node -> prop_attr_num - 1 ];
310+ elemTupleSlot -> tts_isnull [3 ] = slot -> tts_isnull [node -> prop_attr_num - 1 ];
311+ }
280312
281- ExecClearTuple (elemTupleSlot );
313+ // Insert the new vertex
314+ insert_entity_tuple (resultRelInfo , elemTupleSlot , estate );
282315
283- // get the next graphid for this vertex.
284- elemTupleSlot -> tts_values [0 ] = css -> edge_ids [0 ][i ];
285- elemTupleSlot -> tts_isnull [0 ] = false;
286-
287- elemTupleSlot -> tts_values [1 ] = css -> vertex_ids [0 ][node -> dir == CYPHER_REL_DIR_RIGHT ? i : i + 1 ];
288- elemTupleSlot -> tts_isnull [1 ] = false;
289-
290- elemTupleSlot -> tts_values [2 ] = css -> vertex_ids [0 ][node -> dir == CYPHER_REL_DIR_RIGHT ? i + 1 : i ];
291- elemTupleSlot -> tts_isnull [2 ] = false;
292316
317+ if (node -> tuple_position != InvalidAttrNumber ) {
318+ slot -> tts_values [node -> tuple_position - 1 ] = EDGE_GET_DATUM (create_edge (
319+ css -> edge_ids [0 ][i ],
320+ css -> vertex_ids [0 ][node -> dir == CYPHER_REL_DIR_RIGHT ? i : i + 1 ],
321+ css -> vertex_ids [0 ][node -> dir == CYPHER_REL_DIR_RIGHT ? i + 1 : i ],
322+ css -> graph_oid ,
323+ elemTupleSlot -> tts_isnull [3 ] ? NULL : DATUM_GET_GTYPE_P (elemTupleSlot -> tts_values [3 ])));
324+ slot -> tts_isnull [node -> tuple_position - 1 ] = false;
325+ }
293326
294- if (node -> prop_attr_num == InvalidAttrNumber ) {
295- elemTupleSlot -> tts_values [3 ] = NULL ;
296- elemTupleSlot -> tts_isnull [3 ] = true;
297- } else {
298- //TupleTableSlot *scanTupleSlot = econtext->ecxt_scantuple;
299- elemTupleSlot -> tts_values [3 ] = slot -> tts_values [node -> prop_attr_num - 1 ];
300- elemTupleSlot -> tts_isnull [3 ] = slot -> tts_isnull [node -> prop_attr_num - 1 ];
301327 }
328+ /* restore the old result relation info */
329+ estate -> es_result_relations = old_estate_es_result_relations_info ;
330+ }
302331
303- // Insert the new vertex
304- insert_entity_tuple (resultRelInfo , elemTupleSlot , estate );
332+ // if(CYPHER_CLAUSE_IS_TERMINAL(css->flags))
333+ // return NULL;
334+ if (!CYPHER_CLAUSE_IS_TERMINAL (css -> flags )) {
335+ econtext -> ecxt_scantuple = ExecProject (csnode -> ss .ps .lefttree -> ps_ProjInfo );
336+ return ExecProject (csnode -> ss .ps .ps_ProjInfo );
337+ // return return_slot;
305338 }
306- /* restore the old result relation info */
307- estate -> es_result_relations = old_estate_es_result_relations_info ;
308- }
309339
310- return NULL ;
340+ }
311341}
312342
313343static void end_cypher_create (CustomScanState * node )
0 commit comments