aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/prepare.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/prepare.c')
-rw-r--r--src/backend/commands/prepare.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index d768cf8dda3..1ff41661a55 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -52,8 +52,10 @@ static Datum build_regtype_array(Oid *param_types, int num_params);
* Implements the 'PREPARE' utility statement.
*/
void
-PrepareQuery(PrepareStmt *stmt, const char *queryString)
+PrepareQuery(PrepareStmt *stmt, const char *queryString,
+ int stmt_location, int stmt_len)
{
+ RawStmt *rawstmt;
CachedPlanSource *plansource;
Oid *argtypes = NULL;
int nargs;
@@ -71,10 +73,22 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
errmsg("invalid statement name: must not be empty")));
/*
+ * Need to wrap the contained statement in a RawStmt node to pass it to
+ * parse analysis.
+ *
+ * Because parse analysis scribbles on the raw querytree, we must make a
+ * copy to ensure we don't modify the passed-in tree. FIXME someday.
+ */
+ rawstmt = makeNode(RawStmt);
+ rawstmt->stmt = (Node *) copyObject(stmt->query);
+ rawstmt->stmt_location = stmt_location;
+ rawstmt->stmt_len = stmt_len;
+
+ /*
* Create the CachedPlanSource before we do parse analysis, since it needs
* to see the unmodified raw parse tree.
*/
- plansource = CreateCachedPlan(stmt->query, queryString,
+ plansource = CreateCachedPlan(rawstmt, queryString,
CreateCommandTag(stmt->query));
/* Transform list of TypeNames to array of type OIDs */
@@ -108,12 +122,8 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
* Analyze the statement using these parameter types (any parameters
* passed in from above us will not be visible to it), allowing
* information about unknown parameters to be deduced from context.
- *
- * Because parse analysis scribbles on the raw querytree, we must make a
- * copy to ensure we don't modify the passed-in tree. FIXME someday.
*/
- query = parse_analyze_varparams((Node *) copyObject(stmt->query),
- queryString,
+ query = parse_analyze_varparams(rawstmt, queryString,
&argtypes, &nargs);
/*
@@ -256,9 +266,8 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("prepared statement is not a SELECT")));
pstmt = (PlannedStmt *) linitial(plan_list);
- if (!IsA(pstmt, PlannedStmt) ||
- pstmt->commandType != CMD_SELECT ||
- pstmt->utilityStmt != NULL)
+ Assert(IsA(pstmt, PlannedStmt));
+ if (pstmt->commandType != CMD_SELECT)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("prepared statement is not a SELECT")));
@@ -664,10 +673,11 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
{
PlannedStmt *pstmt = (PlannedStmt *) lfirst(p);
- if (IsA(pstmt, PlannedStmt))
+ Assert(IsA(pstmt, PlannedStmt));
+ if (pstmt->commandType != CMD_UTILITY)
ExplainOnePlan(pstmt, into, es, query_string, paramLI, NULL);
else
- ExplainOneUtility((Node *) pstmt, into, es, query_string, paramLI);
+ ExplainOneUtility(pstmt->utilityStmt, into, es, query_string, paramLI);
/* No need for CommandCounterIncrement, as ExplainOnePlan did it */