From: Tom Lane Date: Fri, 1 Dec 2000 20:43:59 +0000 (+0000) Subject: Fix inadequate tree-walking code in exec_eval_clear_fcache. X-Git-Tag: REL7_1_BETA~20 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f5371feef9ea4af23284c0f56d8a28cbf1de2a7f;p=postgresql Fix inadequate tree-walking code in exec_eval_clear_fcache. --- diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 565e304f64..5bf76a9d94 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.32 2000/11/16 22:30:50 tgl Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.33 2000/12/01 20:43:59 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -54,6 +54,7 @@ #include "executor/spi.h" #include "executor/spi_priv.h" #include "fmgr.h" +#include "optimizer/clauses.h" #include "parser/parse_expr.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" @@ -112,6 +113,7 @@ static void exec_prepare_plan(PLpgSQL_execstate * estate, static bool exec_simple_check_node(Node *node); static void exec_simple_check_plan(PLpgSQL_expr * expr); static void exec_eval_clear_fcache(Node *node); +static bool exec_eval_clear_fcache_walker(Node *node, void *context); static Datum exec_eval_simple_expr(PLpgSQL_execstate * estate, PLpgSQL_expr * expr, bool *isNull, @@ -2593,7 +2595,7 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate, *rettype = expr->plan_simple_type; /* ---------- - * Clear the function cache + * Clear any function cache entries in the expression tree * ---------- */ exec_eval_clear_fcache(expr->plan_simple_expr); @@ -2904,33 +2906,35 @@ exec_simple_check_plan(PLpgSQL_expr * expr) static void exec_eval_clear_fcache(Node *node) { - Expr *expr; - List *l; - - if (nodeTag(node) != T_Expr) - return; - - expr = (Expr *) node; + /* This tree walk requires no special setup, so away we go... */ + exec_eval_clear_fcache_walker(node, NULL); +} - switch (expr->opType) +static bool +exec_eval_clear_fcache_walker(Node *node, void *context) +{ + if (node == NULL) + return false; + if (IsA(node, Expr)) { - case OP_EXPR: - ((Oper *) (expr->oper))->op_fcache = NULL; - break; + Expr *expr = (Expr *) node; - case FUNC_EXPR: - ((Func *) (expr->oper))->func_fcache = NULL; - break; - - default: - break; + switch (expr->opType) + { + case OP_EXPR: + ((Oper *) (expr->oper))->op_fcache = NULL; + break; + case FUNC_EXPR: + ((Func *) (expr->oper))->func_fcache = NULL; + break; + default: + break; + } } - - foreach(l, expr->args) - exec_eval_clear_fcache(lfirst(l)); + return expression_tree_walker(node, exec_eval_clear_fcache_walker, + context); } - /* ---------- * exec_set_found Set the global found variable * to true/false