7
7
*
8
8
*
9
9
* 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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -1542,41 +1542,52 @@ QueryRewrite(Query *parsetree)
1542
1542
static void
1543
1543
check_targetlists_are_compatible (List * prev_target , List * current_target )
1544
1544
{
1545
- List * tl ,
1546
- * next_target ;
1545
+ List * tl ;
1547
1546
int prev_len = 0 ,
1548
1547
next_len = 0 ;
1549
1548
1550
1549
foreach (tl , prev_target )
1551
1550
if (!((TargetEntry * ) lfirst (tl ))-> resdom -> resjunk )
1552
- prev_len ++ ;
1551
+ prev_len ++ ;
1553
1552
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 ++ ;
1557
1556
1558
1557
if (prev_len != next_len )
1559
1558
elog (ERROR , "Each UNION | EXCEPT | INTERSECT query must have the same number of columns." );
1560
1559
1561
- foreach (next_target , current_target )
1560
+ foreach (tl , current_target )
1562
1561
{
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 ;
1565
1569
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 ;
1568
1579
1569
1580
/* one or both is a NULL column? then don't convert... */
1570
1581
if (otype == InvalidOid )
1571
1582
{
1572
1583
/* propagate a known type forward, if available */
1573
1584
if (itype != InvalidOid )
1574
- (( TargetEntry * ) lfirst ( prev_target )) -> resdom -> restype = itype ;
1585
+ prev_tle -> resdom -> restype = itype ;
1575
1586
#ifdef NOT_USED
1576
1587
else
1577
1588
{
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 ;
1580
1591
}
1581
1592
#endif
1582
1593
}
@@ -1588,7 +1599,7 @@ check_targetlists_are_compatible(List *prev_target, List *current_target)
1588
1599
{
1589
1600
Node * expr ;
1590
1601
1591
- expr = (( TargetEntry * ) lfirst ( next_target )) -> expr ;
1602
+ expr = next_tle -> expr ;
1592
1603
expr = CoerceTargetExpr (NULL , expr , itype , otype , -1 );
1593
1604
if (expr == NULL )
1594
1605
{
@@ -1597,17 +1608,16 @@ check_targetlists_are_compatible(List *prev_target, List *current_target)
1597
1608
typeidTypeName (itype ),
1598
1609
typeidTypeName (otype ));
1599
1610
}
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 ;
1602
1613
}
1603
1614
1604
1615
/* both are UNKNOWN? then evaluate as text... */
1605
1616
else if (itype == UNKNOWNOID )
1606
1617
{
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 ;
1609
1620
}
1610
- prev_target = lnext (prev_target );
1611
1621
}
1612
1622
}
1613
1623
@@ -1645,7 +1655,6 @@ Except_Intersect_Rewrite(Query *parsetree)
1645
1655
* sortClause ,
1646
1656
* distinctClause ;
1647
1657
List * left_expr ,
1648
- * right_expr ,
1649
1658
* resnames = NIL ;
1650
1659
char * op ,
1651
1660
* into ;
@@ -1664,14 +1673,15 @@ Except_Intersect_Rewrite(Query *parsetree)
1664
1673
* formulated by the user and he wants the columns named by these
1665
1674
* strings. The transformation to DNF can cause another Select
1666
1675
* 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
1668
1677
* targetlist of the new topmost Node at the end of this function
1669
1678
*/
1670
1679
foreach (elist , parsetree -> targetList )
1671
1680
{
1672
1681
TargetEntry * tent = (TargetEntry * ) lfirst (elist );
1673
1682
1674
- resnames = lappend (resnames , tent -> resdom -> resname );
1683
+ if (! tent -> resdom -> resjunk )
1684
+ resnames = lappend (resnames , tent -> resdom -> resname );
1675
1685
}
1676
1686
1677
1687
/*
@@ -1778,7 +1788,6 @@ Except_Intersect_Rewrite(Query *parsetree)
1778
1788
if (prev_target )
1779
1789
check_targetlists_are_compatible (prev_target , intersect_node -> targetList );
1780
1790
prev_target = intersect_node -> targetList ;
1781
- /* End of check for corresponding targetlists */
1782
1791
1783
1792
/*
1784
1793
* Transform all nodes remaining into subselects and add them to
@@ -1800,7 +1809,6 @@ Except_Intersect_Rewrite(Query *parsetree)
1800
1809
*/
1801
1810
check_targetlists_are_compatible (prev_target ,
1802
1811
((Query * ) lfirst (intersect_list ))-> targetList );
1803
- /* End of check for corresponding targetlists */
1804
1812
1805
1813
n -> subselect = lfirst (intersect_list );
1806
1814
op = "=" ;
@@ -1822,7 +1830,6 @@ Except_Intersect_Rewrite(Query *parsetree)
1822
1830
*/
1823
1831
check_targetlists_are_compatible (prev_target ,
1824
1832
((Query * ) lfirst (((Expr * ) lfirst (intersect_list ))-> args ))-> targetList );
1825
- /* End of check for corresponding targetlists */
1826
1833
1827
1834
n -> subselect = (Node * ) lfirst (((Expr * ) lfirst (intersect_list ))-> args );
1828
1835
op = "<>" ;
@@ -1840,7 +1847,8 @@ Except_Intersect_Rewrite(Query *parsetree)
1840
1847
{
1841
1848
TargetEntry * tent = (TargetEntry * ) lfirst (elist );
1842
1849
1843
- n -> lefthand = lappend (n -> lefthand , tent -> expr );
1850
+ if (! tent -> resdom -> resjunk )
1851
+ n -> lefthand = lappend (n -> lefthand , tent -> expr );
1844
1852
}
1845
1853
1846
1854
/*
@@ -1849,17 +1857,21 @@ Except_Intersect_Rewrite(Query *parsetree)
1849
1857
* involved!)
1850
1858
*/
1851
1859
left_expr = n -> lefthand ;
1852
- right_expr = ((Query * ) (n -> subselect ))-> targetList ;
1853
1860
n -> oper = NIL ;
1854
1861
1855
- foreach (elist , left_expr )
1862
+ foreach (elist , (( Query * ) ( n -> subselect )) -> targetList )
1856
1863
{
1857
- Node * lexpr = lfirst (elist );
1858
- TargetEntry * tent = ( TargetEntry * ) lfirst ( right_expr ) ;
1864
+ TargetEntry * tent = ( TargetEntry * ) lfirst (elist );
1865
+ Node * lexpr ;
1859
1866
Operator optup ;
1860
1867
Form_pg_operator opform ;
1861
1868
Oper * newop ;
1862
1869
1870
+ if (tent -> resdom -> resjunk )
1871
+ continue ;
1872
+
1873
+ lexpr = lfirst (left_expr );
1874
+
1863
1875
optup = oper (op ,
1864
1876
exprType (lexpr ),
1865
1877
exprType (tent -> expr ),
@@ -1877,9 +1889,11 @@ Except_Intersect_Rewrite(Query *parsetree)
1877
1889
1878
1890
n -> oper = lappend (n -> oper , newop );
1879
1891
1880
- right_expr = lnext (right_expr );
1892
+ left_expr = lnext (left_expr );
1881
1893
}
1882
1894
1895
+ Assert (left_expr == NIL ); /* should have used 'em all */
1896
+
1883
1897
/*
1884
1898
* If the Select Query node has aggregates in use add all the
1885
1899
* subselects to the HAVING qual else to the WHERE qual
@@ -1930,6 +1944,9 @@ Except_Intersect_Rewrite(Query *parsetree)
1930
1944
{
1931
1945
TargetEntry * tent = (TargetEntry * ) lfirst (elist );
1932
1946
1947
+ if (tent -> resdom -> resjunk )
1948
+ continue ;
1949
+
1933
1950
tent -> resdom -> resname = lfirst (resnames );
1934
1951
resnames = lnext (resnames );
1935
1952
}
0 commit comments