Skip to content

Commit

Permalink
feat: fix translation logic to fail translation for conversions not s…
Browse files Browse the repository at this point in the history
…upported (#12111) (#12118)

Signed-off-by: Manan Gupta <[email protected]>

Signed-off-by: Manan Gupta <[email protected]>

Signed-off-by: Manan Gupta <[email protected]>
  • Loading branch information
GuptaManan100 authored Jan 19, 2023
1 parent 9a5f084 commit b9fd93e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 8 deletions.
15 changes: 15 additions & 0 deletions go/test/endtoend/vtgate/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -860,3 +860,18 @@ func TestIntervalWithMathFunctions(t *testing.T) {
utils.AssertMatches(t, conn, "select '2020-01-01' + interval month(DATE_SUB(FROM_UNIXTIME(1234), interval 1 month))-1 month", `[[CHAR("2020-12-01")]]`)
utils.AssertMatches(t, conn, "select DATE_ADD(MIN(FROM_UNIXTIME(1673444922)),interval -DAYOFWEEK(MIN(FROM_UNIXTIME(1673444922)))+1 DAY)", `[[DATETIME("2023-01-08 13:48:42")]]`)
}

// TestCast tests the queries that contain the cast function.
func TestCast(t *testing.T) {
defer cluster.PanicHandler(t)
ctx := context.Background()
conn, err := mysql.Connect(ctx, &vtParams)
require.NoError(t, err)
defer conn.Close()

utils.AssertMatches(t, conn, "select cast('2023-01-07 12:34:56' as date) limit 1", `[[DATE("2023-01-07")]]`)
utils.AssertMatches(t, conn, "select cast('2023-01-07 12:34:56' as date)", `[[DATE("2023-01-07")]]`)
utils.AssertMatches(t, conn, "select cast('3.2' as float)", `[[FLOAT32(3.2)]]`)
utils.AssertMatches(t, conn, "select cast('3.2' as double)", `[[FLOAT64(3.2)]]`)
utils.AssertMatches(t, conn, "select cast('3.2' as unsigned)", `[[UINT64(3)]]`)
}
14 changes: 6 additions & 8 deletions go/vt/vtgate/evalengine/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ type (
)

func (c *ConvertExpr) unsupported() {
throwEvalError(c.returnUnsupportedError())
}

func (c *ConvertExpr) returnUnsupportedError() error {
var err error
switch {
case c.HasLength && c.HasScale:
Expand All @@ -48,7 +52,7 @@ func (c *ConvertExpr) unsupported() {
default:
err = vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "Unsupported type conversion: %s", c.Type)
}
throwEvalError(err)
return err
}

func (c *ConvertExpr) eval(env *ExpressionEnv, result *EvalResult) {
Expand Down Expand Up @@ -86,15 +90,9 @@ func (c *ConvertExpr) eval(env *ExpressionEnv, result *EvalResult) {
case "FLOAT":
if c.HasLength {
switch p := c.Length; {
case p <= 24:
c.unsupported()
case p <= 53:
result.makeFloat()
default:
case p > 53:
throwEvalError(vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Too-big precision %d specified for 'CONVERT'. Maximum is 53.", p))
}
} else {
c.unsupported()
}
c.unsupported()
case "SIGNED", "SIGNED INTEGER":
Expand Down
5 changes: 5 additions & 0 deletions go/vt/vtgate/evalengine/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,11 @@ func translateConvertExpr(expr sqlparser.Expr, convertType *sqlparser.ConvertTyp
if err != nil {
return nil, err
}
case "BINARY", "DOUBLE", "REAL", "SIGNED", "SIGNED INTEGER", "UNSIGNED", "UNSIGNED INTEGER":
// Supported types for conv expression
default:
// For unsupported types, we should return an error on translation instead of returning an error on runtime.
return nil, convert.returnUnsupportedError()
}

return &convert, nil
Expand Down
34 changes: 34 additions & 0 deletions go/vt/vtgate/evalengine/translate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,37 @@ func TestEvaluateTuple(t *testing.T) {
})
}
}

// TestTranslationFailures tests that translation fails for functions that we don't support evaluation for.
func TestTranslationFailures(t *testing.T) {
testcases := []struct {
expression string
expectedErr string
}{
{
expression: "cast('2023-01-07 12:34:56' as date)",
expectedErr: "Unsupported type conversion: DATE",
}, {
expression: "cast('2023-01-07 12:34:56' as datetime(5))",
expectedErr: "Unsupported type conversion: DATETIME(5)",
}, {
expression: "cast('3.4' as FLOAT)",
expectedErr: "Unsupported type conversion: FLOAT",
}, {
expression: "cast('3.4' as FLOAT(3))",
expectedErr: "Unsupported type conversion: FLOAT(3)",
},
}

for _, testcase := range testcases {
t.Run(testcase.expression, func(t *testing.T) {
// Given
stmt, err := sqlparser.Parse("select " + testcase.expression)
require.NoError(t, err)
astExpr := stmt.(*sqlparser.Select).SelectExprs[0].(*sqlparser.AliasedExpr).Expr
_, err = Translate(astExpr, LookupDefaultCollation(45))
require.EqualError(t, err, testcase.expectedErr)
})
}

}

0 comments on commit b9fd93e

Please sign in to comment.