* query_tree_walker --- initiate a walk of a Query's expressions * * This routine exists just to reduce the number of places that need to know * where all the expression subtrees of a Query are. Note it can be used * for starting a walk at top level of a Query regardless of whether the * walker intends to descend into subqueries. It is also useful for * descending into subqueries within a
| 2476 | * indicated items. (More flag bits may be added as needed.) |
| 2477 | */ |
| 2478 | bool |
| 2479 | query_tree_walker(Query *query, |
| 2480 | bool (*walker) (), |
| 2481 | void *context, |
| 2482 | int flags) |
| 2483 | { |
| 2484 | Assert(query != NULL && IsA(query, Query)); |
| 2485 | |
| 2486 | /* |
| 2487 | * We don't walk any utilityStmt here. However, we can't easily assert |
| 2488 | * that it is absent, since there are at least two code paths by which |
| 2489 | * action statements from CREATE RULE end up here, and NOTIFY is allowed |
| 2490 | * in a rule action. |
| 2491 | */ |
| 2492 | |
| 2493 | if (walker((Node *) query->targetList, context)) |
| 2494 | return true; |
| 2495 | if (walker((Node *) query->withCheckOptions, context)) |
| 2496 | return true; |
| 2497 | if (walker((Node *) query->onConflict, context)) |
| 2498 | return true; |
| 2499 | if (walker((Node *) query->returningList, context)) |
| 2500 | return true; |
| 2501 | if (walker((Node *) query->jointree, context)) |
| 2502 | return true; |
| 2503 | if (walker(query->setOperations, context)) |
| 2504 | return true; |
| 2505 | if (walker(query->havingQual, context)) |
| 2506 | return true; |
| 2507 | if (walker(query->groupClause, context)) |
| 2508 | return true; |
| 2509 | if (walker(query->windowClause, context)) |
| 2510 | return true; |
| 2511 | if (walker(query->limitOffset, context)) |
| 2512 | return true; |
| 2513 | if (walker(query->limitCount, context)) |
| 2514 | return true; |
| 2515 | |
| 2516 | /* |
| 2517 | * Most callers aren't interested in SortGroupClause nodes since those |
| 2518 | * don't contain actual expressions. However they do contain OIDs which |
| 2519 | * may be needed by dependency walkers etc. |
| 2520 | */ |
| 2521 | if ((flags & QTW_EXAMINE_SORTGROUP)) |
| 2522 | { |
| 2523 | if (walker((Node *) query->groupClause, context)) |
| 2524 | return true; |
| 2525 | if (walker((Node *) query->windowClause, context)) |
| 2526 | return true; |
| 2527 | if (walker((Node *) query->sortClause, context)) |
| 2528 | return true; |
| 2529 | if (walker((Node *) query->distinctClause, context)) |
| 2530 | return true; |
| 2531 | } |
| 2532 | else |
| 2533 | { |
| 2534 | /* |
| 2535 | * But we need to walk the expressions under WindowClause nodes even |
no test coverage detected