提交 473d3d9c authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Use TypeInfo in Expression implementations

上级 3f2932f9
...@@ -2440,7 +2440,7 @@ public class Parser { ...@@ -2440,7 +2440,7 @@ public class Parser {
SelectOrderBy order = new SelectOrderBy(); SelectOrderBy order = new SelectOrderBy();
Expression expr = readExpression(); Expression expr = readExpression();
if (canBeNumber && expr instanceof ValueExpression && if (canBeNumber && expr instanceof ValueExpression &&
expr.getType() == Value.INT) { expr.getValueType() == Value.INT) {
order.columnIndexExpr = expr; order.columnIndexExpr = expr;
} else if (expr instanceof Parameter) { } else if (expr instanceof Parameter) {
recompileAlways = true; recompileAlways = true;
...@@ -3837,12 +3837,12 @@ public class Parser { ...@@ -3837,12 +3837,12 @@ public class Parser {
read(); read();
if (currentTokenType == VALUE) { if (currentTokenType == VALUE) {
r = ValueExpression.get(currentValue.negate()); r = ValueExpression.get(currentValue.negate());
if (r.getType() == Value.LONG && if (r.getValueType() == Value.LONG &&
r.getValue(session).getLong() == Integer.MIN_VALUE) { r.getValue(session).getLong() == Integer.MIN_VALUE) {
// convert Integer.MIN_VALUE to type 'int' // convert Integer.MIN_VALUE to type 'int'
// (Integer.MAX_VALUE+1 is of type 'long') // (Integer.MAX_VALUE+1 is of type 'long')
r = ValueExpression.get(ValueInt.get(Integer.MIN_VALUE)); r = ValueExpression.get(ValueInt.get(Integer.MIN_VALUE));
} else if (r.getType() == Value.DECIMAL && } else if (r.getValueType() == Value.DECIMAL &&
r.getValue(session).getBigDecimal() r.getValue(session).getBigDecimal()
.compareTo(Value.MIN_LONG_DECIMAL) == 0) { .compareTo(Value.MIN_LONG_DECIMAL) == 0) {
// convert Long.MIN_VALUE to type 'long' // convert Long.MIN_VALUE to type 'long'
...@@ -5841,7 +5841,7 @@ public class Parser { ...@@ -5841,7 +5841,7 @@ public class Parser {
do { do {
Expression expr = readExpression(); Expression expr = readExpression();
expr = expr.optimize(session); expr = expr.optimize(session);
int type = expr.getType(); int type = expr.getValueType();
long prec; long prec;
int scale, displaySize; int scale, displaySize;
Column column; Column column;
......
...@@ -180,7 +180,7 @@ public class CreateTable extends CommandWithColumns { ...@@ -180,7 +180,7 @@ public class CreateTable extends CommandWithColumns {
ColumnNamer columnNamer= new ColumnNamer(session); ColumnNamer columnNamer= new ColumnNamer(session);
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
Expression expr = expressions.get(i); Expression expr = expressions.get(i);
int type = expr.getType(); int type = expr.getValueType();
String name = columnNamer.getColumnName(expr,i,expr.getAlias()); String name = columnNamer.getColumnName(expr,i,expr.getAlias());
long precision = expr.getPrecision(); long precision = expr.getPrecision();
int displaySize = expr.getDisplaySize(); int displaySize = expr.getDisplaySize();
......
...@@ -76,7 +76,7 @@ public class Call extends Prepared { ...@@ -76,7 +76,7 @@ public class Call extends Prepared {
public void prepare() { public void prepare() {
expression = expression.optimize(session); expression = expression.optimize(session);
expressions = new Expression[] { expression }; expressions = new Expression[] { expression };
isResultSet = expression.getType() == Value.RESULT_SET; isResultSet = expression.getValueType() == Value.RESULT_SET;
if (isResultSet) { if (isResultSet) {
prepareAlways = true; prepareAlways = true;
} }
......
...@@ -121,7 +121,7 @@ public class SelectUnion extends Query { ...@@ -121,7 +121,7 @@ public class SelectUnion extends Query {
Mode mode = session.getDatabase().getMode(); Mode mode = session.getDatabase().getMode();
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
Expression e = expressions.get(i); Expression e = expressions.get(i);
newValues[i] = values[i].convertTo(e.getType(), mode); newValues[i] = values[i].convertTo(e.getValueType(), mode);
} }
return newValues; return newValues;
} }
...@@ -328,7 +328,7 @@ public class SelectUnion extends Query { ...@@ -328,7 +328,7 @@ public class SelectUnion extends Query {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
Expression l = le.get(i); Expression l = le.get(i);
Expression r = re.get(i); Expression r = re.get(i);
int type = Value.getHigherOrder(l.getType(), r.getType()); int type = Value.getHigherOrder(l.getValueType(), r.getValueType());
long prec = Math.max(l.getPrecision(), r.getPrecision()); long prec = Math.max(l.getPrecision(), r.getPrecision());
int scale = Math.max(l.getScale(), r.getScale()); int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize()); int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
......
...@@ -9,6 +9,7 @@ import org.h2.command.Parser; ...@@ -9,6 +9,7 @@ import org.h2.command.Parser;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
/** /**
...@@ -37,10 +38,15 @@ public class Alias extends Expression { ...@@ -37,10 +38,15 @@ public class Alias extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return expr.getType(); return expr.getType();
} }
@Override
public int getValueType() {
return expr.getValueType();
}
@Override @Override
public void mapColumns(ColumnResolver resolver, int level, int state) { public void mapColumns(ColumnResolver resolver, int level, int state) {
expr.mapColumns(resolver, level, state); expr.mapColumns(resolver, level, state);
......
...@@ -14,6 +14,7 @@ import org.h2.table.ColumnResolver; ...@@ -14,6 +14,7 @@ import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -59,6 +60,7 @@ public class BinaryOperation extends Expression { ...@@ -59,6 +60,7 @@ public class BinaryOperation extends Expression {
private OpType opType; private OpType opType;
private Expression left, right; private Expression left, right;
private TypeInfo type;
private int dataType; private int dataType;
private boolean convertRight = true; private boolean convertRight = true;
...@@ -164,6 +166,7 @@ public class BinaryOperation extends Expression { ...@@ -164,6 +166,7 @@ public class BinaryOperation extends Expression {
right = right.optimize(session); right = right.optimize(session);
switch (opType) { switch (opType) {
case CONCAT: case CONCAT:
type = TypeInfo.TYPE_STRING_DEFAULT;
dataType = Value.STRING; dataType = Value.STRING;
break; break;
case PLUS: case PLUS:
...@@ -171,17 +174,19 @@ public class BinaryOperation extends Expression { ...@@ -171,17 +174,19 @@ public class BinaryOperation extends Expression {
case MULTIPLY: case MULTIPLY:
case DIVIDE: case DIVIDE:
case MODULUS: case MODULUS:
int l = left.getType(); int l = left.getValueType();
int r = right.getType(); int r = right.getValueType();
if ((l == Value.NULL && r == Value.NULL) || if ((l == Value.NULL && r == Value.NULL) ||
(l == Value.UNKNOWN && r == Value.UNKNOWN)) { (l == Value.UNKNOWN && r == Value.UNKNOWN)) {
// (? + ?) - use decimal by default (the most safe data type) or // (? + ?) - use decimal by default (the most safe data type) or
// string when text concatenation with + is enabled // string when text concatenation with + is enabled
if (opType == OpType.PLUS && session.getDatabase(). if (opType == OpType.PLUS && session.getDatabase().
getMode().allowPlusForStringConcat) { getMode().allowPlusForStringConcat) {
type = TypeInfo.TYPE_STRING_DEFAULT;
dataType = Value.STRING; dataType = Value.STRING;
opType = OpType.CONCAT; opType = OpType.CONCAT;
} else { } else {
type = TypeInfo.TYPE_DECIMAL_DEFAULT;
dataType = Value.DECIMAL; dataType = Value.DECIMAL;
} }
} else if (DataType.isIntervalType(l) || DataType.isIntervalType(r)) { } else if (DataType.isIntervalType(l) || DataType.isIntervalType(r)) {
...@@ -191,12 +196,15 @@ public class BinaryOperation extends Expression { ...@@ -191,12 +196,15 @@ public class BinaryOperation extends Expression {
} else { } else {
dataType = Value.getHigherOrder(l, r); dataType = Value.getHigherOrder(l, r);
if (dataType == Value.ENUM) { if (dataType == Value.ENUM) {
type = TypeInfo.TYPE_INT;
dataType = Value.INT; dataType = Value.INT;
} else if (DataType.isStringType(dataType) && } else {
session.getDatabase().getMode().allowPlusForStringConcat) { type = TypeInfo.getTypeInfo(dataType);
if (DataType.isStringType(dataType) && session.getDatabase().getMode().allowPlusForStringConcat) {
opType = OpType.CONCAT; opType = OpType.CONCAT;
} }
} }
}
break; break;
default: default:
DbException.throwInternalError("type=" + opType); DbException.throwInternalError("type=" + opType);
...@@ -311,8 +319,10 @@ public class BinaryOperation extends Expression { ...@@ -311,8 +319,10 @@ public class BinaryOperation extends Expression {
case Value.TIME: case Value.TIME:
if (r == Value.TIME || r == Value.TIMESTAMP_TZ) { if (r == Value.TIME || r == Value.TIMESTAMP_TZ) {
dataType = r; dataType = r;
type = TypeInfo.getTypeInfo(r);
return this; return this;
} else { // DATE, TIMESTAMP } else { // DATE, TIMESTAMP
type = TypeInfo.TYPE_TIMESTAMP;
dataType = Value.TIMESTAMP; dataType = Value.TIMESTAMP;
return this; return this;
} }
...@@ -351,6 +361,7 @@ public class BinaryOperation extends Expression { ...@@ -351,6 +361,7 @@ public class BinaryOperation extends Expression {
return f.optimize(session); return f.optimize(session);
} }
case Value.TIME: case Value.TIME:
type = TypeInfo.TYPE_TIMESTAMP;
dataType = Value.TIMESTAMP; dataType = Value.TIMESTAMP;
return this; return this;
case Value.DATE: case Value.DATE:
...@@ -368,11 +379,13 @@ public class BinaryOperation extends Expression { ...@@ -368,11 +379,13 @@ public class BinaryOperation extends Expression {
break; break;
case MULTIPLY: case MULTIPLY:
if (l == Value.TIME) { if (l == Value.TIME) {
type = TypeInfo.TYPE_TIME;
dataType = Value.TIME; dataType = Value.TIME;
convertRight = false; convertRight = false;
return this; return this;
} else if (r == Value.TIME) { } else if (r == Value.TIME) {
swap(); swap();
type = TypeInfo.TYPE_TIME;
dataType = Value.TIME; dataType = Value.TIME;
convertRight = false; convertRight = false;
return this; return this;
...@@ -380,6 +393,7 @@ public class BinaryOperation extends Expression { ...@@ -380,6 +393,7 @@ public class BinaryOperation extends Expression {
break; break;
case DIVIDE: case DIVIDE:
if (l == Value.TIME) { if (l == Value.TIME) {
type = TypeInfo.TYPE_TIME;
dataType = Value.TIME; dataType = Value.TIME;
convertRight = false; convertRight = false;
return this; return this;
...@@ -408,7 +422,12 @@ public class BinaryOperation extends Expression { ...@@ -408,7 +422,12 @@ public class BinaryOperation extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return type;
}
@Override
public int getValueType() {
return dataType; return dataType;
} }
......
...@@ -13,6 +13,7 @@ import org.h2.result.ResultInterface; ...@@ -13,6 +13,7 @@ import org.h2.result.ResultInterface;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
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;
...@@ -84,12 +85,20 @@ public abstract class Expression { ...@@ -84,12 +85,20 @@ public abstract class Expression {
public abstract Value getValue(Session session); public abstract Value getValue(Session session);
/** /**
* Return the data type. The data type may not be known before the * Returns the data type. The data type may not be known before the
* optimization phase. * optimization phase.
* *
* @return the type * @return the data type
*/ */
public abstract int getType(); public abstract TypeInfo getType();
/**
* Return the value type. The value type may not be known before the
* optimization phase.
*
* @return the value type
*/
public abstract int getValueType();
/** /**
* Map the columns of the resolver to expression columns. * Map the columns of the resolver to expression columns.
......
...@@ -22,6 +22,7 @@ import org.h2.table.ColumnResolver; ...@@ -22,6 +22,7 @@ import org.h2.table.ColumnResolver;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.ExtTypeInfo; import org.h2.value.ExtTypeInfo;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -225,7 +226,12 @@ public class ExpressionColumn extends Expression { ...@@ -225,7 +226,12 @@ public class ExpressionColumn extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return column == null ? TypeInfo.TYPE_UNKNOWN : column.getType();
}
@Override
public int getValueType() {
return column == null ? Value.UNKNOWN : column.getType().getValueType(); return column == null ? Value.UNKNOWN : column.getType().getValueType();
} }
......
...@@ -9,6 +9,7 @@ import org.h2.engine.Session; ...@@ -9,6 +9,7 @@ import org.h2.engine.Session;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
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;
import org.h2.value.ValueRow; import org.h2.value.ValueRow;
...@@ -37,7 +38,12 @@ public class ExpressionList extends Expression { ...@@ -37,7 +38,12 @@ public class ExpressionList extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return isArray ? TypeInfo.TYPE_ARRAY : TypeInfo.TYPE_ROW;
}
@Override
public int getValueType() {
return isArray ? Value.ARRAY : Value.ROW; return isArray ? Value.ARRAY : Value.ROW;
} }
...@@ -125,7 +131,7 @@ public class ExpressionList extends Expression { ...@@ -125,7 +131,7 @@ public class ExpressionList extends Expression {
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
Expression e = list[i]; Expression e = list[i];
Column col = new Column("C" + (i + 1), Column col = new Column("C" + (i + 1),
e.getType(), e.getPrecision(), e.getScale(), e.getValueType(), e.getPrecision(), e.getScale(),
e.getDisplaySize()); e.getDisplaySize());
expr[i] = new ExpressionColumn(session.getDatabase(), col); expr[i] = new ExpressionColumn(session.getDatabase(), col);
} }
......
...@@ -26,6 +26,7 @@ import org.h2.table.ColumnResolver; ...@@ -26,6 +26,7 @@ import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.IntervalUtils; import org.h2.util.IntervalUtils;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueDate; import org.h2.value.ValueDate;
import org.h2.value.ValueInterval; import org.h2.value.ValueInterval;
...@@ -77,6 +78,7 @@ public class IntervalOperation extends Expression { ...@@ -77,6 +78,7 @@ public class IntervalOperation extends Expression {
private final IntervalOpType opType; private final IntervalOpType opType;
private Expression left, right; private Expression left, right;
private TypeInfo type;
private int dataType; private int dataType;
private static BigInteger nanosFromValue(Value v) { private static BigInteger nanosFromValue(Value v) {
...@@ -89,24 +91,29 @@ public class IntervalOperation extends Expression { ...@@ -89,24 +91,29 @@ public class IntervalOperation extends Expression {
this.opType = opType; this.opType = opType;
this.left = left; this.left = left;
this.right = right; this.right = right;
int l = left.getType(), r = right.getType(); int l = left.getValueType(), r = right.getValueType();
switch (opType) { switch (opType) {
case INTERVAL_PLUS_INTERVAL: case INTERVAL_PLUS_INTERVAL:
case INTERVAL_MINUS_INTERVAL: case INTERVAL_MINUS_INTERVAL:
dataType = Value.getHigherOrder(l, r); dataType = Value.getHigherOrder(l, r);
type = TypeInfo.getTypeInfo(dataType);
break; break;
case DATETIME_PLUS_INTERVAL: case DATETIME_PLUS_INTERVAL:
case DATETIME_MINUS_INTERVAL: case DATETIME_MINUS_INTERVAL:
case INTERVAL_MULTIPLY_NUMERIC: case INTERVAL_MULTIPLY_NUMERIC:
case INTERVAL_DIVIDE_NUMERIC: case INTERVAL_DIVIDE_NUMERIC:
type = left.getType();
dataType = l; dataType = l;
break; break;
case DATETIME_MINUS_DATETIME: case DATETIME_MINUS_DATETIME:
if (l == Value.TIME && r == Value.TIME) { if (l == Value.TIME && r == Value.TIME) {
type = TypeInfo.TYPE_INTERVAL_HOUR_TO_SECOND;
dataType = Value.INTERVAL_HOUR_TO_SECOND; dataType = Value.INTERVAL_HOUR_TO_SECOND;
} else if (l == Value.DATE && r == Value.DATE) { } else if (l == Value.DATE && r == Value.DATE) {
type = TypeInfo.TYPE_INTERVAL_DAY;
dataType = Value.INTERVAL_DAY; dataType = Value.INTERVAL_DAY;
} else { } else {
type = TypeInfo.TYPE_INTERVAL_DAY_TO_SECOND;
dataType = Value.INTERVAL_DAY_TO_SECOND; dataType = Value.INTERVAL_DAY_TO_SECOND;
} }
} }
...@@ -277,7 +284,12 @@ public class IntervalOperation extends Expression { ...@@ -277,7 +284,12 @@ public class IntervalOperation extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return type;
}
@Override
public int getValueType() {
return dataType; return dataType;
} }
......
...@@ -12,6 +12,7 @@ import org.h2.message.DbException; ...@@ -12,6 +12,7 @@ import org.h2.message.DbException;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -61,7 +62,18 @@ public class Parameter extends Expression implements ParameterInterface { ...@@ -61,7 +62,18 @@ public class Parameter extends Expression implements ParameterInterface {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
if (value != null) {
return value.getType();
}
if (column != null) {
return column.getType();
}
return TypeInfo.TYPE_UNKNOWN;
}
@Override
public int getValueType() {
if (value != null) { if (value != null) {
return value.getValueType(); return value.getValueType();
} }
......
...@@ -48,7 +48,7 @@ public interface ParameterInterface { ...@@ -48,7 +48,7 @@ public interface ParameterInterface {
* *
* @return the data type * @return the data type
*/ */
int getType(); int getValueType();
/** /**
* Get the expected precision of this parameter. * Get the expected precision of this parameter.
......
...@@ -55,7 +55,7 @@ public class ParameterRemote implements ParameterInterface { ...@@ -55,7 +55,7 @@ public class ParameterRemote implements ParameterInterface {
} }
@Override @Override
public int getType() { public int getValueType() {
return value == null ? dataType : value.getValueType(); return value == null ? dataType : value.getValueType();
} }
...@@ -94,7 +94,7 @@ public class ParameterRemote implements ParameterInterface { ...@@ -94,7 +94,7 @@ public class ParameterRemote implements ParameterInterface {
*/ */
public static void writeMetaData(Transfer transfer, ParameterInterface p) public static void writeMetaData(Transfer transfer, ParameterInterface p)
throws IOException { throws IOException {
transfer.writeInt(p.getType()); transfer.writeInt(p.getValueType());
transfer.writeLong(p.getPrecision()); transfer.writeLong(p.getPrecision());
transfer.writeInt(p.getScale()); transfer.writeInt(p.getScale());
transfer.writeInt(p.getNullable()); transfer.writeInt(p.getNullable());
......
...@@ -10,6 +10,7 @@ import org.h2.engine.Session; ...@@ -10,6 +10,7 @@ import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
...@@ -33,7 +34,12 @@ public class Rownum extends Expression { ...@@ -33,7 +34,12 @@ public class Rownum extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return TypeInfo.TYPE_LONG;
}
@Override
public int getValueType() {
return Value.LONG; return Value.LONG;
} }
......
...@@ -10,6 +10,7 @@ import org.h2.message.DbException; ...@@ -10,6 +10,7 @@ import org.h2.message.DbException;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
...@@ -32,7 +33,12 @@ public class SequenceValue extends Expression { ...@@ -32,7 +33,12 @@ public class SequenceValue extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return TypeInfo.TYPE_LONG;
}
@Override
public int getValueType() {
return Value.LONG; return Value.LONG;
} }
......
...@@ -13,6 +13,7 @@ import org.h2.message.DbException; ...@@ -13,6 +13,7 @@ import org.h2.message.DbException;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.h2.value.ValueRow; import org.h2.value.ValueRow;
...@@ -53,10 +54,15 @@ public class Subquery extends Expression { ...@@ -53,10 +54,15 @@ public class Subquery extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return getExpression().getType(); return getExpression().getType();
} }
@Override
public int getValueType() {
return getExpression().getValueType();
}
@Override @Override
public void mapColumns(ColumnResolver resolver, int level, int state) { public void mapColumns(ColumnResolver resolver, int level, int state) {
query.mapColumns(resolver, level + 1); query.mapColumns(resolver, level + 1);
......
...@@ -8,6 +8,7 @@ package org.h2.expression; ...@@ -8,6 +8,7 @@ package org.h2.expression;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -17,7 +18,7 @@ import org.h2.value.ValueNull; ...@@ -17,7 +18,7 @@ import org.h2.value.ValueNull;
public class UnaryOperation extends Expression { public class UnaryOperation extends Expression {
private Expression arg; private Expression arg;
private int dataType; private TypeInfo type;
public UnaryOperation(Expression arg) { public UnaryOperation(Expression arg) {
this.arg = arg; this.arg = arg;
...@@ -33,7 +34,7 @@ public class UnaryOperation extends Expression { ...@@ -33,7 +34,7 @@ public class UnaryOperation extends Expression {
@Override @Override
public Value getValue(Session session) { public Value getValue(Session session) {
Value a = arg.getValue(session).convertTo(dataType, session.getDatabase().getMode()); Value a = arg.getValue(session).convertTo(type.getValueType(), session.getDatabase().getMode());
return a == ValueNull.INSTANCE ? a : a.negate(); return a == ValueNull.INSTANCE ? a : a.negate();
} }
...@@ -45,11 +46,11 @@ public class UnaryOperation extends Expression { ...@@ -45,11 +46,11 @@ public class UnaryOperation extends Expression {
@Override @Override
public Expression optimize(Session session) { public Expression optimize(Session session) {
arg = arg.optimize(session); arg = arg.optimize(session);
dataType = arg.getType(); type = arg.getType();
if (dataType == Value.UNKNOWN) { if (type.getValueType() == Value.UNKNOWN) {
dataType = Value.DECIMAL; type = TypeInfo.TYPE_DECIMAL_DEFAULT;
} else if (dataType == Value.ENUM) { } else if (type.getValueType() == Value.ENUM) {
dataType = Value.INT; type = TypeInfo.TYPE_INT;
} }
if (arg.isConstant()) { if (arg.isConstant()) {
return ValueExpression.get(getValue(session)); return ValueExpression.get(getValue(session));
...@@ -63,8 +64,13 @@ public class UnaryOperation extends Expression { ...@@ -63,8 +64,13 @@ public class UnaryOperation extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return dataType; return type;
}
@Override
public int getValueType() {
return type.getValueType();
} }
@Override @Override
......
...@@ -11,6 +11,7 @@ import org.h2.index.IndexCondition; ...@@ -11,6 +11,7 @@ import org.h2.index.IndexCondition;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
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;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
...@@ -75,7 +76,12 @@ public class ValueExpression extends Expression { ...@@ -75,7 +76,12 @@ public class ValueExpression extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return value.getType();
}
@Override
public int getValueType() {
return value.getValueType(); return value.getValueType();
} }
...@@ -177,7 +183,7 @@ public class ValueExpression extends Expression { ...@@ -177,7 +183,7 @@ public class ValueExpression extends Expression {
@Override @Override
public Expression[] getExpressionColumns(Session session) { public Expression[] getExpressionColumns(Session session) {
if (getType() == Value.ARRAY) { if (getValueType() == Value.ARRAY) {
return getExpressionColumns(session, (ValueArray) getValue(session)); return getExpressionColumns(session, (ValueArray) getValue(session));
} }
return super.getExpressionColumns(session); return super.getExpressionColumns(session);
......
...@@ -10,6 +10,7 @@ import org.h2.engine.Session; ...@@ -10,6 +10,7 @@ import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
/** /**
...@@ -52,7 +53,12 @@ public class Variable extends Expression { ...@@ -52,7 +53,12 @@ public class Variable extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return lastValue.getType();
}
@Override
public int getValueType() {
return lastValue.getValueType(); return lastValue.getValueType();
} }
......
...@@ -15,6 +15,7 @@ import org.h2.table.Column; ...@@ -15,6 +15,7 @@ import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
/** /**
...@@ -67,7 +68,12 @@ public class Wildcard extends Expression { ...@@ -67,7 +68,12 @@ public class Wildcard extends Expression {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
throw DbException.throwInternalError(toString());
}
@Override
public int getValueType() {
throw DbException.throwInternalError(toString()); throw DbException.throwInternalError(toString());
} }
......
...@@ -35,6 +35,7 @@ import org.h2.util.StatementBuilder; ...@@ -35,6 +35,7 @@ import org.h2.util.StatementBuilder;
import org.h2.util.ValueHashMap; import org.h2.util.ValueHashMap;
import org.h2.value.CompareMode; import org.h2.value.CompareMode;
import org.h2.value.DataType; import org.h2.value.DataType;
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;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
...@@ -158,12 +159,13 @@ public class Aggregate extends AbstractAggregate { ...@@ -158,12 +159,13 @@ public class Aggregate extends AbstractAggregate {
private static final HashMap<String, AggregateType> AGGREGATES = new HashMap<>(64); private static final HashMap<String, AggregateType> AGGREGATES = new HashMap<>(64);
private final AggregateType type; private final AggregateType aggregateType;
private Expression on; private Expression on;
private Expression groupConcatSeparator; private Expression groupConcatSeparator;
private ArrayList<SelectOrderBy> orderByList; private ArrayList<SelectOrderBy> orderByList;
private SortOrder orderBySort; private SortOrder orderBySort;
private TypeInfo type;
private int dataType, scale; private int dataType, scale;
private long precision; private long precision;
private int displaySize; private int displaySize;
...@@ -171,7 +173,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -171,7 +173,7 @@ public class Aggregate extends AbstractAggregate {
/** /**
* Create a new aggregate object. * Create a new aggregate object.
* *
* @param type * @param aggregateType
* the aggregate type * the aggregate type
* @param on * @param on
* the aggregated expression * the aggregated expression
...@@ -180,12 +182,12 @@ public class Aggregate extends AbstractAggregate { ...@@ -180,12 +182,12 @@ public class Aggregate extends AbstractAggregate {
* @param distinct * @param distinct
* if distinct is used * if distinct is used
*/ */
public Aggregate(AggregateType type, Expression on, Select select, boolean distinct) { public Aggregate(AggregateType aggregateType, Expression on, Select select, boolean distinct) {
super(select, distinct); super(select, distinct);
if (distinct && type == AggregateType.COUNT_ALL) { if (distinct && aggregateType == AggregateType.COUNT_ALL) {
throw DbException.throwInternalError(); throw DbException.throwInternalError();
} }
this.type = type; this.aggregateType = aggregateType;
this.on = on; this.on = on;
} }
...@@ -272,7 +274,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -272,7 +274,7 @@ public class Aggregate extends AbstractAggregate {
* @return the type of this aggregate * @return the type of this aggregate
*/ */
public AggregateType getAggregateType() { public AggregateType getAggregateType() {
return type; return aggregateType;
} }
private void sortWithOrderBy(Value[] array) { private void sortWithOrderBy(Value[] array) {
...@@ -297,11 +299,11 @@ public class Aggregate extends AbstractAggregate { ...@@ -297,11 +299,11 @@ public class Aggregate extends AbstractAggregate {
} }
private void updateData(Session session, AggregateData data, Value v, Value[] remembered) { private void updateData(Session session, AggregateData data, Value v, Value[] remembered) {
if (type == AggregateType.GROUP_CONCAT) { if (aggregateType == AggregateType.GROUP_CONCAT) {
if (v != ValueNull.INSTANCE) { if (v != ValueNull.INSTANCE) {
v = updateCollecting(session, v.convertTo(Value.STRING), remembered); v = updateCollecting(session, v.convertTo(Value.STRING), remembered);
} }
} else if (type == AggregateType.ARRAY_AGG) { } else if (aggregateType == AggregateType.ARRAY_AGG) {
if (v != ValueNull.INSTANCE) { if (v != ValueNull.INSTANCE) {
v = updateCollecting(session, v, remembered); v = updateCollecting(session, v, remembered);
} }
...@@ -379,7 +381,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -379,7 +381,7 @@ public class Aggregate extends AbstractAggregate {
@Override @Override
protected Object createAggregateData() { protected Object createAggregateData() {
return AggregateData.create(type, distinct); return AggregateData.create(aggregateType, distinct);
} }
@Override @Override
...@@ -388,14 +390,14 @@ public class Aggregate extends AbstractAggregate { ...@@ -388,14 +390,14 @@ public class Aggregate extends AbstractAggregate {
} }
private Value getValueQuick(Session session) { private Value getValueQuick(Session session) {
switch (type) { switch (aggregateType) {
case COUNT: case COUNT:
case COUNT_ALL: case COUNT_ALL:
Table table = select.getTopTableFilter().getTable(); Table table = select.getTopTableFilter().getTable();
return ValueLong.get(table.getRowCount(session)); return ValueLong.get(table.getRowCount(session));
case MIN: case MIN:
case MAX: { case MAX: {
boolean first = type == AggregateType.MIN; boolean first = aggregateType == AggregateType.MIN;
Index index = getMinMaxColumnIndex(); Index index = getMinMaxColumnIndex();
int sortType = index.getIndexColumns()[0].sortType; int sortType = index.getIndexColumns()[0].sortType;
if ((sortType & SortOrder.DESCENDING) != 0) { if ((sortType & SortOrder.DESCENDING) != 0) {
...@@ -416,7 +418,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -416,7 +418,7 @@ public class Aggregate extends AbstractAggregate {
case ENVELOPE: case ENVELOPE:
return ((MVSpatialIndex) AggregateDataEnvelope.getGeometryColumnIndex(on)).getBounds(session); return ((MVSpatialIndex) AggregateDataEnvelope.getGeometryColumnIndex(on)).getBounds(session);
default: default:
throw DbException.throwInternalError("type=" + type); throw DbException.throwInternalError("type=" + aggregateType);
} }
} }
...@@ -426,7 +428,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -426,7 +428,7 @@ public class Aggregate extends AbstractAggregate {
if (data == null) { if (data == null) {
data = (AggregateData) createAggregateData(); data = (AggregateData) createAggregateData();
} }
switch (type) { switch (aggregateType) {
case COUNT: case COUNT:
if (distinct) { if (distinct) {
return ValueLong.get(((AggregateDataCollecting) data).getCount()); return ValueLong.get(((AggregateDataCollecting) data).getCount());
...@@ -443,7 +445,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -443,7 +445,7 @@ public class Aggregate extends AbstractAggregate {
if (c.getCount() == 0) { if (c.getCount() == 0) {
return ValueNull.INSTANCE; return ValueNull.INSTANCE;
} }
AggregateDataDefault d = new AggregateDataDefault(type); AggregateDataDefault d = new AggregateDataDefault(aggregateType);
Database db = session.getDatabase(); Database db = session.getDatabase();
for (Value v : c) { for (Value v : c) {
d.add(db, dataType, v); d.add(db, dataType, v);
...@@ -579,7 +581,12 @@ public class Aggregate extends AbstractAggregate { ...@@ -579,7 +581,12 @@ public class Aggregate extends AbstractAggregate {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return type;
}
@Override
public int getValueType() {
return dataType; return dataType;
} }
...@@ -604,7 +611,8 @@ public class Aggregate extends AbstractAggregate { ...@@ -604,7 +611,8 @@ public class Aggregate extends AbstractAggregate {
super.optimize(session); super.optimize(session);
if (on != null) { if (on != null) {
on = on.optimize(session); on = on.optimize(session);
dataType = on.getType(); type = on.getType();
dataType = on.getValueType();
scale = on.getScale(); scale = on.getScale();
precision = on.getPrecision(); precision = on.getPrecision();
displaySize = on.getDisplaySize(); displaySize = on.getDisplaySize();
...@@ -618,26 +626,30 @@ public class Aggregate extends AbstractAggregate { ...@@ -618,26 +626,30 @@ public class Aggregate extends AbstractAggregate {
if (groupConcatSeparator != null) { if (groupConcatSeparator != null) {
groupConcatSeparator = groupConcatSeparator.optimize(session); groupConcatSeparator = groupConcatSeparator.optimize(session);
} }
switch (type) { switch (aggregateType) {
case GROUP_CONCAT: case GROUP_CONCAT:
type = TypeInfo.TYPE_STRING_DEFAULT;
dataType = Value.STRING; dataType = Value.STRING;
scale = 0; scale = 0;
precision = displaySize = Integer.MAX_VALUE; precision = displaySize = Integer.MAX_VALUE;
break; break;
case COUNT_ALL: case COUNT_ALL:
case COUNT: case COUNT:
type = TypeInfo.TYPE_LONG;
dataType = Value.LONG; dataType = Value.LONG;
scale = 0; scale = 0;
precision = ValueLong.PRECISION; precision = ValueLong.PRECISION;
displaySize = ValueLong.DISPLAY_SIZE; displaySize = ValueLong.DISPLAY_SIZE;
break; break;
case SELECTIVITY: case SELECTIVITY:
type = TypeInfo.TYPE_INT;
dataType = Value.INT; dataType = Value.INT;
scale = 0; scale = 0;
precision = ValueInt.PRECISION; precision = ValueInt.PRECISION;
displaySize = ValueInt.DISPLAY_SIZE; displaySize = ValueInt.DISPLAY_SIZE;
break; break;
case HISTOGRAM: case HISTOGRAM:
type = TypeInfo.TYPE_ARRAY;
dataType = Value.ARRAY; dataType = Value.ARRAY;
scale = 0; scale = 0;
precision = displaySize = Integer.MAX_VALUE; precision = displaySize = Integer.MAX_VALUE;
...@@ -645,11 +657,13 @@ public class Aggregate extends AbstractAggregate { ...@@ -645,11 +657,13 @@ public class Aggregate extends AbstractAggregate {
case SUM: case SUM:
if (dataType == Value.BOOLEAN) { if (dataType == Value.BOOLEAN) {
// example: sum(id > 3) (count the rows) // example: sum(id > 3) (count the rows)
type = TypeInfo.TYPE_LONG;
dataType = Value.LONG; dataType = Value.LONG;
} else if (!DataType.supportsAdd(dataType)) { } else if (!DataType.supportsAdd(dataType)) {
throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL()); throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getSQL());
} else { } else {
dataType = DataType.getAddProofType(dataType); dataType = DataType.getAddProofType(dataType);
type = TypeInfo.getTypeInfo(dataType);
} }
break; break;
case AVG: case AVG:
...@@ -666,6 +680,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -666,6 +680,7 @@ public class Aggregate extends AbstractAggregate {
case STDDEV_SAMP: case STDDEV_SAMP:
case VAR_POP: case VAR_POP:
case VAR_SAMP: case VAR_SAMP:
type = TypeInfo.TYPE_DOUBLE;
dataType = Value.DOUBLE; dataType = Value.DOUBLE;
precision = ValueDouble.PRECISION; precision = ValueDouble.PRECISION;
displaySize = ValueDouble.DISPLAY_SIZE; displaySize = ValueDouble.DISPLAY_SIZE;
...@@ -673,6 +688,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -673,6 +688,7 @@ public class Aggregate extends AbstractAggregate {
break; break;
case EVERY: case EVERY:
case ANY: case ANY:
type = TypeInfo.TYPE_BOOLEAN;
dataType = Value.BOOLEAN; dataType = Value.BOOLEAN;
precision = ValueBoolean.PRECISION; precision = ValueBoolean.PRECISION;
displaySize = ValueBoolean.DISPLAY_SIZE; displaySize = ValueBoolean.DISPLAY_SIZE;
...@@ -685,17 +701,19 @@ public class Aggregate extends AbstractAggregate { ...@@ -685,17 +701,19 @@ public class Aggregate extends AbstractAggregate {
} }
break; break;
case ARRAY_AGG: case ARRAY_AGG:
type = TypeInfo.TYPE_ARRAY;
dataType = Value.ARRAY; dataType = Value.ARRAY;
scale = 0; scale = 0;
precision = displaySize = Integer.MAX_VALUE; precision = displaySize = Integer.MAX_VALUE;
break; break;
case ENVELOPE: case ENVELOPE:
type = TypeInfo.TYPE_GEOMETRY;
dataType = Value.GEOMETRY; dataType = Value.GEOMETRY;
scale = 0; scale = 0;
precision = displaySize = Integer.MAX_VALUE; precision = displaySize = Integer.MAX_VALUE;
break; break;
default: default:
DbException.throwInternalError("type=" + type); DbException.throwInternalError("type=" + aggregateType);
} }
return this; return this;
} }
...@@ -760,7 +778,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -760,7 +778,7 @@ public class Aggregate extends AbstractAggregate {
@Override @Override
public StringBuilder getSQL(StringBuilder builder) { public StringBuilder getSQL(StringBuilder builder) {
String text; String text;
switch (type) { switch (aggregateType) {
case GROUP_CONCAT: case GROUP_CONCAT:
return getSQLGroupConcat(builder); return getSQLGroupConcat(builder);
case COUNT_ALL: case COUNT_ALL:
...@@ -822,7 +840,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -822,7 +840,7 @@ public class Aggregate extends AbstractAggregate {
text = "ENVELOPE"; text = "ENVELOPE";
break; break;
default: default:
throw DbException.throwInternalError("type=" + type); throw DbException.throwInternalError("type=" + aggregateType);
} }
builder.append(text); builder.append(text);
if (distinct) { if (distinct) {
...@@ -862,7 +880,7 @@ public class Aggregate extends AbstractAggregate { ...@@ -862,7 +880,7 @@ public class Aggregate extends AbstractAggregate {
return false; return false;
} }
if (visitor.getType() == ExpressionVisitor.OPTIMIZABLE_AGGREGATE) { if (visitor.getType() == ExpressionVisitor.OPTIMIZABLE_AGGREGATE) {
switch (type) { switch (aggregateType) {
case COUNT: case COUNT:
if (!distinct && on.getNullable() == Column.NOT_NULLABLE) { if (!distinct && on.getNullable() == Column.NOT_NULLABLE) {
return visitor.getTable().canGetRowCount(); return visitor.getTable().canGetRowCount();
......
...@@ -18,6 +18,7 @@ import org.h2.message.DbException; ...@@ -18,6 +18,7 @@ import org.h2.message.DbException;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.DataType; import org.h2.value.DataType;
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;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
...@@ -31,6 +32,7 @@ public class JavaAggregate extends AbstractAggregate { ...@@ -31,6 +32,7 @@ public class JavaAggregate extends AbstractAggregate {
private final UserAggregate userAggregate; private final UserAggregate userAggregate;
private final Expression[] args; private final Expression[] args;
private int[] argTypes; private int[] argTypes;
private TypeInfo type;
private int dataType; private int dataType;
private Connection userConnection; private Connection userConnection;
...@@ -76,7 +78,12 @@ public class JavaAggregate extends AbstractAggregate { ...@@ -76,7 +78,12 @@ public class JavaAggregate extends AbstractAggregate {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return type;
}
@Override
public int getValueType() {
return dataType; return dataType;
} }
...@@ -122,12 +129,13 @@ public class JavaAggregate extends AbstractAggregate { ...@@ -122,12 +129,13 @@ public class JavaAggregate extends AbstractAggregate {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
Expression expr = args[i]; Expression expr = args[i];
args[i] = expr.optimize(session); args[i] = expr.optimize(session);
int type = expr.getType(); int type = expr.getValueType();
argTypes[i] = type; argTypes[i] = type;
} }
try { try {
Aggregate aggregate = getInstance(); Aggregate aggregate = getInstance();
dataType = aggregate.getInternalType(argTypes); dataType = aggregate.getInternalType(argTypes);
type = TypeInfo.getTypeInfo(dataType);
} catch (SQLException e) { } catch (SQLException e) {
throw DbException.convert(e); throw DbException.convert(e);
} }
......
...@@ -16,6 +16,7 @@ import org.h2.expression.Expression; ...@@ -16,6 +16,7 @@ import org.h2.expression.Expression;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueDouble; import org.h2.value.ValueDouble;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
...@@ -286,7 +287,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -286,7 +287,7 @@ public class WindowFunction extends DataAnalysisOperation {
int rowIdColumn) { int rowIdColumn) {
int size = ordered.size(); int size = ordered.size();
int numExpressions = getNumExpressions(); int numExpressions = getNumExpressions();
int dataType = args[0].getType(); int dataType = args[0].getValueType();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Value[] row = ordered.get(i); Value[] row = ordered.get(i);
int rowId = row[rowIdColumn].getInt(); int rowId = row[rowIdColumn].getInt();
...@@ -475,7 +476,30 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -475,7 +476,30 @@ public class WindowFunction extends DataAnalysisOperation {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
switch (type) {
case ROW_NUMBER:
case RANK:
case DENSE_RANK:
case NTILE:
return TypeInfo.TYPE_LONG;
case PERCENT_RANK:
case CUME_DIST:
case RATIO_TO_REPORT:
return TypeInfo.TYPE_DOUBLE;
case LEAD:
case LAG:
case FIRST_VALUE:
case LAST_VALUE:
case NTH_VALUE:
return args[0].getType();
default:
throw DbException.throwInternalError("type=" + type);
}
}
@Override
public int getValueType() {
switch (type) { switch (type) {
case ROW_NUMBER: case ROW_NUMBER:
case RANK: case RANK:
...@@ -491,7 +515,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -491,7 +515,7 @@ public class WindowFunction extends DataAnalysisOperation {
case FIRST_VALUE: case FIRST_VALUE:
case LAST_VALUE: case LAST_VALUE:
case NTH_VALUE: case NTH_VALUE:
return args[0].getType(); return args[0].getValueType();
default: default:
throw DbException.throwInternalError("type=" + type); throw DbException.throwInternalError("type=" + type);
} }
......
...@@ -100,7 +100,7 @@ public class CompareLike extends Condition { ...@@ -100,7 +100,7 @@ public class CompareLike extends Condition {
public Expression optimize(Session session) { public Expression optimize(Session session) {
left = left.optimize(session); left = left.optimize(session);
right = right.optimize(session); right = right.optimize(session);
if (left.getType() == Value.STRING_IGNORECASE) { if (left.getValueType() == Value.STRING_IGNORECASE) {
ignoreCase = true; ignoreCase = true;
} }
if (left.isValueSet()) { if (left.isValueSet()) {
......
...@@ -206,7 +206,7 @@ public class Comparison extends Condition { ...@@ -206,7 +206,7 @@ public class Comparison extends Condition {
if (right != null) { if (right != null) {
right = right.optimize(session); right = right.optimize(session);
// TODO check row values too // TODO check row values too
if (right.getType() == Value.ARRAY && left.getType() != Value.ARRAY) { if (right.getValueType() == Value.ARRAY && left.getValueType() != Value.ARRAY) {
throw DbException.get(ErrorCode.COMPARING_ARRAY_TO_SCALAR); throw DbException.get(ErrorCode.COMPARING_ARRAY_TO_SCALAR);
} }
if (right instanceof ExpressionColumn) { if (right instanceof ExpressionColumn) {
...@@ -225,7 +225,7 @@ public class Comparison extends Condition { ...@@ -225,7 +225,7 @@ public class Comparison extends Condition {
return ValueExpression.getNull(); return ValueExpression.getNull();
} }
} }
int colType = left.getType(); int colType = left.getValueType();
int constType = r.getValueType(); int constType = r.getValueType();
int resType = Value.getHigherOrder(colType, constType); int resType = Value.getHigherOrder(colType, constType);
// If not, the column values will need to be promoted // If not, the column values will need to be promoted
...@@ -516,12 +516,12 @@ public class Comparison extends Condition { ...@@ -516,12 +516,12 @@ public class Comparison extends Condition {
} }
if (addIndex) { if (addIndex) {
if (l != null) { if (l != null) {
if (l.getType() == right.getType() || right.getType() != Value.STRING_IGNORECASE) { if (l.getValueType() == right.getValueType() || right.getValueType() != Value.STRING_IGNORECASE) {
filter.addIndexCondition( filter.addIndexCondition(
IndexCondition.get(compareType, l, right)); IndexCondition.get(compareType, l, right));
} }
} else if (r != null) { } else if (r != null) {
if (r.getType() == left.getType() || left.getType() != Value.STRING_IGNORECASE) { if (r.getValueType() == left.getValueType() || left.getValueType() != Value.STRING_IGNORECASE) {
int compareRev = getReversedCompareType(compareType); int compareRev = getReversedCompareType(compareType);
filter.addIndexCondition( filter.addIndexCondition(
IndexCondition.get(compareRev, r, left)); IndexCondition.get(compareRev, r, left));
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
package org.h2.expression.condition; package org.h2.expression.condition;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
...@@ -15,7 +16,12 @@ import org.h2.value.ValueBoolean; ...@@ -15,7 +16,12 @@ import org.h2.value.ValueBoolean;
abstract class Condition extends Expression { abstract class Condition extends Expression {
@Override @Override
public int getType() { public TypeInfo getType() {
return TypeInfo.TYPE_BOOLEAN;
}
@Override
public int getValueType() {
return Value.BOOLEAN; return Value.BOOLEAN;
} }
......
...@@ -150,7 +150,7 @@ public class ConditionIn extends Condition { ...@@ -150,7 +150,7 @@ public class ConditionIn extends Condition {
return new Comparison(session, Comparison.EQUAL, left, values.get(0)).optimize(session); return new Comparison(session, Comparison.EQUAL, left, values.get(0)).optimize(session);
} }
if (allValuesConstant && !allValuesNull) { if (allValuesConstant && !allValuesNull) {
int leftType = left.getType(); int leftType = left.getValueType();
if (leftType == Value.UNKNOWN) { if (leftType == Value.UNKNOWN) {
return this; return this;
} }
......
...@@ -54,7 +54,7 @@ public class ConditionInConstantSet extends Condition { ...@@ -54,7 +54,7 @@ public class ConditionInConstantSet extends Condition {
this.valueList = valueList; this.valueList = valueList;
Database database = session.getDatabase(); Database database = session.getDatabase();
this.valueSet = new TreeSet<>(database.getCompareMode()); this.valueSet = new TreeSet<>(database.getCompareMode());
type = left.getType(); type = left.getValueType();
Mode mode = database.getMode(); Mode mode = database.getMode();
if (type == Value.ENUM) { if (type == Value.ENUM) {
extTypeInfo = ((ExpressionColumn) left).getColumn().getType().getExtTypeInfo(); extTypeInfo = ((ExpressionColumn) left).getColumn().getType().getExtTypeInfo();
......
...@@ -36,7 +36,7 @@ public interface FunctionCall { ...@@ -36,7 +36,7 @@ public interface FunctionCall {
* *
* @return the data type * @return the data type
*/ */
int getType(); int getValueType();
/** /**
* Optimize the function if possible. * Optimize the function if possible.
......
...@@ -15,6 +15,7 @@ import org.h2.expression.ValueExpression; ...@@ -15,6 +15,7 @@ import org.h2.expression.ValueExpression;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.DataType; import org.h2.value.DataType;
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;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -41,7 +42,12 @@ public class JavaFunction extends Expression implements FunctionCall { ...@@ -41,7 +42,12 @@ public class JavaFunction extends Expression implements FunctionCall {
} }
@Override @Override
public int getType() { public TypeInfo getType() {
return TypeInfo.getTypeInfo(javaMethod.getDataType());
}
@Override
public int getValueType() {
return javaMethod.getDataType(); return javaMethod.getDataType();
} }
...@@ -77,7 +83,7 @@ public class JavaFunction extends Expression implements FunctionCall { ...@@ -77,7 +83,7 @@ public class JavaFunction extends Expression implements FunctionCall {
@Override @Override
public int getScale() { public int getScale() {
return DataType.getDataType(getType()).defaultScale; return DataType.getDataType(getValueType()).defaultScale;
} }
@Override @Override
...@@ -166,7 +172,7 @@ public class JavaFunction extends Expression implements FunctionCall { ...@@ -166,7 +172,7 @@ public class JavaFunction extends Expression implements FunctionCall {
@Override @Override
public Expression[] getExpressionColumns(Session session) { public Expression[] getExpressionColumns(Session session) {
switch (getType()) { switch (getValueType()) {
case Value.RESULT_SET: case Value.RESULT_SET:
ValueResultSet rs = getValueForColumnList(session, getArgs()); ValueResultSet rs = getValueForColumnList(session, getArgs());
return getExpressionColumns(session, rs.getResult()); return getExpressionColumns(session, rs.getResult());
......
...@@ -81,7 +81,7 @@ public class JdbcParameterMetaData extends TraceObject implements ...@@ -81,7 +81,7 @@ public class JdbcParameterMetaData extends TraceObject implements
try { try {
debugCodeCall("getParameterType", param); debugCodeCall("getParameterType", param);
ParameterInterface p = getParameter(param); ParameterInterface p = getParameter(param);
int type = p.getType(); int type = p.getValueType();
if (type == Value.UNKNOWN) { if (type == Value.UNKNOWN) {
type = Value.STRING; type = Value.STRING;
} }
...@@ -174,7 +174,7 @@ public class JdbcParameterMetaData extends TraceObject implements ...@@ -174,7 +174,7 @@ public class JdbcParameterMetaData extends TraceObject implements
try { try {
debugCodeCall("getParameterClassName", param); debugCodeCall("getParameterClassName", param);
ParameterInterface p = getParameter(param); ParameterInterface p = getParameter(param);
int type = p.getType(); int type = p.getValueType();
if (type == Value.UNKNOWN) { if (type == Value.UNKNOWN) {
type = Value.STRING; type = Value.STRING;
} }
...@@ -196,7 +196,7 @@ public class JdbcParameterMetaData extends TraceObject implements ...@@ -196,7 +196,7 @@ public class JdbcParameterMetaData extends TraceObject implements
try { try {
debugCodeCall("getParameterTypeName", param); debugCodeCall("getParameterTypeName", param);
ParameterInterface p = getParameter(param); ParameterInterface p = getParameter(param);
int type = p.getType(); int type = p.getValueType();
if (type == Value.UNKNOWN) { if (type == Value.UNKNOWN) {
type = Value.STRING; type = Value.STRING;
} }
......
...@@ -19,7 +19,7 @@ import org.h2.expression.function.Function; ...@@ -19,7 +19,7 @@ import org.h2.expression.function.Function;
import org.h2.expression.function.FunctionInfo; import org.h2.expression.function.FunctionInfo;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.DataType; import org.h2.value.TypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -203,10 +203,7 @@ public class FunctionsMySQL extends FunctionsBase { ...@@ -203,10 +203,7 @@ public class FunctionsMySQL extends FunctionsBase {
return ValueExpression.get(getValue(session)); return ValueExpression.get(getValue(session));
} }
dataType = info.returnDataType; dataType = info.returnDataType;
DataType dt = DataType.getDataType(dataType); type = TypeInfo.getTypeInfo(dataType);
precision = dt.defaultPrecision;
scale = dt.defaultScale;
displaySize = dt.defaultDisplaySize;
return this; return this;
} }
......
...@@ -140,7 +140,7 @@ public abstract class LazyResult implements ResultInterface { ...@@ -140,7 +140,7 @@ public abstract class LazyResult implements ResultInterface {
@Override @Override
public int getColumnType(int i) { public int getColumnType(int i) {
return expressions[i].getType(); return expressions[i].getValueType();
} }
@Override @Override
......
...@@ -539,7 +539,7 @@ public class LocalResultImpl implements LocalResult { ...@@ -539,7 +539,7 @@ public class LocalResultImpl implements LocalResult {
@Override @Override
public int getColumnType(int i) { public int getColumnType(int i) {
return expressions[i].getType(); return expressions[i].getValueType();
} }
@Override @Override
......
...@@ -117,7 +117,7 @@ public class ResultTempTable implements ResultExternal { ...@@ -117,7 +117,7 @@ public class ResultTempTable implements ResultExternal {
CreateTableData data = new CreateTableData(); CreateTableData data = new CreateTableData();
boolean containsLob = false; boolean containsLob = false;
for (int i = 0; i < expressions.length; i++) { for (int i = 0; i < expressions.length; i++) {
int type = expressions[i].getType(); int type = expressions[i].getValueType();
Column col = new Column(COLUMN_NAME + i, type); Column col = new Column(COLUMN_NAME + i, type);
if (DataType.isLargeObject(type)) { if (DataType.isLargeObject(type)) {
containsLob = true; containsLob = true;
......
...@@ -45,7 +45,7 @@ public class FunctionTable extends Table { ...@@ -45,7 +45,7 @@ public class FunctionTable extends Table {
rowCount = Long.MAX_VALUE; rowCount = Long.MAX_VALUE;
} }
function.optimize(session); function.optimize(session);
int type = function.getType(); int type = function.getValueType();
if (type != Value.RESULT_SET) { if (type != Value.RESULT_SET) {
throw DbException.get( throw DbException.get(
ErrorCode.FUNCTION_MUST_RETURN_RESULT_SET_1, function.getName()); ErrorCode.FUNCTION_MUST_RETURN_RESULT_SET_1, function.getName());
......
...@@ -1762,7 +1762,7 @@ public class MetaTable extends Table { ...@@ -1762,7 +1762,7 @@ public class MetaTable extends Table {
// CONSTANT_NAME // CONSTANT_NAME
identifier(constant.getName()), identifier(constant.getName()),
// DATA_TYPE // DATA_TYPE
ValueInt.get(DataType.convertTypeToSQLType(expr.getType())), ValueInt.get(DataType.convertTypeToSQLType(expr.getValueType())),
// REMARKS // REMARKS
replaceNullWithEmpty(constant.getComment()), replaceNullWithEmpty(constant.getComment()),
// SQL // SQL
......
...@@ -191,7 +191,7 @@ public class TableView extends Table { ...@@ -191,7 +191,7 @@ public class TableView extends Table {
} }
name = columnNamer.getColumnName(expr, i, name); name = columnNamer.getColumnName(expr, i, name);
if (type == Value.UNKNOWN) { if (type == Value.UNKNOWN) {
type = expr.getType(); type = expr.getValueType();
} }
long precision = expr.getPrecision(); long precision = expr.getPrecision();
int scale = expr.getScale(); int scale = expr.getScale();
...@@ -818,7 +818,7 @@ public class TableView extends Table { ...@@ -818,7 +818,7 @@ public class TableView extends Table {
// expression // expression
String columnName = columnNamer.getColumnName(columnExp, i, cols); String columnName = columnNamer.getColumnName(columnExp, i, cols);
columnTemplateList.add(new Column(columnName, columnTemplateList.add(new Column(columnName,
columnExp.getType())); columnExp.getValueType()));
} }
return columnTemplateList; return columnTemplateList;
......
...@@ -377,6 +377,7 @@ public class DataType { ...@@ -377,6 +377,7 @@ public class DataType {
32 32
); );
dataType = new DataType(); dataType = new DataType();
dataType.maxPrecision = dataType.defaultPrecision = dataType.defaultDisplaySize = Integer.MAX_VALUE;
add(Value.RESULT_SET, DataType.TYPE_RESULT_SET, add(Value.RESULT_SET, DataType.TYPE_RESULT_SET,
dataType, dataType,
new String[]{"RESULT_SET"}, new String[]{"RESULT_SET"},
......
...@@ -8,12 +8,18 @@ package org.h2.value; ...@@ -8,12 +8,18 @@ package org.h2.value;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils;
/** /**
* Data type with parameters. * Data type with parameters.
*/ */
public class TypeInfo { public class TypeInfo {
/**
* UNKNOWN type with parameters.
*/
public static final TypeInfo TYPE_UNKNOWN;
/** /**
* NULL type with parameters. * NULL type with parameters.
*/ */
...@@ -44,6 +50,11 @@ public class TypeInfo { ...@@ -44,6 +50,11 @@ public class TypeInfo {
*/ */
public static final TypeInfo TYPE_LONG; public static final TypeInfo TYPE_LONG;
/**
* DECIMAL type with default parameters.
*/
public static final TypeInfo TYPE_DECIMAL_DEFAULT;
/** /**
* DOUBLE type with parameters. * DOUBLE type with parameters.
*/ */
...@@ -69,6 +80,11 @@ public class TypeInfo { ...@@ -69,6 +80,11 @@ public class TypeInfo {
*/ */
public static final TypeInfo TYPE_TIMESTAMP; public static final TypeInfo TYPE_TIMESTAMP;
/**
* STRING type with default parameters.
*/
public static final TypeInfo TYPE_STRING_DEFAULT;
/** /**
* ARRAY type with parameters. * ARRAY type with parameters.
*/ */
...@@ -104,6 +120,21 @@ public class TypeInfo { ...@@ -104,6 +120,21 @@ public class TypeInfo {
*/ */
public static final TypeInfo TYPE_ENUM_UNDEFINED; public static final TypeInfo TYPE_ENUM_UNDEFINED;
/**
* INTERVAL DAY type with parameters.
*/
public static final TypeInfo TYPE_INTERVAL_DAY;
/**
* INTERVAL DAY TO SECOND type with parameters.
*/
public static final TypeInfo TYPE_INTERVAL_DAY_TO_SECOND;
/**
* INTERVAL HOUR TO SECOND type with parameters.
*/
public static final TypeInfo TYPE_INTERVAL_HOUR_TO_SECOND;
/** /**
* ROW (row value) type with parameters. * ROW (row value) type with parameters.
*/ */
...@@ -131,17 +162,20 @@ public class TypeInfo { ...@@ -131,17 +162,20 @@ public class TypeInfo {
infos[i] = createTypeInfo(i, dt); infos[i] = createTypeInfo(i, dt);
} }
} }
TYPE_UNKNOWN = new TypeInfo(Value.UNKNOWN, -1L, -1, -1, null);
TYPE_NULL = infos[Value.NULL]; TYPE_NULL = infos[Value.NULL];
TYPE_BOOLEAN = infos[Value.BOOLEAN]; TYPE_BOOLEAN = infos[Value.BOOLEAN];
TYPE_BYTE = infos[Value.BYTE]; TYPE_BYTE = infos[Value.BYTE];
TYPE_SHORT = infos[Value.SHORT]; TYPE_SHORT = infos[Value.SHORT];
TYPE_INT = infos[Value.INT]; TYPE_INT = infos[Value.INT];
TYPE_LONG = infos[Value.LONG]; TYPE_LONG = infos[Value.LONG];
TYPE_DECIMAL_DEFAULT = infos[Value.DECIMAL];
TYPE_DOUBLE = infos[Value.DOUBLE]; TYPE_DOUBLE = infos[Value.DOUBLE];
TYPE_FLOAT = infos[Value.FLOAT]; TYPE_FLOAT = infos[Value.FLOAT];
TYPE_TIME = infos[Value.TIME]; TYPE_TIME = infos[Value.TIME];
TYPE_DATE = infos[Value.DATE]; TYPE_DATE = infos[Value.DATE];
TYPE_TIMESTAMP = infos[Value.TIMESTAMP]; TYPE_TIMESTAMP = infos[Value.TIMESTAMP];
TYPE_STRING_DEFAULT = infos[Value.STRING];
TYPE_ARRAY = infos[Value.ARRAY]; TYPE_ARRAY = infos[Value.ARRAY];
TYPE_RESULT_SET = infos[Value.RESULT_SET]; TYPE_RESULT_SET = infos[Value.RESULT_SET];
TYPE_JAVA_OBJECT = infos[Value.JAVA_OBJECT]; TYPE_JAVA_OBJECT = infos[Value.JAVA_OBJECT];
...@@ -149,6 +183,9 @@ public class TypeInfo { ...@@ -149,6 +183,9 @@ public class TypeInfo {
TYPE_GEOMETRY = infos[Value.GEOMETRY]; TYPE_GEOMETRY = infos[Value.GEOMETRY];
TYPE_TIMESTAMP_TZ = infos[Value.TIMESTAMP_TZ]; TYPE_TIMESTAMP_TZ = infos[Value.TIMESTAMP_TZ];
TYPE_ENUM_UNDEFINED = infos[Value.ENUM]; TYPE_ENUM_UNDEFINED = infos[Value.ENUM];
TYPE_INTERVAL_DAY = infos[Value.INTERVAL_DAY];
TYPE_INTERVAL_DAY_TO_SECOND = infos[Value.INTERVAL_DAY_TO_SECOND];
TYPE_INTERVAL_HOUR_TO_SECOND = infos[Value.INTERVAL_HOUR_TO_SECOND];
TYPE_ROW = infos[Value.ROW]; TYPE_ROW = infos[Value.ROW];
TYPE_INFOS_BY_VALUE_TYPE = infos; TYPE_INFOS_BY_VALUE_TYPE = infos;
} }
...@@ -157,7 +194,8 @@ public class TypeInfo { ...@@ -157,7 +194,8 @@ public class TypeInfo {
* Get the data type with parameters object for the given value type and * Get the data type with parameters object for the given value type and
* maximum parameters. * maximum parameters.
* *
* @param type the value type * @param type
* the value type
* @return the data type with parameters object * @return the data type with parameters object
*/ */
public static TypeInfo getTypeInfo(int type) { public static TypeInfo getTypeInfo(int type) {
...@@ -165,7 +203,7 @@ public class TypeInfo { ...@@ -165,7 +203,7 @@ public class TypeInfo {
throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, "?"); throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, "?");
} }
if (type >= Value.NULL && type < Value.TYPE_COUNT) { if (type >= Value.NULL && type < Value.TYPE_COUNT) {
TypeInfo t = TypeInfo.TYPE_INFOS_BY_VALUE_TYPE[type]; TypeInfo t = TYPE_INFOS_BY_VALUE_TYPE[type];
if (t != null) { if (t != null) {
return t; return t;
} }
...@@ -176,7 +214,126 @@ public class TypeInfo { ...@@ -176,7 +214,126 @@ public class TypeInfo {
return createTypeInfo(type, dt); return createTypeInfo(type, dt);
} }
} }
return TypeInfo.TYPE_INFOS_BY_VALUE_TYPE[Value.NULL]; return TYPE_NULL;
}
/**
* Get the data type with parameters object for the given value type and the
* specified parameters.
*
* @param type
* the value type
* @param precision
* the precision
* @param scale
* the scale
* @param displaySize
* the display size in characters
* @param extTypeInfo
* the extended type information, or null
* @return the data type with parameters object
*/
public static TypeInfo getTypeInfo(int type, long precision, int scale, int displaySize, ExtTypeInfo extTypeInfo) {
switch (type) {
case Value.NULL:
case Value.BOOLEAN:
case Value.BYTE:
case Value.SHORT:
case Value.INT:
case Value.DOUBLE:
case Value.FLOAT:
case Value.DATE:
case Value.ARRAY:
case Value.RESULT_SET:
case Value.JAVA_OBJECT:
case Value.UUID:
case Value.ROW:
return TYPE_INFOS_BY_VALUE_TYPE[type];
case Value.UNKNOWN:
return TYPE_UNKNOWN;
case Value.DECIMAL:
if (precision < 0) {
precision = ValueDecimal.DEFAULT_PRECISION;
}
if (scale < 0) {
scale = ValueDecimal.DEFAULT_SCALE;
}
return new TypeInfo(Value.DECIMAL, precision, scale, MathUtils.convertLongToInt(precision + 2), null);
case Value.TIME:
if (scale < 0 || scale >= ValueTime.MAXIMUM_SCALE) {
return TYPE_TIME;
}
return new TypeInfo(Value.TIME, ValueTime.MAXIMUM_PRECISION, scale, ValueTime.DEFAULT_PRECISION, null);
case Value.TIMESTAMP:
if (scale < 0 || scale >= ValueTimestamp.MAXIMUM_SCALE) {
return TYPE_TIMESTAMP;
}
return new TypeInfo(Value.TIMESTAMP, ValueTimestamp.MAXIMUM_PRECISION, scale,
ValueTimestamp.MAXIMUM_PRECISION, null);
case Value.TIMESTAMP_TZ:
if (scale < 0 || scale >= ValueTimestampTimeZone.MAXIMUM_SCALE) {
return TYPE_TIMESTAMP_TZ;
}
return new TypeInfo(Value.TIMESTAMP_TZ, ValueTimestampTimeZone.MAXIMUM_PRECISION, scale,
ValueTimestampTimeZone.MAXIMUM_PRECISION, null);
case Value.BYTES:
if (precision < 0) {
precision = Integer.MAX_VALUE;
}
return new TypeInfo(Value.BYTES, precision, scale, MathUtils.convertLongToInt(precision) * 2, null);
case Value.STRING:
if (precision < 0) {
return TYPE_STRING_DEFAULT;
}
//$FALL-THROUGH$
case Value.STRING_FIXED:
case Value.STRING_IGNORECASE:
case Value.BLOB:
case Value.CLOB:
return new TypeInfo(type, precision, 0, MathUtils.convertLongToInt(precision), null);
case Value.GEOMETRY:
if (extTypeInfo == null) {
return TYPE_GEOMETRY;
}
return new TypeInfo(Value.GEOMETRY, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, extTypeInfo);
case Value.ENUM:
if (extTypeInfo == null) {
return TYPE_ENUM_UNDEFINED;
}
return new TypeInfo(Value.ENUM, ValueEnum.PRECISION, 0, ValueEnum.DISPLAY_SIZE, extTypeInfo);
case Value.INTERVAL_YEAR:
case Value.INTERVAL_MONTH:
case Value.INTERVAL_DAY:
case Value.INTERVAL_HOUR:
case Value.INTERVAL_MINUTE:
case Value.INTERVAL_YEAR_TO_MONTH:
case Value.INTERVAL_DAY_TO_HOUR:
case Value.INTERVAL_DAY_TO_MINUTE:
case Value.INTERVAL_HOUR_TO_MINUTE:
if (precision < 0 || precision > ValueInterval.MAXIMUM_PRECISION) {
precision = ValueInterval.MAXIMUM_PRECISION;
}
return new TypeInfo(type, precision, 0, ValueInterval.getDisplaySize(type, (int) precision, 0), null);
case Value.INTERVAL_SECOND:
case Value.INTERVAL_DAY_TO_SECOND:
case Value.INTERVAL_HOUR_TO_SECOND:
case Value.INTERVAL_MINUTE_TO_SECOND:
if (precision < 0 || precision > ValueInterval.MAXIMUM_PRECISION) {
precision = ValueInterval.MAXIMUM_PRECISION;
}
if (scale < 0 || scale > ValueInterval.MAXIMUM_SCALE) {
scale = ValueInterval.MAXIMUM_SCALE;
}
return new TypeInfo(type, precision, scale, ValueInterval.getDisplaySize(type, (int) precision, scale),
null);
}
if (JdbcUtils.customDataTypesHandler != null) {
DataType dt = JdbcUtils.customDataTypesHandler.getDataTypeById(type);
if (dt != null) {
return createTypeInfo(type, dt);
}
}
return TYPE_NULL;
} }
private static TypeInfo createTypeInfo(int valueType, DataType dataType) { private static TypeInfo createTypeInfo(int valueType, DataType dataType) {
......
...@@ -61,11 +61,6 @@ public class ValueArray extends ValueCollectionBase { ...@@ -61,11 +61,6 @@ public class ValueArray extends ValueCollectionBase {
return (ValueArray) EMPTY; return (ValueArray) EMPTY;
} }
@Override
public TypeInfo getType() {
return TypeInfo.TYPE_ARRAY;
}
@Override @Override
public int getValueType() { public int getValueType() {
return ARRAY; return ARRAY;
......
...@@ -47,11 +47,6 @@ public class ValueRow extends ValueCollectionBase { ...@@ -47,11 +47,6 @@ public class ValueRow extends ValueCollectionBase {
return (ValueRow) EMPTY; return (ValueRow) EMPTY;
} }
@Override
public TypeInfo getType() {
return TypeInfo.TYPE_ROW;
}
@Override @Override
public int getValueType() { public int getValueType() {
return ROW; return ROW;
......
...@@ -143,7 +143,7 @@ public class TestDate extends TestBase { ...@@ -143,7 +143,7 @@ public class TestDate extends TestBase {
assertEquals((int) ((nanos >>> 32) ^ nanos), t1.hashCode()); assertEquals((int) ((nanos >>> 32) ^ nanos), t1.hashCode());
// Literals return maximum precision // Literals return maximum precision
TypeInfo type = t1.getType(); TypeInfo type = t1.getType();
assertEquals(ValueTime.MAXIMUM_PRECISION, type.getDisplaySize()); assertEquals(ValueTime.DEFAULT_PRECISION, type.getDisplaySize());
assertEquals(ValueTime.MAXIMUM_PRECISION, type.getPrecision()); assertEquals(ValueTime.MAXIMUM_PRECISION, type.getPrecision());
assertEquals("java.sql.Time", t1.getObject().getClass().getName()); assertEquals("java.sql.Time", t1.getObject().getClass().getName());
ValueTime t1b = ValueTime.parse("11:11:11"); ValueTime t1b = ValueTime.parse("11:11:11");
...@@ -221,7 +221,7 @@ public class TestDate extends TestBase { ...@@ -221,7 +221,7 @@ public class TestDate extends TestBase {
t1.hashCode()); t1.hashCode());
// Literals return maximum precision // Literals return maximum precision
TypeInfo type = t1.getType(); TypeInfo type = t1.getType();
assertEquals(ValueTimestamp.MAXIMUM_PRECISION, type.getDisplaySize()); assertEquals(ValueTimestamp.DEFAULT_PRECISION, type.getDisplaySize());
assertEquals(ValueTimestamp.MAXIMUM_PRECISION, type.getPrecision()); assertEquals(ValueTimestamp.MAXIMUM_PRECISION, type.getPrecision());
assertEquals(9, type.getScale()); assertEquals(9, type.getScale());
assertEquals("java.sql.Timestamp", t1.getObject().getClass().getName()); assertEquals("java.sql.Timestamp", t1.getObject().getClass().getName());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论