Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1f2c6f4

Browse files
committed
Replace rewriter's checkQueryHasAggs and checkQueryHasSubLink
with expression_tree_walker-based code. The former failed to cope with expressions containing SubLinks, and the latter returned TRUE for both SubLinks and Aggrefs (cut-and-paste bug?). There is a lot more scope for using expression_tree_walker in this module, but I'll restrain myself until the 6.6 split occurs from touching not-demonstrably-broken code.
1 parent fd8e580 commit 1f2c6f4

File tree

1 file changed

+29
-226
lines changed

1 file changed

+29
-226
lines changed

src/backend/rewrite/rewriteHandler.c

+29-226
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* 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 $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -29,6 +29,7 @@
2929
#include "parser/parse_target.h"
3030

3131
#include "parser/analyze.h"
32+
#include "optimizer/clauses.h"
3233
#include "optimizer/prep.h"
3334

3435
#include "rewrite/rewriteSupport.h"
@@ -60,6 +61,9 @@ static void modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr);
6061
static SubLink *modifyAggrefMakeSublink(Expr *origexp, Query *parsetree);
6162
static void modifyAggrefQual(Node **nodePtr, Query *parsetree);
6263
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);
6367
static Query *fireRIRrules(Query *parsetree);
6468
static Query *Except_Intersect_Rewrite(Query *parsetree);
6569
static void check_targetlists_are_compatible(List *prev_target,
@@ -1302,242 +1306,41 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
13021306
static bool
13031307
checkQueryHasAggs(Node *node)
13041308
{
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);
14161310
}
14171311

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+
}
14181321

14191322
/*
14201323
* checkQueryHasSubLink -
1421-
* Queries marked hasAggs might not have them any longer after
1324+
* Queries marked hasSubLinks might not have them any longer after
14221325
* rewriting. Check it.
14231326
*/
14241327
static bool
14251328
checkQueryHasSubLink(Node *node)
14261329
{
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+
}
15391332

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);
15411344
}
15421345

15431346

0 commit comments

Comments
 (0)