Skip to content

Commit c6550af

Browse files
craig[bot]mw5h
andcommitted
Merge #141193
141193: Implement types.Any variadic function handling r=mw5h a=mw5h #### builtins: Change pg_column_size from Immutable to Stable pg_column_size() is Stable in Postgres, not Immutable. Epic: none Release note: none #### types: reintroduce the 'any' type In a previous commit, we converted all usages of the old types.Any to types.AnyElement, which reflects our legacy use of type.Any. This patch reintroduces types.Any, which is similar to types.AnyElement, but does not require all instances of types.Any in a function's argument list to have the same type (i.e. it's a true wildcard). Future patches will evaluate whether individual uses of types.AnyElement should really be using types.Any. For reference, types.Any should be used whenever the type of a expression is truly unconstrained. Informs: #136295 Release note: None #### tree: handle builtin overloads with types.Any variadic arguments Previously, variadic argument lists with types.Any variable arguments were being processed as types.AnyElement. An earlier patch changed these instances to types.AnyElement, correcting this error. This patch now takes the reintroduced types.Any (unconstrained wildcard) and makes it available for builtin functions. Much of the overload selection process is constraining untyped arguments to make variadic types.AnyElement work, so the implementation here is an early special case to avoid that processing. Informs: #136295 Release note: None #### builtins: change concat() to take types.Any arguments Previously, concat() took a variable argument list of types.AnyElement. This patch changes the argument type to types.Any and updates some related tests. Fixes: #136295 Release note (sql change): concat() no longer requires all arguments have the same type. #### builtins: change num_nulls()/num_notnulls() to take types.Any arguments Previously, num_nulls() and num_notnulls() required all arguments to have the same type. This patch removes that restriction. Epic: none Release note (sql change): num_nulls and num_notnulls() no longer require all arguments to have the same type. #### builtins: change format() to accept types.Any arguments Previously, format() required all arguments after the format string to have the same argument type. This patch removes that restriction. Release note (sql change): format() no longer requires all post-format string arguments to have the same type. #### builtins: change crdb_internal.datums_to_bytes() to accept types.Any Previously, crdb_internal.datums_to_bytes() required all arguments to have the same type. This patch removes that restriction to allow arguments of any type. Release note: None #### builtins: change concat_ws() to accept arguments of types.Any type Previously, concat_ws() required all arguments to be of type string, this patch changes the requirement such that the first argument (the delimiter) must be a string but that all follow-on arguments may be of any type. Release note (sql change): concat_ws() now accepts arguments of any type in the second and later positions (the separator must still be a string). #### builtins: change json_build_objects/array() to accept types.Any Previously, json_build_objects() and json_build_array() (and their binary variants) required that all arguments have the same type. This patch removes that requirement so that arguments can be of any type. Epic: none Release note (sql change): json_build_objects(), jsonb_build_objects(), json_build_array(), jsonb_build_array() no longer require that all arguments have the same type. #### builtins: change pg_column_size() to accepts arguments of types.Any Previously, pg_column_size() required that all arguments have the same type. This patch removes that restriction so that every argument can have a different type. Epic: none Release note (sql change): pg_column_size() no longer requires that all arguments have the same type. Co-authored-by: Matt White <[email protected]>
2 parents a72d15b + 141d2bb commit c6550af

File tree

15 files changed

+194
-60
lines changed

15 files changed

+194
-60
lines changed

docs/generated/sql/functions.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,9 @@
439439
</span></td><td>Immutable</td></tr>
440440
<tr><td><a name="least"></a><code>least(anyelement...) &rarr; anyelement</code></td><td><span class="funcdesc"><p>Returns the element with the lowest value.</p>
441441
</span></td><td>Immutable</td></tr>
442-
<tr><td><a name="num_nonnulls"></a><code>num_nonnulls(anyelement...) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Returns the number of nonnull arguments.</p>
442+
<tr><td><a name="num_nonnulls"></a><code>num_nonnulls(any...) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Returns the number of nonnull arguments.</p>
443443
</span></td><td>Immutable</td></tr>
444-
<tr><td><a name="num_nulls"></a><code>num_nulls(anyelement...) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Returns the number of null arguments.</p>
444+
<tr><td><a name="num_nulls"></a><code>num_nulls(any...) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Returns the number of null arguments.</p>
445445
</span></td><td>Immutable</td></tr></tbody>
446446
</table>
447447

