Skip to content

Commit ae156f3

Browse files
Allow subquery results which are exec params as gapfill arguments
1 parent f54a722 commit ae156f3

8 files changed

Lines changed: 1425 additions & 73 deletions

File tree

.unreleased/pr_9821

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Implements: #9821 Allow subquery results which are exec params as gapfill arguments
2+
Thanks: @scimad and @Nosfistis for suggesting expanding coverage for gapfill arguments

tsl/src/nodes/gapfill/gapfill_exec.c

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ is_simple_expr_walker(Node *node, void *context)
319319
case T_CaseWhen:
320320
break;
321321
case T_Param:
322-
if (castNode(Param, node)->paramkind != PARAM_EXTERN)
322+
if (castNode(Param, node)->paramkind != PARAM_EXTERN &&
323+
castNode(Param, node)->paramkind != PARAM_EXEC)
323324
{
324325
return true;
325326
}
@@ -799,30 +800,12 @@ gapfill_advance_timestamp(GapFillState *state)
799800
}
800801
}
801802

802-
/*
803-
* Initialize the scan state
804-
*/
805803
static void
806-
gapfill_begin(CustomScanState *node, EState *estate, int eflags)
804+
gapfill_initialize_arguments(GapFillState *state)
807805
{
808-
GapFillState *state = (GapFillState *) node;
809-
CustomScan *cscan = castNode(CustomScan, state->csstate.ss.ps.plan);
810-
811-
/*
812-
* this is the time_bucket_gapfill call from the plan which is used to
813-
* extract arguments and to align gapfill_start
814-
*/
815-
FuncExpr *func = list_nth(cscan->custom_private, GFP_GapfillFunc);
816-
TupleDesc tupledesc = state->csstate.ss.ps.ps_ResultTupleSlot->tts_tupleDescriptor;
817-
List *targetlist = copyObject(state->csstate.ss.ps.plan->targetlist);
818806
bool isnull;
819807
Datum arg_value;
820808

821-
state->gapfill_typid = func->funcresulttype;
822-
state->state = FETCHED_NONE;
823-
state->subslot = MakeSingleTupleTableSlot(tupledesc, &TTSOpsVirtual);
824-
state->scanslot = MakeSingleTupleTableSlot(tupledesc, &TTSOpsVirtual);
825-
826809
/* bucket_width */
827810
if (!is_simple_expr(linitial(state->args)))
828811
{
@@ -840,7 +823,7 @@ gapfill_begin(CustomScanState *node, EState *estate, int eflags)
840823
errmsg("invalid time_bucket_gapfill argument: bucket_width cannot be NULL")));
841824
}
842825

843-
state->gapfill_period = gapfill_period_get_internal(func->funcresulttype,
826+
state->gapfill_period = gapfill_period_get_internal(state->gapfill_typid,
844827
exprType(linitial(state->args)),
845828
arg_value,
846829
&state->gapfill_interval);
@@ -907,8 +890,31 @@ gapfill_begin(CustomScanState *node, EState *estate, int eflags)
907890
errhint("Specify start and finish as arguments or in the WHERE clause.")));
908891
}
909892

910-
state->gapfill_end = gapfill_datum_get_internal(arg_value, func->funcresulttype);
893+
state->gapfill_end = gapfill_datum_get_internal(arg_value, state->gapfill_typid);
911894
}
895+
}
896+
897+
/*
898+
* Initialize the scan state
899+
*/
900+
static void
901+
gapfill_begin(CustomScanState *node, EState *estate, int eflags)
902+
{
903+
GapFillState *state = (GapFillState *) node;
904+
CustomScan *cscan = castNode(CustomScan, state->csstate.ss.ps.plan);
905+
906+
/*
907+
* this is the time_bucket_gapfill call from the plan which is used to
908+
* extract arguments and to align gapfill_start
909+
*/
910+
FuncExpr *func = list_nth(cscan->custom_private, GFP_GapfillFunc);
911+
TupleDesc tupledesc = state->csstate.ss.ps.ps_ResultTupleSlot->tts_tupleDescriptor;
912+
List *targetlist = copyObject(state->csstate.ss.ps.plan->targetlist);
913+
914+
state->gapfill_typid = func->funcresulttype;
915+
state->state = PREFETCH;
916+
state->subslot = MakeSingleTupleTableSlot(tupledesc, &TTSOpsVirtual);
917+
state->scanslot = MakeSingleTupleTableSlot(tupledesc, &TTSOpsVirtual);
912918

913919
gapfill_state_initialize_columns(state, targetlist);
914920

@@ -939,6 +945,12 @@ gapfill_exec(CustomScanState *node)
939945
{
940946
CHECK_FOR_INTERRUPTS();
941947

948+
if (PREFETCH == state->state)
949+
{
950+
gapfill_initialize_arguments(state);
951+
state->state = FETCHED_NONE;
952+
}
953+
942954
/* fetch next tuple from subplan */
943955
if (FETCHED_NONE == state->state)
944956
{
@@ -1043,6 +1055,7 @@ gapfill_rescan(CustomScanState *node)
10431055
ExecReScan(linitial(node->custom_ps));
10441056
}
10451057

1058+
gapfill_initialize_arguments(state);
10461059
state->state = FETCHED_NONE;
10471060
state->next_timestamp = state->gapfill_start;
10481061
state->next_offset = state->gapfill_interval;

tsl/src/nodes/gapfill/gapfill_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
*/
4747
typedef enum GapFillFetchState
4848
{
49+
PREFETCH,
4950
FETCHED_NONE,
5051
FETCHED_ONE,
5152
FETCHED_NEXT_GROUP,

0 commit comments

Comments
 (0)