From ff566b224198ea5e9ce609d9e9c66fc9032ebae2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 25 May 2000 22:42:19 +0000 Subject: [PATCH] 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. --- src/backend/parser/gram.y | 20 ++++++++++---------- src/backend/parser/parse_expr.c | 10 ++++++---- src/include/nodes/primnodes.h | 6 +++--- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index e4f59bc605..ac7beb383d 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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; diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 0bb81dd247..0f16f25aff 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -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 diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 926513e0af..23b91647c2 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -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