1010 *
1111 *
1212 * IDENTIFICATION
13- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.92 1998/01/1704:53:16 momjian Exp $
13+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.93 1998/01/1705:01:34 momjian Exp $
1414 *
1515 * HISTORY
1616 * AUTHORDATEMAJOR EVENT
@@ -63,6 +63,7 @@ extern List *parsetree;
6363
6464static char *xlateSqlType(char *);
6565static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
66+ static Node *makeRowExpr(char *opr, List *largs, List *rargs);
6667void mapTargetColumns(List *source, List *target);
6768static List *makeConstantList( A_Const *node);
6869static char *FlattenStringList(List *list);
@@ -2882,7 +2883,6 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
28822883n->subselect = $7;
28832884$$ = (Node *)n;
28842885}
2885- /* We accept all Operators? */
28862886| '(' row_descriptor ')' Op '(' SubSelect ')'
28872887{
28882888SubLink *n = makeNode(SubLink);
@@ -2892,17 +2892,10 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
28922892n->subselect = $6;
28932893$$ = (Node *)n;
28942894}
2895- /* Do we need this?
28962895| '(' row_descriptor ')' Op '(' row_descriptor ')'
28972896{
2898- SubLink *n = makeNode(SubLink);
2899- n->lefthand = $2;
2900- n->subLinkType = OPER_SUBLINK;
2901- n->oper = lcons($4, NIL);
2902- n->subselect = $6;
2903- $$ = (Node *)n;
2897+ $$ = makeRowExpr($4, $2, $6);
29042898}
2905- */
29062899;
29072900
29082901row_descriptor: row_list ',' a_expr
@@ -3841,6 +3834,68 @@ makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
38413834return (Node *)a;
38423835}
38433836
3837+ /* makeRowExpr()
3838+ * Generate separate operator nodes for a single row descriptor expression.
3839+ * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
3840+ */
3841+ static Node *
3842+ makeRowExpr(char *opr, List *largs, List *rargs)
3843+ {
3844+ Node *expr = NULL;
3845+ Node *larg, *rarg;
3846+
3847+ if (length(largs) != length(rargs))
3848+ elog(ERROR,"Unequal number of entries in row expression");
3849+
3850+ if (lnext(largs) != NIL)
3851+ expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
3852+
3853+ larg = lfirst(largs);
3854+ rarg = lfirst(rargs);
3855+
3856+ if ((strcmp(opr, "=") == 0)
3857+ || (strcmp(opr, "<") == 0)
3858+ || (strcmp(opr, "<=") == 0)
3859+ || (strcmp(opr, ">") == 0)
3860+ || (strcmp(opr, ">=") == 0))
3861+ {
3862+ if (expr == NULL)
3863+ expr = makeA_Expr(OP, opr, larg, rarg);
3864+ else
3865+ expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3866+ }
3867+ else if (strcmp(opr, "<>") == 0)
3868+ {
3869+ if (expr == NULL)
3870+ expr = makeA_Expr(OP, opr, larg, rarg);
3871+ else
3872+ expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3873+ }
3874+ else
3875+ {
3876+ elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
3877+ }
3878+
3879+ #if FALSE
3880+ while ((largs != NIL) && (rargs != NIL))
3881+ {
3882+ larg = lfirst(largs);
3883+ rarg = lfirst(rargs);
3884+
3885+ if (expr == NULL)
3886+ expr = makeA_Expr(OP, opr, larg, rarg);
3887+ else
3888+ expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3889+
3890+ largs = lnext(largs);
3891+ rargs = lnext(rargs);
3892+ }
3893+ pprint(expr);
3894+ #endif
3895+
3896+ return expr;
3897+ }
3898+
38443899void
38453900mapTargetColumns(List *src, List *dst)
38463901{