Skip to content

Commit 6a9fffc

Browse files
committed
Refactor SPI_cursor_open/SPI_cursor_open_with_args so that the latter sets
the PARAM_FLAG_CONST flag on the parameters that are passed into the portal, while the former's behavior is unchanged. This should only affect the case where the portal is executing an EXPLAIN; it will cause the generated plan to look more like what would be generated if the portal were actually executing the command being explained. Per gripe from Pavel.
1 parent 6d19e9f commit 6a9fffc

File tree

1 file changed

+80
-60
lines changed
  • src/backend/executor

1 file changed

+80
-60
lines changed

src/backend/executor/spi.c

+80-60
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.195 2008/05/12 20:02:00 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.196 2008/06/01 17:32:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -36,6 +36,10 @@ static int _SPI_stack_depth = 0; /* allocated size of _SPI_stack */
3636
static int _SPI_connected = -1;
3737
static int _SPI_curid = -1;
3838

39+
static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
40+
Datum *Values, const char *Nulls,
41+
bool read_only, int pflags);
42+
3943
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan,
4044
ParamListInfo boundParams);
4145

@@ -916,6 +920,80 @@ Portal
916920
SPI_cursor_open(const char *name, SPIPlanPtr plan,
917921
Datum *Values, const char *Nulls,
918922
bool read_only)
923+
{
924+
return SPI_cursor_open_internal(name, plan, Values, Nulls,
925+
read_only, 0);
926+
}
927+
928+
929+
/*
930+
* SPI_cursor_open_with_args()
931+
*
932+
* Parse and plan a query and open it as a portal. Like SPI_execute_with_args,
933+
* we can tell the planner to rely on the parameter values as constants,
934+
* because the plan will only be used once.
935+
*/
936+
Portal
937+
SPI_cursor_open_with_args(const char *name,
938+
const char *src,
939+
int nargs, Oid *argtypes,
940+
Datum *Values, const char *Nulls,
941+
bool read_only, int cursorOptions)
942+
{
943+
Portal result;
944+
_SPI_plan plan;
945+
ParamListInfo paramLI;
946+
947+
if (src == NULL || nargs < 0)
948+
elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
949+
950+
if (nargs > 0 && (argtypes == NULL || Values == NULL))
951+
elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
952+
953+
SPI_result = _SPI_begin_call(true);
954+
if (SPI_result < 0)
955+
elog(ERROR, "SPI_cursor_open_with_args called while not connected");
956+
957+
memset(&plan, 0, sizeof(_SPI_plan));
958+
plan.magic = _SPI_PLAN_MAGIC;
959+
plan.cursor_options = cursorOptions;
960+
plan.nargs = nargs;
961+
plan.argtypes = argtypes;
962+
963+
paramLI = _SPI_convert_params(nargs, argtypes,
964+
Values, Nulls,
965+
PARAM_FLAG_CONST);
966+
967+
_SPI_prepare_plan(src, &plan, paramLI);
968+
969+
/* We needn't copy the plan; SPI_cursor_open_internal will do so */
970+
971+
/* Adjust stack so that SPI_cursor_open_internal doesn't complain */
972+
_SPI_curid--;
973+
974+
/* SPI_cursor_open_internal must be called in procedure memory context */
975+
_SPI_procmem();
976+
977+
result = SPI_cursor_open_internal(name, &plan, Values, Nulls,
978+
read_only, PARAM_FLAG_CONST);
979+
980+
/* And clean up */
981+
_SPI_curid++;
982+
_SPI_end_call(true);
983+
984+
return result;
985+
}
986+
987+
988+
/*
989+
* SPI_cursor_open_internal()
990+
*
991+
* Common code for SPI_cursor_open and SPI_cursor_open_with_args
992+
*/
993+
static Portal
994+
SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
995+
Datum *Values, const char *Nulls,
996+
bool read_only, int pflags)
919997
{
920998
CachedPlanSource *plansource;
921999
CachedPlan *cplan;
@@ -997,7 +1075,7 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan,
9971075
ParamExternData *prm = &paramLI->params[k];
9981076

9991077
prm->ptype = plan->argtypes[k];
1000-
prm->pflags = 0;
1078+
prm->pflags = pflags;
10011079
prm->isnull = (Nulls && Nulls[k] == 'n');
10021080
if (prm->isnull)
10031081
{
@@ -1129,64 +1207,6 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan,
11291207
}
11301208

11311209

1132-
/*
1133-
* SPI_cursor_open_with_args()
1134-
*
1135-
* Parse and plan a query and open it as a portal. Like SPI_execute_with_args,
1136-
* we can tell the planner to rely on the parameter values as constants,
1137-
* because the plan will only be used once.
1138-
*/
1139-
Portal
1140-
SPI_cursor_open_with_args(const char *name,
1141-
const char *src,
1142-
int nargs, Oid *argtypes,
1143-
Datum *Values, const char *Nulls,
1144-
bool read_only, int cursorOptions)
1145-
{
1146-
Portal result;
1147-
_SPI_plan plan;
1148-
ParamListInfo paramLI;
1149-
1150-
if (src == NULL || nargs < 0)
1151-
elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
1152-
1153-
if (nargs > 0 && (argtypes == NULL || Values == NULL))
1154-
elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
1155-
1156-
SPI_result = _SPI_begin_call(true);
1157-
if (SPI_result < 0)
1158-
elog(ERROR, "SPI_cursor_open_with_args called while not connected");
1159-
1160-
memset(&plan, 0, sizeof(_SPI_plan));
1161-
plan.magic = _SPI_PLAN_MAGIC;
1162-
plan.cursor_options = cursorOptions;
1163-
plan.nargs = nargs;
1164-
plan.argtypes = argtypes;
1165-
1166-
paramLI = _SPI_convert_params(nargs, argtypes,
1167-
Values, Nulls,
1168-
PARAM_FLAG_CONST);
1169-
1170-
_SPI_prepare_plan(src, &plan, paramLI);
1171-
1172-
/* We needn't copy the plan; SPI_cursor_open will do so */
1173-
1174-
/* Adjust stack so that SPI_cursor_open doesn't complain */
1175-
_SPI_curid--;
1176-
1177-
/* SPI_cursor_open expects to be called in procedure memory context */
1178-
_SPI_procmem();
1179-
1180-
result = SPI_cursor_open(name, &plan, Values, Nulls, read_only);
1181-
1182-
/* And clean up */
1183-
_SPI_curid++;
1184-
_SPI_end_call(true);
1185-
1186-
return result;
1187-
}
1188-
1189-
11901210
/*
11911211
* SPI_cursor_find()
11921212
*

0 commit comments

Comments
 (0)