[Bug] Partition key's type has been changed after executing queries (#3348)

Expr's `uncheckedCastTo()` method should return a new instance of casted expr.
The origin expr should remain unchanged.
This commit is contained in:
Mingyu Chen
2020-04-21 08:30:02 +08:00
committed by GitHub
parent 46272a5621
commit a2c8d14fd9
8 changed files with 96 additions and 10 deletions

View File

@ -321,14 +321,16 @@ public class DateLiteral extends LiteralExpr {
@Override
protected Expr uncheckedCastTo(Type targetType) throws AnalysisException {
if (targetType.isDateType()) {
if (type.equals(targetType)) {
return this;
}
if (targetType.equals(Type.DATE)) {
this.castToDate();
return new DateLiteral(this.year, this.month, this.day);
} else if (targetType.equals(Type.DATETIME)) {
this.type = Type.DATETIME;
return new DateLiteral(this.year, this.month, this.day, this.hour, this.minute, this.second);
} else {
throw new AnalysisException("Error date literal type : " + type);
}
return this;
} else if (targetType.isStringType()) {
return new StringLiteral(getStringValue());
} else if (Type.isImplicitlyCastable(this.type, targetType, true)) {

View File

@ -1227,7 +1227,6 @@ abstract public class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
* Create an expression equivalent to 'this' but returning targetType;
* possibly by inserting an implicit cast,
* or by returning an altogether new expression
* or by returning 'this' with a modified return type'.
*
* @param targetType type to be cast to
* @return cast expression, or converted literal,

View File

@ -156,7 +156,11 @@ public class FloatLiteral extends LiteralExpr {
return super.uncheckedCastTo(targetType);
}
if (targetType.isFloatingPointType()) {
type = targetType;
if (!type.equals(targetType)) {
FloatLiteral floatLiteral = new FloatLiteral(this);
floatLiteral.setType(targetType);
return floatLiteral;
}
return this;
} else if (targetType.isDecimal() || targetType.isDecimalV2()) {
return new DecimalLiteral(new BigDecimal(value));

View File

@ -296,7 +296,11 @@ public class IntLiteral extends LiteralExpr {
}
if (targetType.isFixedPointType()) {
if (!targetType.isScalarType(PrimitiveType.LARGEINT)) {
this.type = targetType;
if (!type.equals(targetType)) {
IntLiteral intLiteral = new IntLiteral(this);
intLiteral.setType(targetType);
return intLiteral;
}
return this;
} else {
//return new LargeIntLiteral(Long.toString(value));

View File

@ -120,7 +120,11 @@ public class NullLiteral extends LiteralExpr {
@Override
protected Expr uncheckedCastTo(Type targetType) throws AnalysisException {
Preconditions.checkState(targetType.isValid());
type = targetType;
if (!type.equals(targetType)) {
NullLiteral nullLiteral = new NullLiteral(this);
nullLiteral.setType(targetType);
return nullLiteral;
}
return this;
}

View File

@ -207,8 +207,9 @@ public class StringLiteral extends LiteralExpr {
} else if (targetType.equals(type)) {
return this;
} else if (targetType.isStringType()) {
type = targetType;
return this;
StringLiteral stringLiteral = new StringLiteral(this);
stringLiteral.setType(targetType);
return stringLiteral;
}
return super.uncheckedCastTo(targetType);
}

View File

@ -128,7 +128,6 @@ public class EsScanNode extends ScanNode {
esScanNode.setFields_context(table.fieldsContext());
}
msg.es_scan_node = esScanNode;
}
// TODO(ygl) assign backend that belong to the same cluster

View File

@ -18,6 +18,7 @@
package org.apache.doris.analysis;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.jmockit.Deencapsulation;
@ -86,4 +87,76 @@ public class ExprTest {
Assert.assertNotEquals(tableBColumns, null);
Assert.assertTrue(tableBColumns.contains("c1"));
}
@Test
public void testUncheckedCastTo() throws AnalysisException {
// uncheckedCastTo should return new object
// date
DateLiteral dateLiteral = new DateLiteral(2020, 4, 5, 12, 0, 5);
Assert.assertTrue(dateLiteral.getType().equals(Type.DATETIME));
DateLiteral castLiteral = (DateLiteral) dateLiteral.uncheckedCastTo(Type.DATE);
Assert.assertFalse(dateLiteral == castLiteral);
Assert.assertTrue(dateLiteral.getType().equals(Type.DATETIME));
Assert.assertTrue(castLiteral.getType().equals(Type.DATE));
Assert.assertEquals(0, castLiteral.getHour());
Assert.assertEquals(0, castLiteral.getMinute());
Assert.assertEquals(0, castLiteral.getSecond());
Assert.assertEquals(12, dateLiteral.getHour());
Assert.assertEquals(0, dateLiteral.getMinute());
Assert.assertEquals(5, dateLiteral.getSecond());
DateLiteral dateLiteral2 = new DateLiteral(2020, 4, 5);
Assert.assertTrue(dateLiteral2.getType().equals(Type.DATE));
castLiteral = (DateLiteral) dateLiteral2.uncheckedCastTo(Type.DATETIME);
Assert.assertFalse(dateLiteral2 == castLiteral);
Assert.assertTrue(dateLiteral2.getType().equals(Type.DATE));
Assert.assertTrue(castLiteral.getType().equals(Type.DATETIME));
Assert.assertEquals(0, castLiteral.getHour());
Assert.assertEquals(0, castLiteral.getMinute());
Assert.assertEquals(0, castLiteral.getSecond());
// float
FloatLiteral floatLiteral = new FloatLiteral(0.1, Type.FLOAT);
Assert.assertTrue(floatLiteral.getType().equals(Type.FLOAT));
FloatLiteral castFloatLiteral = (FloatLiteral) floatLiteral.uncheckedCastTo(Type.DOUBLE);
Assert.assertTrue(floatLiteral.getType().equals(Type.FLOAT));
Assert.assertTrue(castFloatLiteral.getType().equals(Type.DOUBLE));
Assert.assertFalse(floatLiteral == castFloatLiteral);
FloatLiteral castFloatLiteral2 = (FloatLiteral) floatLiteral.uncheckedCastTo(Type.FLOAT);
Assert.assertTrue(floatLiteral == castFloatLiteral2);
// int
IntLiteral intLiteral = new IntLiteral(200);
Assert.assertTrue(intLiteral.getType().equals(Type.SMALLINT));
IntLiteral castIntLiteral = (IntLiteral) intLiteral.uncheckedCastTo(Type.INT);
Assert.assertTrue(intLiteral.getType().equals(Type.SMALLINT));
Assert.assertTrue(castIntLiteral.getType().equals(Type.INT));
Assert.assertFalse(intLiteral == castIntLiteral);
IntLiteral castIntLiteral2 = (IntLiteral) intLiteral.uncheckedCastTo(Type.SMALLINT);
Assert.assertTrue(intLiteral == castIntLiteral2);
// null
NullLiteral nullLiternal = NullLiteral.create(Type.DATE);
Assert.assertTrue(nullLiternal.getType().equals(Type.DATE));
NullLiteral castNullLiteral = (NullLiteral) nullLiternal.uncheckedCastTo(Type.DATETIME);
Assert.assertTrue(nullLiternal.getType().equals(Type.DATE));
Assert.assertTrue(castNullLiteral.getType().equals(Type.DATETIME));
Assert.assertFalse(nullLiternal == castNullLiteral);
NullLiteral castNullLiteral2 = (NullLiteral) nullLiternal.uncheckedCastTo(Type.DATE);
Assert.assertTrue(nullLiternal == castNullLiteral2);
// string
StringLiteral stringLiteral = new StringLiteral("abc");
Assert.assertTrue(stringLiteral.getType().equals(Type.VARCHAR));
StringLiteral castStringLiteral = (StringLiteral) stringLiteral.uncheckedCastTo(Type.CHAR);
Assert.assertTrue(stringLiteral.getType().equals(Type.VARCHAR));
Assert.assertTrue(castStringLiteral.getType().equals(Type.CHAR));
Assert.assertFalse(stringLiteral == castStringLiteral);
StringLiteral castStringLiteral2 = (StringLiteral) stringLiteral.uncheckedCastTo(Type.VARCHAR);
Assert.assertTrue(stringLiteral == castStringLiteral2);
}
}