aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/gram.y191
-rw-r--r--src/backend/parser/keywords.c20
-rw-r--r--src/backend/parser/parse_clause.c4
-rw-r--r--src/backend/parser/parse_coerce.c101
-rw-r--r--src/backend/parser/parse_expr.c167
-rw-r--r--src/backend/parser/parse_target.c11
6 files changed, 233 insertions, 261 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index cc400407363..a1511870f28 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.569 2006/12/21 16:05:14 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.570 2006/12/24 00:29:18 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -348,8 +348,8 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
%type <target> xml_attribute_el
%type <list> xml_attribute_list xml_attributes
-%type <node> xml_root_version
-%type <ival> opt_xml_root_standalone document_or_content xml_whitespace_option
+%type <node> xml_root_version opt_xml_root_standalone
+%type <boolean> document_or_content xml_whitespace_option
/*
@@ -371,13 +371,13 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
COMMITTED CONCURRENTLY CONNECTION CONSTRAINT CONSTRAINTS
- CONTENT CONVERSION_P CONVERT COPY CREATE CREATEDB
+ CONTENT_P CONVERSION_P CONVERT COPY CREATE CREATEDB
CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_ROLE CURRENT_TIME
CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
- DESC DISABLE_P DISTINCT DO DOCUMENT DOMAIN_P DOUBLE_P DROP
+ DESC DISABLE_P DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
@@ -404,7 +404,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
- NAME NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
+ NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC
@@ -423,9 +423,9 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
- SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE START STATEMENT
- STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP SUBSTRING SUPERUSER_P SYMMETRIC
- SYSID SYSTEM_P
+ SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
+ STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
+ SYMMETRIC SYSID SYSTEM_P
TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
@@ -434,15 +434,15 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
UPDATE USER USING
- VACUUM VALID VALIDATOR VALUE VALUES VARCHAR VARYING
- VERBOSE VERSION VIEW VOLATILE
+ VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARYING
+ VERBOSE VERSION_P VIEW VOLATILE
- WHEN WHERE WHITESPACE WITH WITHOUT WORK WRITE
+ WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
XMLPI XMLROOT XMLSERIALIZE
- YEAR_P YES
+ YEAR_P YES_P
ZONE
@@ -493,7 +493,8 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
* left-associativity among the JOIN rules themselves.
*/
%left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
-%right PRESERVE STRIP
+/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
+%right PRESERVE STRIP_P
%%
/*
@@ -7880,95 +7881,54 @@ func_expr: func_name '(' ')'
}
| XMLCONCAT '(' expr_list ')'
{
- $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NULL, $3);
+ $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3);
}
- | XMLELEMENT '(' NAME ColLabel ')'
+ | XMLELEMENT '(' NAME_P ColLabel ')'
{
- $$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, NULL);
+ $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, NIL);
}
- | XMLELEMENT '(' NAME ColLabel ',' xml_attributes ')'
+ | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
{
- $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NULL);
+ $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NIL);
}
- | XMLELEMENT '(' NAME ColLabel ',' expr_list ')'
+ | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
{
- $$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, $6);
+ $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, $6);
}
- | XMLELEMENT '(' NAME ColLabel ',' xml_attributes ',' expr_list ')'
+ | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
{
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8);
}
| XMLFOREST '(' xml_attribute_list ')'
{
- $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NULL);
+ $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL);
}
| XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
{
- FuncCall *n = makeNode(FuncCall);
- n->funcname = SystemFuncName("xmlparse");
- n->args = list_make3(makeBoolAConst($3 == DOCUMENT), $4, makeBoolAConst($5 == PRESERVE));
- n->agg_star = FALSE;
- n->agg_distinct = FALSE;
- n->location = @1;
- $$ = (Node *)n;
+ $$ = makeXmlExpr(IS_XMLPARSE, NULL, NIL,
+ list_make3($4,
+ makeBoolAConst($3),
+ makeBoolAConst($5)));
}
- | XMLPI '(' NAME ColLabel ')'
+ | XMLPI '(' NAME_P ColLabel ')'
{
- FuncCall *n = makeNode(FuncCall);
- n->funcname = SystemFuncName("xmlpi");
- n->args = list_make1(makeStringConst($4, NULL));
- n->agg_star = FALSE;
- n->agg_distinct = FALSE;
- n->location = @1;
- $$ = (Node *)n;
+ $$ = makeXmlExpr(IS_XMLPI, $4, NULL, NIL);
}
- | XMLPI '(' NAME ColLabel ',' a_expr ')'
+ | XMLPI '(' NAME_P ColLabel ',' a_expr ')'
{
- FuncCall *n = makeNode(FuncCall);
- n->funcname = SystemFuncName("xmlpi");
- n->args = list_make2(makeStringConst($4, NULL), $6);
- n->agg_star = FALSE;
- n->agg_distinct = FALSE;
- n->location = @1;
- $$ = (Node *)n;
+ $$ = makeXmlExpr(IS_XMLPI, $4, NULL, list_make1($6));
}
| XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
{
- FuncCall *n = makeNode(FuncCall);
- Node *ver;
- A_Const *sa;
-
- if ($5)
- ver = $5;
- else
- {
- A_Const *val;
-
- val = makeNode(A_Const);
- val->val.type = T_Null;
- ver = (Node *) val;
- }
-
- if ($6)
- sa = makeBoolAConst($6 == 1);
- else
- {
- sa = makeNode(A_Const);
- sa->val.type = T_Null;
- }
-
- n->funcname = SystemFuncName("xmlroot");
- n->args = list_make3($3, ver, sa);
- n->agg_star = FALSE;
- n->agg_distinct = FALSE;
- n->location = @1;
- $$ = (Node *)n;
+ $$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
+ list_make3($3, $5, $6));
}
| XMLSERIALIZE '(' document_or_content a_expr AS Typename ')'
{
/*
* FIXME: This should be made distinguishable from
- * CAST (for reverse compilation at least).
+ * CAST (for reverse compilation at least). Also,
+ * what about the document/content option??
*/
$$ = makeTypeCast($4, $6);
}
@@ -7977,17 +7937,35 @@ func_expr: func_name '(' ')'
/*
* SQL/XML support
*/
-xml_root_version: VERSION a_expr { $$ = $2; }
- | VERSION NO VALUE { $$ = NULL; }
+xml_root_version: VERSION_P a_expr
+ { $$ = $2; }
+ | VERSION_P NO VALUE_P
+ {
+ A_Const *val = makeNode(A_Const);
+ val->val.type = T_Null;
+ $$ = (Node *) val;
+ }
;
-opt_xml_root_standalone: ',' STANDALONE YES { $$ = 1; }
- | ',' STANDALONE NO { $$ = -1; }
- | ',' STANDALONE NO VALUE { $$ = 0; }
- | /*EMPTY*/ { $$ = 0; }
+opt_xml_root_standalone: ',' STANDALONE_P YES_P
+ { $$ = (Node *) makeBoolAConst(true); }
+ | ',' STANDALONE_P NO
+ { $$ = (Node *) makeBoolAConst(false); }
+ | ',' STANDALONE_P NO VALUE_P
+ {
+ A_Const *val = makeNode(A_Const);
+ val->val.type = T_Null;
+ $$ = (Node *) val;
+ }
+ | /*EMPTY*/
+ {
+ A_Const *val = makeNode(A_Const);
+ val->val.type = T_Null;
+ $$ = (Node *) val;
+ }
;
-xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
+xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
;
xml_attribute_list: xml_attribute_el { $$ = list_make1($1); }
@@ -8000,7 +7978,7 @@ xml_attribute_el: a_expr AS ColLabel
$$->name = $3;
$$->indirection = NULL;
$$->val = (Node *) $1;
-
+ $$->location = @1;
}
| a_expr
{
@@ -8008,16 +7986,21 @@ xml_attribute_el: a_expr AS ColLabel
$$->name = NULL;
$$->indirection = NULL;
$$->val = (Node *) $1;
+ $$->location = @1;
}
;
-document_or_content: DOCUMENT { $$ = DOCUMENT; }
- | CONTENT { $$ = CONTENT; }
+document_or_content: DOCUMENT_P { $$ = TRUE; }
+ | CONTENT_P { $$ = FALSE; }
;
-xml_whitespace_option: PRESERVE WHITESPACE { $$ = PRESERVE; }
- | STRIP WHITESPACE { $$ = STRIP; }
- | /*EMPTY*/ { $$ = STRIP; }
+/*
+ * XXX per SQL spec, the default should be STRIP WHITESPACE, but since we
+ * haven't implemented that yet, temporarily default to PRESERVE.
+ */
+xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = TRUE; }
+ | STRIP_P WHITESPACE_P { $$ = FALSE; }
+ | /*EMPTY*/ { $$ = TRUE; }
;
/*
@@ -8712,7 +8695,7 @@ unreserved_keyword:
| CONCURRENTLY
| CONNECTION
| CONSTRAINTS
- | CONTENT
+ | CONTENT_P
| CONVERSION_P
| COPY
| CREATEDB
@@ -8732,7 +8715,7 @@ unreserved_keyword:
| DELIMITER
| DELIMITERS
| DISABLE_P
- | DOCUMENT
+ | DOCUMENT_P
| DOMAIN_P
| DOUBLE_P
| DROP
@@ -8792,7 +8775,7 @@ unreserved_keyword:
| MODE
| MONTH_P
| MOVE
- | NAME
+ | NAME_P
| NAMES
| NEXT
| NO
@@ -8853,18 +8836,18 @@ unreserved_keyword:
| SHOW
| SIMPLE
| STABLE
- | STANDALONE
+ | STANDALONE_P
| START
| STATEMENT
| STATISTICS
| STDIN
| STDOUT
| STORAGE
- | STRIP
+ | STRICT_P
+ | STRIP_P
| SUPERUSER_P
| SYSID
| SYSTEM_P
- | STRICT_P
| TABLESPACE
| TEMP
| TEMPLATE
@@ -8883,18 +8866,18 @@ unreserved_keyword:
| VACUUM
| VALID
| VALIDATOR
+ | VALUE_P
| VARYING
- | VERSION
+ | VERSION_P
| VIEW
- | VALUE
| VOLATILE
- | WHITESPACE
+ | WHITESPACE_P
| WITH
| WITHOUT
| WORK
| WRITE
| YEAR_P
- | YES
+ | YES_P
| ZONE
;
@@ -8948,8 +8931,8 @@ col_name_keyword:
| VALUES
| VARCHAR
| XMLATTRIBUTES
- | XMLELEMENT
| XMLCONCAT
+ | XMLELEMENT
| XMLFOREST
| XMLPARSE
| XMLPI
@@ -9492,10 +9475,16 @@ doNegateFloat(Value *v)
static Node *
makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
{
- XmlExpr *x = makeNode(XmlExpr);
+ XmlExpr *x = makeNode(XmlExpr);
+
x->op = op;
x->name = name;
+ /*
+ * named_args is a list of ResTarget; it'll be split apart into separate
+ * expression and name lists in transformXmlExpr().
+ */
x->named_args = named_args;
+ x->arg_names = NIL;
x->args = args;
return (Node *) x;
}
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index b5e49e955fc..4865d360b3e 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.178 2006/12/21 16:05:14 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.179 2006/12/24 00:29:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -89,7 +89,7 @@ static const ScanKeyword ScanKeywords[] = {
{"connection", CONNECTION},
{"constraint", CONSTRAINT},
{"constraints", CONSTRAINTS},
- {"content", CONTENT},
+ {"content", CONTENT_P},
{"conversion", CONVERSION_P},
{"convert", CONVERT},
{"copy", COPY},
@@ -124,7 +124,7 @@ static const ScanKeyword ScanKeywords[] = {
{"disable", DISABLE_P},
{"distinct", DISTINCT},
{"do", DO},
- {"document", DOCUMENT},
+ {"document", DOCUMENT_P},
{"domain", DOMAIN_P},
{"double", DOUBLE_P},
{"drop", DROP},
@@ -220,7 +220,7 @@ static const ScanKeyword ScanKeywords[] = {
{"mode", MODE},
{"month", MONTH_P},
{"move", MOVE},
- {"name", NAME},
+ {"name", NAME_P},
{"names", NAMES},
{"national", NATIONAL},
{"natural", NATURAL},
@@ -317,7 +317,7 @@ static const ScanKeyword ScanKeywords[] = {
{"smallint", SMALLINT},
{"some", SOME},
{"stable", STABLE},
- {"standalone", STANDALONE},
+ {"standalone", STANDALONE_P},
{"start", START},
{"statement", STATEMENT},
{"statistics", STATISTICS},
@@ -325,7 +325,7 @@ static const ScanKeyword ScanKeywords[] = {
{"stdout", STDOUT},
{"storage", STORAGE},
{"strict", STRICT_P},
- {"strip", STRIP},
+ {"strip", STRIP_P},
{"substring", SUBSTRING},
{"superuser", SUPERUSER_P},
{"symmetric", SYMMETRIC},
@@ -362,17 +362,17 @@ static const ScanKeyword ScanKeywords[] = {
{"vacuum", VACUUM},
{"valid", VALID},
{"validator", VALIDATOR},
- {"value", VALUE},
+ {"value", VALUE_P},
{"values", VALUES},
{"varchar", VARCHAR},
{"varying", VARYING},
{"verbose", VERBOSE},
- {"version", VERSION},
+ {"version", VERSION_P},
{"view", VIEW},
{"volatile", VOLATILE},
{"when", WHEN},
{"where", WHERE},
- {"whitespace", WHITESPACE},
+ {"whitespace", WHITESPACE_P},
{"with", WITH},
{"without", WITHOUT},
{"work", WORK},
@@ -386,7 +386,7 @@ static const ScanKeyword ScanKeywords[] = {
{"xmlroot", XMLROOT},
{"xmlserialize", XMLSERIALIZE},
{"year", YEAR_P},
- {"yes", YES},
+ {"yes", YES_P},
{"zone", ZONE},
};
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 996c724d1ce..145caab101a 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.159 2006/11/28 12:54:41 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.160 2006/12/24 00:29:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1094,7 +1094,7 @@ transformLimitClause(ParseState *pstate, Node *clause,
qual = transformExpr(pstate, clause);
- qual = coerce_to_bigint(pstate, qual, constructName);
+ qual = coerce_to_specific_type(pstate, qual, INT8OID, constructName);
/*
* LIMIT can't refer to any vars or aggregates of the current query; we
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 5670ed4fe74..45c8e97be1d 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.148 2006/12/21 16:05:14 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.149 2006/12/24 00:29:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -840,8 +840,8 @@ coerce_to_boolean(ParseState *pstate, Node *node,
}
/*
- * coerce_to_integer()
- * Coerce an argument of a construct that requires integer input.
+ * coerce_to_specific_type()
+ * Coerce an argument of a construct that requires a specific data type.
* Also check that input is not a set.
*
* Returns the possibly-transformed node tree.
@@ -850,103 +850,26 @@ coerce_to_boolean(ParseState *pstate, Node *node,
* processing is wanted.
*/
Node *
-coerce_to_integer(ParseState *pstate, Node *node,
- const char *constructName)
-{
- Oid inputTypeId = exprType(node);
-
- if (inputTypeId != INT4OID)
- {
- node = coerce_to_target_type(pstate, node, inputTypeId,
- INT4OID, -1,
- COERCION_ASSIGNMENT,
- COERCE_IMPLICIT_CAST);
- if (node == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- /* translator: first %s is name of a SQL construct, eg LIMIT */
- errmsg("argument of %s must be type integer, not type %s",
- constructName, format_type_be(inputTypeId))));
- }
-
- if (expression_returns_set(node))
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- /* translator: %s is name of a SQL construct, eg LIMIT */
- errmsg("argument of %s must not return a set",
- constructName)));
-
- return node;
-}
-
-/*
- * coerce_to_bigint()
- * Coerce an argument of a construct that requires int8 input.
- * Also check that input is not a set.
- *
- * Returns the possibly-transformed node tree.
- *
- * As with coerce_type, pstate may be NULL if no special unknown-Param
- * processing is wanted.
- */
-Node *
-coerce_to_bigint(ParseState *pstate, Node *node,
- const char *constructName)
-{
- Oid inputTypeId = exprType(node);
-
- if (inputTypeId != INT8OID)
- {
- node = coerce_to_target_type(pstate, node, inputTypeId,
- INT8OID, -1,
- COERCION_ASSIGNMENT,
- COERCE_IMPLICIT_CAST);
- if (node == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- /* translator: first %s is name of a SQL construct, eg LIMIT */
- errmsg("argument of %s must be type bigint, not type %s",
- constructName, format_type_be(inputTypeId))));
- }
-
- if (expression_returns_set(node))
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- /* translator: %s is name of a SQL construct, eg LIMIT */
- errmsg("argument of %s must not return a set",
- constructName)));
-
- return node;
-}
-
-/*
- * coerce_to_xml()
- * Coerce an argument of a construct that requires xml input.
- * Also check that input is not a set.
- *
- * Returns the possibly-transformed node tree.
- *
- * As with coerce_type, pstate may be NULL if no special unknown-Param
- * processing is wanted.
- */
-Node *
-coerce_to_xml(ParseState *pstate, Node *node,
- const char *constructName)
+coerce_to_specific_type(ParseState *pstate, Node *node,
+ Oid targetTypeId,
+ const char *constructName)
{
Oid inputTypeId = exprType(node);
- if (inputTypeId != XMLOID)
+ if (inputTypeId != targetTypeId)
{
node = coerce_to_target_type(pstate, node, inputTypeId,
- XMLOID, -1,
+ targetTypeId, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST);
if (node == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
/* translator: first %s is name of a SQL construct, eg LIMIT */
- errmsg("argument of %s must be type xml, not type %s",
- constructName, format_type_be(inputTypeId))));
+ errmsg("argument of %s must be type %s, not type %s",
+ constructName,
+ format_type_be(targetTypeId),
+ format_type_be(inputTypeId))));
}
if (expression_returns_set(node))
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 2a48741b3a2..7dbbb9a33a8 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.201 2006/12/23 00:43:11 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.202 2006/12/24 00:29:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -220,6 +220,10 @@ transformExpr(ParseState *pstate, Node *expr)
result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
break;
+ case T_XmlExpr:
+ result = transformXmlExpr(pstate, (XmlExpr *) expr);
+ break;
+
case T_NullTest:
{
NullTest *n = (NullTest *) expr;
@@ -234,10 +238,6 @@ transformExpr(ParseState *pstate, Node *expr)
result = transformBooleanTest(pstate, (BooleanTest *) expr);
break;
- case T_XmlExpr:
- result = transformXmlExpr(pstate, (XmlExpr *) expr);
- break;
-
/*********************************************
* Quietly accept node types that may be presented when we are
* called on an already-transformed tree.
@@ -1376,6 +1376,107 @@ transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
}
static Node *
+transformXmlExpr(ParseState *pstate, XmlExpr *x)
+{
+ XmlExpr *newx = makeNode(XmlExpr);
+ ListCell *lc;
+ int i;
+
+ newx->op = x->op;
+ if (x->name)
+ newx->name = map_sql_identifier_to_xml_name(x->name, false);
+ else
+ newx->name = NULL;
+
+ /*
+ * gram.y built the named args as a list of ResTarget. Transform each,
+ * and break the names out as a separate list.
+ */
+ newx->named_args = NIL;
+ newx->arg_names = NIL;
+
+ foreach(lc, x->named_args)
+ {
+ ResTarget *r = (ResTarget *) lfirst(lc);
+ Node *expr;
+ char *argname;
+
+ Assert(IsA(r, ResTarget));
+
+ expr = transformExpr(pstate, r->val);
+
+ if (r->name)
+ argname = map_sql_identifier_to_xml_name(r->name, false);
+ else if (IsA(r->val, ColumnRef))
+ argname = map_sql_identifier_to_xml_name(FigureColname(r->val),
+ true);
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ x->op == IS_XMLELEMENT
+ ? errmsg("unnamed attribute value must be a column reference")
+ : errmsg("unnamed element value must be a column reference")));
+ argname = NULL; /* keep compiler quiet */
+ }
+
+ newx->named_args = lappend(newx->named_args, expr);
+ newx->arg_names = lappend(newx->arg_names, makeString(argname));
+ }
+
+ /* The other arguments are of varying types depending on the function */
+ newx->args = NIL;
+ i = 0;
+ foreach(lc, x->args)
+ {
+ Node *e = (Node *) lfirst(lc);
+ Node *newe;
+
+ newe = transformExpr(pstate, e);
+ switch (x->op)
+ {
+ case IS_XMLCONCAT:
+ newe = coerce_to_specific_type(pstate, newe, XMLOID,
+ "XMLCONCAT");
+ break;
+ case IS_XMLELEMENT:
+ newe = coerce_to_specific_type(pstate, newe, XMLOID,
+ "XMLELEMENT");
+ break;
+ case IS_XMLFOREST:
+ newe = coerce_to_specific_type(pstate, newe, XMLOID,
+ "XMLFOREST");
+ break;
+ case IS_XMLPARSE:
+ if (i == 0)
+ newe = coerce_to_specific_type(pstate, newe, TEXTOID,
+ "XMLPARSE");
+ else
+ newe = coerce_to_boolean(pstate, newe, "XMLPARSE");
+ break;
+ case IS_XMLPI:
+ newe = coerce_to_specific_type(pstate, newe, TEXTOID,
+ "XMLPI");
+ break;
+ case IS_XMLROOT:
+ if (i == 0)
+ newe = coerce_to_specific_type(pstate, newe, XMLOID,
+ "XMLROOT");
+ else if (i == 1)
+ newe = coerce_to_specific_type(pstate, newe, TEXTOID,
+ "XMLROOT");
+ else
+ newe = coerce_to_boolean(pstate, newe, "XMLROOT");
+ break;
+ }
+ newx->args = lappend(newx->args, newe);
+ i++;
+ }
+
+ return (Node *) newx;
+}
+
+static Node *
transformBooleanTest(ParseState *pstate, BooleanTest *b)
{
const char *clausename;
@@ -1415,56 +1516,6 @@ transformBooleanTest(ParseState *pstate, BooleanTest *b)
return (Node *) b;
}
-static Node *
-transformXmlExpr(ParseState *pstate, XmlExpr *x)
-{
- ListCell *lc;
- XmlExpr *newx = makeNode(XmlExpr);
-
- newx->op = x->op;
- if (x->name)
- newx->name = map_sql_identifier_to_xml_name(x->name, false);
- else
- newx->name = NULL;
-
- foreach(lc, x->named_args)
- {
- ResTarget *r = (ResTarget *) lfirst(lc);
- Node *expr = transformExpr(pstate, r->val);
- char *argname = NULL;
-
- if (r->name)
- argname = map_sql_identifier_to_xml_name(r->name, false);
- else if (IsA(r->val, ColumnRef))
- argname = map_sql_identifier_to_xml_name(FigureColname(r->val), true);
- else
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- x->op == IS_XMLELEMENT
- ? errmsg("unnamed attribute value must be a column reference")
- : errmsg("unnamed element value must be a column reference")));
-
- newx->named_args = lappend(newx->named_args,
- makeTargetEntry((Expr *) expr, 0, argname, false));
- }
-
- foreach(lc, x->args)
- {
- Node *e = (Node *) lfirst(lc);
- Node *newe;
-
- newe = coerce_to_xml(pstate, transformExpr(pstate, e),
- (x->op == IS_XMLCONCAT
- ? "XMLCONCAT"
- : (x->op == IS_XMLELEMENT
- ? "XMLELEMENT"
- : "XMLFOREST")));
- newx->args = lappend(newx->args, newe);
- }
-
- return (Node *) newx;
-}
-
/*
* Construct a whole-row reference to represent the notation "relation.*".
*
@@ -1715,6 +1766,9 @@ exprType(Node *expr)
case T_MinMaxExpr:
type = ((MinMaxExpr *) expr)->minmaxtype;
break;
+ case T_XmlExpr:
+ type = XMLOID;
+ break;
case T_NullIfExpr:
type = exprType((Node *) linitial(((NullIfExpr *) expr)->args));
break;
@@ -1724,9 +1778,6 @@ exprType(Node *expr)
case T_BooleanTest:
type = BOOLOID;
break;
- case T_XmlExpr:
- type = XMLOID;
- break;
case T_CoerceToDomain:
type = ((CoerceToDomain *) expr)->resulttype;
break;
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 906d96e45c6..ef4b9083ac6 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.150 2006/12/21 16:05:14 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.151 2006/12/24 00:29:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1328,6 +1328,15 @@ FigureColnameInternal(Node *node, char **name)
case IS_XMLFOREST:
*name = "xmlforest";
return 2;
+ case IS_XMLPARSE:
+ *name = "xmlparse";
+ return 2;
+ case IS_XMLPI:
+ *name = "xmlpi";
+ return 2;
+ case IS_XMLROOT:
+ *name = "xmlroot";
+ return 2;
}
break;
default: