55#include "utils/builtins.h"
66#include "utils/elog.h"
77#include "utils/lsyscache.h"
8+
89#include "nodes/print.h"
10+
911#include "catalog/pg_proc.h"
1012#include "catalog/pg_operator.h"
1113#include "commands/explain.h"
@@ -37,12 +39,15 @@ typedef struct
3739{
3840CustomScanState css ;
3941
40- HeapTupleData scan_tuple ;/* buffer to fetch tuple */
41- List * dev_tlist ;/* tlist to be returned from the device */
42- List * dev_quals ;/* quals to be run on the device */
42+ List * scan_tlist ;
43+
44+ Relation outer_rel ;
45+ ItemPointer outer_ptr ;
46+ HeapTuple outer_tup ;
4347
44- Relation left ;
45- Relation right ;
48+ Relation inner_rel ;
49+ ItemPointer inner_ptr ;
50+ HeapTuple inner_tup ;
4651}CrossmatchScanState ;
4752
4853static CustomPathMethods crossmatch_path_methods ;
@@ -232,6 +237,12 @@ create_crossmatch_plan(PlannerInfo *root,
232237List * otherclauses ;
233238CustomScan * cscan ;
234239
240+ Index lrel = gpath -> outer_path -> parent -> relid ;
241+ Index rrel = gpath -> inner_path -> parent -> relid ;
242+
243+ /* relids should not be 0 */
244+ Assert (lrel != 0 && rrel != 0 );
245+
235246if (IS_OUTER_JOIN (gpath -> jointype ))
236247{
237248extract_actual_join_clauses (joinrestrictclauses ,
@@ -246,17 +257,16 @@ create_crossmatch_plan(PlannerInfo *root,
246257
247258cscan = makeNode (CustomScan );
248259cscan -> scan .plan .targetlist = tlist ;
260+ cscan -> custom_scan_tlist = tlist ;/* output of this node */
249261cscan -> scan .plan .qual = NIL ;
250262cscan -> scan .scanrelid = 0 ;
251263
252- cscan -> custom_scan_tlist = tlist ;/* TODO: recheck target list */
253-
254- elog (LOG ,"tlist:" );
255- pprint (tlist );
256-
257264cscan -> flags = best_path -> flags ;
258265cscan -> methods = & crossmatch_plan_methods ;
259266
267+ cscan -> custom_private = list_make2_oid (root -> simple_rte_array [lrel ]-> relid ,
268+ root -> simple_rte_array [rrel ]-> relid );
269+
260270return & cscan -> scan .plan ;
261271}
262272
@@ -271,6 +281,12 @@ crossmatch_create_scan_state(CustomScan *node)
271281
272282scan_state -> css .ss .ps .ps_TupFromTlist = false;
273283
284+ scan_state -> scan_tlist = node -> custom_scan_tlist ;
285+ scan_state -> outer_rel = heap_open (linitial_oid (node -> custom_private ),
286+ AccessShareLock );
287+ scan_state -> inner_rel = heap_open (lsecond_oid (node -> custom_private ),
288+ AccessShareLock );
289+
274290return (Node * )scan_state ;
275291}
276292
@@ -283,49 +299,53 @@ crossmatch_begin(CustomScanState *node, EState *estate, int eflags)
283299static TupleTableSlot *
284300crossmatch_exec (CustomScanState * node )
285301{
286- TupleTableSlot * slot = node -> ss .ps .ps_ResultTupleSlot ;
287- TupleDesc tupdesc = node -> ss .ps .ps_ResultTupleSlot -> tts_tupleDescriptor ;
288- ExprContext * econtext = node -> ss .ps .ps_ProjInfo -> pi_exprContext ;
302+ TupleTableSlot * slot = node -> ss .ss_ScanTupleSlot ;
303+ TupleDesc tupdesc = node -> ss .ss_ScanTupleSlot -> tts_tupleDescriptor ;
289304HeapTuple htup ;
290-
291- HeapTupleData fetched_tup ;
292-
293- ResetExprContext (econtext );
305+ TupleTableSlot * result ;
294306
295307/* TODO: fill with real data from joined tables */
296- Datum values [4 ]= {DirectFunctionCall1 (spherepoint_in ,CStringGetDatum ("(0d, 0d)" )),
308+ Datum values [2 ]= {DirectFunctionCall1 (spherepoint_in ,CStringGetDatum ("(0d, 0d)" )),
297309DirectFunctionCall1 (spherepoint_in ,CStringGetDatum ("(0d, 0d)" )) };
298- bool nulls [4 ]= {0 ,1 , 1 , 1 };
310+ bool nulls [2 ]= {0 ,0 };
299311
300312elog (LOG ,"slot.natts: %d" ,tupdesc -> natts );
301313
302314htup = heap_form_tuple (tupdesc ,values ,nulls );
303315
304- if (node -> ss .ps .ps_ProjInfo -> pi_itemIsDone != ExprEndResult )
316+ if (node -> ss .ps .ps_ProjInfo )
305317{
306- TupleTableSlot * result ;
307- ExprDoneCond isDone ;
318+ if (* (node -> ss .ps .ps_ProjInfo -> pi_itemIsDone )!= ExprEndResult )
319+ {
320+ ExprDoneCond isDone ;
308321
309- econtext -> ecxt_scantuple = ExecStoreTuple (htup ,slot ,InvalidBuffer , false);
322+ node -> ss . ps . ps_ProjInfo -> pi_exprContext -> ecxt_scantuple = ExecStoreTuple (htup ,slot ,InvalidBuffer , false);
310323
311- result = ExecProject (node -> ss .ps .ps_ProjInfo ,& isDone );
324+ result = ExecProject (node -> ss .ps .ps_ProjInfo ,& isDone );
312325
313- if (isDone != ExprEndResult )
314- {
315- node -> ss .ps .ps_TupFromTlist = (isDone == ExprMultipleResult );
316- return result ;
326+ if (isDone != ExprEndResult )
327+ {
328+ node -> ss .ps .ps_TupFromTlist = (isDone == ExprMultipleResult );
329+ }
317330}
331+ else
332+ result = ExecClearTuple (node -> ss .ps .ps_ResultTupleSlot );
318333}
319334else
320- ExecClearTuple (slot );
335+ {
336+ result = ExecClearTuple (node -> ss .ps .ps_ResultTupleSlot );
337+ }
321338
322- return slot ;
339+ return result ;
323340}
324341
325342static void
326343crossmatch_end (CustomScanState * node )
327344{
345+ CrossmatchScanState * scan_state = (CrossmatchScanState * )node ;
328346
347+ heap_close (scan_state -> outer_rel ,AccessShareLock );
348+ heap_close (scan_state -> inner_rel ,AccessShareLock );
329349}
330350
331351static void