Skip to content

Commit 45dce2d

Browse files
committed
sql: fix CITEXT formatting panic
CITEXT was taking the default formatting path of `CollatedStringFamily` which formats datums with the COLLATE expression, causing a panic. This PR fixes this by separating CITEXT from the default collated string formatting path. Fixes: #149876 Epic: None Release note: None
1 parent 99d44a0 commit 45dce2d

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

pkg/sql/logictest/testdata/logic_test/citext

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,8 @@ citext
209209

210210
query error syntax error
211211
CREATE TABLE citext_with_width_tbl (a CITEXT(10));
212+
213+
query T
214+
SELECT cast('test'::TEXT AS CITEXT);
215+
----
216+
test

pkg/sql/sem/tree/expr.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ import (
1212
"strconv"
1313

1414
"github.com/cockroachdb/cockroach/pkg/sql/lex"
15+
"github.com/cockroachdb/cockroach/pkg/sql/oidext"
1516
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
1617
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
1718
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree/treebin"
1819
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree/treecmp"
1920
"github.com/cockroachdb/cockroach/pkg/sql/types"
21+
"github.com/cockroachdb/cockroach/pkg/util/buildutil"
2022
"github.com/cockroachdb/cockroach/pkg/util/iterutil"
2123
"github.com/cockroachdb/errors"
2224
"github.com/cockroachdb/redact"
25+
"github.com/lib/pq/oid"
2326
)
2427

2528
// Expr represents an expression.
@@ -1522,7 +1525,7 @@ func (node *CastExpr) Format(ctx *FmtCtx) {
15221525
ctx.WriteString("CAST(")
15231526
ctx.FormatNode(node.Expr)
15241527
ctx.WriteString(" AS ")
1525-
if typ, ok := GetStaticallyKnownType(node.Type); ok && typ.Family() == types.CollatedStringFamily {
1528+
if typ, ok := GetStaticallyKnownType(node.Type); ok && typeDisplaysCollate(typ) {
15261529
// Need to write closing parentheses before COLLATE clause, so create
15271530
// equivalent string type without the locale.
15281531
strTyp := types.MakeScalar(
@@ -1542,6 +1545,25 @@ func (node *CastExpr) Format(ctx *FmtCtx) {
15421545
}
15431546
}
15441547

1548+
// typeDisplaysCollate is a helper function that returns true if the type
1549+
// displays a COLLATE clause when formatted.
1550+
func typeDisplaysCollate(typ *types.T) bool {
1551+
if typ.Family() == types.CollatedStringFamily {
1552+
switch typ.Oid() {
1553+
case oid.T_text, oid.T_varchar, oid.T_char, oid.T_name, oid.T_bpchar:
1554+
return true
1555+
case oidext.T_citext:
1556+
return false
1557+
default:
1558+
if buildutil.CrdbTestBuild {
1559+
panic(errors.AssertionFailedf("unexpected oid %d for collated string", typ.Oid()))
1560+
}
1561+
return false
1562+
}
1563+
}
1564+
return false
1565+
}
1566+
15451567
// NewTypedCastExpr returns a new CastExpr that is verified to be well-typed.
15461568
func NewTypedCastExpr(expr TypedExpr, typ *types.T) *CastExpr {
15471569
node := &CastExpr{Expr: expr, Type: typ, SyntaxMode: CastShort}

pkg/sql/sem/tree/pretty.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ func (node *CastExpr) doc(p *PrettyCfg) pretty.Doc {
10511051
typ,
10521052
)
10531053
default:
1054-
if nTyp, ok := GetStaticallyKnownType(node.Type); ok && nTyp.Family() == types.CollatedStringFamily {
1054+
if nTyp, ok := GetStaticallyKnownType(node.Type); ok && typeDisplaysCollate(nTyp) {
10551055
// COLLATE clause needs to go after CAST expression, so create
10561056
// equivalent string type without the locale to get name of string
10571057
// type without the COLLATE.
@@ -1080,7 +1080,7 @@ func (node *CastExpr) doc(p *PrettyCfg) pretty.Doc {
10801080
),
10811081
)
10821082

1083-
if nTyp, ok := GetStaticallyKnownType(node.Type); ok && nTyp.Family() == types.CollatedStringFamily {
1083+
if nTyp, ok := GetStaticallyKnownType(node.Type); ok && typeDisplaysCollate(nTyp) {
10841084
ret = pretty.Fold(pretty.ConcatSpace,
10851085
ret,
10861086
pretty.Keyword("COLLATE"),

0 commit comments

Comments
 (0)