|
6 | 6 | *
|
7 | 7 | *
|
8 | 8 | * IDENTIFICATION
|
9 |
| - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.39 1999/05/1215:01:53 wieck Exp $ |
| 9 | + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.40 1999/05/1217:04:47 wieck Exp $ |
10 | 10 | *
|
11 | 11 | *-------------------------------------------------------------------------
|
12 | 12 | */
|
@@ -59,6 +59,7 @@ static void modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_ind
|
59 | 59 | staticvoidmodifyAggrefDropQual(Node**nodePtr,Node*orignode,Expr*expr);
|
60 | 60 | staticSubLink*modifyAggrefMakeSublink(Expr*origexp,Query*parsetree);
|
61 | 61 | staticvoidmodifyAggrefQual(Node**nodePtr,Query*parsetree);
|
| 62 | +staticboolcheckQueryHasAggs(Node*node); |
62 | 63 | staticQuery*fireRIRrules(Query*parsetree);
|
63 | 64 |
|
64 | 65 |
|
@@ -1272,6 +1273,126 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
|
1272 | 1273 | }
|
1273 | 1274 |
|
1274 | 1275 |
|
| 1276 | +/* |
| 1277 | + * checkQueryHasAggs - |
| 1278 | + *Queries marked hasAggs might not have them any longer after |
| 1279 | + *rewriting. Check it. |
| 1280 | + */ |
| 1281 | +staticbool |
| 1282 | +checkQueryHasAggs(Node*node) |
| 1283 | +{ |
| 1284 | +if (node==NULL) |
| 1285 | +return FALSE; |
| 1286 | + |
| 1287 | +switch(nodeTag(node)) { |
| 1288 | +caseT_TargetEntry: |
| 1289 | +{ |
| 1290 | +TargetEntry*tle= (TargetEntry*)node; |
| 1291 | + |
| 1292 | +returncheckQueryHasAggs((Node*)(tle->expr)); |
| 1293 | +} |
| 1294 | +break; |
| 1295 | + |
| 1296 | +caseT_Aggref: |
| 1297 | +return TRUE; |
| 1298 | + |
| 1299 | +caseT_Expr: |
| 1300 | +{ |
| 1301 | +Expr*exp= (Expr*)node; |
| 1302 | + |
| 1303 | +returncheckQueryHasAggs((Node*)(exp->args)); |
| 1304 | +} |
| 1305 | +break; |
| 1306 | + |
| 1307 | +caseT_Iter: |
| 1308 | +{ |
| 1309 | +Iter*iter= (Iter*)node; |
| 1310 | + |
| 1311 | +returncheckQueryHasAggs((Node*)(iter->iterexpr)); |
| 1312 | +} |
| 1313 | +break; |
| 1314 | + |
| 1315 | +caseT_ArrayRef: |
| 1316 | +{ |
| 1317 | +ArrayRef*ref= (ArrayRef*)node; |
| 1318 | + |
| 1319 | +if (checkQueryHasAggs((Node*)(ref->refupperindexpr))) |
| 1320 | +return TRUE; |
| 1321 | + |
| 1322 | +if (checkQueryHasAggs((Node*)(ref->reflowerindexpr))) |
| 1323 | +return TRUE; |
| 1324 | + |
| 1325 | +if (checkQueryHasAggs((Node*)(ref->refexpr))) |
| 1326 | +return TRUE; |
| 1327 | + |
| 1328 | +if (checkQueryHasAggs((Node*)(ref->refassgnexpr))) |
| 1329 | +return TRUE; |
| 1330 | + |
| 1331 | +return FALSE; |
| 1332 | +} |
| 1333 | +break; |
| 1334 | + |
| 1335 | +caseT_Var: |
| 1336 | +return FALSE; |
| 1337 | + |
| 1338 | +caseT_Param: |
| 1339 | +return FALSE; |
| 1340 | + |
| 1341 | +caseT_Const: |
| 1342 | +return FALSE; |
| 1343 | + |
| 1344 | +caseT_List: |
| 1345 | +{ |
| 1346 | +List*l; |
| 1347 | + |
| 1348 | +foreach (l, (List*)node) { |
| 1349 | +if (checkQueryHasAggs((Node*)lfirst(l))) |
| 1350 | +return TRUE; |
| 1351 | +} |
| 1352 | +return FALSE; |
| 1353 | +} |
| 1354 | +break; |
| 1355 | + |
| 1356 | +caseT_CaseExpr: |
| 1357 | +{ |
| 1358 | +CaseExpr*exp= (CaseExpr*)node; |
| 1359 | + |
| 1360 | +if (checkQueryHasAggs((Node*)(exp->args))) |
| 1361 | +return TRUE; |
| 1362 | + |
| 1363 | +if (checkQueryHasAggs((Node*)(exp->defresult))) |
| 1364 | +return TRUE; |
| 1365 | + |
| 1366 | +return FALSE; |
| 1367 | +} |
| 1368 | +break; |
| 1369 | + |
| 1370 | +caseT_CaseWhen: |
| 1371 | +{ |
| 1372 | +CaseWhen*when= (CaseWhen*)node; |
| 1373 | + |
| 1374 | +if (checkQueryHasAggs((Node*)(when->expr))) |
| 1375 | +return TRUE; |
| 1376 | + |
| 1377 | +if (checkQueryHasAggs((Node*)(when->result))) |
| 1378 | +return TRUE; |
| 1379 | + |
| 1380 | +return FALSE; |
| 1381 | +} |
| 1382 | +break; |
| 1383 | + |
| 1384 | +default: |
| 1385 | +elog(NOTICE,"unknown node tag %d in checkQueryHasAggs()",nodeTag(node)); |
| 1386 | +elog(NOTICE,"Node is: %s",nodeToString(node)); |
| 1387 | +break; |
| 1388 | + |
| 1389 | + |
| 1390 | +} |
| 1391 | + |
| 1392 | +return FALSE; |
| 1393 | +} |
| 1394 | + |
| 1395 | + |
1275 | 1396 | staticNode*
|
1276 | 1397 | FindMatchingTLEntry(List*tlist,char*e_attname)
|
1277 | 1398 | {
|
@@ -2574,8 +2695,17 @@ BasicQueryRewrite(Query *parsetree)
|
2574 | 2695 | * Apply all the RIR rules on each query
|
2575 | 2696 | */
|
2576 | 2697 | foreach (l,querylist) {
|
2577 |
| -query= (Query*)lfirst(l); |
2578 |
| -results=lappend(results,fireRIRrules(query)); |
| 2698 | +query=fireRIRrules((Query*)lfirst(l)); |
| 2699 | +/* |
| 2700 | + * If the query was marked having aggregates, check if |
| 2701 | + * this is still true after rewriting. This check must get |
| 2702 | + * expanded when someday aggregates can appear somewhere |
| 2703 | + * else than in the targetlist or the having qual. |
| 2704 | + */ |
| 2705 | +if (query->hasAggs) |
| 2706 | +query->hasAggs=checkQueryHasAggs((Node*)(query->targetList)) |
| 2707 | + |checkQueryHasAggs((Node*)(query->havingQual)); |
| 2708 | +results=lappend(results,query); |
2579 | 2709 | }
|
2580 | 2710 | returnresults;
|
2581 | 2711 | }
|
|