|
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 | static SubLink *modifyAggrefMakeSublink(Expr *origexp, Query *parsetree);
|
61 | 62 | static void modifyAggrefQual(Node **nodePtr, Query *parsetree);
|
62 | 63 | static bool checkQueryHasAggs(Node *node);
|
| 64 | +static bool checkQueryHasAggs_walker(Node *node, void *context); |
| 65 | +static bool checkQueryHasSubLink(Node *node); |
| 66 | +static bool checkQueryHasSubLink_walker(Node *node, void *context); |
63 | 67 | static Query *fireRIRrules(Query *parsetree);
|
64 | 68 | static Query *Except_Intersect_Rewrite(Query *parsetree);
|
65 | 69 | static void check_targetlists_are_compatible(List *prev_target,
|
@@ -1302,242 +1306,41 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
|
1302 | 1306 | static bool
|
1303 | 1307 | checkQueryHasAggs(Node *node)
|
1304 | 1308 | {
|
1305 |
| - if (node == NULL) |
1306 |
| - return FALSE; |
1307 |
| - |
1308 |
| - switch (nodeTag(node)) |
1309 |
| - { |
1310 |
| - case T_TargetEntry: |
1311 |
| - { |
1312 |
| - TargetEntry *tle = (TargetEntry *) node; |
1313 |
| - |
1314 |
| - return checkQueryHasAggs((Node *) (tle->expr)); |
1315 |
| - } |
1316 |
| - break; |
1317 |
| - |
1318 |
| - case T_Aggref: |
1319 |
| - return TRUE; |
1320 |
| - |
1321 |
| - case T_Expr: |
1322 |
| - { |
1323 |
| - Expr *exp = (Expr *) node; |
1324 |
| - |
1325 |
| - return checkQueryHasAggs((Node *) (exp->args)); |
1326 |
| - } |
1327 |
| - break; |
1328 |
| - |
1329 |
| - case T_Iter: |
1330 |
| - { |
1331 |
| - Iter *iter = (Iter *) node; |
1332 |
| - |
1333 |
| - return checkQueryHasAggs((Node *) (iter->iterexpr)); |
1334 |
| - } |
1335 |
| - break; |
1336 |
| - |
1337 |
| - case T_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 |
| - case T_Var: |
1358 |
| - return FALSE; |
1359 |
| - |
1360 |
| - case T_Param: |
1361 |
| - return FALSE; |
1362 |
| - |
1363 |
| - case T_Const: |
1364 |
| - return FALSE; |
1365 |
| - |
1366 |
| - case T_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 |
| - case T_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 |
| - case T_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 | + return checkQueryHasAggs_walker(node, NULL); |
1416 | 1310 | }
|
1417 | 1311 |
|
| 1312 | +static bool |
| 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 | + return expression_tree_walker(node, checkQueryHasAggs_walker, context); |
| 1320 | +} |
1418 | 1321 |
|
1419 | 1322 | /*
|
1420 | 1323 | * checkQueryHasSubLink -
|
1421 |
| - * Queries marked hasAggs might not have them any longer after |
| 1324 | + * Queries marked hasSubLinks might not have them any longer after |
1422 | 1325 | * rewriting. Check it.
|
1423 | 1326 | */
|
1424 | 1327 | static bool
|
1425 | 1328 | checkQueryHasSubLink(Node *node)
|
1426 | 1329 | {
|
1427 |
| - if (node == NULL) |
1428 |
| - return FALSE; |
1429 |
| - |
1430 |
| - switch (nodeTag(node)) |
1431 |
| - { |
1432 |
| - case T_TargetEntry: |
1433 |
| - { |
1434 |
| - TargetEntry *tle = (TargetEntry *) node; |
1435 |
| - |
1436 |
| - return checkQueryHasSubLink((Node *) (tle->expr)); |
1437 |
| - } |
1438 |
| - break; |
1439 |
| - |
1440 |
| - case T_Aggref: |
1441 |
| - return TRUE; |
1442 |
| - |
1443 |
| - case T_Expr: |
1444 |
| - { |
1445 |
| - Expr *exp = (Expr *) node; |
1446 |
| - |
1447 |
| - return checkQueryHasSubLink((Node *) (exp->args)); |
1448 |
| - } |
1449 |
| - break; |
1450 |
| - |
1451 |
| - case T_Iter: |
1452 |
| - { |
1453 |
| - Iter *iter = (Iter *) node; |
1454 |
| - |
1455 |
| - return checkQueryHasSubLink((Node *) (iter->iterexpr)); |
1456 |
| - } |
1457 |
| - break; |
1458 |
| - |
1459 |
| - case T_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 |
| - case T_Var: |
1480 |
| - return FALSE; |
1481 |
| - |
1482 |
| - case T_Param: |
1483 |
| - return FALSE; |
1484 |
| - |
1485 |
| - case T_Const: |
1486 |
| - return FALSE; |
1487 |
| - |
1488 |
| - case T_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 |
| - case T_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 |
| - case T_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 |
| - case T_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 | + return checkQueryHasSubLink_walker(node, NULL); |
| 1331 | +} |
1539 | 1332 |
|
1540 |
| - return FALSE; |
| 1333 | +static bool |
| 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 | + return expression_tree_walker(node, checkQueryHasSubLink_walker, context); |
1541 | 1344 | }
|
1542 | 1345 |
|
1543 | 1346 |
|
|
0 commit comments