-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Test and fix cast from bigint to varchar #17152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,6 +83,7 @@ | |
| import static com.facebook.presto.common.type.VarcharType.VARCHAR; | ||
| import static com.facebook.presto.common.type.VarcharType.createVarcharType; | ||
| import static com.facebook.presto.operator.scalar.ApplyFunction.APPLY_FUNCTION; | ||
| import static com.facebook.presto.spi.StandardErrorCode.INVALID_CAST_ARGUMENT; | ||
| import static com.facebook.presto.spi.relation.ExpressionOptimizer.Level; | ||
| import static com.facebook.presto.spi.relation.ExpressionOptimizer.Level.OPTIMIZED; | ||
| import static com.facebook.presto.spi.relation.ExpressionOptimizer.Level.SERIALIZABLE; | ||
|
|
@@ -102,6 +103,7 @@ | |
| import static org.testng.Assert.assertEquals; | ||
| import static org.testng.Assert.assertThrows; | ||
| import static org.testng.Assert.assertTrue; | ||
| import static org.testng.Assert.fail; | ||
|
|
||
| public class TestExpressionInterpreter | ||
| { | ||
|
|
@@ -584,6 +586,42 @@ public void testCastToString() | |
| // TODO enabled when DECIMAL is default for literal: assertOptimizedEquals("cast(12345678901234567890.123 as VARCHAR)", "'12345678901234567890.123'"); | ||
| } | ||
|
|
||
| @Test | ||
| public void testCastBigintToBoundedVarchar() | ||
| { | ||
| assertEvaluatedEquals("CAST(12300000000 AS varchar(11))", "'12300000000'"); | ||
| assertEvaluatedEquals("CAST(12300000000 AS varchar(50))", "'12300000000'"); | ||
|
|
||
| try { | ||
| evaluate("CAST(12300000000 AS varchar(3))", true); | ||
| fail("Expected to throw an INVALID_CAST_ARGUMENT exception"); | ||
| } | ||
| catch (PrestoException e) { | ||
| try { | ||
| assertEquals(e.getErrorCode(), INVALID_CAST_ARGUMENT.toErrorCode()); | ||
| assertEquals(e.getMessage(), "Value 12300000000 cannot be represented as varchar(3)"); | ||
| } | ||
| catch (Throwable failure) { | ||
| failure.addSuppressed(e); | ||
| throw failure; | ||
| } | ||
| } | ||
|
|
||
| try { | ||
| evaluate("CAST(-12300000000 AS varchar(3))", true); | ||
| } | ||
| catch (PrestoException e) { | ||
|
||
| try { | ||
| assertEquals(e.getErrorCode(), INVALID_CAST_ARGUMENT.toErrorCode()); | ||
| assertEquals(e.getMessage(), "Value -12300000000 cannot be represented as varchar(3)"); | ||
| } | ||
| catch (Throwable failure) { | ||
| failure.addSuppressed(e); | ||
| throw failure; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void testCastToBoolean() | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
|
|
||
| import com.facebook.presto.common.type.Type; | ||
| import com.facebook.presto.metadata.MetadataManager; | ||
| import com.facebook.presto.spi.PrestoException; | ||
| import com.facebook.presto.spi.relation.RowExpression; | ||
| import com.facebook.presto.spi.relation.VariableReferenceExpression; | ||
| import com.facebook.presto.sql.TestingRowExpressionTranslator; | ||
|
|
@@ -23,6 +24,7 @@ | |
| import com.facebook.presto.sql.planner.PlanVariableAllocator; | ||
| import com.facebook.presto.sql.planner.TypeProvider; | ||
| import com.facebook.presto.sql.planner.VariablesExtractor; | ||
| import com.facebook.presto.sql.tree.Cast; | ||
| import com.facebook.presto.sql.tree.Expression; | ||
| import com.facebook.presto.sql.tree.ExpressionRewriter; | ||
| import com.facebook.presto.sql.tree.ExpressionTreeRewriter; | ||
|
|
@@ -42,6 +44,7 @@ | |
| import static com.facebook.presto.SessionTestUtils.TEST_SESSION; | ||
| import static com.facebook.presto.common.type.BooleanType.BOOLEAN; | ||
| import static com.facebook.presto.metadata.MetadataManager.createTestMetadataManager; | ||
| import static com.facebook.presto.spi.StandardErrorCode.INVALID_CAST_ARGUMENT; | ||
| import static com.facebook.presto.sql.ExpressionUtils.binaryExpression; | ||
| import static com.facebook.presto.sql.ExpressionUtils.extractPredicates; | ||
| import static com.facebook.presto.sql.ExpressionUtils.rewriteIdentifiersToSymbolReferences; | ||
|
|
@@ -51,6 +54,7 @@ | |
| import static java.util.stream.Collectors.toList; | ||
| import static java.util.stream.Collectors.toMap; | ||
| import static org.testng.Assert.assertEquals; | ||
| import static org.testng.Assert.fail; | ||
|
|
||
| public class TestSimplifyExpressions | ||
| { | ||
|
|
@@ -132,6 +136,45 @@ public void testExtractCommonPredicates() | |
| " OR (A51 AND A52) OR (A53 AND A54) OR (A55 AND A56) OR (A57 AND A58) OR (A59 AND A60)"); | ||
| } | ||
|
|
||
| @Test | ||
| public void testCastBigintToBoundedVarchar() | ||
| { | ||
| // the varchar type length is enough to contain the number's representation | ||
| assertSimplifies("CAST(12300000000 AS varchar(11))", "'12300000000'"); | ||
| // The last argument "'-12300000000'" is varchar(12). Need varchar(50) to the following test pass. | ||
| //assertSimplifies("CAST(-12300000000 AS varchar(50))", "CAST('-12300000000' AS varchar(50))", "'-12300000000'"); | ||
|
|
||
| // cast from bigint to varchar fails, so the expression is not modified | ||
| try { | ||
| assertSimplifies("CAST(12300000000 AS varchar(3))", "CAST(12300000000 AS varchar(3))"); | ||
| fail("Expected to throw an PrestoException exception"); | ||
| } | ||
| catch (PrestoException e) { | ||
| try { | ||
| assertEquals(e.getErrorCode(), INVALID_CAST_ARGUMENT.toErrorCode()); | ||
| assertEquals(e.getMessage(), "Value 12300000000 cannot be represented as varchar(3)"); | ||
| } | ||
| catch (Throwable failure) { | ||
| failure.addSuppressed(e); | ||
| throw failure; | ||
| } | ||
| } | ||
|
|
||
| try { | ||
| assertSimplifies("CAST(-12300000000 AS varchar(3))", "CAST(-12300000000 AS varchar(3))"); | ||
| } | ||
| catch (PrestoException e) { | ||
|
||
| try { | ||
| assertEquals(e.getErrorCode(), INVALID_CAST_ARGUMENT.toErrorCode()); | ||
| assertEquals(e.getMessage(), "Value -12300000000 cannot be represented as varchar(3)"); | ||
| } | ||
| catch (Throwable failure) { | ||
| failure.addSuppressed(e); | ||
| throw failure; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private static void assertSimplifies(String expression, String expected) | ||
| { | ||
| assertSimplifies(expression, expected, null); | ||
|
|
@@ -177,5 +220,13 @@ public Expression rewriteLogicalBinaryExpression(LogicalBinaryExpression node, V | |
| .collect(toList()); | ||
| return binaryExpression(node.getOperator(), predicates); | ||
| } | ||
|
|
||
| @Override | ||
| public Expression rewriteCast(Cast node, Void context, ExpressionTreeRewriter<Void> treeRewriter) | ||
| { | ||
| // the `expected` Cast expression comes out of the AstBuilder with the `typeOnly` flag set to false. | ||
| // always set the `typeOnly` flag to false so that it does not break the comparison. | ||
| return new Cast(node.getExpression(), node.getType(), node.isSafe(), false); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be used in other similar PRs, like #17232