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