|
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 |
|
|