Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f106779

Browse files
committed
Except_Intersect_Rewrite() failed to ignore resjunk targetlist entries,
thus causing failure if one sub-select had resjunk entries that the other did not (cf. bug report from Espinosa 4/27/00).
1 parent fb7318a commit f106779

File tree

1 file changed

+50
-33
lines changed

1 file changed

+50
-33
lines changed

src/backend/rewrite/rewriteHandler.c

+50-33
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.72 2000/04/20 00:31:49 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.73 2000/04/27 20:32:41 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1542,41 +1542,52 @@ QueryRewrite(Query *parsetree)
15421542
static void
15431543
check_targetlists_are_compatible(List *prev_target, List *current_target)
15441544
{
1545-
List *tl,
1546-
*next_target;
1545+
List *tl;
15471546
int prev_len = 0,
15481547
next_len = 0;
15491548

15501549
foreach(tl, prev_target)
15511550
if (!((TargetEntry *) lfirst(tl))->resdom->resjunk)
1552-
prev_len++;
1551+
prev_len++;
15531552

1554-
foreach(next_target, current_target)
1555-
if (!((TargetEntry *) lfirst(next_target))->resdom->resjunk)
1556-
next_len++;
1553+
foreach(tl, current_target)
1554+
if (!((TargetEntry *) lfirst(tl))->resdom->resjunk)
1555+
next_len++;
15571556

15581557
if (prev_len != next_len)
15591558
elog(ERROR, "Each UNION | EXCEPT | INTERSECT query must have the same number of columns.");
15601559

1561-
foreach(next_target, current_target)
1560+
foreach(tl, current_target)
15621561
{
1563-
Oid itype;
1564-
Oid otype;
1562+
TargetEntry *next_tle = (TargetEntry *) lfirst(tl);
1563+
TargetEntry *prev_tle;
1564+
Oid itype;
1565+
Oid otype;
1566+
1567+
if (next_tle->resdom->resjunk)
1568+
continue;
15651569

1566-
otype = ((TargetEntry *) lfirst(prev_target))->resdom->restype;
1567-
itype = ((TargetEntry *) lfirst(next_target))->resdom->restype;
1570+
/* This loop must find an entry, since we counted them above. */
1571+
do
1572+
{
1573+
prev_tle = (TargetEntry *) lfirst(prev_target);
1574+
prev_target = lnext(prev_target);
1575+
} while (prev_tle->resdom->resjunk);
1576+
1577+
itype = next_tle->resdom->restype;
1578+
otype = prev_tle->resdom->restype;
15681579

15691580
/* one or both is a NULL column? then don't convert... */
15701581
if (otype == InvalidOid)
15711582
{
15721583
/* propagate a known type forward, if available */
15731584
if (itype != InvalidOid)
1574-
((TargetEntry *) lfirst(prev_target))->resdom->restype = itype;
1585+
prev_tle->resdom->restype = itype;
15751586
#ifdef NOT_USED
15761587
else
15771588
{
1578-
((TargetEntry *) lfirst(prev_target))->resdom->restype = UNKNOWNOID;
1579-
((TargetEntry *) lfirst(next_target))->resdom->restype = UNKNOWNOID;
1589+
prev_tle->resdom->restype = UNKNOWNOID;
1590+
next_tle->resdom->restype = UNKNOWNOID;
15801591
}
15811592
#endif
15821593
}
@@ -1588,7 +1599,7 @@ check_targetlists_are_compatible(List *prev_target, List *current_target)
15881599
{
15891600
Node *expr;
15901601

1591-
expr = ((TargetEntry *) lfirst(next_target))->expr;
1602+
expr = next_tle->expr;
15921603
expr = CoerceTargetExpr(NULL, expr, itype, otype, -1);
15931604
if (expr == NULL)
15941605
{
@@ -1597,17 +1608,16 @@ check_targetlists_are_compatible(List *prev_target, List *current_target)
15971608
typeidTypeName(itype),
15981609
typeidTypeName(otype));
15991610
}
1600-
((TargetEntry *) lfirst(next_target))->expr = expr;
1601-
((TargetEntry *) lfirst(next_target))->resdom->restype = otype;
1611+
next_tle->expr = expr;
1612+
next_tle->resdom->restype = otype;
16021613
}
16031614

16041615
/* both are UNKNOWN? then evaluate as text... */
16051616
else if (itype == UNKNOWNOID)
16061617
{
1607-
((TargetEntry *) lfirst(next_target))->resdom->restype = TEXTOID;
1608-
((TargetEntry *) lfirst(prev_target))->resdom->restype = TEXTOID;
1618+
next_tle->resdom->restype = TEXTOID;
1619+
prev_tle->resdom->restype = TEXTOID;
16091620
}
1610-
prev_target = lnext(prev_target);
16111621
}
16121622
}
16131623

