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)
15421542static void
15431543check_targetlists_are_compatible (List * prev_target ,List * current_target )
15441544{
1545- List * tl ,
1546- * next_target ;
1545+ List * tl ;
15471546int prev_len = 0 ,
15481547next_len = 0 ;
15491548
15501549foreach (tl ,prev_target )
15511550if (!((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
15581557if (prev_len != next_len )
15591558elog (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... */
15701581if (otype == InvalidOid )
15711582{
15721583/* propagate a known type forward, if available */
15731584if (itype != InvalidOid )
1574- (( TargetEntry * ) lfirst ( prev_target )) -> resdom -> restype = itype ;
1585+ prev_tle -> resdom -> restype = itype ;
15751586#ifdef NOT_USED
15761587else
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{
15891600Node * expr ;
15901601
1591- expr = (( TargetEntry * ) lfirst ( next_target )) -> expr ;
1602+ expr = next_tle -> expr ;
15921603expr = CoerceTargetExpr (NULL ,expr ,itype ,otype ,-1 );
15931604if (expr == NULL )
15941605{
@@ -1597,17 +1608,16 @@ check_targetlists_are_compatible(List *prev_target, List *current_target)
15971608typeidTypeName (itype ),
15981609typeidTypeName (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... */
16051616else 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 ;
16471657List * left_expr ,
1648- * right_expr ,
16491658* resnames = NIL ;
16501659char * 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 weremeber the original names and attach them to the
1676+ * Therefore weremember the original names and attach them to the
16681677 * targetlist of the new topmost Node at the end of this function
16691678 */
16701679foreach (elist ,parsetree -> targetList )
16711680{
16721681TargetEntry * 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)
17781788if (prev_target )
17791789check_targetlists_are_compatible (prev_target ,intersect_node -> targetList );
17801790prev_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 */
18011810check_targetlists_are_compatible (prev_target ,
18021811 ((Query * )lfirst (intersect_list ))-> targetList );
1803- /* End of check for corresponding targetlists */
18041812
18051813n -> subselect = lfirst (intersect_list );
18061814op = "=" ;
@@ -1822,7 +1830,6 @@ Except_Intersect_Rewrite(Query *parsetree)
18221830 */
18231831check_targetlists_are_compatible (prev_target ,
18241832 ((Query * )lfirst (((Expr * )lfirst (intersect_list ))-> args ))-> targetList );
1825- /* End of check for corresponding targetlists */
18261833
18271834n -> subselect = (Node * )lfirst (((Expr * )lfirst (intersect_list ))-> args );
18281835op = "<>" ;
@@ -1840,7 +1847,8 @@ Except_Intersect_Rewrite(Query *parsetree)
18401847{
18411848TargetEntry * 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 */
18511859left_expr = n -> lefthand ;
1852- right_expr = ((Query * ) (n -> subselect ))-> targetList ;
18531860n -> 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 ;
18591866Operator optup ;
18601867Form_pg_operator opform ;
18611868Oper * newop ;
18621869
1870+ if (tent -> resdom -> resjunk )
1871+ continue ;
1872+
1873+ lexpr = lfirst (left_expr );
1874+
18631875optup = oper (op ,
18641876exprType (lexpr ),
18651877exprType (tent -> expr ),
@@ -1877,9 +1889,11 @@ Except_Intersect_Rewrite(Query *parsetree)
18771889
18781890n -> 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{
19311945TargetEntry * tent = (TargetEntry * )lfirst (elist );
19321946
1947+ if (tent -> resdom -> resjunk )
1948+ continue ;
1949+
19331950tent -> resdom -> resname = lfirst (resnames );
19341951resnames = lnext (resnames );
19351952}