Modify raw parsetree representation returned by gram.y for SubLinks:
the oper field should be a valid Node structure so it can be dumped by outfuncs.c without risk of coredump. (We had been using a raw pointer to character string, which surely is NOT a valid Node.) This doesn't cause any backwards compatibility problems for stored rules, since raw unanalyzed parsetrees are never stored.
This commit is contained in:
parent
610abfd57b
commit
ff566b2241
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.167 2000/04/07 13:39:34 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.168 2000/05/25 22:42:17 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -4153,7 +4153,7 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->lefthand = $2;
|
||||
n->oper = lcons("=", NIL);
|
||||
n->oper = (List *) makeA_Expr(OP, "=", NULL, NULL);
|
||||
n->useor = false;
|
||||
n->subLinkType = ANY_SUBLINK;
|
||||
n->subselect = $6;
|
||||
@ -4163,7 +4163,7 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->lefthand = $2;
|
||||
n->oper = lcons("<>", NIL);
|
||||
n->oper = (List *) makeA_Expr(OP, "<>", NULL, NULL);
|
||||
n->useor = true;
|
||||
n->subLinkType = ALL_SUBLINK;
|
||||
n->subselect = $7;
|
||||
@ -4173,8 +4173,8 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->lefthand = $2;
|
||||
n->oper = lcons($4, NIL);
|
||||
if (strcmp($4,"<>") == 0)
|
||||
n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL);
|
||||
if (strcmp($4, "<>") == 0)
|
||||
n->useor = true;
|
||||
else
|
||||
n->useor = false;
|
||||
@ -4186,8 +4186,8 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->lefthand = $2;
|
||||
n->oper = lcons($4, NIL);
|
||||
if (strcmp($4,"<>") == 0)
|
||||
n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL);
|
||||
if (strcmp($4, "<>") == 0)
|
||||
n->useor = true;
|
||||
else
|
||||
n->useor = false;
|
||||
@ -4436,7 +4436,7 @@ a_expr: c_expr
|
||||
{
|
||||
SubLink *n = (SubLink *)$4;
|
||||
n->lefthand = lcons($1, NIL);
|
||||
n->oper = lcons("=", NIL);
|
||||
n->oper = (List *) makeA_Expr(OP, "=", NULL, NULL);
|
||||
n->useor = false;
|
||||
n->subLinkType = ANY_SUBLINK;
|
||||
$$ = (Node *)n;
|
||||
@ -4463,7 +4463,7 @@ a_expr: c_expr
|
||||
{
|
||||
SubLink *n = (SubLink *)$5;
|
||||
n->lefthand = lcons($1, NIL);
|
||||
n->oper = lcons("<>", NIL);
|
||||
n->oper = (List *) makeA_Expr(OP, "<>", NULL, NULL);
|
||||
n->useor = false;
|
||||
n->subLinkType = ALL_SUBLINK;
|
||||
$$ = (Node *)n;
|
||||
@ -4487,7 +4487,7 @@ a_expr: c_expr
|
||||
{
|
||||
SubLink *n = makeNode(SubLink);
|
||||
n->lefthand = lcons($1, NIL);
|
||||
n->oper = lcons($2, NIL);
|
||||
n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
|
||||
n->useor = false; /* doesn't matter since only one col */
|
||||
n->subLinkType = $3;
|
||||
n->subselect = $5;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.76 2000/04/12 17:15:26 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.77 2000/05/25 22:42:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -324,23 +324,25 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
|
||||
else
|
||||
{
|
||||
/* ALL, ANY, or MULTIEXPR: generate operator list */
|
||||
char *op = lfirst(sublink->oper);
|
||||
List *left_list = sublink->lefthand;
|
||||
List *right_list = qtree->targetList;
|
||||
char *op;
|
||||
List *elist;
|
||||
|
||||
foreach(elist, left_list)
|
||||
lfirst(elist) = transformExpr(pstate, lfirst(elist),
|
||||
precedence);
|
||||
|
||||
Assert(IsA(sublink->oper, A_Expr));
|
||||
op = ((A_Expr *) sublink->oper)->opname;
|
||||
sublink->oper = NIL;
|
||||
|
||||
/* Combining operators other than =/<> is dubious... */
|
||||
if (length(left_list) != 1 &&
|
||||
strcmp(op, "=") != 0 && strcmp(op, "<>") != 0)
|
||||
elog(ERROR, "Row comparison cannot use '%s'",
|
||||
op);
|
||||
|
||||
sublink->oper = NIL;
|
||||
|
||||
/*
|
||||
* Scan subquery's targetlist to find values that will
|
||||
* be matched against lefthand values. We need to
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: primnodes.h,v 1.41 2000/04/12 17:16:40 momjian Exp $
|
||||
* $Id: primnodes.h,v 1.42 2000/05/25 22:42:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -350,8 +350,8 @@ typedef struct Aggref
|
||||
* NOTE: lefthand and oper have varying meanings depending on where you look
|
||||
* in the parse/plan pipeline:
|
||||
* 1. gram.y delivers a list of the (untransformed) lefthand expressions in
|
||||
* lefthand, and sets oper to a one-element list containing the string
|
||||
* name of the operator.
|
||||
* lefthand, and sets oper to a single A_Expr (not a list!) containing
|
||||
* the string name of the operator, but no arguments.
|
||||
* 2. The parser's expression transformation transforms lefthand normally,
|
||||
* and replaces oper with a list of Oper nodes, one per lefthand
|
||||
* expression. These nodes represent the parser's resolution of exactly
|
||||
|
Loading…
x
Reference in New Issue
Block a user