|
6 | 6 | *
|
7 | 7 | *
|
8 | 8 | * IDENTIFICATION
|
9 |
| - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.46 1999/05/26 12:55:46 momjian Exp $ |
| 9 | + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.47 1999/06/21 01:26:56 tgl Exp $ |
10 | 10 | *
|
11 | 11 | *-------------------------------------------------------------------------
|
12 | 12 | */
|
|
29 | 29 | #include"parser/parse_target.h"
|
30 | 30 |
|
31 | 31 | #include"parser/analyze.h"
|
| 32 | +#include"optimizer/clauses.h" |
32 | 33 | #include"optimizer/prep.h"
|
33 | 34 |
|
34 | 35 | #include"rewrite/rewriteSupport.h"
|
@@ -60,6 +61,9 @@ static void modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr);
|
60 | 61 | staticSubLink*modifyAggrefMakeSublink(Expr*origexp,Query*parsetree);
|
61 | 62 | staticvoidmodifyAggrefQual(Node**nodePtr,Query*parsetree);
|
62 | 63 | staticboolcheckQueryHasAggs(Node*node);
|
| 64 | +staticboolcheckQueryHasAggs_walker(Node*node,void*context); |
| 65 | +staticboolcheckQueryHasSubLink(Node*node); |
| 66 | +staticboolcheckQueryHasSubLink_walker(Node*node,void*context); |
63 | 67 | staticQuery*fireRIRrules(Query*parsetree);
|
64 | 68 | staticQuery*Except_Intersect_Rewrite(Query*parsetree);
|
65 | 69 | staticvoidcheck_targetlists_are_compatible(List*prev_target,
|
@@ -1302,242 +1306,41 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
|
1302 | 1306 | staticbool
|
1303 | 1307 | checkQueryHasAggs(Node*node)
|
1304 | 1308 | {
|
1305 |
| -if (node==NULL) |
1306 |
| -return FALSE; |
1307 |
| - |
1308 |
| -switch (nodeTag(node)) |
1309 |
| -{ |
1310 |
| -caseT_TargetEntry: |
1311 |
| -{ |
1312 |
| -TargetEntry*tle= (TargetEntry*)node; |
1313 |
| - |
1314 |
| -returncheckQueryHasAggs((Node*) (tle->expr)); |
1315 |
| -} |
1316 |
| -break; |
1317 |
| - |
1318 |
| -caseT_Aggref: |
1319 |
| -return TRUE; |
1320 |
| - |
1321 |
| -caseT_Expr: |
1322 |
| -{ |
1323 |
| -Expr*exp= (Expr*)node; |
1324 |
| - |
1325 |
| -returncheckQueryHasAggs((Node*) (exp->args)); |
1326 |
| -} |
1327 |
| -break; |
1328 |
| - |
1329 |
| -caseT_Iter: |
1330 |
| -{ |
1331 |
| -Iter*iter= (Iter*)node; |
1332 |
| - |
1333 |
| -returncheckQueryHasAggs((Node*) (iter->iterexpr)); |
1334 |
| -} |
1335 |
| -break; |
1336 |
| - |
1337 |
| -caseT_ArrayRef: |
1338 |
| -{ |
1339 |
| -ArrayRef*ref= (ArrayRef*)node; |
1340 |
| - |
1341 |
| -if (checkQueryHasAggs((Node*) (ref->refupperindexpr))) |
1342 |
| -return TRUE; |
1343 |
| - |
1344 |
| -if (checkQueryHasAggs((Node*) (ref->reflowerindexpr))) |
1345 |
| -return TRUE; |
1346 |
| - |
1347 |
| -if (checkQueryHasAggs((Node*) (ref->refexpr))) |
1348 |
| -return TRUE; |
1349 |
| - |
1350 |
| -if (checkQueryHasAggs((Node*) (ref->refassgnexpr))) |
1351 |
| -return TRUE; |
1352 |
| - |
1353 |
| -return FALSE; |
1354 |
| -} |
1355 |
| -break; |
1356 |
| - |
1357 |
| -caseT_Var: |
1358 |
| -return FALSE; |
1359 |
| - |
1360 |
| -caseT_Param: |
1361 |
| -return FALSE; |
1362 |
| - |
1363 |
| -caseT_Const: |
1364 |
| -return FALSE; |
1365 |
| - |
1366 |
| -caseT_List: |
1367 |
| -{ |
1368 |
| -List*l; |
1369 |
| - |
1370 |
| -foreach(l, (List*)node) |
1371 |
| -{ |
1372 |
| -if (checkQueryHasAggs((Node*)lfirst(l))) |
1373 |
| -return TRUE; |
1374 |
| -} |
1375 |
| -return FALSE; |
1376 |
| -} |
1377 |
| -break; |
1378 |
| - |
1379 |
| -caseT_CaseExpr: |
1380 |
| -{ |
1381 |
| -CaseExpr*exp= (CaseExpr*)node; |
1382 |
| - |
1383 |
| -if (checkQueryHasAggs((Node*) (exp->args))) |
1384 |
| -return TRUE; |
1385 |
| - |
1386 |
| -if (checkQueryHasAggs((Node*) (exp->defresult))) |
1387 |
| -return TRUE; |
1388 |
| - |
1389 |
| -return FALSE; |
1390 |
| -} |
1391 |
| -break; |
1392 |
| - |
1393 |
| -caseT_CaseWhen: |
1394 |
| -{ |
1395 |
| -CaseWhen*when= (CaseWhen*)node; |
1396 |
| - |
1397 |
| -if (checkQueryHasAggs((Node*) (when->expr))) |
1398 |
| -return TRUE; |
1399 |
| - |
1400 |
| -if (checkQueryHasAggs((Node*) (when->result))) |
1401 |
| -return TRUE; |
1402 |
| - |
1403 |
| -return FALSE; |
1404 |
| -} |
1405 |
| -break; |
1406 |
| - |
1407 |
| -default: |
1408 |
| -elog(NOTICE,"unknown node tag %d in checkQueryHasAggs()",nodeTag(node)); |
1409 |
| -elog(NOTICE,"Node is: %s",nodeToString(node)); |
1410 |
| -break; |
1411 |
| - |
1412 |
| - |
1413 |
| -} |
1414 |
| - |
1415 |
| -return FALSE; |
| 1309 | +returncheckQueryHasAggs_walker(node,NULL); |
1416 | 1310 | }
|
1417 | 1311 |
|
| 1312 | +staticbool |
| 1313 | +checkQueryHasAggs_walker(Node*node,void*context) |
| 1314 | +{ |
| 1315 | +if (node==NULL) |
| 1316 | +return false; |
| 1317 | +if (IsA(node,Aggref)) |
| 1318 | +return true;/* abort the tree traversal and return true */ |
| 1319 | +returnexpression_tree_walker(node,checkQueryHasAggs_walker,context); |
| 1320 | +} |
1418 | 1321 |
|
1419 | 1322 | /*
|
1420 | 1323 | * checkQueryHasSubLink -
|
1421 |
| - *Queries markedhasAggs might not have them any longer after |
| 1324 | + *Queries markedhasSubLinks might not have them any longer after |
1422 | 1325 | *rewriting. Check it.
|
1423 | 1326 | */
|
1424 | 1327 | staticbool
|
1425 | 1328 | checkQueryHasSubLink(Node*node)
|
1426 | 1329 | {
|
1427 |
| -if (node==NULL) |
1428 |
| -return FALSE; |
1429 |
| - |
1430 |
| -switch (nodeTag(node)) |
1431 |
| -{ |
1432 |
| -caseT_TargetEntry: |
1433 |
| -{ |
1434 |
| -TargetEntry*tle= (TargetEntry*)node; |
1435 |
| - |
1436 |
| -returncheckQueryHasSubLink((Node*) (tle->expr)); |
1437 |
| -} |
1438 |
| -break; |
1439 |
| - |
1440 |
| -caseT_Aggref: |
1441 |
| -return TRUE; |
1442 |
| - |
1443 |
| -caseT_Expr: |
1444 |
| -{ |
1445 |
| -Expr*exp= (Expr*)node; |
1446 |
| - |
1447 |
| -returncheckQueryHasSubLink((Node*) (exp->args)); |
1448 |
| -} |
1449 |
| -break; |
1450 |
| - |
1451 |
| -caseT_Iter: |
1452 |
| -{ |
1453 |
| -Iter*iter= (Iter*)node; |
1454 |
| - |
1455 |
| -returncheckQueryHasSubLink((Node*) (iter->iterexpr)); |
1456 |
| -} |
1457 |
| -break; |
1458 |
| - |
1459 |
| -caseT_ArrayRef: |
1460 |
| -{ |
1461 |
| -ArrayRef*ref= (ArrayRef*)node; |
1462 |
| - |
1463 |
| -if (checkQueryHasSubLink((Node*) (ref->refupperindexpr))) |
1464 |
| -return TRUE; |
1465 |
| - |
1466 |
| -if (checkQueryHasSubLink((Node*) (ref->reflowerindexpr))) |
1467 |
| -return TRUE; |
1468 |
| - |
1469 |
| -if (checkQueryHasSubLink((Node*) (ref->refexpr))) |
1470 |
| -return TRUE; |
1471 |
| - |
1472 |
| -if (checkQueryHasSubLink((Node*) (ref->refassgnexpr))) |
1473 |
| -return TRUE; |
1474 |
| - |
1475 |
| -return FALSE; |
1476 |
| -} |
1477 |
| -break; |
1478 |
| - |
1479 |
| -caseT_Var: |
1480 |
| -return FALSE; |
1481 |
| - |
1482 |
| -caseT_Param: |
1483 |
| -return FALSE; |
1484 |
| - |
1485 |
| -caseT_Const: |
1486 |
| -return FALSE; |
1487 |
| - |
1488 |
| -caseT_List: |
1489 |
| -{ |
1490 |
| -List*l; |
1491 |
| - |
1492 |
| -foreach(l, (List*)node) |
1493 |
| -{ |
1494 |
| -if (checkQueryHasSubLink((Node*)lfirst(l))) |
1495 |
| -return TRUE; |
1496 |
| -} |
1497 |
| -return FALSE; |
1498 |
| -} |
1499 |
| -break; |
1500 |
| - |
1501 |
| -caseT_CaseExpr: |
1502 |
| -{ |
1503 |
| -CaseExpr*exp= (CaseExpr*)node; |
1504 |
| - |
1505 |
| -if (checkQueryHasSubLink((Node*) (exp->args))) |
1506 |
| -return TRUE; |
1507 |
| - |
1508 |
| -if (checkQueryHasSubLink((Node*) (exp->defresult))) |
1509 |
| -return TRUE; |
1510 |
| - |
1511 |
| -return FALSE; |
1512 |
| -} |
1513 |
| -break; |
1514 |
| - |
1515 |
| -caseT_CaseWhen: |
1516 |
| -{ |
1517 |
| -CaseWhen*when= (CaseWhen*)node; |
1518 |
| - |
1519 |
| -if (checkQueryHasSubLink((Node*) (when->expr))) |
1520 |
| -return TRUE; |
1521 |
| - |
1522 |
| -if (checkQueryHasSubLink((Node*) (when->result))) |
1523 |
| -return TRUE; |
1524 |
| - |
1525 |
| -return FALSE; |
1526 |
| -} |
1527 |
| -break; |
1528 |
| - |
1529 |
| -caseT_SubLink: |
1530 |
| -return TRUE; |
1531 |
| - |
1532 |
| -default: |
1533 |
| -elog(NOTICE,"unknown node tag %d in checkQueryHasSubLink()",nodeTag(node)); |
1534 |
| -elog(NOTICE,"Node is: %s",nodeToString(node)); |
1535 |
| -break; |
1536 |
| - |
1537 |
| - |
1538 |
| -} |
| 1330 | +returncheckQueryHasSubLink_walker(node,NULL); |
| 1331 | +} |
1539 | 1332 |
|
1540 |
| -return FALSE; |
| 1333 | +staticbool |
| 1334 | +checkQueryHasSubLink_walker(Node*node,void*context) |
| 1335 | +{ |
| 1336 | +if (node==NULL) |
| 1337 | +return false; |
| 1338 | +if (IsA(node,SubLink)) |
| 1339 | +return true;/* abort the tree traversal and return true */ |
| 1340 | +/* Note: we assume the tree has not yet been rewritten by subselect.c, |
| 1341 | + * therefore we will find bare SubLink nodes and not SUBPLAN nodes. |
| 1342 | + */ |
| 1343 | +returnexpression_tree_walker(node,checkQueryHasSubLink_walker,context); |
1541 | 1344 | }
|
1542 | 1345 |
|
1543 | 1346 |
|
|