@@ -1180,9 +1180,9 @@ available replica will error.</p>
11801180
</span></td><td>Immutable</td></tr>
11811181
<tr><td><a name="json_array_length"></a><code>json_array_length(json: jsonb) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Returns the number of elements in the outermost JSON or JSONB array.</p>
11821182
</span></td><td>Immutable</td></tr>
1183-
<tr><td><a name="json_build_array"></a><code>json_build_array(anyelement...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a possibly-heterogeneously-typed JSON or JSONB array out of a variadic argument list.</p>
1183+
<tr><td><a name="json_build_array"></a><code>json_build_array(any...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a possibly-heterogeneously-typed JSON or JSONB array out of a variadic argument list.</p>
11841184
</span></td><td>Stable</td></tr>
1185-
<tr><td><a name="json_build_object"></a><code>json_build_object(anyelement...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a JSON object out of a variadic argument list.</p>
1185+
<tr><td><a name="json_build_object"></a><code>json_build_object(any...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a JSON object out of a variadic argument list.</p>
11861186
</span></td><td>Stable</td></tr>
11871187
<tr><td><a name="json_each"></a><code>json_each(input: jsonb) &rarr; tuple{string AS key, jsonb AS value}</code></td><td><span class="funcdesc"><p>Expands the outermost JSON or JSONB object into a set of key/value pairs.</p>
11881188
</span></td><td>Immutable</td></tr>
@@ -1218,9 +1218,9 @@ available replica will error.</p>
12181218
</span></td><td>Immutable</td></tr>
12191219
<tr><td><a name="jsonb_array_length"></a><code>jsonb_array_length(json: jsonb) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Returns the number of elements in the outermost JSON or JSONB array.</p>
12201220
</span></td><td>Immutable</td></tr>
1221-
<tr><td><a name="jsonb_build_array"></a><code>jsonb_build_array(anyelement...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a possibly-heterogeneously-typed JSON or JSONB array out of a variadic argument list.</p>
1221+
<tr><td><a name="jsonb_build_array"></a><code>jsonb_build_array(any...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a possibly-heterogeneously-typed JSON or JSONB array out of a variadic argument list.</p>
12221222
</span></td><td>Stable</td></tr>
1223-
<tr><td><a name="jsonb_build_object"></a><code>jsonb_build_object(anyelement...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a JSON object out of a variadic argument list.</p>
1223+
<tr><td><a name="jsonb_build_object"></a><code>jsonb_build_object(any...) &rarr; jsonb</code></td><td><span class="funcdesc"><p>Builds a JSON object out of a variadic argument list.</p>
12241224
</span></td><td>Stable</td></tr>
12251225
<tr><td><a name="jsonb_each"></a><code>jsonb_each(input: jsonb) &rarr; tuple{string AS key, jsonb AS value}</code></td><td><span class="funcdesc"><p>Expands the outermost JSON or JSONB object into a set of key/value pairs.</p>
12261226
</span></td><td>Immutable</td></tr>
@@ -2912,9 +2912,9 @@ Can be used to define the tile bounds required by ST_AsMVTGeom to convert geomet
29122912
</span></td><td>Immutable</td></tr>
29132913
<tr><td><a name="compress"></a><code>compress(data: <a href="bytes.html">bytes</a>, codec: <a href="string.html">string</a>) &rarr; <a href="bytes.html">bytes</a></code></td><td><span class="funcdesc"><p>Compress <code>data</code> with the specified <code>codec</code> (<code>gzip</code>, ‘lz4’, ‘snappy’, 'zstd).</p>
29142914
</span></td><td>Immutable</td></tr>
2915-
<tr><td><a name="concat"></a><code>concat(anyelement...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Concatenates a comma-separated list of strings.</p>
2915+
<tr><td><a name="concat"></a><code>concat(any...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Concatenates a comma-separated list of strings.</p>
29162916
</span></td><td>Immutable</td></tr>
2917-
<tr><td><a name="concat_ws"></a><code>concat_ws(<a href="string.html">string</a>...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Uses the first argument as a separator between the concatenation of the subsequent arguments.</p>
2917+
<tr><td><a name="concat_ws"></a><code>concat_ws(<a href="string.html">string</a>, any...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Uses the first argument as a separator between the concatenation of the subsequent arguments.</p>
29182918
<p>For example <code>concat_ws('!','wow','great')</code> returns <code>wow!great</code>.</p>
29192919
</span></td><td>Immutable</td></tr>
29202920
<tr><td><a name="convert_from"></a><code>convert_from(str: <a href="bytes.html">bytes</a>, enc: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Decode the bytes in <code>str</code> into a string using encoding <code>enc</code>. Supports encodings ‘UTF8’ and ‘LATIN1’.</p>
@@ -2929,7 +2929,7 @@ Can be used to define the tile bounds required by ST_AsMVTGeom to convert geomet
29292929
</span></td><td>Immutable</td></tr>
29302930
<tr><td><a name="encode"></a><code>encode(data: <a href="bytes.html">bytes</a>, format: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Encodes <code>data</code> using <code>format</code> (<code>hex</code> / <code>escape</code> / <code>base64</code>).</p>
29312931
</span></td><td>Immutable</td></tr>
2932-
<tr><td><a name="format"></a><code>format(<a href="string.html">string</a>, anyelement...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Interprets the first argument as a format string similar to C sprintf and interpolates the remaining arguments.</p>
2932+
<tr><td><a name="format"></a><code>format(<a href="string.html">string</a>, any...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Interprets the first argument as a format string similar to C sprintf and interpolates the remaining arguments.</p>
29332933
</span></td><td>Stable</td></tr>
29342934
<tr><td><a name="from_ip"></a><code>from_ip(val: <a href="bytes.html">bytes</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Converts the byte string representation of an IP to its character string representation.</p>
29352935
</span></td><td>Immutable</td></tr>
@@ -3500,8 +3500,8 @@ may increase either contention or retry errors, or both.</p>
35003500
</span></td><td>Stable</td></tr>
35013501
<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>
35023502
</span></td><td>Stable</td></tr>
3503-
<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>
3504-
</span></td><td>Immutable</td></tr>
3503+
<tr><td><a name="pg_column_size"></a><code>pg_column_size(any...) &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>
3504+
</span></td><td>Stable</td></tr>
35053505
<tr><td><a name="pg_function_is_visible"></a><code>pg_function_is_visible(oid: oid) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Returns whether the function with the given OID belongs to one of the schemas on the search path.</p>
35063506
</span></td><td>Stable</td></tr>
35073507
<tr><td><a name="pg_get_function_arg_default"></a><code>pg_get_function_arg_default(func_oid: oid, arg_num: int4) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Get textual representation of a function argument’s default value. The second argument of this function is the argument number among all arguments (i.e. proallargtypes, <em>not</em> proargtypes), starting with 1, because that’s how information_schema.sql uses it. Currently, this always returns NULL, since CockroachDB does not support default values.</p>

pkg/kv/kvserver/replicate_queue_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ func filterRangeLog(
17571757
eventType kvserverpb.RangeLogEventType,
17581758
reason kvserverpb.RangeLogEventReason,
17591759
) ([]kvserverpb.RangeLogEvent_Info, error) {
1760-
return queryRangeLog(conn, `SELECT info FROM system.rangelog WHERE "rangeID" = $1 AND "eventType" = $2 AND info LIKE concat('%', $3, '%') ORDER BY timestamp ASC;`, rangeID, eventType.String(), reason)
1760+
return queryRangeLog(conn, `SELECT info FROM system.rangelog WHERE "rangeID" = $1 AND "eventType" = $2 AND info LIKE concat('%', $3::STRING, '%') ORDER BY timestamp ASC;`, rangeID, eventType.String(), reason)
17611761
}
17621762

17631763
func toggleReplicationQueues(tc *testcluster.TestCluster, active bool) {

pkg/sql/logictest/testdata/logic_test/builtin_function

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ SELECT concat('foo'::concat_enum, ' ', 64.532, ' ', 'baz'::concat_enum, ' ', 42,
203203
----
204204
foo 64.532 baz 42 f {"foo": "bar"} {1,2,3}
205205

206+
statement ok
207+
PREPARE concat_stmt AS SELECT concat("foo"."a", $1::STRING) FROM foo
208+
209+
query T
210+
EXECUTE concat_stmt(':')
211+
----
212+
1:
213+
206214
query T
207215
SELECT substr('RoacH', 2, 3)
208216
----
@@ -420,8 +428,10 @@ SELECT concat_ws(',', 'abcde', '2')
420428
----
421429
abcde,2
422430

423-
statement error unknown signature: concat_ws\(string, string, int, unknown, int\)
431+
query T
424432
SELECT concat_ws(',', 'abcde', 2, NULL, 22)
433+
----
434+
abcde,2,22
425435

426436
query T
427437
SELECT split_part('abc~@~def~@~ghi', '~@~', 2)
@@ -2672,6 +2682,19 @@ SELECT format('|%-*s|', -10, 'foo')
26722682
----
26732683
|foo |
26742684

2685+
statement
2686+
PREPARE format_stmt AS SELECT format('|%*s|', $1::INT, $2::STRING)
2687+
2688+
query T
2689+
EXECUTE format_stmt(10, 'foo')
2690+
----
2691+
| foo|
2692+
2693+
query T
2694+
EXECUTE format_stmt(-10, 'foo')
2695+
----
2696+
|foo |
2697+
26752698
# Escaping $ into \x24 only needed in testlogic or prepared statements
26762699
query T
26772700
SELECT format(E'Testing %3\x24s, %2\x24s, %1\x24s', 'one', 'two', 'three')
@@ -3055,6 +3078,33 @@ SELECT num_nulls(a, b), num_nonnulls(a, b) FROM nulls_test
30553078
1 1
30563079
2 0
30573080

3081+
statement ok
3082+
PREPARE nn_stmt AS SELECT num_nulls(42, $1::STRING, a, b),
3083+
num_nulls(b, $1, 42, a),
3084+
num_nulls(a, b, $1, 42),
3085+
num_nulls($1, a, b, 42),
3086+
num_nonnulls(42, $1, a, b),
3087+
num_nonnulls(b, $1, 42, a),
3088+
num_nonnulls(a, b, $1, 42),
3089+
num_nonnulls($1, a, b, 42)
3090+
FROM nulls_test
3091+
3092+
query IIIIIIII rowsort
3093+
EXECUTE nn_stmt(NULL)
3094+
----
3095+
1 1 1 1 3 3 3 3
3096+
2 2 2 2 2 2 2 2
3097+
2 2 2 2 2 2 2 2
3098+
3 3 3 3 1 1 1 1
3099+
3100+
query IIIIIIII rowsort
3101+
EXECUTE nn_stmt('foo')
3102+
----
3103+
0 0 0 0 4 4 4 4
3104+
1 1 1 1 3 3 3 3
3105+
1 1 1 1 3 3 3 3
3106+
2 2 2 2 2 2 2 2
3107+
30583108
subtest pb_to_json
30593109

30603110
query T

pkg/sql/logictest/testdata/logic_test/computed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ CREATE TABLE y (
357357
c TIMESTAMPTZ AS (a+ b) STORED
358358
)
359359

360-
statement error concat\(\): uuid_v4\(\): volatile functions are not allowed in STORED COMPUTED COLUMN
360+
statement error pq: concat\(\): error type checking resolved expression:: uuid_v4\(\): volatile functions are not allowed in STORED COMPUTED COLUMN
361361
CREATE TABLE y (
362362
a STRING AS (concat('foo', uuid_v4()::STRING)) STORED
363363
)

pkg/sql/logictest/testdata/logic_test/grant_table

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ test pg_catalog "char" type
122122
test pg_catalog "char"[] type admin ALL false
123123
test pg_catalog "char"[] type public USAGE false
124124
test pg_catalog "char"[] type root ALL false
125+
test pg_catalog any type admin ALL false
126+
test pg_catalog any type public USAGE false
127+
test pg_catalog any type root ALL false
125128
test pg_catalog anyarray type admin ALL false
126129
test pg_catalog anyarray type public USAGE false
127130
test pg_catalog anyarray type root ALL false
@@ -537,6 +540,8 @@ test pg_catalog "char" type admin ALL
537540
test pg_catalog "char" type root ALL false
538541
test pg_catalog "char"[] type admin ALL false
539542
test pg_catalog "char"[] type root ALL false
543+
test pg_catalog any type admin ALL false
544+
test pg_catalog any type root ALL false
540545
test pg_catalog anyarray type admin ALL false
541546
test pg_catalog anyarray type root ALL false
542547
test pg_catalog anyelement type admin ALL false
@@ -787,6 +792,8 @@ a pg_catalog "char" type admin ALL
787792
a pg_catalog "char" type root ALL false
788793
a pg_catalog "char"[] type admin ALL false
789794
a pg_catalog "char"[] type root ALL false
795+
a pg_catalog any type admin ALL false
796+
a pg_catalog any type root ALL false
790797
a pg_catalog anyarray type admin ALL false
791798
a pg_catalog anyarray type root ALL false
792799
a pg_catalog anyelement type admin ALL false
@@ -975,6 +982,8 @@ defaultdb pg_catalog "char" type admin ALL
975982
defaultdb pg_catalog "char" type root ALL false
976983
defaultdb pg_catalog "char"[] type admin ALL false
977984
defaultdb pg_catalog "char"[] type root ALL false
985+
defaultdb pg_catalog any type admin ALL false
986+
defaultdb pg_catalog any type root ALL false
978987
defaultdb pg_catalog anyarray type admin ALL false
979988
defaultdb pg_catalog anyarray type root ALL false
980989
defaultdb pg_catalog anyelement type admin ALL false
@@ -1163,6 +1172,8 @@ postgres pg_catalog "char" type admin ALL
11631172
postgres pg_catalog "char" type root ALL false
11641173
postgres pg_catalog "char"[] type admin ALL false
11651174
postgres pg_catalog "char"[] type root ALL false
1175+
postgres pg_catalog any type admin ALL false
1176+
postgres pg_catalog any type root ALL false
11661177
postgres pg_catalog anyarray type admin ALL false
11671178
postgres pg_catalog anyarray type root ALL false
11681179
postgres pg_catalog anyelement type admin ALL false
@@ -1359,6 +1370,8 @@ test pg_catalog "char" type admin ALL
13591370
test pg_catalog "char" type root ALL false
13601371
test pg_catalog "char"[] type admin ALL false
13611372
test pg_catalog "char"[] type root ALL false
1373+
test pg_catalog any type admin ALL false
1374+
test pg_catalog any type root ALL false
13621375
test pg_catalog anyarray type admin ALL false
13631376
test pg_catalog anyarray type root ALL false
13641377
test pg_catalog anyelement type admin ALL false

pkg/sql/logictest/testdata/logic_test/json_builtins

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,20 @@ SELECT json_build_object('a', '0100110'::varbit)
562562
----
563563
{"a": "0100110"}
564564

565+
statement ok
566+
CREATE TABLE foo (a INT);
567+
568+
statement ok
569+
INSERT INTO foo VALUES (42);
570+
571+
statement ok
572+
PREPARE jbo_stmt AS SELECT json_build_object('a', a, 'b', $1::STRING) FROM foo;
573+
574+
query T
575+
EXECUTE jbo_stmt(':');
576+
----
577+
{"a": 42, "b": ":"}
578+
565579
# Regression for an internal error when using an enum and void in the key.
566580
statement ok
567581
CREATE TYPE e AS ENUM ('e');
@@ -713,6 +727,14 @@ SELECT json_build_array(1, '1'::JSON, 1.2, NULL, ARRAY['x', 'y'])
713727
----
714728
[1, 1, 1.2, null, ["x", "y"]]
715729

730+
statement ok
731+
PREPARE jba_stmt AS SELECT json_build_array(a, $1::STRING) FROM foo;
732+
733+
query T
734+
EXECUTE jba_stmt(':');
735+
----
736+
[42, ":"]
737+
716738
query T
717739
SELECT jsonb_build_array()
718740
----

0 commit comments

Comments
 (0)