Skip to content

Commit

Permalink
sql: Allow DEFAULT/ON UPDATE types that can be assignment-cast
Browse files Browse the repository at this point in the history
Release note (sql change): A column's DEFAULT/ON UPDATE clause
can now have a type that differs from the column type,as long as
that type can be assignment-cast into the column's type. This
increases our PostgreSQL compatibility.
  • Loading branch information
e-mbrown committed May 5, 2022
1 parent 4d1f40b commit fccdc69
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
22 changes: 21 additions & 1 deletion pkg/sql/catalog/tabledesc/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/catalog/schemaexpr"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
"github.com/cockroachdb/cockroach/pkg/sql/sem/cast"
"github.com/cockroachdb/cockroach/pkg/sql/sem/eval"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/sem/volatility"
Expand Down Expand Up @@ -145,13 +146,22 @@ func MakeColumnDefDescs(
col.Type = resType

if d.HasDefaultExpr() {
var innerErr error
// Verify the default expression type is compatible with the column type
// and does not contain invalid functions.
ret.DefaultExpr, err = schemaexpr.SanitizeVarFreeExpr(
ctx, d.DefaultExpr.Expr, resType, "DEFAULT", semaCtx, volatility.Volatile,
)
if err != nil {
return nil, err
// Check if the default expression type can be assignment-cast into the
// column type. If it can allow the default and column type to differ.
ret.DefaultExpr, innerErr = d.DefaultExpr.Expr.TypeCheck(ctx, semaCtx, types.Any)
if innerErr != nil {
return nil, err
}
if ok := cast.ValidCast(resType, ret.DefaultExpr.ResolvedType(), cast.ContextAssignment); !ok {
return nil, err
}
}

// Keep the type checked expression so that the type annotation gets
Expand All @@ -167,10 +177,20 @@ func MakeColumnDefDescs(
if d.HasOnUpdateExpr() {
// Verify the on update expression type is compatible with the column type
// and does not contain invalid functions.
var innerErr error
ret.OnUpdateExpr, err = schemaexpr.SanitizeVarFreeExpr(
ctx, d.OnUpdateExpr.Expr, resType, "ON UPDATE", semaCtx, volatility.Volatile,
)
if err != nil {
// Check if the on update expression type can be assignment-cast into the
// column type. If it can allow the default and column type to differ.
ret.OnUpdateExpr, innerErr = d.OnUpdateExpr.Expr.TypeCheck(ctx, semaCtx, types.Any)
if innerErr != nil {
return nil, err
}
if ok := cast.ValidCast(resType, ret.OnUpdateExpr.ResolvedType(), cast.ContextAssignment); !ok {
return nil, err
}
return nil, err
}

Expand Down
22 changes: 22 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/cast
Original file line number Diff line number Diff line change
Expand Up @@ -1401,3 +1401,25 @@ select CASE WHEN false THEN 1::REGTYPE ELSE 2::REGNAMESPACE END;
select CASE WHEN false THEN 1::REGTYPE ELSE 2::REGPROC END;
select CASE WHEN false THEN 1::REGTYPE ELSE 2::REGPROCEDURE END;
select CASE WHEN false THEN 1::REGTYPE ELSE 2::REGROLE END;


# Test that default/on update expression differing from column type
statement ok
CREATE TABLE def_assn_cast (
a INT4 DEFAULT 1.0::FLOAT4,
b VARCHAR DEFAULT 'true'::BOOL,
c NAME DEFAULT 'foo'::BPCHAR,
d JSONB DEFAULT 'null'::CHAR,
)

# Due to cast context we support cases that Postgres doesn't
statement ok
CREATE TABLE nonpg_assn_cast (
a BOOL DEFAULT 'foo',
b JSONB DEFAULT 'null'::CHAR,
)

statement error pq: expected DEFAULT expression to have type ., but . has type .
CREATE TABLE def_assn_cast (
a INT4 DEFAULT 1.0::BOOL
)

0 comments on commit fccdc69

Please sign in to comment.