diff --git a/docs/generated/sql/functions.md b/docs/generated/sql/functions.md index 7373393fc2fc..168becb28d2d 100644 --- a/docs/generated/sql/functions.md +++ b/docs/generated/sql/functions.md @@ -3138,6 +3138,8 @@ SELECT * FROM crdb_internal.check_consistency(true, ‘\x02’, ‘\x04’)

pg_get_serial_sequence(table_name: string, column_name: string) → string

Returns the name of the sequence used by the given column_name in the table table_name.

+pg_is_other_temp_schema(oid: oid) → bool

Returns true if the given OID is the OID of another session’s temporary schema. (This can be useful, for example, to exclude other sessions’ temporary tables from a catalog display.)

+
pg_my_temp_schema() → oid

Returns the OID of the current session’s temporary schema, or zero if it has none (because it has not created any temporary tables).

pg_relation_is_updatable(reloid: oid, include_triggers: bool) → int4

Returns the update events the relation supports.

diff --git a/pkg/bench/rttanalysis/orm_queries_bench_test.go b/pkg/bench/rttanalysis/orm_queries_bench_test.go index 3b4353fd65ca..181554e2cc03 100644 --- a/pkg/bench/rttanalysis/orm_queries_bench_test.go +++ b/pkg/bench/rttanalysis/orm_queries_bench_test.go @@ -197,6 +197,22 @@ WHERE CREATE TEMP TABLE t(a int primary key, b int)`, Stmt: `SELECT pg_my_temp_schema() FROM generate_series(1, 10)`, }, + + { + Name: "pg_is_other_temp_schema", + Setup: `SET experimental_enable_temp_tables = true; + CREATE TEMP TABLE t(a int primary key, b int)`, + Stmt: `SELECT nspname, pg_is_other_temp_schema(oid) FROM + (SELECT * FROM pg_namespace WHERE nspname = 'public') n`, + }, + + { + Name: "pg_is_other_temp_schema multiple times", + Setup: `SET experimental_enable_temp_tables = true; + CREATE TEMP TABLE t(a int primary key, b int)`, + Stmt: `SELECT nspname, pg_is_other_temp_schema(oid) FROM + (SELECT * FROM pg_namespace LIMIT 5) n`, + }, } RunRoundTripBenchmark(b, tests) diff --git a/pkg/sql/logictest/testdata/logic_test/pg_builtins b/pkg/sql/logictest/testdata/logic_test/pg_builtins index fb5f14faf6d0..627d78d74e87 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_builtins +++ b/pkg/sql/logictest/testdata/logic_test/pg_builtins @@ -379,6 +379,42 @@ true statement ok SET DATABASE = test; +# pg_is_other_temp_schema +# +# Returns true if the provided OID meets the following conditions: +# - is a reference to a schema +# - that is temporary +# - and is owned by a different session + +query B +SELECT pg_is_other_temp_schema((SELECT oid FROM pg_type LIMIT 1)) +---- +false + +query B +SELECT pg_is_other_temp_schema((SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog')) +---- +false + +query TB +SELECT user, pg_is_other_temp_schema((SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp_%')) +---- +root false + +# Switch users as a means of switching sessions. GRANT to ensure visibility. + +statement ok +GRANT root TO testuser + +user testuser + +query TB +SELECT user, pg_is_other_temp_schema((SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp_%')) +---- +testuser true + +user root + # information_schema._pg_truetypid and information_schema._pg_truetypmod # # We can't exhaustively test these until we support domain types. diff --git a/pkg/sql/sem/builtins/pg_builtins.go b/pkg/sql/sem/builtins/pg_builtins.go index 54b88b2036cd..8a60b08b4a95 100644 --- a/pkg/sql/sem/builtins/pg_builtins.go +++ b/pkg/sql/sem/builtins/pg_builtins.go @@ -863,6 +863,40 @@ var pgBuiltins = map[string]builtinDefinition{ }, ), + // pg_is_other_temp_schema returns true if the given OID is the OID of another + // session's temporary schema. + // https://www.postgresql.org/docs/11/functions-info.html + "pg_is_other_temp_schema": makeBuiltin(defProps(), + tree.Overload{ + Types: tree.ArgTypes{{"oid", types.Oid}}, + ReturnType: tree.FixedReturnType(types.Bool), + Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) { + schemaArg := tree.UnwrapDatum(ctx, args[0]) + schema, err := getNameForArg(ctx, schemaArg, "pg_namespace", "nspname") + if err != nil { + return nil, err + } + if schema == "" { + // OID does not exist. + return tree.DBoolFalse, nil + } + if !strings.HasPrefix(schema, catconstants.PgTempSchemaName) { + // OID is not a reference to a temporary schema. + // + // This string matching is what Postgres does too. See isAnyTempNamespace. + return tree.DBoolFalse, nil + } + if schema == ctx.SessionData().SearchPath.GetTemporarySchemaName() { + // OID is a reference to this session's temporary schema. + return tree.DBoolFalse, nil + } + return tree.DBoolTrue, nil + }, + Info: "Returns true if the given OID is the OID of another session's temporary schema. (This can be useful, for example, to exclude other sessions' temporary tables from a catalog display.)", + Volatility: tree.VolatilityStable, + }, + ), + // TODO(bram): Make sure the reported type is correct for tuples. See #25523. "pg_typeof": makeBuiltin(tree.FunctionProperties{NullableArgs: true}, tree.Overload{