提交 bdaca84d authored 作者: Thomas Mueller's avatar Thomas Mueller

The data type of a SUBSTRING method was wrong.

上级 8dc0ecdd
...@@ -101,6 +101,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -101,6 +101,7 @@ public class Function extends Expression implements FunctionCall {
FILE_READ = 225, TRANSACTION_ID = 226; FILE_READ = 225, TRANSACTION_ID = 226;
private static final int VAR_ARGS = -1; private static final int VAR_ARGS = -1;
private static final long PRECISION_UNKNOWN = -1;
private static final HashMap FUNCTIONS = new HashMap(); private static final HashMap FUNCTIONS = new HashMap();
private static final HashMap DATE_PART = new HashMap(); private static final HashMap DATE_PART = new HashMap();
...@@ -113,7 +114,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -113,7 +114,7 @@ public class Function extends Expression implements FunctionCall {
private FunctionInfo info; private FunctionInfo info;
private ObjectArray varArgs; private ObjectArray varArgs;
private int dataType, scale; private int dataType, scale;
private long precision; private long precision = PRECISION_UNKNOWN;
private int displaySize; private int displaySize;
private Database database; private Database database;
...@@ -1612,6 +1613,8 @@ public class Function extends Expression implements FunctionCall { ...@@ -1612,6 +1613,8 @@ public class Function extends Expression implements FunctionCall {
allConst = false; allConst = false;
} }
} }
int t, s, d;
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 IFNULL: case IFNULL:
...@@ -1619,36 +1622,40 @@ public class Function extends Expression implements FunctionCall { ...@@ -1619,36 +1622,40 @@ public class Function extends Expression implements FunctionCall {
case COALESCE: case COALESCE:
case LEAST: case LEAST:
case GREATEST: { case GREATEST: {
dataType = Value.UNKNOWN; t = Value.UNKNOWN;
scale = 0; s = 0;
precision = 0; p = 0;
displaySize = 0; d = 0;
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
Expression e = args[i]; Expression e = args[i];
if (e != ValueExpression.getNull() && e.getType() != Value.UNKNOWN) { if (e != ValueExpression.getNull() && e.getType() != Value.UNKNOWN) {
dataType = Value.getHigherOrder(dataType, e.getType()); t = Value.getHigherOrder(t, e.getType());
scale = Math.max(scale, e.getScale()); s = Math.max(s, e.getScale());
precision = Math.max(precision, e.getPrecision()); p = Math.max(p, e.getPrecision());
displaySize = Math.max(displaySize, e.getDisplaySize()); d = Math.max(d, e.getDisplaySize());
} }
} }
if (dataType == Value.UNKNOWN) { if (t == Value.UNKNOWN) {
dataType = Value.STRING; t = Value.STRING;
scale = 0; s = 0;
precision = Integer.MAX_VALUE; p = Integer.MAX_VALUE;
displaySize = Integer.MAX_VALUE; d = Integer.MAX_VALUE;
} }
break; break;
} }
case CASEWHEN: case CASEWHEN:
dataType = Value.getHigherOrder(args[1].getType(), args[2].getType()); t = Value.getHigherOrder(args[1].getType(), args[2].getType());
precision = Math.max(args[1].getPrecision(), args[2].getPrecision()); p = Math.max(args[1].getPrecision(), args[2].getPrecision());
displaySize = Math.max(args[1].getDisplaySize(), args[2].getDisplaySize()); d = Math.max(args[1].getDisplaySize(), args[2].getDisplaySize());
scale = Math.max(args[1].getScale(), args[2].getScale()); s = Math.max(args[1].getScale(), args[2].getScale());
break; break;
case CAST: case CAST:
case CONVERT: case CONVERT:
// data type, precision and scale is already set // data type, precision and scale is already set
t = dataType;
p = precision;
s = scale;
d = displaySize;
break; break;
case ABS: case ABS:
case FLOOR: case FLOOR:
...@@ -1656,23 +1663,23 @@ public class Function extends Expression implements FunctionCall { ...@@ -1656,23 +1663,23 @@ public class Function extends Expression implements FunctionCall {
case ROUND: case ROUND:
case TRUNCATE: case TRUNCATE:
case POWER: case POWER:
dataType = p0.getType(); t = p0.getType();
scale = p0.getScale(); s = p0.getScale();
precision = p0.getPrecision(); p = p0.getPrecision();
displaySize = p0.getDisplaySize(); d = p0.getDisplaySize();
if (dataType == Value.NULL) { if (t == Value.NULL) {
dataType = Value.INT; t = Value.INT;
precision = ValueInt.PRECISION; p = ValueInt.PRECISION;
displaySize = ValueInt.DISPLAY_SIZE; d = ValueInt.DISPLAY_SIZE;
scale = 0; s = 0;
} }
break; break;
case SET: { case SET: {
Expression p1 = args[1]; Expression p1 = args[1];
dataType = p1.getType(); t = p1.getType();
precision = p1.getPrecision(); p = p1.getPrecision();
scale = p1.getScale(); s = p1.getScale();
displaySize = p1.getDisplaySize(); d = p1.getDisplaySize();
if (!(p0 instanceof Variable)) { if (!(p0 instanceof Variable)) {
throw Message.getSQLException(ErrorCode.CAN_ONLY_ASSIGN_TO_VARIABLE_1, p0.getSQL()); throw Message.getSQLException(ErrorCode.CAN_ONLY_ASSIGN_TO_VARIABLE_1, p0.getSQL());
} }
...@@ -1680,38 +1687,44 @@ public class Function extends Expression implements FunctionCall { ...@@ -1680,38 +1687,44 @@ public class Function extends Expression implements FunctionCall {
} }
case FILE_READ: { case FILE_READ: {
if (args.length == 1) { if (args.length == 1) {
dataType = Value.BLOB; t = Value.BLOB;
} else { } else {
dataType = Value.CLOB; t = Value.CLOB;
} }
precision = Integer.MAX_VALUE; p = Integer.MAX_VALUE;
scale = 0; s = 0;
displaySize = Integer.MAX_VALUE; d = Integer.MAX_VALUE;
break; break;
} }
case SUBSTRING: case SUBSTRING:
case SUBSTR: { case SUBSTR: {
precision = args[0].getPrecision(); t = info.dataType;
p = args[0].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
precision -= args[1].getValue(session).getLong() - 1; p -= args[1].getValue(session).getLong() - 1;
} }
if (args.length == 3 && args[2].isConstant()) { if (args.length == 3 && args[2].isConstant()) {
// if the third argument is constant it is at most this value // if the third argument is constant it is at most this value
precision = Math.min(precision, args[2].getValue(session).getLong()); p = Math.min(p, args[2].getValue(session).getLong());
} }
precision = Math.max(0, precision); p = Math.max(0, p);
displaySize = MathUtils.convertLongToInt(precision); d = MathUtils.convertLongToInt(p);
break; break;
} }
default: default:
dataType = info.dataType; t = info.dataType;
DataType type = DataType.getDataType(dataType); DataType type = DataType.getDataType(t);
precision = 0; p = PRECISION_UNKNOWN;
displaySize = 0; d = 0;
scale = type.defaultScale; s = type.defaultScale;
} }
dataType = t;
precision = p;
scale = s;
displaySize = d;
if (allConst) { if (allConst) {
return ValueExpression.get(getValue(session)); return ValueExpression.get(getValue(session));
} }
...@@ -1732,14 +1745,14 @@ public class Function extends Expression implements FunctionCall { ...@@ -1732,14 +1745,14 @@ public class Function extends Expression implements FunctionCall {
} }
public long getPrecision() { public long getPrecision() {
if (precision == 0) { if (precision == PRECISION_UNKNOWN) {
calculatePrecisionAndDisplaySize(); calculatePrecisionAndDisplaySize();
} }
return precision; return precision;
} }
public int getDisplaySize() { public int getDisplaySize() {
if (precision == 0) { if (precision == PRECISION_UNKNOWN) {
calculatePrecisionAndDisplaySize(); calculatePrecisionAndDisplaySize();
} }
return displaySize; return displaySize;
......
...@@ -2008,8 +2008,8 @@ CREATE ALIAS PARSE_INT2 FOR "java.lang.Integer.parseInt(java.lang.String, int)"; ...@@ -2008,8 +2008,8 @@ CREATE ALIAS PARSE_INT2 FOR "java.lang.Integer.parseInt(java.lang.String, int)";
> ok > ok
select min(SUBSTRING(random_uuid(), 15,1)='4') from system_range(1, 10); select min(SUBSTRING(random_uuid(), 15,1)='4') from system_range(1, 10);
> MIN(CAST(SUBSTRING(RANDOM_UUID(), 15, 1) AS VARCHAR(1)) = '4') > MIN(SUBSTRING(RANDOM_UUID(), 15, 1) = '4')
> -------------------------------------------------------------- > ------------------------------------------
> TRUE > TRUE
> rows: 1 > rows: 1
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论