Skip to content

Commit 918e88d

Browse files
author
James Cor
committed
clean up
1 parent 1ddf983 commit 918e88d

File tree

1 file changed

+5
-67
lines changed

1 file changed

+5
-67
lines changed

sql/expression/in.go

Lines changed: 5 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -59,79 +59,17 @@ func NewInTuple(left sql.Expression, right sql.Expression) *InTuple {
5959
return &InTuple{BinaryExpressionStub{left, right}}
6060
}
6161

62-
// validateAndEvalRightTuple will evaluate the right tuple, check if leftType and the right Tuple are comparable,
63-
// determine what type to use to compare the two sides, and indicate if right Tuple contains any NULL elements.
64-
// Returns
65-
// - slice of the evaluated elements
66-
// - sql.Type to convert elements to before hashing
67-
// - bool indicating if there are null elements
68-
// - error
69-
func validateAndEvalRightTuple(ctx *sql.Context, lType sql.Type, right Tuple, row sql.Row) ([]any, sql.Type, bool, error) {
70-
// The NULL handling for IN expressions is tricky. According to
71-
// https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_in:
72-
// To comply with the SQL standard, IN() returns NULL not only if the expression on the left hand side is NULL, but
73-
// also if no match is found in the list and one of the expressions in the list is NULL.
74-
75-
// If left is StringType and ANY of the right is NumberType, then we should use Double Type for comparison
76-
// If left is NumberType and ANT of the left is StringType, then we should use Double Type for comparison
77-
lColCount := types.NumColumns(lType)
78-
lIsNumType := types.IsNumber(lType)
79-
lIsStrType := types.IsText(lType)
80-
var rHasNumType, rHasStrType, rHasNull bool
81-
rVals := make([]any, len(right))
82-
for i, el := range right {
83-
rType := el.Type()
84-
85-
// Nested tuples must have the same number of columns
86-
rColCount := types.NumColumns(rType)
87-
if rColCount != lColCount {
88-
return nil, nil, false, sql.ErrInvalidOperandColumns.New(lColCount, types.NumColumns(el.Type()))
89-
}
90-
91-
if types.IsNumber(rType) {
92-
rHasNumType = true
93-
} else if types.IsText(rType) {
94-
rHasStrType = true
95-
}
96-
97-
// Null elements are not hashed into the Tuple Map
98-
if types.IsNullType(rType) {
99-
rHasNull = true
100-
continue
101-
}
102-
v, err := el.Eval(ctx, row)
103-
if err != nil {
104-
return nil, nil, false, err
105-
}
106-
if v == nil {
107-
rHasNull = true
108-
continue
109-
}
110-
111-
rVals[i] = v
112-
}
113-
114-
var cmpType sql.Type
115-
if (lIsStrType && rHasNumType) || (lIsNumType && rHasStrType) {
116-
cmpType = types.Float64
117-
} else if types.IsEnum(lType) || types.IsSet(lType) || types.IsText(lType) {
118-
cmpType = lType
119-
} else {
120-
cmpType = lType
121-
for _, el := range right {
122-
cmpType = types.GetCompareType(cmpType, el.Type())
123-
}
124-
}
125-
126-
return rVals, cmpType, rHasNull, nil
127-
}
128-
12962
// Eval implements the Expression interface.
13063
func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
13164
lVal, err := in.Left().Eval(ctx, row)
13265
if err != nil {
13366
return nil, err
13467
}
68+
69+
// The NULL handling for IN expressions is tricky. According to
70+
// https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_in:
71+
// To comply with the SQL standard, IN() returns NULL not only if the expression on the left hand side is NULL, but
72+
// also if no match is found in the list and one of the expressions in the list is NULL.
13573
if lVal == nil {
13674
return nil, nil
13775
}

0 commit comments

Comments
 (0)