git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6d19e9f)
Refactor SPI_cursor_open/SPI_cursor_open_with_args so that the latter sets
Sun, 1 Jun 2008 17:32:48 +0000 (17:32 +0000)
Sun, 1 Jun 2008 17:32:48 +0000 (17:32 +0000)
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.


diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 555bdd1a6f265094d432c33aa5d52061ce59724d..32e53265d975c6320219120a3e9955ae79db4c5a 100644 (file)
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -36,6 +36,10 @@ static int _SPI_stack_depth = 0; /* allocated size of _SPI_stack */
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);
@@ -916,6 +920,80 @@ Portal
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;
@@ -997,7 +1075,7 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan,
ParamExternData *prm = &paramLI->params[k];
prm->ptype = plan->argtypes[k];
- prm->pflags = 0;
+ prm->pflags = pflags;
prm->isnull = (Nulls && Nulls[k] == 'n');
if (prm->isnull)
{
@@ -1129,64 +1207,6 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan,
}
-/*
- * 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()
*
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /