From 15621a2c8bbff2f72c2df8f7afd24910a51289c9 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 5 Jul 2018 16:27:44 +0200 Subject: [PATCH] Cache pg_get_expr deparse context between calls --- src/backend/utils/adt/ruleutils.c | 49 ++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 065238b0fe..aa73bb35d6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -327,7 +327,7 @@ static char *pg_get_partkeydef_worker(Oid relid, int prettyFlags, bool attrsOnly, bool missing_ok); static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, int prettyFlags, bool missing_ok); -static text *pg_get_expr_worker(text *expr, Oid relid, const char *relname, +static text *pg_get_expr_worker(FunctionCallInfo fcinfo, text *expr, Oid relid, const char *relname, int prettyFlags); static int print_function_arguments(StringInfo buf, HeapTuple proctup, bool print_table_args, bool print_defaults); @@ -2292,7 +2292,7 @@ pg_get_expr(PG_FUNCTION_ARGS) else relname = NULL; - PG_RETURN_TEXT_P(pg_get_expr_worker(expr, relid, relname, prettyFlags)); + PG_RETURN_TEXT_P(pg_get_expr_worker(fcinfo, expr, relid, relname, prettyFlags)); } Datum @@ -2317,14 +2317,20 @@ pg_get_expr_ext(PG_FUNCTION_ARGS) else relname = NULL; - PG_RETURN_TEXT_P(pg_get_expr_worker(expr, relid, relname, prettyFlags)); + PG_RETURN_TEXT_P(pg_get_expr_worker(fcinfo, expr, relid, relname, prettyFlags)); } +struct cached_context +{ + Oid relid; + List *context; +}; + static text * -pg_get_expr_worker(text *expr, Oid relid, const char *relname, int prettyFlags) +pg_get_expr_worker(FunctionCallInfo fcinfo, text *expr, Oid relid, const char *relname, int prettyFlags) { Node *node; - List *context; + List *context = NIL; char *exprstr; char *str; @@ -2338,9 +2344,36 @@ pg_get_expr_worker(text *expr, Oid relid, const char *relname, int prettyFlags) /* Prepare deparse context if needed */ if (OidIsValid(relid)) - context = deparse_context_for(relname, relid); - else - context = NIL; + { + struct cached_context *cc; + + if (fcinfo->flinfo && fcinfo->flinfo->fn_extra) + { + cc = fcinfo->flinfo->fn_extra; + if (cc->relid == relid) + context = cc->context; + } + + if (!context) + { + MemoryContext oldcontext = NULL; + struct cached_context *cc; + + if (fcinfo->flinfo) + oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt); + + context = deparse_context_for(relname, relid); + + if (fcinfo->flinfo) + { + cc = palloc(sizeof(*cc)); + cc->relid = relid; + cc->context = context; + fcinfo->flinfo->fn_extra = cc; + MemoryContextSwitchTo(oldcontext); + } + } + } /* Deparse */ str = deparse_expression_pretty(node, context, false, false, base-commit: f61988d160c1af8c1ed495e5c547726e88a45036 -- 2.18.0