Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
69909: sql: implement pg_my_temp_schema and pg_is_other_temp_schema r=nvanbenschoten a=nvanbenschoten

Needed for cockroachdb#69010.

This PR adds a real implementation for the `pg_my_temp_schema` builtin
function. `pg_my_temp_schema` returns the OID of session's temporary schema, or 0
if the session has not yet created a temporary schema.

The PR then implements the `pg_is_other_temp_schema` builtin function.
`pg_is_other_temp_schema` 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.

Release note (sql change): The pg_my_temp_schema builtin function now properly
returns the OID of the active session's temporary schema, if one exists.

Release note (sql change): The pg_is_other_temp_schema builtin function is now
supported, which returns whether the given OID is the OID of another session's
temporary schema.

Release justification: None, waiting for v22.1.

Co-authored-by: Nathan VanBenschoten <nvanbenschoten@gmail.com>
  • Loading branch information
craig[bot] and nvanbenschoten committed Sep 14, 2021
2 parents 11b003b + f9a8de9 commit a355ffe
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 77 deletions.
12 changes: 8 additions & 4 deletions docs/generated/sql/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1070,8 +1070,6 @@ the locality flag on node startup. Returns an error if no region is set.</p>
</span></td></tr>
<tr><td><a name="nextval"></a><code>nextval(sequence_name: regclass) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Advances the given sequence and returns its new value.</p>
</span></td></tr>
<tr><td><a name="pg_get_serial_sequence"></a><code>pg_get_serial_sequence(table_name: <a href="string.html">string</a>, column_name: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the name of the sequence used by the given column_name in the table table_name.</p>
</span></td></tr>
<tr><td><a name="setval"></a><code>setval(sequence_name: <a href="string.html">string</a>, value: <a href="int.html">int</a>) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Set the given sequence’s current value. The next call to nextval will return <code>value + Increment</code></p>
</span></td></tr>
<tr><td><a name="setval"></a><code>setval(sequence_name: <a href="string.html">string</a>, value: <a href="int.html">int</a>, is_called: <a href="bool.html">bool</a>) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Set the given sequence’s current value. If is_called is false, the next call to nextval will return <code>value</code>; otherwise <code>value + Increment</code>.</p>
Expand Down Expand Up @@ -2577,8 +2575,6 @@ The output can be used to recreate a database.’</p>
</span></td></tr>
<tr><td><a name="parse_timetz"></a><code>parse_timetz(val: <a href="string.html">string</a>) &rarr; timetz</code></td><td><span class="funcdesc"><p>Parses a timetz assuming the date (if any) is in MDY format.</p>
</span></td></tr>
<tr><td><a name="pg_collation_for"></a><code>pg_collation_for(str: anyelement) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the collation of the argument</p>
</span></td></tr>
<tr><td><a name="quote_ident"></a><code>quote_ident(val: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Return <code>val</code> suitably quoted to serve as identifier in a SQL statement.</p>
</span></td></tr>
<tr><td><a name="quote_literal"></a><code>quote_literal(val: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Return <code>val</code> suitably quoted to serve as string literal in a SQL statement.</p>
Expand Down Expand Up @@ -3134,10 +3130,18 @@ SELECT * FROM crdb_internal.check_consistency(true, ‘\x02’, ‘\x04’)</p>
</span></td></tr>
<tr><td><a name="oid"></a><code>oid(int: <a href="int.html">int</a>) &rarr; oid</code></td><td><span class="funcdesc"><p>Converts an integer to an OID.</p>
</span></td></tr>
<tr><td><a name="pg_collation_for"></a><code>pg_collation_for(str: anyelement) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the collation of the argument</p>
</span></td></tr>
<tr><td><a name="pg_column_is_updatable"></a><code>pg_column_is_updatable(reloid: oid, attnum: int2, include_triggers: <a href="bool.html">bool</a>) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Returns whether the given column can be updated.</p>
</span></td></tr>
<tr><td><a name="pg_column_size"></a><code>pg_column_size(anyelement...) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Return size in bytes of the column provided as an argument</p>
</span></td></tr>
<tr><td><a name="pg_get_serial_sequence"></a><code>pg_get_serial_sequence(table_name: <a href="string.html">string</a>, column_name: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the name of the sequence used by the given column_name in the table table_name.</p>
</span></td></tr>
<tr><td><a name="pg_is_other_temp_schema"></a><code>pg_is_other_temp_schema(oid: oid) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>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.)</p>
</span></td></tr>
<tr><td><a name="pg_my_temp_schema"></a><code>pg_my_temp_schema() &rarr; oid</code></td><td><span class="funcdesc"><p>Returns the OID of the current session’s temporary schema, or zero if it has none (because it has not created any temporary tables).</p>
</span></td></tr>
<tr><td><a name="pg_relation_is_updatable"></a><code>pg_relation_is_updatable(reloid: oid, include_triggers: <a href="bool.html">bool</a>) &rarr; int4</code></td><td><span class="funcdesc"><p>Returns the update events the relation supports.</p>
</span></td></tr>
<tr><td><a name="pg_sleep"></a><code>pg_sleep(seconds: <a href="float.html">float</a>) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>pg_sleep makes the current session’s process sleep until seconds seconds have elapsed. seconds is a value of type double precision, so fractional-second delays can be specified.</p>
Expand Down
34 changes: 34 additions & 0 deletions pkg/bench/rttanalysis/orm_queries_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,26 +159,60 @@ WHERE
Setup: `CREATE TABLE t1(a int primary key, b int);`,
Stmt: `SELECT * FROM pg_attribute`,
},

{
Name: "has_table_privilege real table",
Setup: `CREATE TABLE t(a int primary key, b int)`,
Stmt: `SELECT has_table_privilege('t', 'SELECT')`,
},

{
Name: "has_table_privilege virtual table",
Setup: `CREATE TABLE t(a int primary key, b int)`,
Stmt: `SELECT has_table_privilege('t', 'SELECT')`,
},

{
Name: "has_column_privilege using attnum",
Setup: `CREATE TABLE t(a int primary key, b int)`,
Stmt: `SELECT has_column_privilege('t', 1, 'INSERT')`,
},

{
Name: "has_column_privilege using column name",
Setup: `CREATE TABLE t(a int primary key, b int)`,
Stmt: `SELECT has_column_privilege('t', 'a', 'INSERT')`,
},

{
Name: "pg_my_temp_schema",
Setup: `SET experimental_enable_temp_tables = true;
CREATE TEMP TABLE t(a int primary key, b int)`,
Stmt: `SELECT pg_my_temp_schema()`,
},

{
Name: "pg_my_temp_schema multiple times",
Setup: `SET experimental_enable_temp_tables = true;
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)
Expand Down
84 changes: 79 additions & 5 deletions pkg/sql/logictest/testdata/logic_test/pg_builtins
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ query T
SELECT aclexplode(ARRAY['foo'])
----

query O
SELECT pg_my_temp_schema()
----
0

# Regression test for #43166.
statement ok
SELECT has_table_privilege('root'::NAME, 0, 'select')
Expand Down Expand Up @@ -341,6 +336,85 @@ SELECT pg_catalog.set_config('woo', 'woo', false)
query error configuration setting.*not supported
SELECT set_config('vacuum_cost_delay', '0', false)

# pg_my_temp_schema
#
# Before a temporary schema is created, it returns 0. Afterwards, it returns the
# OID of session's temporary schema.

query O
SELECT pg_my_temp_schema()
----
0

statement ok
SET experimental_enable_temp_tables = true;

statement ok
CREATE TEMP TABLE temp1 (a int);

query B
SELECT pg_my_temp_schema()::TEXT LIKE 'pg_temp_%'
----
true

# If the user changes databases, it no longer has access to its temp tables.
# pg_my_temp_schema reverts to returning 0 again.

statement ok
SET DATABASE = db2;

query O
SELECT pg_my_temp_schema()
----
0

statement ok
CREATE TEMP TABLE temp2 (a int);

query B
SELECT pg_my_temp_schema()::TEXT LIKE 'pg_temp_%'
----
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.
Expand Down
14 changes: 7 additions & 7 deletions pkg/sql/logictest/testdata/logic_test/pg_catalog
Original file line number Diff line number Diff line change
Expand Up @@ -4945,20 +4945,20 @@ CREATE TEMPORARY TABLE test_temp (id UUID PRIMARY KEY);
CREATE UNLOGGED TABLE test_unlogged (id UUID PRIMARY KEY);
CREATE TABLE test_persistent (id UUID PRIMARY KEY);

# we don't store UNLOGGED beyond the parser at the moment so we expect 'p' for test_unlogged
query T
# We don't store UNLOGGED beyond the parser at the moment so we expect 'p' for test_unlogged.
query TTB
SELECT
relpersistence
relname, relpersistence, relistemp
FROM
pg_catalog.pg_class
WHERE
relname IN ('test_temp', 'test_unlogged', 'test_persistent')
ORDER BY
relpersistence
relname
----
p
p
t
test_persistent p false
test_temp t true
test_unlogged p false

# Issue 44793
statement ok
Expand Down
6 changes: 3 additions & 3 deletions pkg/sql/pg_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,9 @@ https://www.postgresql.org/docs/9.5/catalog-pg-class.html`,
oidZero, // reltoastrelid
tree.MakeDBool(tree.DBool(table.IsPhysicalTable())), // relhasindex
tree.DBoolFalse, // relisshared
relPersistence, // relPersistence
tree.DBoolFalse, // relistemp
relKind, // relkind
relPersistence, // relpersistence
tree.MakeDBool(tree.DBool(table.IsTemporary())), // relistemp
relKind, // relkind
tree.NewDInt(tree.DInt(len(table.AccessibleColumns()))), // relnatts
tree.NewDInt(tree.DInt(len(table.GetChecks()))), // relchecks
tree.DBoolFalse, // relhasoids
Expand Down
53 changes: 0 additions & 53 deletions pkg/sql/sem/builtins/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -2095,35 +2095,6 @@ var builtins = map[string]builtinDefinition{
},
),

"pg_get_serial_sequence": makeBuiltin(
tree.FunctionProperties{
Category: categorySequences,
},
tree.Overload{
Types: tree.ArgTypes{{"table_name", types.String}, {"column_name", types.String}},
ReturnType: tree.FixedReturnType(types.String),
Fn: func(evalCtx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
tableName := tree.MustBeDString(args[0])
columnName := tree.MustBeDString(args[1])
qualifiedName, err := parser.ParseQualifiedTableName(string(tableName))
if err != nil {
return nil, err
}
res, err := evalCtx.Sequence.GetSerialSequenceNameFromColumn(evalCtx.Ctx(), qualifiedName, tree.Name(columnName))
if err != nil {
return nil, err
}
if res == nil {
return tree.DNull, nil
}
res.ExplicitCatalog = false
return tree.NewDString(fmt.Sprintf(`%s.%s`, res.Schema(), res.Object())), nil
},
Info: "Returns the name of the sequence used by the given column_name in the table table_name.",
Volatility: tree.VolatilityStable,
},
),

"lastval": makeBuiltin(
tree.FunctionProperties{
Category: categorySequences,
Expand Down Expand Up @@ -4252,30 +4223,6 @@ value if you rely on the HLC for accuracy.`,
},
),

// https://www.postgresql.org/docs/10/functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE
"pg_collation_for": makeBuiltin(
tree.FunctionProperties{Category: categoryString},
tree.Overload{
Types: tree.ArgTypes{{"str", types.Any}},
ReturnType: tree.FixedReturnType(types.String),
Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
var collation string
switch t := args[0].(type) {
case *tree.DString:
collation = "default"
case *tree.DCollatedString:
collation = t.Locale
default:
return tree.DNull, pgerror.Newf(pgcode.DatatypeMismatch,
"collations are not supported by type: %s", t.ResolvedType())
}
return tree.NewDString(fmt.Sprintf(`"%s"`, collation)), nil
},
Info: "Returns the collation of the argument",
Volatility: tree.VolatilityStable,
},
),

// Get the current trace ID.
"crdb_internal.trace_id": makeBuiltin(
tree.FunctionProperties{Category: categorySystemInfo},
Expand Down
Loading

0 comments on commit a355ffe

Please sign in to comment.