Skip to content

Commit

Permalink
cast: set volatility of casts to/from TEXT and NAME to leak-proof
Browse files Browse the repository at this point in the history
In Postgres 14, some casts which were previously immutable and not
leak-proof are now leak-proof. This commit updates the volatility of
casts to and from TEXT and NAME to leak-proof to match Postgres. This
should aid the optimizer in decorrelating more subqueries. This is not
backward incompatible because it is less restrictive and should not
change the behavior of any users' existing queries.

There are many other casts that can be changed to leak-proof, but our
implementations of those casts need to be audited to ensure that they
cannot err (one of the requirements for leak-proof). I leave this as
future work.

We must also take care with assignment casts, which currently use the
same volatility as a normal cast. Some casts which cannot err and are
leak-proof can err as an assignment cast, so the assignment cast cannot
be leak-proof. For example, a cast like `'foo'::VARCHAR(1)` does not
err, but an assignment cast with the same inputs will err because the
value does not fit into the target type's width. To handle cases like
this, we may need to label each cast with two volatilities, one for
regular casts and one for assignment casts.

Release note: None
  • Loading branch information
mgartner committed May 24, 2022
1 parent 9dcebeb commit b5e68e5
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 4 deletions.
4 changes: 2 additions & 2 deletions pkg/sql/sem/cast/cast_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
},
oid.T_name: {
oid.T_bpchar: {MaxContext: ContextAssignment, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
oid.T_text: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
oid.T_text: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.LeakProof},
oid.T_varchar: {MaxContext: ContextAssignment, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
// Automatic I/O conversions to string types.
oid.T_char: {MaxContext: ContextAssignment, origin: ContextOriginAutomaticIOConversion, Volatility: volatility.Immutable},
Expand Down Expand Up @@ -720,7 +720,7 @@ var castMap = map[oid.Oid]map[oid.Oid]Cast{
oid.T_bpchar: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
oid.T_char: {MaxContext: ContextAssignment, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
oidext.T_geometry: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
oid.T_name: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Immutable},
oid.T_name: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.LeakProof},
oid.T_regclass: {MaxContext: ContextImplicit, origin: ContextOriginPgCast, Volatility: volatility.Stable},
// We include a TEXT->TEXT entry to mimic the VARCHAR->VARCHAR entry
// that is included in the pg_cast table. Postgres doesn't include a
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/sem/cast/testdata/pg_cast_dump.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ castsource|casttarget|provolatile|proleakproof|castcontext|pg_version
18|25|i|f|i|13.5
18|1042|i|f|a|13.5
18|1043|i|f|a|13.5
19|25|i|f|i|13.5
19|25|i|t|i|14.2
19|1042|i|f|a|13.5
19|1043|i|f|a|13.5
20|21|i|f|a|13.5
Expand Down Expand Up @@ -57,7 +57,7 @@ castsource|casttarget|provolatile|proleakproof|castcontext|pg_version
23|1700|i|f|i|13.5
24|20|i|f|a|13.5
25|18|i|f|a|13.5
25|19|i|f|i|13.5
25|19|i|t|i|14.2
25|142|s|f|e|13.5
25|2205|s|f|i|13.5
26|20|i|f|a|13.5
Expand Down

0 comments on commit b5e68e5

Please sign in to comment.