Skip to content

Commit 603321d

Browse files
committed
added GeneralizeTypes function
1 parent 48f6247 commit 603321d

File tree

3 files changed

+23
-18
lines changed

3 files changed

+23
-18
lines changed

sql/expression/function/if.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,7 @@ func (f *If) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
9595

9696
// Type implements the Expression interface.
9797
func (f *If) Type() sql.Type {
98-
// if either type is string type, this should be a string type, regardless need to promote
99-
typ1 := f.ifTrue.Type()
100-
typ2 := f.ifFalse.Type()
101-
if types.IsText(typ1) || types.IsText(typ2) {
102-
return types.Text
103-
}
104-
105-
if typ1 == types.Null {
106-
return typ2.Promote()
107-
}
108-
return typ1.Promote()
98+
return types.GeneralizeTypes(f.ifTrue.Type(), f.ifFalse.Type())
10999
}
110100

111101
// CollationCoercibility implements the interface sql.CollationCoercible.

sql/expression/function/ifnull.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,7 @@ func (f *IfNull) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
6969

7070
// Type implements the Expression interface.
7171
func (f *IfNull) Type() sql.Type {
72-
if types.IsNull(f.LeftChild) {
73-
if types.IsNull(f.RightChild) {
74-
return types.Null
75-
}
76-
return f.RightChild.Type()
77-
}
78-
return f.LeftChild.Type()
72+
return types.GeneralizeTypes(f.LeftChild.Type(), f.RightChild.Type())
7973
}
8074

8175
// CollationCoercibility implements the interface sql.CollationCoercible.

sql/types/conversion.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,3 +554,24 @@ func TypesEqual(a, b sql.Type) bool {
554554
return a.Equals(b)
555555
}
556556
}
557+
558+
// GeneralizeTypes returns the more "general" of two types as defined by
559+
// https://dev.mysql.com/doc/refman/8.4/en/flow-control-functions.html#function_if and
560+
// https://dev.mysql.com/doc/refman/8.4/en/flow-control-functions.html#function_ifnull
561+
// TODO: Currently returns the most general type. Update to match MySQL (pick the more general of the two given types)
562+
func GeneralizeTypes(a, b sql.Type) sql.Type {
563+
if IsText(a) || IsText(b) {
564+
// TODO: handle case-sensitive strings
565+
return Text
566+
}
567+
568+
if IsFloat(a) || IsFloat(b) {
569+
return Float64
570+
}
571+
572+
if a == Null {
573+
return b.Promote()
574+
}
575+
576+
return a.Promote()
577+
}

0 commit comments

Comments
 (0)