|
6 | 6 | * |
7 | 7 | * |
8 | 8 | * IDENTIFICATION |
9 | | - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.43 1999/05/17 18:22:19 momjian Exp $ |
| 9 | + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.44 1999/05/25 13:16:10 wieck Exp $ |
10 | 10 | * |
11 | 11 | *------------------------------------------------------------------------- |
12 | 12 | */ |
@@ -1393,6 +1393,129 @@ checkQueryHasAggs(Node *node) |
1393 | 1393 | } |
1394 | 1394 |
|
1395 | 1395 |
|
| 1396 | +/* |
| 1397 | + * checkQueryHasSubLink - |
| 1398 | + *Queries marked hasAggs might not have them any longer after |
| 1399 | + *rewriting. Check it. |
| 1400 | + */ |
| 1401 | +staticbool |
| 1402 | +checkQueryHasSubLink(Node*node) |
| 1403 | +{ |
| 1404 | +if (node==NULL) |
| 1405 | +return FALSE; |
| 1406 | + |
| 1407 | +switch(nodeTag(node)) { |
| 1408 | +caseT_TargetEntry: |
| 1409 | +{ |
| 1410 | +TargetEntry*tle= (TargetEntry*)node; |
| 1411 | + |
| 1412 | +returncheckQueryHasSubLink((Node*)(tle->expr)); |
| 1413 | +} |
| 1414 | +break; |
| 1415 | + |
| 1416 | +caseT_Aggref: |
| 1417 | +return TRUE; |
| 1418 | + |
| 1419 | +caseT_Expr: |
| 1420 | +{ |
| 1421 | +Expr*exp= (Expr*)node; |
| 1422 | + |
| 1423 | +returncheckQueryHasSubLink((Node*)(exp->args)); |
| 1424 | +} |
| 1425 | +break; |
| 1426 | + |
| 1427 | +caseT_Iter: |
| 1428 | +{ |
| 1429 | +Iter*iter= (Iter*)node; |
| 1430 | + |
| 1431 | +returncheckQueryHasSubLink((Node*)(iter->iterexpr)); |
| 1432 | +} |
| 1433 | +break; |
| 1434 | + |
| 1435 | +caseT_ArrayRef: |
| 1436 | +{ |
| 1437 | +ArrayRef*ref= (ArrayRef*)node; |
| 1438 | + |
| 1439 | +if (checkQueryHasSubLink((Node*)(ref->refupperindexpr))) |
| 1440 | +return TRUE; |
| 1441 | + |
| 1442 | +if (checkQueryHasSubLink((Node*)(ref->reflowerindexpr))) |
| 1443 | +return TRUE; |
| 1444 | + |
| 1445 | +if (checkQueryHasSubLink((Node*)(ref->refexpr))) |
| 1446 | +return TRUE; |
| 1447 | + |
| 1448 | +if (checkQueryHasSubLink((Node*)(ref->refassgnexpr))) |
| 1449 | +return TRUE; |
| 1450 | + |
| 1451 | +return FALSE; |
| 1452 | +} |
| 1453 | +break; |
| 1454 | + |
| 1455 | +caseT_Var: |
| 1456 | +return FALSE; |
| 1457 | + |
| 1458 | +caseT_Param: |
| 1459 | +return FALSE; |
| 1460 | + |
| 1461 | +caseT_Const: |
| 1462 | +return FALSE; |
| 1463 | + |
| 1464 | +caseT_List: |
| 1465 | +{ |
| 1466 | +List*l; |
| 1467 | + |
| 1468 | +foreach (l, (List*)node) { |
| 1469 | +if (checkQueryHasSubLink((Node*)lfirst(l))) |
| 1470 | +return TRUE; |
| 1471 | +} |
| 1472 | +return FALSE; |
| 1473 | +} |
| 1474 | +break; |
| 1475 | + |
| 1476 | +caseT_CaseExpr: |
| 1477 | +{ |
| 1478 | +CaseExpr*exp= (CaseExpr*)node; |
| 1479 | + |
| 1480 | +if (checkQueryHasSubLink((Node*)(exp->args))) |
| 1481 | +return TRUE; |
| 1482 | + |
| 1483 | +if (checkQueryHasSubLink((Node*)(exp->defresult))) |
| 1484 | +return TRUE; |
| 1485 | + |
| 1486 | +return FALSE; |
| 1487 | +} |
| 1488 | +break; |
| 1489 | + |
| 1490 | +caseT_CaseWhen: |
| 1491 | +{ |
| 1492 | +CaseWhen*when= (CaseWhen*)node; |
| 1493 | + |
| 1494 | +if (checkQueryHasSubLink((Node*)(when->expr))) |
| 1495 | +return TRUE; |
| 1496 | + |
| 1497 | +if (checkQueryHasSubLink((Node*)(when->result))) |
| 1498 | +return TRUE; |
| 1499 | + |
| 1500 | +return FALSE; |
| 1501 | +} |
| 1502 | +break; |
| 1503 | + |
| 1504 | +caseT_SubLink: |
| 1505 | +return TRUE; |
| 1506 | + |
| 1507 | +default: |
| 1508 | +elog(NOTICE,"unknown node tag %d in checkQueryHasSubLink()",nodeTag(node)); |
| 1509 | +elog(NOTICE,"Node is: %s",nodeToString(node)); |
| 1510 | +break; |
| 1511 | + |
| 1512 | + |
| 1513 | +} |
| 1514 | + |
| 1515 | +return FALSE; |
| 1516 | +} |
| 1517 | + |
| 1518 | + |
1396 | 1519 | staticNode* |
1397 | 1520 | FindMatchingTLEntry(List*tlist,char*e_attname) |
1398 | 1521 | { |
@@ -2116,10 +2239,23 @@ fireRIRrules(Query *parsetree) |
2116 | 2239 | while(rt_index<length(parsetree->rtable)) { |
2117 | 2240 | ++rt_index; |
2118 | 2241 |
|
| 2242 | +rte=nth(rt_index-1,parsetree->rtable); |
| 2243 | + |
2119 | 2244 | if (!rangeTableEntry_used((Node*)parsetree,rt_index,0)) |
| 2245 | +{ |
| 2246 | +/* |
| 2247 | + * Unused range table entries must not be marked as coming |
| 2248 | + * from a clause. Otherwise the planner will generate |
| 2249 | + * joins over relations that in fact shouldn't be scanned |
| 2250 | + * at all and the result will contain duplicates |
| 2251 | + * |
| 2252 | + * Jan |
| 2253 | + * |
| 2254 | + */ |
| 2255 | +rte->inFromCl= FALSE; |
2120 | 2256 | continue; |
| 2257 | +} |
2121 | 2258 |
|
2122 | | -rte=nth(rt_index-1,parsetree->rtable); |
2123 | 2259 | rel=heap_openr(rte->relname); |
2124 | 2260 | if (rel->rd_rules==NULL) { |
2125 | 2261 | heap_close(rel); |
@@ -2705,6 +2841,8 @@ BasicQueryRewrite(Query *parsetree) |
2705 | 2841 | if (query->hasAggs) |
2706 | 2842 | query->hasAggs=checkQueryHasAggs((Node*)(query->targetList)) |
2707 | 2843 | |checkQueryHasAggs((Node*)(query->havingQual)); |
| 2844 | +query->hasSubLinks=checkQueryHasSubLink((Node*)(query->qual)) |
| 2845 | + |checkQueryHasSubLink((Node*)(query->havingQual)); |
2708 | 2846 | results=lappend(results,query); |
2709 | 2847 | } |
2710 | 2848 | returnresults; |
|