| 1960 | */ |
| 1961 | |
| 1962 | bool |
| 1963 | expression_tree_walker(Node *node, |
| 1964 | bool (*walker) (), |
| 1965 | void *context) |
| 1966 | { |
| 1967 | ListCell *temp; |
| 1968 | |
| 1969 | /* |
| 1970 | * The walker has already visited the current node, and so we need only |
| 1971 | * recurse into any sub-nodes it has. |
| 1972 | * |
| 1973 | * We assume that the walker is not interested in List nodes per se, so |
| 1974 | * when we expect a List we just recurse directly to self without |
| 1975 | * bothering to call the walker. |
| 1976 | */ |
| 1977 | if (node == NULL) |
| 1978 | return false; |
| 1979 | |
| 1980 | /* Guard against stack overflow due to overly complex expressions */ |
| 1981 | check_stack_depth(); |
| 1982 | |
| 1983 | switch (nodeTag(node)) |
| 1984 | { |
| 1985 | case T_Var: |
| 1986 | case T_Const: |
| 1987 | case T_Param: |
| 1988 | case T_CaseTestExpr: |
| 1989 | case T_SQLValueFunction: |
| 1990 | case T_CoerceToDomainValue: |
| 1991 | case T_SetToDefault: |
| 1992 | case T_CurrentOfExpr: |
| 1993 | case T_NextValueExpr: |
| 1994 | case T_RangeTblRef: |
| 1995 | case T_SortGroupClause: |
| 1996 | case T_DMLActionExpr: |
| 1997 | case T_AggExprId: |
| 1998 | case T_RowIdExpr: |
| 1999 | case T_CTESearchClause: |
| 2000 | case T_Gather: |
| 2001 | case T_GatherMerge: |
| 2002 | /* primitive node types with no expression subnodes */ |
| 2003 | break; |
| 2004 | case T_WithCheckOption: |
| 2005 | return walker(((WithCheckOption *) node)->qual, context); |
| 2006 | case T_Aggref: |
| 2007 | { |
| 2008 | Aggref *expr = (Aggref *) node; |
| 2009 | |
| 2010 | /* recurse directly on List */ |
| 2011 | if (expression_tree_walker((Node *) expr->aggdirectargs, |
| 2012 | walker, context)) |
| 2013 | return true; |
| 2014 | if (expression_tree_walker((Node *) expr->args, |
| 2015 | walker, context)) |
| 2016 | return true; |
| 2017 | if (expression_tree_walker((Node *) expr->aggorder, |
| 2018 | walker, context)) |
| 2019 | return true; |
no test coverage detected