Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1f2c6f4

Browse files
committed
Replace rewriter's checkQueryHasAggs and checkQueryHasSubLink
with expression_tree_walker-based code. The former failed to cope withexpressions containing SubLinks, and the latter returned TRUE for bothSubLinks and Aggrefs (cut-and-paste bug?). There is a lot more scope forusing expression_tree_walker in this module, but I'll restrain myselfuntil the 6.6 split occurs from touching not-demonstrably-broken code.
1 parentfd8e580 commit1f2c6f4

File tree

1 file changed

+29
-226
lines changed

1 file changed

+29
-226
lines changed

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 29 additions & 226 deletions
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
staticSubLink*modifyAggrefMakeSublink(Expr*origexp,Query*parsetree);
6162
staticvoidmodifyAggrefQual(Node**nodePtr,Query*parsetree);
6263
staticboolcheckQueryHasAggs(Node*node);
64+
staticboolcheckQueryHasAggs_walker(Node*node,void*context);
65+
staticboolcheckQueryHasSubLink(Node*node);
66+
staticboolcheckQueryHasSubLink_walker(Node*node,void*context);
6367
staticQuery*fireRIRrules(Query*parsetree);
6468
staticQuery*Except_Intersect_Rewrite(Query*parsetree);
6569
staticvoidcheck_targetlists_are_compatible(List*prev_target,
@@ -1302,242 +1306,41 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
13021306
staticbool
13031307
checkQueryHasAggs(Node*node)
13041308
{
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);
14161310
}
14171311

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

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

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

15431346

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp