Skip to content

Commit 48c5c90

Browse files
committed
Use the "pg_temp" schema alias in EXPLAIN and related output.
This patch causes EXPLAIN output to refer to objects that are in the current session's temp schema with the "pg_temp" schema alias rather than that schema's actual name. This is useful for our own testing purposes since it will stabilize EXPLAIN VERBOSE output for such cases, allowing us to use that in regression tests. It should be less confusing for end users too. Since ruleutils.c needs to change behavior for this, the change also leaks into a few other users of ruleutils.c, for example pg_get_viewdef(). AFAICS that won't cause any problems. We did find that aggressively trying to change this behavior across-the-board would cause issues, but as long as "pg_temp" only appears within generated SQL text, I think it'll be fine. Along the way, make get_namespace_name_or_temp conform to the same API as get_namespace_name, ie that it returns a palloc'd string or NULL. The current behavior hasn't caused any bugs since no callers attempt to pfree the result, but if it gets more widespread usage that could become a problem. Amul Sul, reviewed and extended by me Discussion: https://postgr.es/m/CAAJ_b97W=QaGmag9AhWNbmx3uEYsNkXWL+OVW1_E1D3BtgWvtw@mail.gmail.com
1 parent 91d7661 commit 48c5c90

File tree

6 files changed

+36
-15
lines changed

6 files changed

+36
-15
lines changed

contrib/postgres_fdw/postgres_fdw.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2854,7 +2854,7 @@ postgresExplainForeignScan(ForeignScanState *node, ExplainState *es)
28542854
{
28552855
char *namespace;
28562856

2857-
namespace = get_namespace_name(get_rel_namespace(rte->relid));
2857+
namespace = get_namespace_name_or_temp(get_rel_namespace(rte->relid));
28582858
appendStringInfo(relations, "%s.%s",
28592859
quote_identifier(namespace),
28602860
quote_identifier(relname));

src/backend/commands/explain.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -3747,7 +3747,7 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
37473747
Assert(rte->rtekind == RTE_RELATION);
37483748
objectname = get_rel_name(rte->relid);
37493749
if (es->verbose)
3750-
namespace = get_namespace_name(get_rel_namespace(rte->relid));
3750+
namespace = get_namespace_name_or_temp(get_rel_namespace(rte->relid));
37513751
objecttag = "Relation Name";
37523752
break;
37533753
case T_FunctionScan:
@@ -3774,8 +3774,7 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
37743774

37753775
objectname = get_func_name(funcid);
37763776
if (es->verbose)
3777-
namespace =
3778-
get_namespace_name(get_func_namespace(funcid));
3777+
namespace = get_namespace_name_or_temp(get_func_namespace(funcid));
37793778
}
37803779
}
37813780
objecttag = "Function Name";

src/backend/utils/adt/ruleutils.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,7 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
16171617

