mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-13 19:57:53 +08:00
Arrange for ORDER BY an expression on a UNION/INTERSECT/EXCEPT result,
such as SELECT f1 FROM foo UNION SELECT ... ORDER BY upper(f1) to draw 'ORDER BY on a UNION/INTERSECT/EXCEPT result must be on one of the result columns' rather than the uninformative 'f1 not found' we were producing before. Eventually this should actually work, but that looks much too hard to try to implement in late beta...
This commit is contained in:
parent
c7d2ce7bc6
commit
de434c2d5f
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: analyze.c,v 1.180 2001/02/14 23:32:38 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.181 2001/02/15 01:10:28 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1871,7 +1871,11 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
List *forUpdate;
|
||||
Node *node;
|
||||
List *lefttl,
|
||||
*dtlist;
|
||||
*dtlist,
|
||||
*targetvars,
|
||||
*targetnames,
|
||||
*sv_namespace;
|
||||
JoinExpr *jnode;
|
||||
int tllen;
|
||||
|
||||
qry->commandType = CMD_SELECT;
|
||||
@ -1934,22 +1938,26 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
Assert(leftmostQuery != NULL);
|
||||
/*
|
||||
* Generate dummy targetlist for outer query using column names of
|
||||
* leftmost select and common datatypes of topmost set operation
|
||||
* leftmost select and common datatypes of topmost set operation.
|
||||
* Also make lists of the dummy vars and their names for use in
|
||||
* parsing ORDER BY.
|
||||
*/
|
||||
qry->targetList = NIL;
|
||||
targetvars = NIL;
|
||||
targetnames = NIL;
|
||||
lefttl = leftmostQuery->targetList;
|
||||
foreach(dtlist, sostmt->colTypes)
|
||||
{
|
||||
Oid colType = (Oid) lfirsti(dtlist);
|
||||
Resdom *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
|
||||
char *colName = leftResdom->resname;
|
||||
char *colName = pstrdup(leftResdom->resname);
|
||||
Resdom *resdom;
|
||||
Node *expr;
|
||||
|
||||
resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
|
||||
colType,
|
||||
-1,
|
||||
pstrdup(colName),
|
||||
colName,
|
||||
false);
|
||||
expr = (Node *) makeVar(leftmostRTI,
|
||||
leftResdom->resno,
|
||||
@ -1958,6 +1966,8 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
0);
|
||||
qry->targetList = lappend(qry->targetList,
|
||||
makeTargetEntry(resdom, expr));
|
||||
targetvars = lappend(targetvars, expr);
|
||||
targetnames = lappend(targetnames, makeString(colName));
|
||||
lefttl = lnext(lefttl);
|
||||
}
|
||||
/*
|
||||
@ -1997,6 +2007,23 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
qry->isBinary = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* As a first step towards supporting sort clauses that are expressions
|
||||
* using the output columns, generate a namespace entry that makes the
|
||||
* output columns visible. A JoinExpr node is handy for this, since
|
||||
* we can easily control the Vars generated upon matches.
|
||||
*
|
||||
* Note: we don't yet do anything useful with such cases, but at least
|
||||
* "ORDER BY upper(foo)" will draw the right error message rather than
|
||||
* "foo not found".
|
||||
*/
|
||||
jnode = makeNode(JoinExpr);
|
||||
jnode->colnames = targetnames;
|
||||
jnode->colvars = targetvars;
|
||||
|
||||
sv_namespace = pstate->p_namespace;
|
||||
pstate->p_namespace = makeList1(jnode);
|
||||
|
||||
/*
|
||||
* For now, we don't support resjunk sort clauses on the output of a
|
||||
* setOperation tree --- you can only use the SQL92-spec options of
|
||||
@ -2009,6 +2036,8 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
sortClause,
|
||||
qry->targetList);
|
||||
|
||||
pstate->p_namespace = sv_namespace;
|
||||
|
||||
if (tllen != length(qry->targetList))
|
||||
elog(ERROR, "ORDER BY on a UNION/INTERSECT/EXCEPT result must be on one of the result columns");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user