Skip to content

Commit

Permalink
opt: fix BPCHAR type and CASE typing
Browse files Browse the repository at this point in the history
This commit addresses inconsistencies from Postgres' behavior. First, it
makes the `BPCHAR` type distinct from `CHAR`. The former is a
blank-padded character type with no type width, meaning that it could
have any length. The latter is a blank-padded character type with a type
width of exactly 1 - it is essentially an alias of `CHAR(1)`.
Previously, a column of type `BPCHAR` behaved the same as a column of
type `CHAR(1)` - it enforced a length limit of 1.

Second, the typing of `CASE` and `CASE`-like expressions has been fixed.
The branches of these conditionals is no longer forced to have the same
type-width.

Fixes cockroachdb#127889
Fixes cockroachdb#108360

Release note (bug fix): A bug has been fixed that caused incorrect
evaluation of `CASE`, `COALESCE`, and `IF` expressions with branches
producing fixed-width string-like types, such as `CHAR`. In addition,
the `BPCHAR` type has been fixed so that it no longer incorrectly
imposes a length limit of 1.
  • Loading branch information
mgartner committed Sep 17, 2024
1 parent d177175 commit bb2563d
Show file tree
Hide file tree
Showing 28 changed files with 6,537 additions and 66 deletions.
620 changes: 620 additions & 0 deletions pkg/ccl/backupccl/data_driven_generated_test.go

Large diffs are not rendered by default.

174 changes: 174 additions & 0 deletions pkg/ccl/kvccl/kvtenantccl/upgradeinterlockccl/generated_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/bpchar
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
query T
SELECT 'foo'::BPCHAR
----
foo

statement ok
CREATE TABLE t (c BPCHAR PRIMARY KEY, FAMILY (c))

statement ok
INSERT INTO t VALUES ('foo'), ('ba'), ('c'), ('foobarbaz')

query T rowsort
SELECT c FROM t
----
foo
ba
c
foobarbaz

query T
SELECT create_statement FROM [SHOW CREATE TABLE t]
----
CREATE TABLE public.t (
c BPCHAR NOT NULL,
CONSTRAINT t_pkey PRIMARY KEY (c ASC),
FAMILY fam_0_c (c)
)
47 changes: 47 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/case
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# LogicTest: local

# Regression test for #127889. CASE-like expressions should not impose type
# widths of one branch on other branches.
subtest regression_127889

query T
SELECT CASE WHEN true THEN 'foo'::TEXT ELSE 'b'::CHAR END
----
foo

query T
SELECT COALESCE(NULL::CHAR, 'bar'::CHAR(2))
----
ba

query T
SELECT IF(false, 'foo'::CHAR, 'bar'::CHAR(2))
----
ba

query T
SELECT CASE WHEN false THEN 'b'::CHAR ELSE 'foo'::TEXT END
----
foo

query T
SELECT (CASE WHEN false THEN 'b'::CHAR ELSE 'foo'::TEXT END)::CHAR
----
f

query T
SELECT (CASE WHEN false THEN 'b'::CHAR ELSE 'foo'::TEXT END)::BPCHAR
----
foo

query R
SELECT CASE WHEN true THEN 1.2345::DECIMAL(5, 4) ELSE NULL::DECIMAL(10, 2) END
----
1.2345

query R
SELECT CASE WHEN false THEN NULL::DECIMAL(10, 2) ELSE 1.2345::DECIMAL(5, 4) END
----
1.2345

subtest end
2 changes: 1 addition & 1 deletion pkg/sql/logictest/testdata/logic_test/cast
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,7 @@ CREATE TABLE def_assn_cast (
id INT4,
a INT4 DEFAULT 1.0::FLOAT4,
b VARCHAR DEFAULT 'true'::BOOL,
c NAME DEFAULT 'foo'::BPCHAR
c NAME DEFAULT 'foo'::CHAR
)

statement ok
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/logictest/testdata/logic_test/decimal
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ NaN NaN NaN NaN NaN
# TODO(drewk): There are a few differences vs postgres in the number of decimal
# places and negative zeros.
query RRRRR
WITH v(id, x) AS (VALUES (1, '0'::numeric), (2, '1'::numeric), (3, '-1'::numeric),
WITH v(id, x) AS (VALUES (1, '0'::numeric), (2, '1'::numeric), (3, '-1'::numeric),
(4, '4.2'::numeric), (5, 'inf'::numeric), (6, '-inf'::numeric), (7, 'nan'::numeric)
)
SELECT x1, x2,
Expand Down
30 changes: 30 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/drop_function
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,33 @@ DROP FUNCTION f114677;

statement error pgcode 42883 unknown function: f114677\(\)
SHOW CREATE FUNCTION f114677;

statement ok
CREATE FUNCTION f_char(c CHAR) RETURNS INT LANGUAGE SQL AS 'SELECT 1'

statement ok
DROP FUNCTION f_char(BPCHAR)

statement ok
CREATE FUNCTION f_char(c CHAR(2)) RETURNS INT LANGUAGE SQL AS 'SELECT 1'

statement ok
DROP FUNCTION f_char(BPCHAR)

statement ok
CREATE FUNCTION f_char(c BPCHAR) RETURNS INT LANGUAGE SQL AS 'SELECT 1'

statement ok
DROP FUNCTION f_char(BPCHAR)

statement ok
CREATE FUNCTION f_char(c BPCHAR) RETURNS INT LANGUAGE SQL AS 'SELECT 1'

statement ok
DROP FUNCTION f_char(CHAR)

statement ok
CREATE FUNCTION f_char(c BPCHAR) RETURNS INT LANGUAGE SQL AS 'SELECT 1'

statement ok
DROP FUNCTION f_char(CHAR(2))
Loading

0 comments on commit bb2563d

Please sign in to comment.