Tom Lane escribió:
> Alvaro Herrera <[EMAIL PROTECTED]> writes:
> > Tom Lane escribió:
> >> They're logically different things, and after I get done putting a parse
> >> location field into A_Const, they'll still be physically different too.
>
> > Aha. Are you working from Brendan's patch? I was going to commit it.
>
> Sure, go ahead. I was going to add the parse location at the same time,
> but it can perfectly well be done as a separate patch.
I came up with the attached patch. I added the location bits (although
I am unsure if I got the locations right in the parser), but they are
unused -- figuring out how to use them would take me longer than I can
to spend on this.
--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/nodes/copyfuncs.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.392
diff -c -p -r1.392 copyfuncs.c
*** src/backend/nodes/copyfuncs.c 14 Apr 2008 17:05:33 -0000 1.392
--- src/backend/nodes/copyfuncs.c 28 Apr 2008 20:20:44 -0000
*************** _copyAConst(A_Const *from)
*** 1639,1645 ****
break;
}
! COPY_NODE_FIELD(typename);
return newnode;
}
--- 1639,1645 ----
break;
}
! COPY_SCALAR_FIELD(location);
return newnode;
}
Index: src/backend/nodes/equalfuncs.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.321
diff -c -p -r1.321 equalfuncs.c
*** src/backend/nodes/equalfuncs.c 14 Apr 2008 17:05:33 -0000 1.321
--- src/backend/nodes/equalfuncs.c 28 Apr 2008 16:17:02 -0000
*************** _equalParamRef(ParamRef *a, ParamRef *b)
*** 1691,1701 ****
static bool
_equalAConst(A_Const *a, A_Const *b)
{
! if (!equal(&a->val, &b->val)) /* hack for in-line Value field */
! return false;
! COMPARE_NODE_FIELD(typename);
!
! return true;
}
static bool
--- 1691,1697 ----
static bool
_equalAConst(A_Const *a, A_Const *b)
{
! return equal(&a->val, &b->val); /* hack for in-line Value field */
}
static bool
Index: src/backend/nodes/outfuncs.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/nodes/outfuncs.c,v
retrieving revision 1.325
diff -c -p -r1.325 outfuncs.c
*** src/backend/nodes/outfuncs.c 13 Apr 2008 20:51:20 -0000 1.325
--- src/backend/nodes/outfuncs.c 28 Apr 2008 17:24:10 -0000
*************** _outAConst(StringInfo str, A_Const *node
*** 1945,1951 ****
appendStringInfo(str, " :val ");
_outValue(str, &(node->val));
! WRITE_NODE_FIELD(typename);
}
static void
--- 1945,1951 ----
appendStringInfo(str, " :val ");
_outValue(str, &(node->val));
! WRITE_INT_FIELD(location);
}
static void
Index: src/backend/parser/gram.y
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.612
diff -c -p -r2.612 gram.y
*** src/backend/parser/gram.y 14 Apr 2008 17:05:33 -0000 2.612
--- src/backend/parser/gram.y 28 Apr 2008 19:48:16 -0000
*************** static bool QueryIsRule = FALSE;
*** 91,101 ****
static Node *makeColumnRef(char *relname, List *indirection, int location);
static Node *makeTypeCast(Node *arg, TypeName *typename);
! static Node *makeStringConst(char *str, TypeName *typename);
! static Node *makeIntConst(int val);
! static Node *makeFloatConst(char *str);
! static Node *makeAConst(Value *v);
! static A_Const *makeBoolAConst(bool state);
static FuncCall *makeOverlaps(List *largs, List *rargs, int location);
static void check_qualified_name(List *names);
static List *check_func_name(List *names);
--- 91,102 ----
static Node *makeColumnRef(char *relname, List *indirection, int location);
static Node *makeTypeCast(Node *arg, TypeName *typename);
! static Node *makeStringConst(char *str, int location);
! static Node *makeStringConstCast(char *str, TypeName *typename, int location);
! static Node *makeIntConst(int val, int location);
! static Node *makeFloatConst(char *str, int location);
! static Node *makeAConst(Value *v, int location);
! static Node *makeBoolAConst(bool state, int location);
static FuncCall *makeOverlaps(List *largs, List *rargs, int location);
static void check_qualified_name(List *names);
static List *check_func_name(List *names);
*************** set_rest: /* Generic SET syntaxes: */
*** 1112,1118 ****
n->kind = VAR_SET_VALUE;
n->name = "client_encoding";
if ($2 != NULL)
! n->args = list_make1(makeStringConst($2, NULL));
else
n->kind = VAR_SET_DEFAULT;
$$ = n;
--- 1113,1119 ----
n->kind = VAR_SET_VALUE;
n->name = "client_encoding";
if ($2 != NULL)
! n->args = list_make1(makeStringConst($2, @2));
else
n->kind = VAR_SET_DEFAULT;
$$ = n;
*************** set_rest: /* Generic SET syntaxes: */
*** 1122,1128 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "role";
! n->args = list_make1(makeStringConst($2, NULL));
$$ = n;
}
| SESSION AUTHORIZATION ColId_or_Sconst
--- 1123,1129 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "role";
! n->args = list_make1(makeStringConst($2, @2));
$$ = n;
}
| SESSION AUTHORIZATION ColId_or_Sconst
*************** set_rest: /* Generic SET syntaxes: */
*** 1130,1136 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "session_authorization";
! n->args = list_make1(makeStringConst($3, NULL));
$$ = n;
}
| SESSION AUTHORIZATION DEFAULT
--- 1131,1137 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "session_authorization";
! n->args = list_make1(makeStringConst($3, @3));
$$ = n;
}
| SESSION AUTHORIZATION DEFAULT
*************** set_rest: /* Generic SET syntaxes: */
*** 1145,1151 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "xmloption";
! n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", NULL));
$$ = n;
}
;
--- 1146,1153 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "xmloption";
! n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ?
! "DOCUMENT" : "CONTENT", @3));
$$ = n;
}
;
*************** var_list: var_value { $$ = list_m
*** 1163,1173 ****
;
var_value: opt_boolean
! { $$ = makeStringConst($1, NULL); }
| ColId_or_Sconst
! { $$ = makeStringConst($1, NULL); }
| NumericOnly
! { $$ = makeAConst($1); }
;
iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; }
--- 1165,1175 ----
;
var_value: opt_boolean
! { $$ = makeStringConst($1, @1); }
| ColId_or_Sconst
! { $$ = makeStringConst($1, @1); }
| NumericOnly
! { $$ = makeAConst($1, @1); }
;
iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; }
*************** opt_boolean:
*** 1194,1231 ****
zone_value:
Sconst
{
! $$ = makeStringConst($1, NULL);
}
| IDENT
{
! $$ = makeStringConst($1, NULL);
}
| ConstInterval Sconst opt_interval
{
! A_Const *n = (A_Const *) makeStringConst($2, $1);
if ($3 != INTERVAL_FULL_RANGE)
{
if (($3 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
! n->typename->typmods = list_make1(makeIntConst($3));
}
! $$ = (Node *)n;
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
! A_Const *n = (A_Const *) makeStringConst($5, $1);
if (($6 != INTERVAL_FULL_RANGE)
&& (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
! n->typename->typmods = list_make2(makeIntConst($6),
! makeIntConst($3));
! $$ = (Node *)n;
}
! | NumericOnly { $$ = makeAConst($1); }
| DEFAULT { $$ = NULL; }
| LOCAL { $$ = NULL; }
;
--- 1196,1233 ----
zone_value:
Sconst
{
! $$ = makeStringConst($1, @1);
}
| IDENT
{
! $$ = makeStringConst($1, @1);
}
| ConstInterval Sconst opt_interval
{
! TypeName *t = $1;
if ($3 != INTERVAL_FULL_RANGE)
{
if (($3 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
! t->typmods = list_make1(makeIntConst($3, @3));
}
! $$ = (Node *)makeStringConstCast($2, t, @2);
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
! TypeName *t = $1;
if (($6 != INTERVAL_FULL_RANGE)
&& (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
! t->typmods = list_make2(makeIntConst($6, @6),
! makeIntConst($3, @3));
! $$ = (Node *)makeStringConstCast($5, t, @5);
}
! | NumericOnly { $$ = makeAConst($1, @1); }
| DEFAULT { $$ = NULL; }
| LOCAL { $$ = NULL; }
;
*************** opt_transaction: WORK {}
*** 5207,5219 ****
transaction_mode_item:
ISOLATION LEVEL iso_level
{ $$ = makeDefElem("transaction_isolation",
! makeStringConst($3, NULL)); }
| READ ONLY
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(TRUE)); }
| READ WRITE
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(FALSE)); }
;
/* Syntax with commas is SQL-spec, without commas is Postgres historical */
--- 5209,5221 ----
transaction_mode_item:
ISOLATION LEVEL iso_level
{ $$ = makeDefElem("transaction_isolation",
! makeStringConst($3, @3)); }
| READ ONLY
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(TRUE, -1)); }
| READ WRITE
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(FALSE, -1)); }
;
/* Syntax with commas is SQL-spec, without commas is Postgres historical */
*************** select_limit_value:
*** 6396,6401 ****
--- 6398,6404 ----
/* LIMIT ALL is represented as a NULL constant */
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
+ n->location = @1;
$$ = (Node *)n;
}
;
*************** SimpleTypename:
*** 6898,6910 ****
{
$$ = $1;
if ($2 != INTERVAL_FULL_RANGE)
! $$->typmods = list_make1(makeIntConst($2));
}
| ConstInterval '(' Iconst ')' opt_interval
{
$$ = $1;
! $$->typmods = list_make2(makeIntConst($5),
! makeIntConst($3));
}
;
--- 6901,6913 ----
{
$$ = $1;
if ($2 != INTERVAL_FULL_RANGE)
! $$->typmods = list_make1(makeIntConst($2, @2));
}
| ConstInterval '(' Iconst ')' opt_interval
{
$$ = $1;
! $$->typmods = list_make2(makeIntConst($5, @5),
! makeIntConst($3, @3));
}
;
*************** BitWithoutLength:
*** 7090,7096 ****
else
{
$$ = SystemTypeName("bit");
! $$->typmods = list_make1(makeIntConst(1));
}
$$->location = @1;
}
--- 7093,7099 ----
else
{
$$ = SystemTypeName("bit");
! $$->typmods = list_make1(makeIntConst(1, -1));
}
$$->location = @1;
}
*************** CharacterWithLength: character '(' Icon
*** 7142,7148 ****
}
$$ = SystemTypeName($1);
! $$->typmods = list_make1(makeIntConst($3));
$$->location = @1;
}
;
--- 7145,7151 ----
}
$$ = SystemTypeName($1);
! $$->typmods = list_make1(makeIntConst($3, @3));
$$->location = @1;
}
;
*************** CharacterWithoutLength: character opt_c
*** 7164,7170 ****
/* char defaults to char(1), varchar to no limit */
if (strcmp($1, "bpchar") == 0)
! $$->typmods = list_make1(makeIntConst(1));
$$->location = @1;
}
--- 7167,7173 ----
/* char defaults to char(1), varchar to no limit */
if (strcmp($1, "bpchar") == 0)
! $$->typmods = list_make1(makeIntConst(1, -1));
$$->location = @1;
}
*************** ConstDatetime:
*** 7204,7210 ****
$$ = SystemTypeName("timestamptz");
else
$$ = SystemTypeName("timestamp");
! $$->typmods = list_make1(makeIntConst($3));
$$->location = @1;
}
| TIMESTAMP opt_timezone
--- 7207,7213 ----
$$ = SystemTypeName("timestamptz");
else
$$ = SystemTypeName("timestamp");
! $$->typmods = list_make1(makeIntConst($3, @3));
$$->location = @1;
}
| TIMESTAMP opt_timezone
*************** ConstDatetime:
*** 7221,7227 ****
$$ = SystemTypeName("timetz");
else
$$ = SystemTypeName("time");
! $$->typmods = list_make1(makeIntConst($3));
$$->location = @1;
}
| TIME opt_timezone
--- 7224,7230 ----
$$ = SystemTypeName("timetz");
else
$$ = SystemTypeName("time");
! $$->typmods = list_make1(makeIntConst($3, @3));
$$->location = @1;
}
| TIME opt_timezone
*************** a_expr: c_expr { $$ = $1; }
*** 7411,7416 ****
--- 7414,7420 ----
A_Const *c = makeNode(A_Const);
FuncCall *n = makeNode(FuncCall);
c->val.type = T_Null;
+ c->location = -1;
n->funcname = SystemFuncName("similar_escape");
n->args = list_make2($4, (Node *) c);
n->agg_star = FALSE;
*************** a_expr: c_expr { $$ = $1; }
*** 7433,7438 ****
--- 7437,7443 ----
A_Const *c = makeNode(A_Const);
FuncCall *n = makeNode(FuncCall);
c->val.type = T_Null;
+ c->location = -1;
n->funcname = SystemFuncName("similar_escape");
n->args = list_make2($5, (Node *) c);
n->agg_star = FALSE;
*************** func_expr: func_name '(' ')'
*** 7912,7927 ****
* that is actually possible, but not clear that we want
* to rely on it.)
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
!
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
! d = SystemTypeName("date");
!
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| CURRENT_TIME
{
--- 7917,7927 ----
* that is actually possible, but not clear that we want
* to rely on it.)
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! $$ = (Node *)makeTypeCast((Node *)n,
! SystemTypeName("date"));
}
| CURRENT_TIME
{
*************** func_expr: func_name '(' ')'
*** 7929,7944 ****
* Translate as "'now'::text::timetz".
* See comments for CURRENT_DATE.
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
!
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
!
! d = SystemTypeName("timetz");
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| CURRENT_TIME '(' Iconst ')'
{
--- 7929,7939 ----
* Translate as "'now'::text::timetz".
* See comments for CURRENT_DATE.
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! $$ = (Node *)makeTypeCast((Node *)n,
! SystemTypeName("timetz"));
}
| CURRENT_TIME '(' Iconst ')'
{
*************** func_expr: func_name '(' ')'
*** 7946,7961 ****
* Translate as "'now'::text::timetz(n)".
* See comments for CURRENT_DATE.
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
! d = SystemTypeName("timetz");
! d->typmods = list_make1(makeIntConst($3));
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| CURRENT_TIMESTAMP
{
--- 7941,7953 ----
* Translate as "'now'::text::timetz(n)".
* See comments for CURRENT_DATE.
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! TypeName *d = SystemTypeName("timetz");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = (Node *)makeTypeCast((Node *)n, d);
}
| CURRENT_TIMESTAMP
{
*************** func_expr: func_name '(' ')'
*** 7977,7993 ****
* Translate as "'now'::text::timestamptz(n)".
* See comments for CURRENT_DATE.
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
! d = SystemTypeName("timestamptz");
! d->typmods = list_make1(makeIntConst($3));
!
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| LOCALTIME
{
--- 7969,7981 ----
* Translate as "'now'::text::timestamptz(n)".
* See comments for CURRENT_DATE.
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! TypeName *d = SystemTypeName("timestamptz");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = (Node *)makeTypeCast((Node *)n, d);
}
| LOCALTIME
{
*************** func_expr: func_name '(' ')'
*** 7995,8010 ****
* Translate as "'now'::text::time".
* See comments for CURRENT_DATE.
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
!
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
!
! d = SystemTypeName("time");
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| LOCALTIME '(' Iconst ')'
{
--- 7983,7993 ----
* Translate as "'now'::text::time".
* See comments for CURRENT_DATE.
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! $$ = (Node *)makeTypeCast((Node *)n,
! SystemTypeName("time"));
}
| LOCALTIME '(' Iconst ')'
{
*************** func_expr: func_name '(' ')'
*** 8012,8027 ****
* Translate as "'now'::text::time(n)".
* See comments for CURRENT_DATE.
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
! d = SystemTypeName("time");
! d->typmods = list_make1(makeIntConst($3));
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| LOCALTIMESTAMP
{
--- 7995,8007 ----
* Translate as "'now'::text::time(n)".
* See comments for CURRENT_DATE.
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! TypeName *d = SystemTypeName("time");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = (Node *)makeTypeCast((Node *)n, d);
}
| LOCALTIMESTAMP
{
*************** func_expr: func_name '(' ')'
*** 8029,8044 ****
* Translate as "'now'::text::timestamp".
* See comments for CURRENT_DATE.
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
!
! d = SystemTypeName("timestamp");
!
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| LOCALTIMESTAMP '(' Iconst ')'
{
--- 8009,8019 ----
* Translate as "'now'::text::timestamp".
* See comments for CURRENT_DATE.
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! $$ = (Node *)makeTypeCast((Node *)n,
! SystemTypeName("timestamp"));
}
| LOCALTIMESTAMP '(' Iconst ')'
{
*************** func_expr: func_name '(' ')'
*** 8046,8062 ****
* Translate as "'now'::text::timestamp(n)".
* See comments for CURRENT_DATE.
*/
! A_Const *s = makeNode(A_Const);
! TypeName *d;
!
! s->val.type = T_String;
! s->val.val.str = "now";
! s->typename = SystemTypeName("text");
! d = SystemTypeName("timestamp");
! d->typmods = list_make1(makeIntConst($3));
! $$ = (Node *)makeTypeCast((Node *)s, d);
}
| CURRENT_ROLE
{
--- 8021,8033 ----
* Translate as "'now'::text::timestamp(n)".
* See comments for CURRENT_DATE.
*/
! Node *n = makeStringConstCast("now",
! SystemTypeName("text"), @1);
! TypeName *d = SystemTypeName("timestamp");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = (Node *)makeTypeCast((Node *)n, d);
}
| CURRENT_ROLE
{
*************** func_expr: func_name '(' ')'
*** 8263,8269 ****
{
XmlExpr *x = (XmlExpr *) makeXmlExpr(IS_XMLPARSE, NULL, NIL,
list_make2($4,
! makeBoolAConst($5)));
x->xmloption = $3;
$$ = (Node *)x;
}
--- 8234,8240 ----
{
XmlExpr *x = (XmlExpr *) makeXmlExpr(IS_XMLPARSE, NULL, NIL,
list_make2($4,
! makeBoolAConst($5, @5)));
x->xmloption = $3;
$$ = (Node *)x;
}
*************** xml_root_version: VERSION_P a_expr
*** 8299,8316 ****
{
A_Const *val = makeNode(A_Const);
val->val.type = T_Null;
$$ = (Node *) val;
}
;
opt_xml_root_standalone: ',' STANDALONE_P YES_P
! { $$ = (Node *) makeIntConst(XML_STANDALONE_YES); }
| ',' STANDALONE_P NO
! { $$ = (Node *) makeIntConst(XML_STANDALONE_NO); }
| ',' STANDALONE_P NO VALUE_P
! { $$ = (Node *) makeIntConst(XML_STANDALONE_NO_VALUE); }
| /*EMPTY*/
! { $$ = (Node *) makeIntConst(XML_STANDALONE_OMITTED); }
;
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
--- 8270,8288 ----
{
A_Const *val = makeNode(A_Const);
val->val.type = T_Null;
+ val->location = @1;
$$ = (Node *) val;
}
;
opt_xml_root_standalone: ',' STANDALONE_P YES_P
! { $$ = (Node *) makeIntConst(XML_STANDALONE_YES, @2); }
| ',' STANDALONE_P NO
! { $$ = (Node *) makeIntConst(XML_STANDALONE_NO, @2); }
| ',' STANDALONE_P NO VALUE_P
! { $$ = (Node *) makeIntConst(XML_STANDALONE_NO_VALUE, @2); }
| /*EMPTY*/
! { $$ = (Node *) makeIntConst(XML_STANDALONE_OMITTED, -1); }
;
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
*************** extract_list:
*** 8457,8462 ****
--- 8429,8435 ----
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = $1;
+ n->location = @1;
$$ = list_make2((Node *) n, $3);
}
| /*EMPTY*/ { $$ = NIL; }
*************** substr_list:
*** 8544,8549 ****
--- 8517,8523 ----
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
n->val.val.ival = 1;
+ n->location = -1;
$$ = list_make3($1, (Node *) n,
makeTypeCast($2, SystemTypeName("int4")));
}
*************** AexprConst: Iconst
*** 8859,8864 ****
--- 8833,8839 ----
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
n->val.val.ival = $1;
+ n->location = @1;
$$ = (Node *)n;
}
| FCONST
*************** AexprConst: Iconst
*** 8866,8871 ****
--- 8841,8847 ----
A_Const *n = makeNode(A_Const);
n->val.type = T_Float;
n->val.val.str = $1;
+ n->location = @1;
$$ = (Node *)n;
}
| Sconst
*************** AexprConst: Iconst
*** 8873,8878 ****
--- 8849,8855 ----
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = $1;
+ n->location = @1;
$$ = (Node *)n;
}
| BCONST
*************** AexprConst: Iconst
*** 8880,8885 ****
--- 8857,8863 ----
A_Const *n = makeNode(A_Const);
n->val.type = T_BitString;
n->val.val.str = $1;
+ n->location = @1;
$$ = (Node *)n;
}
| XCONST
*************** AexprConst: Iconst
*** 8892,8961 ****
A_Const *n = makeNode(A_Const);
n->val.type = T_BitString;
n->val.val.str = $1;
$$ = (Node *)n;
}
| func_name Sconst
{
/* generic type 'literal' syntax */
! A_Const *n = makeNode(A_Const);
! n->typename = makeTypeNameFromNameList($1);
! n->typename->location = @1;
! n->val.type = T_String;
! n->val.val.str = $2;
! $$ = (Node *)n;
}
| func_name '(' expr_list ')' Sconst
{
/* generic syntax with a type modifier */
! A_Const *n = makeNode(A_Const);
! n->typename = makeTypeNameFromNameList($1);
! n->typename->typmods = $3;
! n->typename->location = @1;
! n->val.type = T_String;
! n->val.val.str = $5;
! $$ = (Node *)n;
}
| ConstTypename Sconst
{
! A_Const *n = makeNode(A_Const);
! n->typename = $1;
! n->val.type = T_String;
! n->val.val.str = $2;
! $$ = (Node *)n;
}
| ConstInterval Sconst opt_interval
{
! A_Const *n = makeNode(A_Const);
! n->typename = $1;
! n->val.type = T_String;
! n->val.val.str = $2;
/* precision is not specified, but fields may be... */
if ($3 != INTERVAL_FULL_RANGE)
! n->typename->typmods = list_make1(makeIntConst($3));
! $$ = (Node *)n;
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
! A_Const *n = makeNode(A_Const);
! n->typename = $1;
! n->val.type = T_String;
! n->val.val.str = $5;
! n->typename->typmods = list_make2(makeIntConst($6),
! makeIntConst($3));
! $$ = (Node *)n;
}
| TRUE_P
{
! $$ = (Node *)makeBoolAConst(TRUE);
}
| FALSE_P
{
! $$ = (Node *)makeBoolAConst(FALSE);
}
| NULL_P
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
$$ = (Node *)n;
}
;
--- 8870,8926 ----
A_Const *n = makeNode(A_Const);
n->val.type = T_BitString;
n->val.val.str = $1;
+ n->location = @1;
$$ = (Node *)n;
}
| func_name Sconst
{
/* generic type 'literal' syntax */
! TypeName *t = makeTypeNameFromNameList($1);
! t->location = @1;
!
! $$ = (Node *)makeStringConstCast($2, t, @1);
}
| func_name '(' expr_list ')' Sconst
{
/* generic syntax with a type modifier */
! TypeName *t = makeTypeNameFromNameList($1);
! t->typmods = $3;
! t->location = @1;
! $$ = (Node *)makeStringConstCast($5, t, @1);
}
| ConstTypename Sconst
{
! $$ = (Node *)makeStringConstCast($2, $1, @1);
}
| ConstInterval Sconst opt_interval
{
! TypeName *t = $1;
/* precision is not specified, but fields may be... */
if ($3 != INTERVAL_FULL_RANGE)
! t->typmods = list_make1(makeIntConst($3, @3));
! $$ = (Node *)makeStringConstCast($2, t, @1);
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
! TypeName *t = $1;
! t->typmods = list_make2(makeIntConst($6, @6),
! makeIntConst($3, @3));
! $$ = (Node *)makeStringConstCast($5, t, @1);
}
| TRUE_P
{
! $$ = (Node *)makeBoolAConst(TRUE, @1);
}
| FALSE_P
{
! $$ = (Node *)makeBoolAConst(FALSE, @1);
}
| NULL_P
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
+ n->location = @1;
$$ = (Node *)n;
}
;
*************** makeTypeCast(Node *arg, TypeName *typena
*** 9506,9563 ****
}
static Node *
! makeStringConst(char *str, TypeName *typename)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = str;
! n->typename = typename;
return (Node *)n;
}
static Node *
! makeIntConst(int val)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
n->val.val.ival = val;
! n->typename = SystemTypeName("int4");
return (Node *)n;
}
static Node *
! makeFloatConst(char *str)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Float;
n->val.val.str = str;
! n->typename = SystemTypeName("float8");
! return (Node *)n;
}
static Node *
! makeAConst(Value *v)
{
Node *n;
switch (v->type)
{
case T_Float:
! n = makeFloatConst(v->val.str);
break;
case T_Integer:
! n = makeIntConst(v->val.ival);
break;
case T_String:
default:
! n = makeStringConst(v->val.str, NULL);
break;
}
--- 9471,9537 ----
}
static Node *
! makeStringConst(char *str, int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = str;
! n->location = location;
return (Node *)n;
}
static Node *
! makeStringConstCast(char *str, TypeName *typename, int location)
! {
! Node *s = makeStringConst(str, location);
!
! return makeTypeCast(s, typename);
! }
!
! static Node *
! makeIntConst(int val, int location)
{
A_Const *n = makeNode(A_Const);
+
n->val.type = T_Integer;
n->val.val.ival = val;
! n->location = location;
return (Node *)n;
}
static Node *
! makeFloatConst(char *str, int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Float;
n->val.val.str = str;
! n->location = location;
! return makeTypeCast((Node *)n, SystemTypeName("float8"));
}
static Node *
! makeAConst(Value *v, int location)
{
Node *n;
switch (v->type)
{
case T_Float:
! n = makeFloatConst(v->val.str, location);
break;
case T_Integer:
! n = makeIntConst(v->val.ival, location);
break;
case T_String:
default:
! n = makeStringConst(v->val.str, location);
break;
}
*************** makeAConst(Value *v)
*** 9565,9580 ****
}
/* makeBoolAConst()
! * Create an A_Const node and initialize to a boolean constant.
*/
! static A_Const *
! makeBoolAConst(bool state)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = (state ? "t" : "f");
! n->typename = SystemTypeName("bool");
! return n;
}
/* makeOverlaps()
--- 9539,9556 ----
}
/* makeBoolAConst()
! * Create an A_Const string node and put it inside a boolean cast.
*/
! static Node *
! makeBoolAConst(bool state, int location)
{
A_Const *n = makeNode(A_Const);
+
n->val.type = T_String;
n->val.val.str = (state ? "t" : "f");
! n->location = location;
!
! return makeTypeCast((Node *)n, SystemTypeName("bool"));
}
/* makeOverlaps()
Index: src/backend/parser/parse_expr.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/parser/parse_expr.c,v
retrieving revision 1.227
diff -c -p -r1.227 parse_expr.c
*** src/backend/parser/parse_expr.c 20 Mar 2008 21:42:48 -0000 1.227
--- src/backend/parser/parse_expr.c 28 Apr 2008 16:17:02 -0000
*************** transformExpr(ParseState *pstate, Node *
*** 127,135 ****
Value *val = &con->val;
result = (Node *) make_const(val);
- if (con->typename != NULL)
- result = typecast_expression(pstate, result,
- con->typename);
break;
}
--- 127,132 ----
*************** exprIsNullConstant(Node *arg)
*** 649,656 ****
{
A_Const *con = (A_Const *) arg;
! if (con->val.type == T_Null &&
! con->typename == NULL)
return true;
}
return false;
--- 646,652 ----
{
A_Const *con = (A_Const *) arg;
! if (con->val.type == T_Null)
return true;
}
return false;
Index: src/backend/parser/parse_target.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/parser/parse_target.c,v
retrieving revision 1.159
diff -c -p -r1.159 parse_target.c
*** src/backend/parser/parse_target.c 20 Mar 2008 21:42:48 -0000 1.159
--- src/backend/parser/parse_target.c 28 Apr 2008 16:17:02 -0000
*************** FigureColnameInternal(Node *node, char *
*** 1266,1278 ****
return 2;
}
break;
- case T_A_Const:
- if (((A_Const *) node)->typename != NULL)
- {
- *name = strVal(llast(((A_Const *) node)->typename->names));
- return 1;
- }
- break;
case T_TypeCast:
strength = FigureColnameInternal(((TypeCast *) node)->arg,
name);
--- 1266,1271 ----
Index: src/backend/parser/parse_type.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/parser/parse_type.c,v
retrieving revision 1.95
diff -c -p -r1.95 parse_type.c
*** src/backend/parser/parse_type.c 11 Apr 2008 22:54:23 -0000 1.95
--- src/backend/parser/parse_type.c 28 Apr 2008 16:17:02 -0000
*************** typenameTypeMod(ParseState *pstate, cons
*** 289,308 ****
{
A_Const *ac = (A_Const *) tm;
- /*
- * The grammar hands back some integers with ::int4 attached, so
- * allow a cast decoration if it's an Integer value, but not
- * otherwise.
- */
if (IsA(&ac->val, Integer))
{
cstr = (char *) palloc(32);
snprintf(cstr, 32, "%ld", (long) ac->val.val.ival);
}
! else if (ac->typename == NULL) /* no casts allowed */
! {
! /* otherwise we can just use the str field directly. */
cstr = ac->val.val.str;
}
}
else if (IsA(tm, ColumnRef))
--- 289,321 ----
{
A_Const *ac = (A_Const *) tm;
if (IsA(&ac->val, Integer))
{
cstr = (char *) palloc(32);
snprintf(cstr, 32, "%ld", (long) ac->val.val.ival);
}
! else
! /* we can just use the str field directly. */
cstr = ac->val.val.str;
+ }
+ else if (IsA(tm, TypeCast))
+ {
+ /*
+ * The grammar hands back some integers with ::int4 attached, so
+ * allow a cast decoration if it's an Integer value, but not
+ * otherwise.
+ */
+ TypeCast *tc = (TypeCast *) tm;
+
+ if (IsA(tc->arg, A_Const))
+ {
+ A_Const *ac = (A_Const *) tc->arg;
+
+ if (IsA(&ac->val, Integer))
+ {
+ cstr = (char *) palloc(32);
+ snprintf(cstr, 32, "%ld", (long) ac->val.val.ival);
+ }
}
}
else if (IsA(tm, ColumnRef))
Index: src/backend/parser/parse_utilcmd.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/parser/parse_utilcmd.c,v
retrieving revision 2.12
diff -c -p -r2.12 parse_utilcmd.c
*** src/backend/parser/parse_utilcmd.c 24 Apr 2008 20:46:49 -0000 2.12
--- src/backend/parser/parse_utilcmd.c 28 Apr 2008 16:17:02 -0000
*************** transformColumnDefinition(ParseState *ps
*** 308,313 ****
--- 308,314 ----
char *sname;
char *qstring;
A_Const *snamenode;
+ TypeCast *castnode;
FuncCall *funccallnode;
CreateSeqStmt *seqstmt;
AlterSeqStmt *altseqstmt;
*************** transformColumnDefinition(ParseState *ps
*** 379,388 ****
snamenode = makeNode(A_Const);
snamenode->val.type = T_String;
snamenode->val.val.str = qstring;
! snamenode->typename = SystemTypeName("regclass");
funccallnode = makeNode(FuncCall);
funccallnode->funcname = SystemFuncName("nextval");
! funccallnode->args = list_make1(snamenode);
funccallnode->agg_star = false;
funccallnode->agg_distinct = false;
funccallnode->location = -1;
--- 380,391 ----
snamenode = makeNode(A_Const);
snamenode->val.type = T_String;
snamenode->val.val.str = qstring;
! castnode = makeNode(TypeCast);
! castnode->typename = SystemTypeName("regclass");
! castnode->arg = (Node *) snamenode;
funccallnode = makeNode(FuncCall);
funccallnode->funcname = SystemFuncName("nextval");
! funccallnode->args = list_make1(castnode);
funccallnode->agg_star = false;
funccallnode->agg_distinct = false;
funccallnode->location = -1;
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.447
diff -c -p -r1.447 guc.c
*** src/backend/utils/misc/guc.c 18 Apr 2008 01:42:17 -0000 1.447
--- src/backend/utils/misc/guc.c 28 Apr 2008 20:14:31 -0000
*************** flatten_set_variable_args(const char *na
*** 5207,5235 ****
initStringInfo(&buf);
foreach(l, args)
{
! A_Const *arg = (A_Const *) lfirst(l);
char *val;
if (l != list_head(args))
appendStringInfo(&buf, ", ");
if (!IsA(arg, A_Const))
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg));
! switch (nodeTag(&arg->val))
{
case T_Integer:
! appendStringInfo(&buf, "%ld", intVal(&arg->val));
break;
case T_Float:
/* represented as a string, so just copy it */
! appendStringInfoString(&buf, strVal(&arg->val));
break;
case T_String:
! val = strVal(&arg->val);
! if (arg->typename != NULL)
{
/*
* Must be a ConstInterval argument for TIME ZONE. Coerce
--- 5207,5254 ----
initStringInfo(&buf);
+ /*
+ * Each list member may be a plain A_Const node, or an A_Const within a
+ * TypeCast, as produced by makeFloatConst() et al in gram.y.
+ */
foreach(l, args)
{
! Node *arg = (Node *) lfirst(l);
char *val;
+ TypeName *typename = NULL;
+ A_Const *con;
if (l != list_head(args))
appendStringInfo(&buf, ", ");
+ if (IsA(arg, TypeCast))
+ {
+ TypeCast *tc = (TypeCast *) arg;
+
+ arg = tc->arg;
+ typename = tc->typename;
+ }
+
if (!IsA(arg, A_Const))
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg));
! con = (A_Const *) arg;
! switch (nodeTag(&con->val))
{
case T_Integer:
! appendStringInfo(&buf, "%ld", intVal(&con->val));
break;
case T_Float:
/* represented as a string, so just copy it */
! appendStringInfoString(&buf, strVal(&con->val));
break;
case T_String:
! /*
! * Plain string literal or identifier. For quote mode,
! * quote it if it's not a vanilla identifier.
! */
! val = strVal(&con->val);
! if (typename != NULL)
{
/*
* Must be a ConstInterval argument for TIME ZONE. Coerce
*************** flatten_set_variable_args(const char *na
*** 5241,5247 ****
Datum interval;
char *intervalout;
! typoid = typenameTypeId(NULL, arg->typename, &typmod);
Assert(typoid == INTERVALOID);
interval =
--- 5260,5266 ----
Datum interval;
char *intervalout;
! typoid = typenameTypeId(NULL, typename, &typmod);
Assert(typoid == INTERVALOID);
interval =
*************** flatten_set_variable_args(const char *na
*** 5254,5266 ****
DatumGetCString(DirectFunctionCall1(interval_out,
interval));
appendStringInfo(&buf, "INTERVAL '%s'", intervalout);
}
else
{
- /*
- * Plain string literal or identifier. For quote mode,
- * quote it if it's not a vanilla identifier.
- */
if (flags & GUC_LIST_QUOTE)
appendStringInfoString(&buf, quote_identifier(val));
else
--- 5273,5284 ----
DatumGetCString(DirectFunctionCall1(interval_out,
interval));
appendStringInfo(&buf, "INTERVAL '%s'", intervalout);
+
+ /* don't leave this set */
+ typename = NULL;
}
else
{
if (flags & GUC_LIST_QUOTE)
appendStringInfoString(&buf, quote_identifier(val));
else
*************** flatten_set_variable_args(const char *na
*** 5269,5275 ****
break;
default:
elog(ERROR, "unrecognized node type: %d",
! (int) nodeTag(&arg->val));
break;
}
}
--- 5287,5293 ----
break;
default:
elog(ERROR, "unrecognized node type: %d",
! (int) nodeTag(&con->val));
break;
}
}
Index: src/include/catalog/catversion.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/catalog/catversion.h,v
retrieving revision 1.451
diff -c -p -r1.451 catversion.h
*** src/include/catalog/catversion.h 28 Apr 2008 14:57:35 -0000 1.451
--- src/include/catalog/catversion.h 28 Apr 2008 16:17:17 -0000
***************
*** 53,58 ****
*/
/* yyyymmddN */
! #define CATALOG_VERSION_NO 200804281
#endif
--- 53,58 ----
*/
/* yyyymmddN */
! #define CATALOG_VERSION_NO 200804282
#endif
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.362
diff -c -p -r1.362 parsenodes.h
*** src/include/nodes/parsenodes.h 14 Apr 2008 17:05:34 -0000 1.362
--- src/include/nodes/parsenodes.h 28 Apr 2008 19:16:49 -0000
*************** typedef struct A_Const
*** 234,250 ****
{
NodeTag type;
Value val; /* the value (with the tag) */
! TypeName *typename; /* typecast, or NULL if none */
} A_Const;
/*
* TypeCast - a CAST expression
- *
- * NOTE: for mostly historical reasons, A_Const parsenodes contain
- * room for a TypeName, allowing a constant to be marked as being of a given
- * type without a separate TypeCast node. Either representation will work,
- * but the combined representation saves a bit of code in many
- * productions in gram.y.
*/
typedef struct TypeCast
{
--- 234,244 ----
{
NodeTag type;
Value val; /* the value (with the tag) */
! int location; /* token location, or -1 if unknown */
} A_Const;
/*
* TypeCast - a CAST expression
*/
typedef struct TypeCast
{
--
Sent via pgsql-patches mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches