[SQL] support StringLiteral try to cast BigInt (#4445)

This commit is contained in:
xueyan.li
2020-08-27 12:15:28 +08:00
committed by GitHub
parent b85bb0e2e9
commit 3c784b9c90
3 changed files with 69 additions and 1 deletions

View File

@ -307,6 +307,28 @@ public class BinaryPredicate extends Predicate implements Writable {
return Type.LARGEINT;
}
// Implicit conversion affects query performance.
// For a common example datekey='20200825' which datekey is int type.
// If we up conversion to double type directly.
// PartitionPruner will not take effect. Then it will scan all partitions.
// When int column compares with string, Mysql will convert string to int.
// So it is also compatible with Mysql.
if (t1 == PrimitiveType.BIGINT && t2 == PrimitiveType.VARCHAR) {
Expr rightChild = getChild(1);
Long parsedLong = Type.tryParseToLong(rightChild);
if(parsedLong != null) {
return Type.BIGINT;
}
}
if (t1 == PrimitiveType.VARCHAR && t2 == PrimitiveType.BIGINT) {
Expr leftChild = getChild(0);
Long parsedLong = Type.tryParseToLong(leftChild);
if(parsedLong != null) {
return Type.BIGINT;
}
}
return Type.DOUBLE;
}

View File

@ -386,6 +386,18 @@ public abstract class Type {
return ScalarType.INVALID;
}
/**
* Returns null if this expr is not instance of StringLiteral or StringLiteral
* inner value could not parse to long. otherwise return parsed Long result.
*/
public static Long tryParseToLong(Expr expectStringExpr){
if (expectStringExpr instanceof StringLiteral) {
String value = ((StringLiteral)expectStringExpr).getValue();
return Longs.tryParse(value);
}
return null;
}
/**
* Returns true if this type exceeds the MAX_NESTING_DEPTH, false otherwise.
*/

View File

@ -50,9 +50,25 @@ public class SelectStmtTest {
+ "AGGREGATE KEY(k1, k2,k3,k4) distributed by hash(k1) buckets 3 properties('replication_num' = '1');";
String createBaseAllStmtStr = "create table db1.baseall(k1 int, k2 varchar(32)) distributed by hash(k1) "
+ "buckets 3 properties('replication_num' = '1');";
String createPratitionTableStr = "CREATE TABLE db1.partition_table (\n" +
"datekey int(11) NULL COMMENT \"datekey\",\n" +
"poi_id bigint(20) NULL COMMENT \"poi_id\"\n" +
") ENGINE=OLAP\n" +
"AGGREGATE KEY(datekey, poi_id)\n" +
"COMMENT \"OLAP\"\n" +
"PARTITION BY RANGE(datekey)\n" +
"(PARTITION p20200727 VALUES [(\"20200726\"), (\"20200727\")),\n" +
"PARTITION p20200728 VALUES [(\"20200727\"), (\"20200728\")))\n" +
"DISTRIBUTED BY HASH(poi_id) BUCKETS 2\n" +
"PROPERTIES (\n" +
"\"storage_type\" = \"COLUMN\",\n" +
"\"replication_num\" = \"1\"\n" +
");";
dorisAssert = new DorisAssert();
dorisAssert.withDatabase("db1").useDatabase("db1");
dorisAssert.withTable(createTblStmtStr).withTable(createBaseAllStmtStr);
dorisAssert.withTable(createTblStmtStr)
.withTable(createBaseAllStmtStr)
.withTable(createPratitionTableStr);
}
@Test
@ -362,4 +378,22 @@ public class SelectStmtTest {
"from information_schema.collations";
dorisAssert.query(sql).explainQuery();
}
@Test
public void testVarcharToLongSupport() throws Exception {
String sql = "select count(*)\n" +
"from db1.partition_table\n" +
"where datekey='20200730'";
Assert.assertTrue(dorisAssert
.query(sql)
.explainQuery()
.contains("`datekey` = 20200730"));
sql = "select count(*)\n" +
"from db1.partition_table\n" +
"where '20200730'=datekey";
Assert.assertTrue(dorisAssert
.query(sql)
.explainQuery()
.contains("`datekey` = 20200730"));
}
}