summaryrefslogtreecommitdiff
path: root/src/backend/parser/analyze.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r--src/backend/parser/analyze.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index a488d1d91e5..ad2d5ab5681 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.269 2003/05/02 20:54:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.270 2003/05/05 00:44:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -83,6 +83,12 @@ typedef struct
IndexStmt *pkey; /* PRIMARY KEY index, if any */
} CreateStmtContext;
+typedef struct
+{
+ Oid *paramTypes;
+ int numParams;
+} check_parameter_resolution_context;
+
static List *do_parse_analyze(Node *parseTree, ParseState *pstate);
static Query *transformStmt(ParseState *pstate, Node *stmt,
@@ -124,6 +130,8 @@ static void transformColumnType(ParseState *pstate, ColumnDef *column);
static bool relationHasPrimaryKey(Oid relationOid);
static void release_pstate_resources(ParseState *pstate);
static FromExpr *makeFromExpr(List *fromlist, Node *quals);
+static bool check_parameter_resolution_walker(Node *node,
+ check_parameter_resolution_context *context);
/*
@@ -179,6 +187,16 @@ parse_analyze_varparams(Node *parseTree, Oid **paramTypes, int *numParams)
pfree(pstate);
+ /* make sure all is well with parameter types */
+ if (*numParams > 0)
+ {
+ check_parameter_resolution_context context;
+
+ context.paramTypes = *paramTypes;
+ context.numParams = *numParams;
+ check_parameter_resolution_walker((Node *) result, &context);
+ }
+
return result;
}
@@ -2465,7 +2483,7 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
result->commandType = CMD_UTILITY;
result->utilityStmt = (Node *) stmt;
- paramtypes = FetchQueryParams(stmt->name);
+ paramtypes = FetchPreparedStatementParams(stmt->name);
if (stmt->params || paramtypes)
{
@@ -2879,3 +2897,44 @@ analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
return result;
}
+
+/*
+ * Traverse a fully-analyzed tree to verify that parameter symbols
+ * match their types. We need this because some Params might still
+ * be UNKNOWN, if there wasn't anything to force their coercion,
+ * and yet other instances seen later might have gotten coerced.
+ */
+static bool
+check_parameter_resolution_walker(Node *node,
+ check_parameter_resolution_context *context)
+{
+ if (node == NULL)
+ return false;
+ if (IsA(node, Param))
+ {
+ Param *param = (Param *) node;
+
+ if (param->paramkind == PARAM_NUM)
+ {
+ int paramno = param->paramid;
+
+ if (paramno <= 0 || /* shouldn't happen, but... */
+ paramno > context->numParams)
+ elog(ERROR, "Parameter '$%d' is out of range", paramno);
+
+ if (param->paramtype != context->paramTypes[paramno-1])
+ elog(ERROR, "Could not determine datatype of parameter $%d",
+ paramno);
+ }
+ return false;
+ }
+ if (IsA(node, Query))
+ {
+ /* Recurse into RTE subquery or not-yet-planned sublink subquery */
+ return query_tree_walker((Query *) node,
+ check_parameter_resolution_walker,
+ (void *) context, 0);
+ }
+ return expression_tree_walker(node, check_parameter_resolution_walker,
+ (void *) context);
+}