提交 46dc74c4 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Use single data type variable in Function.optimize()

上级 4b88dc6d
......@@ -60,7 +60,6 @@ import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
import org.h2.value.DataType;
import org.h2.value.TypeInfo;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -2308,20 +2307,16 @@ public class Function extends Expression implements FunctionCall {
allConst = false;
}
}
int t, s;
long p;
TypeInfo typeInfo;
Expression p0 = args.length < 1 ? null : args[0];
switch (info.type) {
case DATE_ADD: {
t = Value.TIMESTAMP;
p = ValueTimestamp.DEFAULT_PRECISION;
s = ValueTimestamp.MAXIMUM_SCALE;
typeInfo = TypeInfo.TYPE_TIMESTAMP;
if (p0.isConstant()) {
Expression p2 = args[2];
switch (p2.getType().getValueType()) {
case Value.TIME:
t = Value.TIME;
p = ValueTime.DEFAULT_PRECISION;
typeInfo = TypeInfo.TYPE_TIME;
break;
case Value.DATE: {
int field = DateTimeFunctions.getDatePart(p0.getValue(session).getString());
......@@ -2336,74 +2331,55 @@ public class Function extends Expression implements FunctionCall {
// TIMESTAMP result
break;
default:
t = Value.DATE;
p = ValueDate.PRECISION;
s = 0;
type = TypeInfo.TYPE_DATE;
}
break;
}
case Value.TIMESTAMP_TZ:
t = Value.TIMESTAMP_TZ;
p = ValueTimestampTimeZone.DEFAULT_PRECISION;
type = TypeInfo.TYPE_TIMESTAMP_TZ;
}
}
break;
}
case EXTRACT: {
if (p0.isConstant() && DateTimeFunctions.getDatePart(p0.getValue(session).getString()) == Function.EPOCH) {
t = Value.DECIMAL;
p = ValueLong.PRECISION + ValueTimestamp.MAXIMUM_SCALE;
s = ValueTimestamp.MAXIMUM_SCALE;
typeInfo = TypeInfo.getTypeInfo(Value.DECIMAL, ValueLong.PRECISION + ValueTimestamp.MAXIMUM_SCALE,
ValueTimestamp.MAXIMUM_SCALE, null);
} else {
t = Value.INT;
p = ValueInt.PRECISION;
s = 0;
typeInfo = TypeInfo.TYPE_INT;
}
break;
}
case DATE_TRUNC: {
Expression p1 = args[1];
t = p1.getType().getValueType();
if (t == Value.TIMESTAMP_TZ) {
p = ValueTimestampTimeZone.DEFAULT_PRECISION;
} else {
t = Value.TIMESTAMP;
p = ValueTimestamp.DEFAULT_PRECISION;
case DATE_TRUNC:
typeInfo = args[1].getType();
// TODO set scale when possible
if (typeInfo.getValueType() != Value.TIMESTAMP_TZ) {
typeInfo = TypeInfo.TYPE_TIMESTAMP;
}
s = ValueTimestamp.MAXIMUM_SCALE;
break;
}
case IFNULL:
case NULLIF:
case COALESCE:
case LEAST:
case GREATEST: {
t = Value.UNKNOWN;
s = 0;
p = 0;
typeInfo = TypeInfo.TYPE_UNKNOWN;
for (Expression e : args) {
if (e != ValueExpression.getNull()) {
TypeInfo type = e.getType();
int valueType = type.getValueType();
if (valueType != Value.UNKNOWN && valueType != Value.NULL) {
t = Value.getHigherOrder(t, valueType);
s = Math.max(s, type.getScale());
p = Math.max(p, type.getPrecision());
typeInfo = Value.getHigherType(typeInfo, type);
}
}
}
if (t == Value.UNKNOWN) {
t = Value.STRING;
s = 0;
p = Integer.MAX_VALUE;
if (typeInfo.getValueType() == Value.UNKNOWN) {
typeInfo = TypeInfo.TYPE_STRING_DEFAULT;
}
break;
}
case CASE:
case DECODE: {
t = Value.UNKNOWN;
s = 0;
p = 0;
typeInfo = TypeInfo.TYPE_UNKNOWN;
// (expr, when, then)
// (expr, when, then, else)
// (expr, when, then, when, then)
......@@ -2414,9 +2390,7 @@ public class Function extends Expression implements FunctionCall {
TypeInfo type = then.getType();
int valueType = type.getValueType();
if (valueType != Value.UNKNOWN && valueType != Value.NULL) {
t = Value.getHigherOrder(t, valueType);
s = Math.max(s, type.getScale());
p = Math.max(p, type.getPrecision());
typeInfo = Value.getHigherType(typeInfo, type);
}
}
}
......@@ -2426,26 +2400,18 @@ public class Function extends Expression implements FunctionCall {
TypeInfo type = elsePart.getType();
int valueType = type.getValueType();
if (valueType != Value.UNKNOWN && valueType != Value.NULL) {
t = Value.getHigherOrder(t, valueType);
s = Math.max(s, type.getScale());
p = Math.max(p, type.getPrecision());
typeInfo = Value.getHigherType(typeInfo, type);
}
}
}
if (t == Value.UNKNOWN) {
t = Value.STRING;
s = 0;
p = Integer.MAX_VALUE;
if (typeInfo.getValueType() == Value.UNKNOWN) {
typeInfo = TypeInfo.TYPE_STRING_DEFAULT;
}
break;
}
case CASEWHEN: {
TypeInfo t1 = args[1].getType(), t2 = args[2].getType();
t = Value.getHigherOrder(t1.getValueType(), t2.getValueType());
p = Math.max(t1.getPrecision(), t2.getPrecision());
s = Math.max(t1.getScale(), t2.getScale());
case CASEWHEN:
typeInfo = Value.getHigherType(args[1].getType(), args[2].getType());
break;
}
case NVL2: {
TypeInfo t1 = args[1].getType(), t2 = args[2].getType();
switch (t1.getValueType()) {
......@@ -2453,14 +2419,12 @@ public class Function extends Expression implements FunctionCall {
case Value.CLOB:
case Value.STRING_FIXED:
case Value.STRING_IGNORECASE:
t = t1.getValueType();
typeInfo = TypeInfo.getTypeInfo(t1.getValueType(), -1, 0, null);
break;
default:
t = Value.getHigherOrder(t1.getValueType(), t2.getValueType());
typeInfo = Value.getHigherType(t1, t2);
break;
}
p = Math.max(t1.getPrecision(), t2.getPrecision());
s = Math.max(t1.getScale(), t2.getScale());
break;
}
case CAST:
......@@ -2468,12 +2432,9 @@ public class Function extends Expression implements FunctionCall {
case TRUNCATE_VALUE:
if (type != null) {
// data type, precision and scale is already set
t = type.getValueType();
p = type.getPrecision();
s = type.getScale();
typeInfo = type;
} else {
t = Value.UNKNOWN;
p = s = 0;
typeInfo = TypeInfo.TYPE_UNKNOWN;
}
break;
case TRUNCATE:
......@@ -2481,61 +2442,43 @@ public class Function extends Expression implements FunctionCall {
case Value.STRING:
case Value.DATE:
case Value.TIMESTAMP:
t = Value.TIMESTAMP;
p = ValueTimestamp.DEFAULT_PRECISION;
s = 0;
typeInfo = TypeInfo.getTypeInfo(Value.TIMESTAMP, -1, 0, null);
break;
case Value.TIMESTAMP_TZ:
t = Value.TIMESTAMP;
p = ValueTimestampTimeZone.DEFAULT_PRECISION;
s = 0;
typeInfo = TypeInfo.getTypeInfo(Value.TIMESTAMP_TZ, -1, 0, null);
break;
default:
t = Value.DOUBLE;
s = 0;
p = ValueDouble.PRECISION;
typeInfo = TypeInfo.TYPE_DOUBLE;
}
break;
case ABS:
case FLOOR:
case ROUND: {
TypeInfo type = p0.getType();
t = type.getValueType();
s = type.getScale();
p = type.getPrecision();
if (t == Value.NULL) {
t = Value.INT;
p = ValueInt.PRECISION;
s = 0;
typeInfo = type;
if (typeInfo.getValueType() == Value.NULL) {
typeInfo = TypeInfo.TYPE_INT;
}
break;
}
case SET: {
TypeInfo type = args[1].getType();
t = type.getValueType();
p = type.getPrecision();
s = type.getScale();
case SET:
typeInfo = args[1].getType();
if (!(p0 instanceof Variable)) {
throw DbException.get(
ErrorCode.CAN_ONLY_ASSIGN_TO_VARIABLE_1, p0.getSQL());
}
break;
}
case FILE_READ: {
if (args.length == 1) {
t = Value.BLOB;
typeInfo = TypeInfo.getTypeInfo(Value.BLOB, Integer.MAX_VALUE, 0, null);
} else {
t = Value.CLOB;
typeInfo = TypeInfo.getTypeInfo(Value.CLOB, Integer.MAX_VALUE, 0, null);
}
p = Integer.MAX_VALUE;
s = 0;
break;
}
case SUBSTRING:
case SUBSTR: {
t = info.returnDataType;
p = args[0].getType().getPrecision();
s = 0;
long p = args[0].getType().getPrecision();
if (args[1].isConstant()) {
// if only two arguments are used,
// subtract offset from first argument length
......@@ -2546,32 +2489,21 @@ public class Function extends Expression implements FunctionCall {
p = Math.min(p, args[2].getValue(session).getLong());
}
p = Math.max(0, p);
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, p, 0, null);
break;
}
case ENCRYPT:
case DECRYPT: {
t = info.returnDataType;
TypeInfo type = args[2].getType();
p = type.getPrecision();
s = 0;
case DECRYPT:
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, args[2].getType().getPrecision(), 0, null);
break;
}
case COMPRESS: {
t = info.returnDataType;
TypeInfo type = args[0].getType();
p = type.getPrecision();
s = 0;
case COMPRESS:
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, args[0].getType().getPrecision(), 0, null);
break;
}
case CHAR:
t = info.returnDataType;
p = 1;
s = 0;
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, 1, 0, null);
break;
case CONCAT:
t = info.returnDataType;
p = 0;
s = 0;
case CONCAT: {
long p = 0;
for (Expression e : args) {
TypeInfo type = e.getType();
p += type.getPrecision();
......@@ -2579,11 +2511,11 @@ public class Function extends Expression implements FunctionCall {
p = Long.MAX_VALUE;
}
}
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, p, 0, null);
break;
}
case HEXTORAW:
t = info.returnDataType;
p = (args[0].getType().getPrecision() + 3) / 4;
s = 0;
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, (args[0].getType().getPrecision() + 3) / 4, 0, null);
break;
case LCASE:
case LTRIM:
......@@ -2594,37 +2526,24 @@ public class Function extends Expression implements FunctionCall {
case UPPER:
case TRIM:
case STRINGDECODE:
case UTF8TOSTRING: {
t = info.returnDataType;
TypeInfo type = args[0].getType();
p = type.getPrecision();
s = 0;
case UTF8TOSTRING:
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, args[0].getType().getPrecision(), 0, null);
break;
}
case RAWTOHEX:
t = info.returnDataType;
p = args[0].getType().getPrecision() * 4;
s = 0;
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, args[0].getType().getPrecision() * 4, 0, null);
break;
case SOUNDEX:
t = info.returnDataType;
p = 4;
s = 0;
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, 4, 0, null);
break;
case DAY_NAME:
case MONTH_NAME:
t = info.returnDataType;
// day and month names may be long in some languages
p = 20;
s = 0;
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, 20, 0, null);
break;
default:
t = info.returnDataType;
DataType type = DataType.getDataType(t);
p = type.maxPrecision;
s = type.defaultScale;
typeInfo = TypeInfo.getTypeInfo(info.returnDataType, -1, -1, null);
}
type = TypeInfo.getTypeInfo(t, p, s, type != null ? type.getExtTypeInfo() : null);
type = typeInfo;
if (allConst) {
Value v = getValue(session);
if (v == ValueNull.INSTANCE) {
......
......@@ -287,8 +287,15 @@ public class TypeInfo {
//$FALL-THROUGH$
case Value.STRING_FIXED:
case Value.STRING_IGNORECASE:
if (precision < 0) {
precision = Integer.MAX_VALUE;
}
return new TypeInfo(type, precision, 0, MathUtils.convertLongToInt(precision), null);
case Value.BLOB:
case Value.CLOB:
if (precision < 0) {
precision = Long.MAX_VALUE;
}
return new TypeInfo(type, precision, 0, MathUtils.convertLongToInt(precision), null);
case Value.GEOMETRY:
if (extTypeInfo instanceof ExtTypeInfoGeometry) {
......
......@@ -806,4 +806,4 @@ econd irst bcef ordinality nord unnest
analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan
corrupts splitted disruption unintentional octets preconditions predicates subq objectweb insn opcodes
preserves masking holder unboxing avert iae transformed subtle reevaluate exclusions subclause ftbl rgr
presorted inclusion contexts
presorted inclusion contexts aax
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论