4747#include <utils/datum.h>
4848
4949#include "guc.h"
50+ #include "nodes/decompress_chunk/decompress_chunk.h"
5051#include "nodes/skip_scan/skip_scan.h"
5152
5253typedef enum SkipScanStage
@@ -88,6 +89,12 @@ typedef struct SkipScanState
8889 /* rescan required before getting next tuple */
8990 bool needs_rescan ;
9091
92+ /* child_plan node is the input for skip scan plan node.
93+ * if skipscan is directly over index, child_plan = idx_scan
94+ * if skip scan is over compressed index, idx_scan = compressed_index,
95+ * child_plan = decompressed input into skip scan
96+ */
97+ Plan * child_plan ;
9198 void * idx_scan ;
9299} SkipScanState ;
93100
@@ -102,8 +109,19 @@ skip_scan_begin(CustomScanState *node, EState *estate, int eflags)
102109 SkipScanState * state = (SkipScanState * ) node ;
103110 state -> ctx = AllocSetContextCreate (estate -> es_query_cxt , "skipscan" , ALLOCSET_DEFAULT_SIZES );
104111
105- state -> idx = (ScanState * ) ExecInitNode (state -> idx_scan , estate , eflags );
106- node -> custom_ps = list_make1 (state -> idx );
112+ node -> custom_ps = list_make1 ((ScanState * ) ExecInitNode (state -> child_plan , estate , eflags ));
113+ ScanState * child_state = linitial (node -> custom_ps );
114+ if (state -> child_plan == state -> idx_scan )
115+ {
116+ state -> idx = child_state ;
117+ }
118+ else if (IsA (child_state , CustomScanState ))
119+ {
120+ Assert (ts_is_decompress_chunk_plan (state -> child_plan ));
121+ state -> idx = linitial (castNode (CustomScanState , child_state )-> custom_ps );
122+ }
123+ else
124+ elog (ERROR , "unknown subscan type in SkipScan" );
107125
108126 if (IsA (state -> idx_scan , IndexScan ))
109127 {
@@ -242,6 +260,7 @@ skip_scan_exec(CustomScanState *node)
242260{
243261 SkipScanState * state = (SkipScanState * ) node ;
244262 TupleTableSlot * result ;
263+ ScanState * child_state ;
245264
246265 /*
247266 * We are not supporting projection here since no plan
@@ -267,7 +286,8 @@ skip_scan_exec(CustomScanState *node)
267286 break ;
268287
269288 case SS_NULLS_FIRST :
270- result = state -> idx -> ps .ExecProcNode (& state -> idx -> ps );
289+ child_state = linitial (state -> cscan_state .custom_ps );
290+ result = child_state -> ps .ExecProcNode (& child_state -> ps );
271291
272292 /*
273293 * if we found a NULL value we return it, otherwise
@@ -281,7 +301,8 @@ skip_scan_exec(CustomScanState *node)
281301
282302 case SS_NOT_NULL :
283303 case SS_VALUES :
284- result = state -> idx -> ps .ExecProcNode (& state -> idx -> ps );
304+ child_state = linitial (state -> cscan_state .custom_ps );
305+ result = child_state -> ps .ExecProcNode (& child_state -> ps );
285306
286307 if (!TupIsNull (result ))
287308 {
@@ -314,7 +335,8 @@ skip_scan_exec(CustomScanState *node)
314335 break ;
315336
316337 case SS_NULLS_LAST :
317- result = state -> idx -> ps .ExecProcNode (& state -> idx -> ps );
338+ child_state = linitial (state -> cscan_state .custom_ps );
339+ result = child_state -> ps .ExecProcNode (& child_state -> ps );
318340 skip_scan_switch_stage (state , SS_END );
319341 return result ;
320342 break ;
@@ -330,7 +352,8 @@ static void
330352skip_scan_end (CustomScanState * node )
331353{
332354 SkipScanState * state = (SkipScanState * ) node ;
333- ExecEndNode (& state -> idx -> ps );
355+ ScanState * child_state = linitial (state -> cscan_state .custom_ps );
356+ ExecEndNode (& child_state -> ps );
334357}
335358
336359static void
@@ -352,7 +375,8 @@ skip_scan_rescan(CustomScanState *node)
352375 state -> prev_datum = 0 ;
353376
354377 state -> needs_rescan = false;
355- ExecReScan (& state -> idx -> ps );
378+ ScanState * child_state = linitial (state -> cscan_state .custom_ps );
379+ ExecReScan (& child_state -> ps );
356380 MemoryContextReset (state -> ctx );
357381}
358382
@@ -369,7 +393,16 @@ tsl_skip_scan_state_create(CustomScan *cscan)
369393{
370394 SkipScanState * state = (SkipScanState * ) newNode (sizeof (SkipScanState ), T_CustomScanState );
371395
372- state -> idx_scan = linitial (cscan -> custom_plans );
396+ state -> child_plan = linitial (cscan -> custom_plans );
397+ if (ts_is_decompress_chunk_plan (state -> child_plan ))
398+ {
399+ CustomScan * csplan = castNode (CustomScan , state -> child_plan );
400+ state -> idx_scan = linitial (csplan -> custom_plans );
401+ }
402+ else
403+ {
404+ state -> idx_scan = state -> child_plan ;
405+ }
373406 state -> stage = SS_BEGIN ;
374407
375408 state -> distinct_col_attnum = linitial_int (cscan -> custom_private );
0 commit comments