@@ -1645,7 +1655,6 @@ Except_Intersect_Rewrite(Query *parsetree)
16451655
*sortClause,
16461656
*distinctClause;
16471657
List *left_expr,
1648-
*right_expr,
16491658
*resnames = NIL;
16501659
char *op,
16511660
*into;
@@ -1664,14 +1673,15 @@ Except_Intersect_Rewrite(Query *parsetree)
16641673
* formulated by the user and he wants the columns named by these
16651674
* strings. The transformation to DNF can cause another Select
16661675
* Statment to be the top one which uses other names for its columns.
1667-
* Therefore we remeber the original names and attach them to the
1676+
* Therefore we remember the original names and attach them to the
16681677
* targetlist of the new topmost Node at the end of this function
16691678
*/
16701679
foreach(elist, parsetree->targetList)
16711680
{
16721681
TargetEntry *tent = (TargetEntry *) lfirst(elist);
16731682

1674-
resnames = lappend(resnames, tent->resdom->resname);
1683+
if (! tent->resdom->resjunk)
1684+
resnames = lappend(resnames, tent->resdom->resname);
16751685
}
16761686

16771687
/*
@@ -1778,7 +1788,6 @@ Except_Intersect_Rewrite(Query *parsetree)
17781788
if (prev_target)
17791789
check_targetlists_are_compatible(prev_target, intersect_node->targetList);
17801790
prev_target = intersect_node->targetList;
1781-
/* End of check for corresponding targetlists */
17821791

17831792
/*
17841793
* Transform all nodes remaining into subselects and add them to
@@ -1800,7 +1809,6 @@ Except_Intersect_Rewrite(Query *parsetree)
18001809
*/
18011810
check_targetlists_are_compatible(prev_target,
18021811
((Query *) lfirst(intersect_list))->targetList);
1803-
/* End of check for corresponding targetlists */
18041812

18051813
n->subselect = lfirst(intersect_list);
18061814
op = "=";
@@ -1822,7 +1830,6 @@ Except_Intersect_Rewrite(Query *parsetree)
18221830
*/
18231831
check_targetlists_are_compatible(prev_target,
18241832
((Query *) lfirst(((Expr *) lfirst(intersect_list))->args))->targetList);
1825-
/* End of check for corresponding targetlists */
18261833

18271834
n->subselect = (Node *) lfirst(((Expr *) lfirst(intersect_list))->args);
18281835
op = "<>";
@@ -1840,7 +1847,8 @@ Except_Intersect_Rewrite(Query *parsetree)
18401847
{
18411848
TargetEntry *tent = (TargetEntry *) lfirst(elist);
18421849

1843-
n->lefthand = lappend(n->lefthand, tent->expr);
1850+
if (! tent->resdom->resjunk)
1851+
n->lefthand = lappend(n->lefthand, tent->expr);
18441852
}
18451853

18461854
/*
@@ -1849,17 +1857,21 @@ Except_Intersect_Rewrite(Query *parsetree)
18491857
* involved!)
18501858
*/
18511859
left_expr = n->lefthand;
1852-
right_expr = ((Query *) (n->subselect))->targetList;
18531860
n->oper = NIL;
18541861

1855-
foreach(elist, left_expr)
1862+
foreach(elist, ((Query *) (n->subselect))->targetList)
18561863
{
1857-
Node *lexpr = lfirst(elist);
1858-
TargetEntry *tent = (TargetEntry *) lfirst(right_expr);
1864+
TargetEntry *tent = (TargetEntry *) lfirst(elist);
1865+
Node *lexpr;
18591866
Operator optup;
18601867
Form_pg_operator opform;
18611868
Oper *newop;
18621869

1870+
if (tent->resdom->resjunk)
1871+
continue;
1872+
1873+
lexpr = lfirst(left_expr);
1874+
18631875
optup = oper(op,
18641876
exprType(lexpr),
18651877
exprType(tent->expr),
@@ -1877,9 +1889,11 @@ Except_Intersect_Rewrite(Query *parsetree)
18771889

18781890
n->oper = lappend(n->oper, newop);
18791891

1880-
right_expr = lnext(right_expr);
1892+
left_expr = lnext(left_expr);
18811893
}
18821894

1895+
Assert(left_expr == NIL); /* should have used 'em all */
1896+
18831897
/*
18841898
* If the Select Query node has aggregates in use add all the
18851899
* subselects to the HAVING qual else to the WHERE qual
@@ -1930,6 +1944,9 @@ Except_Intersect_Rewrite(Query *parsetree)
19301944
{
19311945
TargetEntry *tent = (TargetEntry *) lfirst(elist);
19321946

1947+
if (tent->resdom->resjunk)
1948+
continue;
1949+
19331950
tent->resdom->resname = lfirst(resnames);
19341951
resnames = lnext(resnames);
19351952
}

0 commit comments

Comments
 (0)