[Bug](cast) change binary predicate finally cast to varchar (#11796)

This commit is contained in:
Pxl
2022-08-21 10:13:47 +08:00
committed by GitHub
parent 25b427d0c6
commit 192cdd4d76
5 changed files with 80 additions and 19 deletions

View File

@ -376,18 +376,12 @@ public class BinaryPredicate extends Predicate implements Writable {
// 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 || t2 == PrimitiveType.STRING)) {
Expr rightChild = getChild(1);
Long parsedLong = Type.tryParseToLong(rightChild);
if (parsedLong != null) {
return Type.BIGINT;
if (t1.isStringType() || t2.isStringType()) {
if ((t1 == PrimitiveType.BIGINT || t1 == PrimitiveType.LARGEINT) && Type.canParseTo(getChild(1), t1)) {
return Type.fromPrimitiveType(t1);
}
}
if ((t1 == PrimitiveType.VARCHAR || t1 == PrimitiveType.STRING) && t2 == PrimitiveType.BIGINT) {
Expr leftChild = getChild(0);
Long parsedLong = Type.tryParseToLong(leftChild);
if (parsedLong != null) {
return Type.BIGINT;
if ((t2 == PrimitiveType.BIGINT || t2 == PrimitiveType.LARGEINT) && Type.canParseTo(getChild(0), t2)) {
return Type.fromPrimitiveType(t2);
}
}

View File

@ -414,7 +414,6 @@ public class CastExpr extends Expr {
} else if (type.isDecimalV2() || type.isDecimalV3()) {
return new DecimalLiteral(value.getStringValue());
} else if (type.isFloatingPointType()) {
return new FloatLiteral(value.getDoubleValue(), type);
} else if (type.isStringType()) {
return new StringLiteral(value.getStringValue());

View File

@ -18,7 +18,9 @@
package org.apache.doris.catalog;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.LargeIntLiteral;
import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.Pair;
import org.apache.doris.thrift.TColumnType;
@ -545,15 +547,39 @@ public abstract class Type {
}
/**
* Returns null if this expr is not instance of StringLiteral or StringLiteral
* inner value could not parse to long. otherwise return parsed Long result.
* Returns true if expr is StringLiteral and can parse to valid type, false
* otherwise.
* This function only support LargeInt and BigInt now.
*/
public static Long tryParseToLong(Expr expectStringExpr) {
if (expectStringExpr instanceof StringLiteral) {
String value = ((StringLiteral) expectStringExpr).getValue();
return Longs.tryParse(value);
public static boolean canParseTo(Expr expr, PrimitiveType type) {
if (expr instanceof StringLiteral) {
if (type == PrimitiveType.BIGINT) {
return canParseToBigInt((StringLiteral) expr);
} else if (type == PrimitiveType.LARGEINT) {
return canParseToLargeInt((StringLiteral) expr);
}
}
return null;
return false;
}
/**
* Returns true if expr can parse to valid BigInt, false otherwise.
*/
private static boolean canParseToBigInt(StringLiteral expr) {
String value = ((StringLiteral) expr).getValue();
return Longs.tryParse(value) != null;
}
/**
* Returns true if expr can parse to valid LargeInt, false otherwise.
*/
private static boolean canParseToLargeInt(Expr expr) {
try {
new LargeIntLiteral(((StringLiteral) expr).getValue());
} catch (AnalysisException e) {
return false;
}
return true;
}
/**

View File

@ -0,0 +1,6 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !test_largeint_string --
10003 195456789345678955654444443878
10004 195456789345678955654444443878
10006 195456789345678955654444443878
10009 195456789345678955654444443878

View File

@ -0,0 +1,36 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
suite("test_binary_predicate_cast") {
sql """
CREATE TABLE IF NOT EXISTS test_demo
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`phone` LARGEINT COMMENT "用户电话"
)
UNIQUE KEY(`user_id`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
"""
sql """insert into test_demo values (10003,195456789345678955654444443875),(10003,195456789345678955654444443874),(10003,195456789345678955654444443873),(10003,195456789345678955654444443877),(10003,195456789345678955654444443878),(10004,195456789345678955654444443878),(10005,195456789345678955654444443877),(10006,195456789345678955654444443878),(10009,195456789345678955654444443878)
"""
qt_test_largeint_string "select * from test_demo where phone='195456789345678955654444443878' order by user_id"
}