16181618
if (!columns_only)
16191619
{
1620-
nsp = get_namespace_name(statextrec->stxnamespace);
1620+
nsp = get_namespace_name_or_temp(statextrec->stxnamespace);
16211621
appendStringInfo(&buf, "CREATE STATISTICS %s",
16221622
quote_qualified_identifier(nsp,
16231623
NameStr(statextrec->stxname)));
@@ -2811,7 +2811,7 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
28112811
* We always qualify the function name, to ensure the right function gets
28122812
* replaced.
28132813
*/
2814-
nsp = get_namespace_name(proc->pronamespace);
2814+
nsp = get_namespace_name_or_temp(proc->pronamespace);
28152815
appendStringInfo(&buf, "CREATE OR REPLACE %s %s(",
28162816
isfunction ? "FUNCTION" : "PROCEDURE",
28172817
quote_qualified_identifier(nsp, name));
@@ -11183,7 +11183,7 @@ get_opclass_name(Oid opclass, Oid actual_datatype,
1118311183
appendStringInfo(buf, " %s", quote_identifier(opcname));
1118411184
else
1118511185
{
11186-
nspname = get_namespace_name(opcrec->opcnamespace);
11186+
nspname = get_namespace_name_or_temp(opcrec->opcnamespace);
1118711187
appendStringInfo(buf, " %s.%s",
1118811188
quote_identifier(nspname),
1118911189
quote_identifier(opcname));
@@ -11495,7 +11495,7 @@ generate_relation_name(Oid relid, List *namespaces)
1149511495
need_qual = !RelationIsVisible(relid);
1149611496

1149711497
if (need_qual)
11498-
nspname = get_namespace_name(reltup->relnamespace);
11498+
nspname = get_namespace_name_or_temp(reltup->relnamespace);
1149911499
else
1150011500
nspname = NULL;
1150111501

@@ -11527,7 +11527,7 @@ generate_qualified_relation_name(Oid relid)
1152711527
reltup = (Form_pg_class) GETSTRUCT(tp);
1152811528
relname = NameStr(reltup->relname);
1152911529

11530-
nspname = get_namespace_name(reltup->relnamespace);
11530+
nspname = get_namespace_name_or_temp(reltup->relnamespace);
1153111531
if (!nspname)
1153211532
elog(ERROR, "cache lookup failed for namespace %u",
1153311533
reltup->relnamespace);
@@ -11639,7 +11639,7 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes,
1163911639
p_funcid == funcid)
1164011640
nspname = NULL;
1164111641
else
11642-
nspname = get_namespace_name(procform->pronamespace);
11642+
nspname = get_namespace_name_or_temp(procform->pronamespace);
1164311643

1164411644
result = quote_qualified_identifier(nspname, proname);
1164511645

@@ -11702,7 +11702,7 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2)
1170211702
nspname = NULL;
1170311703
else
1170411704
{
11705-
nspname = get_namespace_name(operform->oprnamespace);
11705+
nspname = get_namespace_name_or_temp(operform->oprnamespace);
1170611706
appendStringInfo(&buf, "OPERATOR(%s.", quote_identifier(nspname));
1170711707
}
1170811708

@@ -11790,7 +11790,7 @@ add_cast_to(StringInfo buf, Oid typid)
1179011790
typform = (Form_pg_type) GETSTRUCT(typetup);
1179111791

1179211792
typname = NameStr(typform->typname);
11793-
nspname = get_namespace_name(typform->typnamespace);
11793+
nspname = get_namespace_name_or_temp(typform->typnamespace);
1179411794

1179511795
appendStringInfo(buf, "::%s.%s",
1179611796
quote_identifier(nspname), quote_identifier(typname));
@@ -11822,7 +11822,7 @@ generate_qualified_type_name(Oid typid)
1182211822
typtup = (Form_pg_type) GETSTRUCT(tp);
1182311823
typname = NameStr(typtup->typname);
1182411824

11825-
nspname = get_namespace_name(typtup->typnamespace);
11825+
nspname = get_namespace_name_or_temp(typtup->typnamespace);
1182611826
if (!nspname)
1182711827
elog(ERROR, "cache lookup failed for namespace %u",
1182811828
typtup->typnamespace);
@@ -11856,7 +11856,7 @@ generate_collation_name(Oid collid)
1185611856
collname = NameStr(colltup->collname);
1185711857

1185811858
if (!CollationIsVisible(collid))
11859-
nspname = get_namespace_name(colltup->collnamespace);
11859+
nspname = get_namespace_name_or_temp(colltup->collnamespace);
1186011860
else
1186111861
nspname = NULL;
1186211862

src/backend/utils/cache/lsyscache.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3340,7 +3340,7 @@ char *
33403340
get_namespace_name_or_temp(Oid nspid)
33413341
{
33423342
if (isTempNamespace(nspid))
3343-
return "pg_temp";
3343+
return pstrdup("pg_temp");
33443344
else
33453345
return get_namespace_name(nspid);
33463346
}

src/test/regress/expected/explain.out

+13
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,19 @@ select jsonb_pretty(
477477
(1 row)
478478

479479
rollback;
480+
-- Test display of temporary objects
481+
create temp table t1(f1 float8);
482+
create function pg_temp.mysin(float8) returns float8 language plpgsql
483+
as 'begin return sin($1); end';
484+
select explain_filter('explain (verbose) select * from t1 where pg_temp.mysin(f1) < 0.5');
485+
explain_filter
486+
------------------------------------------------------------
487+
Seq Scan on pg_temp.t1 (cost=N.N..N.N rows=N width=N)
488+
Output: f1
489+
Filter: (pg_temp.mysin(t1.f1) < 'N.N'::double precision)
490+
(3 rows)
491+
492+
-- Test compute_query_id
480493
set compute_query_id = on;
481494
select explain_filter('explain (verbose) select * from int8_tbl i8');
482495
explain_filter

src/test/regress/sql/explain.sql

+9
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,14 @@ select jsonb_pretty(
104104

105105
rollback;
106106

107+
-- Test display of temporary objects
108+
create temp table t1(f1 float8);
109+
110+
create function pg_temp.mysin(float8) returns float8 language plpgsql
111+
as 'begin return sin($1); end';
112+
113+
select explain_filter('explain (verbose) select * from t1 where pg_temp.mysin(f1) < 0.5');
114+
115+
-- Test compute_query_id
107116
set compute_query_id = on;
108117
select explain_filter('explain (verbose) select * from int8_tbl i8');

0 commit comments

Comments
 (0)