Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make polymorphic variadic builtin functions heterogeneous #140643

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

mw5h
Copy link
Contributor

@mw5h mw5h commented Feb 6, 2025

tree: polymorphic variadic builtin functions are now heterogeneous

Previously, builtin functions with the parameter type VariadicType{VarType: types.Any} required that all variable arguments have the same type. This is what Postgres documents as its behavior, but the reality is that Postgres polymorphic builtins accept any heterogeneous arguments. This patch changes our overload handling to allow heterogeneous arguments to CRDB builtins.

Fixes: #136295
Release notes (bug fix): PREPARE now accepts heterogeneous arguments to the concat, json_build_object, jsonb_build_object, json_build_array, jsonb_build_array functions.

builtins: support polymorphic variadic arguments in concat_ws()

Previously, concat_ws took a variable length argument list of strings. Postgres allows anyelement data types for concat_ws(). Rewrite concat_ws() so that it takes a fixed string first argument followed by a variable list of anyelement arguments.

Release note (sql change): The concat_ws builtin function will now accept non-string arguments in the second and later positions.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@mw5h mw5h force-pushed the variadic_builtins branch from 8d3e74d to e120af7 Compare February 7, 2025 16:18
@mw5h mw5h changed the title make polymorphic variadic builtin fucntions heeterogeneous make polymorphic variadic builtin functions heterogeneous Feb 7, 2025
mw5h added 2 commits February 7, 2025 10:34
Previously, builtin functions with the parameter type
VariadicType{VarType: types.Any} required that all variable arguments
have the same type. This is what Postgres documents as its behavior, but
the reality is that Postgres polymorphic builtins accept any
heterogeneous arguments. This patch changes our overload handling to
allow heterogeneous arguments to CRDB builtins.

Fixes: cockroachdb#136295
Release notes (bug fix): PREPARE now accepts heterogeneous arguments to
the concat, json_build_object, jsonb_build_object, json_build_array,
jsonb_build_array functions.
Previously, concat_ws took a variable length argument list of strings.
Postgres allows anyelement data types for concat_ws(). Rewrite
concat_ws() so that it takes a fixed string first argument followed by a
variable list of anyelement arguments.

Epic: none
Release note (sql change): The concat_ws builtin function will now
accept non-string arguments in the second and later positions.
@mw5h mw5h force-pushed the variadic_builtins branch from e120af7 to b2d205c Compare February 7, 2025 18:34
By making polymorphic system builtin functions heterogeneous, we open
ourselves to the possibility that a prepared statement will have untyped
placeholders. This change treats those placeholders as string data (how
very MySQL of us).

Fixes: cockroachdb#136295
Release note (sql change): Untyped data is now accepted over the wire
protocol.
@mw5h mw5h force-pushed the variadic_builtins branch from b2d205c to f9ac168 Compare February 7, 2025 18:46
@mw5h mw5h requested a review from michae2 February 7, 2025 19:04
@mw5h mw5h marked this pull request as ready for review February 7, 2025 19:55
@mw5h mw5h requested review from a team as code owners February 7, 2025 19:55
Copy link
Collaborator

@michae2 michae2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 7 of 7 files at r1, 4 of 4 files at r2.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @mw5h)


-- commits line 20 at r2:
after that slack conversation, I think we need to be careful about 'any' vs 'anyelement', and this should be 'any'


pkg/sql/pgwire/pgwirebase/encoding.go line 861 at r3 (raw file):

	}
	switch id {
	case oid.T_text, oid.T_varchar, oid.T_unknown, oid.T_anyelement:

does PG have a different oid type for any?


pkg/sql/sem/tree/overload.go line 1208 at r1 (raw file):

	if numOverloads == 1 {
		routineType, _, _ := s.overloads[0].outParamInfo()
		if vt, ok := s.params[0].(VariadicType); ok && vt.VarType == types.Any && routineType == BuiltinRoutine {

as discussed in slack, instead of checking routineType == BuiltinRoutine, we might want to divide types.Any from a new types.AnyElement, since they seem to be different pseudo-types in PG


pkg/sql/sem/tree/overload.go line 1429 at r1 (raw file):

		// operators).
		for i, ok := s.placeholderIdxs.Next(0); ok; i, ok = s.placeholderIdxs.Next(i + 1) {
			if s.typedExprs[i] != nil && heterogeneousBuiltin {

Do we need this check? (since homogeneousTyp is set to nil when heterogeneousBuiltin is set to true)

Copy link
Contributor Author

@mw5h mw5h left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @michae2)


pkg/sql/pgwire/pgwirebase/encoding.go line 861 at r3 (raw file):

Previously, michae2 (Michael Erickson) wrote…

does PG have a different oid type for any?

Yeah, oid.T_any exists (in both code bases).


pkg/sql/sem/tree/overload.go line 1208 at r1 (raw file):

Previously, michae2 (Michael Erickson) wrote…

as discussed in slack, instead of checking routineType == BuiltinRoutine, we might want to divide types.Any from a new types.AnyElement, since they seem to be different pseudo-types in PG

Yikes. So, you're suggesting that we change the current types.Any into types.AnyElement and then introduce a new types.Any that is only used for builtin functions?


pkg/sql/sem/tree/overload.go line 1429 at r1 (raw file):

Previously, michae2 (Michael Erickson) wrote…

Do we need this check? (since homogeneousTyp is set to nil when heterogeneousBuiltin is set to true)

homgoneousTyp can be set again at line 1396. I frankly don't like that very much (I don't like to reassign variables if possible), but I'm a bit afraid to monkey too much with this code because the knock-on effects can be subtle.

@mw5h mw5h marked this pull request as draft February 8, 2025 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants