diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 1999-11-15 02:00:15 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 1999-11-15 02:00:15 +0000 |
commit | f68e11f373de8b7b1d19203b8edac1a13a8d406d (patch) | |
tree | c4e61de2b9bd9b8dd7c70545dc861de3547294d4 /src/backend/utils/adt/ruleutils.c | |
parent | 1ecb129d206f30f5813b01e1f1efe75c06febe49 (diff) | |
download | postgresql-f68e11f373de8b7b1d19203b8edac1a13a8d406d.tar.gz postgresql-f68e11f373de8b7b1d19203b8edac1a13a8d406d.zip |
Implement subselects in target lists. Also, relax requirement that
subselects can only appear on the righthand side of a binary operator.
That's still true for quantified predicates like x = ANY (SELECT ...),
but a subselect that delivers a single result can now appear anywhere
in an expression. This is implemented by changing EXPR_SUBLINK sublinks
to represent just the (SELECT ...) expression, without any 'left hand
side' or combining operator --- so they're now more like EXISTS_SUBLINK.
To handle the case of '(x, y, z) = (SELECT ...)', I added a new sublink
type MULTIEXPR_SUBLINK, which acts just like EXPR_SUBLINK used to.
But the grammar will only generate one for a multiple-left-hand-side
row expression.
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 22f904b60d5..89febb159b9 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * out of it's tuple * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.30 1999/11/07 23:08:24 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.31 1999/11/15 02:00:05 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -1681,15 +1681,17 @@ get_sublink_expr(Node *node, deparse_context *context) StringInfo buf = context->buf; SubLink *sublink = (SubLink *) node; Query *query = (Query *) (sublink->subselect); - Oper *oper; List *l; char *sep; + Oper *oper; + bool need_paren; appendStringInfo(buf, "("); - if (sublink->lefthand != NULL) + if (sublink->lefthand != NIL) { - if (length(sublink->lefthand) > 1) + need_paren = (length(sublink->lefthand) > 1); + if (need_paren) appendStringInfo(buf, "("); sep = ""; @@ -1700,12 +1702,14 @@ get_sublink_expr(Node *node, deparse_context *context) get_rule_expr((Node *) lfirst(l), context); } - if (length(sublink->lefthand) > 1) + if (need_paren) appendStringInfo(buf, ") "); else appendStringInfo(buf, " "); } + need_paren = true; + switch (sublink->subLinkType) { case EXISTS_SUBLINK: @@ -1722,20 +1726,30 @@ get_sublink_expr(Node *node, deparse_context *context) appendStringInfo(buf, "%s ALL ", get_opname(oper->opno)); break; - case EXPR_SUBLINK: + case MULTIEXPR_SUBLINK: oper = (Oper *) lfirst(sublink->oper); appendStringInfo(buf, "%s ", get_opname(oper->opno)); break; + case EXPR_SUBLINK: + need_paren = false; + break; + default: elog(ERROR, "get_sublink_expr: unsupported sublink type %d", sublink->subLinkType); break; } - appendStringInfo(buf, "("); + if (need_paren) + appendStringInfo(buf, "("); + get_query_def(query, buf, context->rangetables); - appendStringInfo(buf, "))"); + + if (need_paren) + appendStringInfo(buf, "))"); + else + appendStringInfo(buf, ")"); } /* ---------- |