Unverified 提交 13dc84af authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1339 from katzyn/datetime

Add support of TIMESTAMP WITH TIME ZONE to addition and subtraction operators
......@@ -216,10 +216,30 @@ public class Operation extends Expression {
} else {
dataType = Value.DECIMAL;
}
} else if (l == Value.DATE || l == Value.TIMESTAMP ||
l == Value.TIME || r == Value.DATE ||
r == Value.TIMESTAMP || r == Value.TIME) {
if (opType == OpType.PLUS) {
} else if (DataType.isDateTimeType(l) || DataType.isDateTimeType(r)) {
return optimizeDateTime(session, l, r);
} else {
dataType = Value.getHigherOrder(l, r);
if (dataType == Value.ENUM) {
dataType = Value.INT;
} else if (DataType.isStringType(dataType) &&
session.getDatabase().getMode().allowPlusForStringConcat) {
opType = OpType.CONCAT;
}
}
break;
default:
DbException.throwInternalError("type=" + opType);
}
if (left.isConstant() && (right == null || right.isConstant())) {
return ValueExpression.get(getValue(session));
}
return this;
}
private Expression optimizeDateTime(Session session, int l, int r) {
switch (opType) {
case PLUS:
if (r != Value.getHigherOrder(l, r)) {
// order left and right: INT < TIME < DATE < TIMESTAMP
swap();
......@@ -227,7 +247,8 @@ public class Operation extends Expression {
l = r;
r = t;
}
if (l == Value.INT) {
switch (l) {
case Value.INT: {
// Oracle date add
Function f = Function.getFunction(session.getDatabase(), "DATEADD");
f.setParameter(0, ValueExpression.get(ValueString.get("DAY")));
......@@ -235,7 +256,10 @@ public class Operation extends Expression {
f.setParameter(2, right);
f.doneWithParameters();
return f.optimize(session);
} else if (l == Value.DECIMAL || l == Value.FLOAT || l == Value.DOUBLE) {
}
case Value.DECIMAL:
case Value.FLOAT:
case Value.DOUBLE: {
// Oracle date add
Function f = Function.getFunction(session.getDatabase(), "DATEADD");
f.setParameter(0, ValueExpression.get(ValueString.get("SECOND")));
......@@ -245,15 +269,24 @@ public class Operation extends Expression {
f.setParameter(2, right);
f.doneWithParameters();
return f.optimize(session);
} else if (l == Value.TIME && r == Value.TIME) {
dataType = Value.TIME;
}
case Value.TIME:
if (r == Value.TIME || r == Value.TIMESTAMP_TZ) {
dataType = r;
return this;
} else if (l == Value.TIME) {
} else { // DATE, TIMESTAMP
dataType = Value.TIMESTAMP;
return this;
}
} else if (opType == OpType.MINUS) {
if ((l == Value.DATE || l == Value.TIMESTAMP) && r == Value.INT) {
}
break;
case MINUS:
switch (l) {
case Value.DATE:
case Value.TIMESTAMP:
case Value.TIMESTAMP_TZ:
switch (r) {
case Value.INT: {
// Oracle date subtract
Function f = Function.getFunction(session.getDatabase(), "DATEADD");
f.setParameter(0, ValueExpression.get(ValueString.get("DAY")));
......@@ -263,8 +296,10 @@ public class Operation extends Expression {
f.setParameter(2, left);
f.doneWithParameters();
return f.optimize(session);
} else if ((l == Value.DATE || l == Value.TIMESTAMP) &&
(r == Value.DECIMAL || r == Value.FLOAT || r == Value.DOUBLE)) {
}
case Value.DECIMAL:
case Value.FLOAT:
case Value.DOUBLE: {
// Oracle date subtract
Function f = Function.getFunction(session.getDatabase(), "DATEADD");
f.setParameter(0, ValueExpression.get(ValueString.get("SECOND")));
......@@ -276,11 +311,13 @@ public class Operation extends Expression {
f.setParameter(2, left);
f.doneWithParameters();
return f.optimize(session);
} else if (l == Value.DATE || l == Value.TIMESTAMP) {
if (r == Value.TIME) {
}
case Value.TIME:
dataType = Value.TIMESTAMP;
return this;
} else if (r == Value.DATE || r == Value.TIMESTAMP) {
case Value.DATE:
case Value.TIMESTAMP:
case Value.TIMESTAMP_TZ: {
// Oracle date subtract
Function f = Function.getFunction(session.getDatabase(), "DATEDIFF");
f.setParameter(0, ValueExpression.get(ValueString.get("DAY")));
......@@ -289,11 +326,17 @@ public class Operation extends Expression {
f.doneWithParameters();
return f.optimize(session);
}
} else if (l == Value.TIME && r == Value.TIME) {
}
break;
case Value.TIME:
if (r == Value.TIME) {
dataType = Value.TIME;
return this;
}
} else if (opType == OpType.MULTIPLY) {
break;
}
break;
case MULTIPLY:
if (l == Value.TIME) {
dataType = Value.TIME;
convertRight = false;
......@@ -304,34 +347,20 @@ public class Operation extends Expression {
convertRight = false;
return this;
}
} else if (opType == OpType.DIVIDE) {
break;
case DIVIDE:
if (l == Value.TIME) {
dataType = Value.TIME;
convertRight = false;
return this;
}
break;
default:
}
throw DbException.getUnsupportedException(
DataType.getDataType(l).name + " " +
getOperationToken() + " " +
DataType.getDataType(r).name);
} else {
dataType = Value.getHigherOrder(l, r);
if (dataType == Value.ENUM) {
dataType = Value.INT;
} else if (DataType.isStringType(dataType) &&
session.getDatabase().getMode().allowPlusForStringConcat) {
opType = OpType.CONCAT;
}
}
break;
default:
DbException.throwInternalError("type=" + opType);
}
if (left.isConstant() && (right == null || right.isConstant())) {
return ValueExpression.get(getValue(session));
}
return this;
}
private void swap() {
......
......@@ -93,3 +93,22 @@ SELECT T0 FROM TEST;
DROP TABLE TEST;
> ok
SELECT (LOCALTIMESTAMP + 1) = (CURRENT_TIMESTAMP + 1);
>> TRUE
SELECT (TIMESTAMP WITH TIME ZONE '2010-01-01 10:00:00+01' + 1) A,
(1 + TIMESTAMP WITH TIME ZONE '2010-01-01 10:00:00+01') B;
> A B
> ---------------------- ----------------------
> 2010-01-02 10:00:00+01 2010-01-02 10:00:00+01
> rows: 1
SELECT (LOCALTIMESTAMP - 1) = (CURRENT_TIMESTAMP - 1);
>> TRUE
SELECT (TIMESTAMP WITH TIME ZONE '2010-01-01 10:00:00+01' - 1) A;
> A
> ----------------------
> 2009-12-31 10:00:00+01
> rows: 1
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论