*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.195 2008/05/12 20:02:00 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.196 2008/06/01 17:32:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static int _SPI_connected = -1;
static int _SPI_curid = -1;
+static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
+ Datum *Values, const char *Nulls,
+ bool read_only, int pflags);
+
static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan,
ParamListInfo boundParams);
SPI_cursor_open(const char *name, SPIPlanPtr plan,
Datum *Values, const char *Nulls,
bool read_only)
+{
+ return SPI_cursor_open_internal(name, plan, Values, Nulls,
+ read_only, 0);
+}
+
+
+/*
+ * SPI_cursor_open_with_args()
+ *
+ * Parse and plan a query and open it as a portal. Like SPI_execute_with_args,
+ * we can tell the planner to rely on the parameter values as constants,
+ * because the plan will only be used once.
+ */
+Portal
+SPI_cursor_open_with_args(const char *name,
+ const char *src,
+ int nargs, Oid *argtypes,
+ Datum *Values, const char *Nulls,
+ bool read_only, int cursorOptions)
+{
+ Portal result;
+ _SPI_plan plan;
+ ParamListInfo paramLI;
+
+ if (src == NULL || nargs < 0)
+ elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
+
+ if (nargs > 0 && (argtypes == NULL || Values == NULL))
+ elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
+
+ SPI_result = _SPI_begin_call(true);
+ if (SPI_result < 0)
+ elog(ERROR, "SPI_cursor_open_with_args called while not connected");
+
+ memset(&plan, 0, sizeof(_SPI_plan));
+ plan.magic = _SPI_PLAN_MAGIC;
+ plan.cursor_options = cursorOptions;
+ plan.nargs = nargs;
+ plan.argtypes = argtypes;
+
+ paramLI = _SPI_convert_params(nargs, argtypes,
+ Values, Nulls,
+ PARAM_FLAG_CONST);
+
+ _SPI_prepare_plan(src, &plan, paramLI);
+
+ /* We needn't copy the plan; SPI_cursor_open_internal will do so */
+
+ /* Adjust stack so that SPI_cursor_open_internal doesn't complain */
+ _SPI_curid--;
+
+ /* SPI_cursor_open_internal must be called in procedure memory context */
+ _SPI_procmem();
+
+ result = SPI_cursor_open_internal(name, &plan, Values, Nulls,
+ read_only, PARAM_FLAG_CONST);
+
+ /* And clean up */
+ _SPI_curid++;
+ _SPI_end_call(true);
+
+ return result;
+}
+
+
+/*
+ * SPI_cursor_open_internal()
+ *
+ * Common code for SPI_cursor_open and SPI_cursor_open_with_args
+ */
+static Portal
+SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
+ Datum *Values, const char *Nulls,
+ bool read_only, int pflags)
{
CachedPlanSource *plansource;
CachedPlan *cplan;
ParamExternData *prm = ¶mLI->params[k];
prm->ptype = plan->argtypes[k];
- prm->pflags = 0;
+ prm->pflags = pflags;
prm->isnull = (Nulls && Nulls[k] == 'n');
if (prm->isnull)
{
}
-/*
- * SPI_cursor_open_with_args()
- *
- * Parse and plan a query and open it as a portal. Like SPI_execute_with_args,
- * we can tell the planner to rely on the parameter values as constants,
- * because the plan will only be used once.
- */
-Portal
-SPI_cursor_open_with_args(const char *name,
- const char *src,
- int nargs, Oid *argtypes,
- Datum *Values, const char *Nulls,
- bool read_only, int cursorOptions)
-{
- Portal result;
- _SPI_plan plan;
- ParamListInfo paramLI;
-
- if (src == NULL || nargs < 0)
- elog(ERROR, "SPI_cursor_open_with_args called with invalid arguments");
-
- if (nargs > 0 && (argtypes == NULL || Values == NULL))
- elog(ERROR, "SPI_cursor_open_with_args called with missing parameters");
-
- SPI_result = _SPI_begin_call(true);
- if (SPI_result < 0)
- elog(ERROR, "SPI_cursor_open_with_args called while not connected");
-
- memset(&plan, 0, sizeof(_SPI_plan));
- plan.magic = _SPI_PLAN_MAGIC;
- plan.cursor_options = cursorOptions;
- plan.nargs = nargs;
- plan.argtypes = argtypes;
-
- paramLI = _SPI_convert_params(nargs, argtypes,
- Values, Nulls,
- PARAM_FLAG_CONST);
-
- _SPI_prepare_plan(src, &plan, paramLI);
-
- /* We needn't copy the plan; SPI_cursor_open will do so */
-
- /* Adjust stack so that SPI_cursor_open doesn't complain */
- _SPI_curid--;
-
- /* SPI_cursor_open expects to be called in procedure memory context */
- _SPI_procmem();
-
- result = SPI_cursor_open(name, &plan, Values, Nulls, read_only);
-
- /* And clean up */
- _SPI_curid++;
- _SPI_end_call(true);
-
- return result;
-}
-
-
/*
* SPI_cursor_find()
*