mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
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.
This commit is contained in:
@ -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, ")");
|
||||
}
|
||||
|
||||
/* ----------
|
||||
|
Reference in New Issue
Block a user