Infrastructure for deducing Param types from context, in the same way

that the types of untyped string-literal constants are deduced (ie,
when coerce_type is applied to 'em, that's what the type must be).
Remove the ancient hack of storing the input Param-types array as a
global variable, and put the info into ParseState instead.  This touches
a lot of files because of adjustment of routine parameter lists, but
it's really not a large patch.  Note: PREPARE statement still insists on
exact specification of parameter types, but that could easily be relaxed
now, if we wanted to do so.
This commit is contained in:
Tom Lane
2003-04-29 22:13:11 +00:00
parent 19141f5584
commit aa282d4446
29 changed files with 442 additions and 247 deletions

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: analyze.h,v 1.20 2002/06/20 20:29:51 momjian Exp $
* $Id: analyze.h,v 1.21 2003/04/29 22:13:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -15,7 +15,11 @@
#include "parser/parse_node.h"
extern List *parse_analyze(Node *parseTree, ParseState *parentParseState);
extern List *parse_analyze(Node *parseTree, Oid *paramTypes, int numParams);
extern List *parse_analyze_varparams(Node *parseTree, Oid **paramTypes,
int *numParams);
extern List *parse_sub_analyze(Node *parseTree, ParseState *parentParseState);
extern List *analyzeCreateSchemaStmt(CreateSchemaStmt *stmt);
extern void CheckSelectForUpdate(Query *qry);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: gramparse.h,v 1.26 2003/04/27 20:09:44 tgl Exp $
* $Id: gramparse.h,v 1.27 2003/04/29 22:13:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -17,9 +17,8 @@
#include "nodes/parsenodes.h"
/* from parser.c */
extern void parser_param_set(Oid *typev, int nargs);
extern Oid param_type(int t);
extern int yylex(void);
/* from scan.l */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parse_coerce.h,v 1.50 2003/04/08 23:20:04 tgl Exp $
* $Id: parse_coerce.h,v 1.51 2003/04/29 22:13:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -17,6 +17,7 @@
#include "catalog/pg_type.h"
#include "parser/parse_node.h"
typedef enum CATEGORY
{
INVALID_TYPE,
@ -38,22 +39,26 @@ extern bool IsBinaryCoercible(Oid srctype, Oid targettype);
extern bool IsPreferredType(CATEGORY category, Oid type);
extern CATEGORY TypeCategory(Oid type);
extern Node *coerce_to_target_type(Node *expr, Oid exprtype,
extern Node *coerce_to_target_type(ParseState *pstate,
Node *expr, Oid exprtype,
Oid targettype, int32 targettypmod,
CoercionContext ccontext,
CoercionForm cformat);
extern bool can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
CoercionContext ccontext);
extern Node *coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
extern Node *coerce_type(ParseState *pstate, Node *node,
Oid inputTypeId, Oid targetTypeId,
CoercionContext ccontext, CoercionForm cformat);
extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, Oid typeId,
CoercionForm cformat);
extern Node *coerce_to_boolean(Node *node, const char *constructName);
extern Node *coerce_to_boolean(ParseState *pstate, Node *node,
const char *constructName);
extern Oid select_common_type(List *typeids, const char *context);
extern Node *coerce_to_common_type(Node *node, Oid targetTypeId,
const char *context);
extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
Oid targetTypeId,
const char *context);
extern bool check_generic_type_consistency(Oid *actual_arg_types,
Oid *declared_arg_types,

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parse_func.h,v 1.44 2003/04/08 23:20:04 tgl Exp $
* $Id: parse_func.h,v 1.45 2003/04/29 22:13:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -16,6 +16,7 @@
#include "parser/parse_node.h"
/*
* This structure is used to explore the inheritance hierarchy above
* nodes in the type tree in order to disambiguate among polymorphic
@ -49,7 +50,8 @@ extern FuncDetailCode func_get_detail(List *funcname, List *fargs,
extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);
extern void make_fn_arguments(List *fargs,
extern void make_fn_arguments(ParseState *pstate,
List *fargs,
Oid *actual_arg_types,
Oid *declared_arg_types);

View File

@ -1,12 +1,13 @@
/*-------------------------------------------------------------------------
*
* parse_node.h
* Internal definitions for parser
*
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parse_node.h,v 1.34 2003/04/08 23:20:04 tgl Exp $
* $Id: parse_node.h,v 1.35 2003/04/29 22:13:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -32,6 +33,15 @@
* joinlist. Note that an RTE that is present in p_namespace, but does not
* have its inFromCl flag set, is accessible only with an explicit qualifier;
* lookups of unqualified column names should ignore it.
*
* p_paramtypes: an array of p_numparams type OIDs for $n parameter symbols
* (zeroth entry in array corresponds to $1). If p_variableparams is true, the
* set of param types is not predetermined; in that case, a zero array entry
* means that parameter number hasn't been seen, and UNKNOWNOID means the
* parameter has been used but its type is not yet known. NOTE: in a stack
* of ParseStates, only the topmost ParseState contains paramtype info; but
* we copy the p_variableparams flag down to the child nodes for speed in
* coerce_type.
*/
typedef struct ParseState
{
@ -40,9 +50,12 @@ typedef struct ParseState
List *p_joinlist; /* join items so far (will become FromExpr
* node's fromlist) */
List *p_namespace; /* current lookup namespace (join items) */
int p_last_resno; /* last targetlist resno assigned */
Oid *p_paramtypes; /* OIDs of types for $n parameter symbols */
int p_numparams; /* allocated size of p_paramtypes[] */
int p_next_resno; /* next targetlist resno to assign */
List *p_forUpdate; /* FOR UPDATE clause, if any (see gram.y) */
Node *p_value_substitute; /* what to replace VALUE with, if any */
bool p_variableparams;
bool p_hasAggs;
bool p_hasSubLinks;
bool p_is_insert;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parse_oper.h,v 1.24 2003/04/08 23:20:04 tgl Exp $
* $Id: parse_oper.h,v 1.25 2003/04/29 22:13:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -15,7 +15,8 @@
#define PARSE_OPER_H
#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
typedef HeapTuple Operator;
@ -50,8 +51,10 @@ extern Oid oprid(Operator op);
extern Oid oprfuncid(Operator op);
/* Build expression tree for an operator invocation */
extern Expr *make_op(List *opname, Node *ltree, Node *rtree);
extern Expr *make_op_expr(Operator op, Node *ltree, Node *rtree,
extern Expr *make_op(ParseState *pstate, List *opname,
Node *ltree, Node *rtree);
extern Expr *make_op_expr(ParseState *pstate, Operator op,
Node *ltree, Node *rtree,
Oid ltypeId, Oid rtypeId);
#endif /* PARSE_OPER_H */

View File

@ -1,21 +1,19 @@
/*-------------------------------------------------------------------------
*
* parser.h
*
* Definitions for the "raw" parser (lex and yacc phases only)
*
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parser.h,v 1.14 2003/04/27 20:09:44 tgl Exp $
* $Id: parser.h,v 1.15 2003/04/29 22:13:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PARSER_H
#define PARSER_H
#include "parser/parse_node.h"
extern List *parser(const char *str, Oid *typev, int nargs);
extern List *raw_parser(const char *str);
#endif /* PARSER_H */