DRILL-8424: Accommodate RexBuilder changes made for SAFE_CAST (#2794)
diff --git a/.gitignore b/.gitignore
index 76a5687..99e56d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
.checkstyle
.settings/
.idea/
+.mvn/maven.config
TAGS
*.log
*.lck
@@ -28,4 +29,3 @@
.*.html
venv/
tools/venv/
-
diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml
index f3e73ca..216b30d 100644
--- a/.mvn/extensions.xml
+++ b/.mvn/extensions.xml
@@ -23,6 +23,6 @@
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
- <version>1.6.1</version>
+ <version>1.7.1</version>
</extension>
</extensions>
diff --git a/distribution/pom.xml b/distribution/pom.xml
index 565e73b..d4c8e4e 100644
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -245,7 +245,7 @@
<executions>
<execution>
<id>distro-assembly</id>
- <phase>package</phase>
+ <phase>install</phase>
<goals>
<goal>single</goal>
</goals>
diff --git a/exec/java-exec/src/main/codegen/templates/Parser.jj b/exec/java-exec/src/main/codegen/templates/Parser.jj
index b5d9f96..472ac65 100644
--- a/exec/java-exec/src/main/codegen/templates/Parser.jj
+++ b/exec/java-exec/src/main/codegen/templates/Parser.jj
@@ -15,9 +15,13 @@
* limitations under the License.
*/
-// TODO: Delete this file to reinstate its extraction from calcite-core.jar
-// once CALCITE-5579 is resolved and the incompatible grammar changes introduced
-// by CALCITE-5469 have been backed out. Also see: exec/java-exec/pom.xml.
+// To have Drill use this parser grammar instead of Calcite's (normally
+// in order to exclude incompatibilities that have been introduced
+// upstream), rename this file to Parser.jj, otherwise use the name
+// Parser.jj.disabled. Currently this parser grammar is in effect because of
+// CALCITE-5469 which should be resolved by CALCITE-5579 after which it can be
+// disabled. Also see the calcite-parser-grammar profile in
+// exec/java-exec/pom.xml.
<@pp.dropOutputFile />
@@ -59,6 +63,7 @@
import org.apache.calcite.sql.SqlExplain;
import org.apache.calcite.sql.SqlExplainFormat;
import org.apache.calcite.sql.SqlExplainLevel;
+import org.apache.calcite.sql.SqlFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
import org.apache.calcite.sql.SqlHint;
import org.apache.calcite.sql.SqlIdentifier;
@@ -5131,6 +5136,8 @@
| <MINUTE> { return new SqlIntervalQualifier(TimeUnit.MINUTE, null, getPos()); }
| <HOUR> { return new SqlIntervalQualifier(TimeUnit.HOUR, null, getPos()); }
| <DAY> { return new SqlIntervalQualifier(TimeUnit.DAY, null, getPos()); }
+| <DAYOFWEEK> { return new SqlIntervalQualifier(TimeUnit.DOW, null, getPos()); }
+| <DAYOFYEAR> { return new SqlIntervalQualifier(TimeUnit.DOY, null, getPos()); }
| <DOW> { return new SqlIntervalQualifier(TimeUnit.DOW, null, getPos()); }
| <DOY> { return new SqlIntervalQualifier(TimeUnit.DOY, null, getPos()); }
| <ISODOW> { return new SqlIntervalQualifier(TimeUnit.ISODOW, null, getPos()); }
@@ -5998,11 +6005,16 @@
SqlDataTypeSpec dt;
final SqlIntervalQualifier unit;
final SqlNode node;
+ final SqlLiteral style; // mssql convert 'style' operand
+ final SqlFunction f;
}
{
//~ FUNCTIONS WITH SPECIAL SYNTAX ---------------------------------------
(
- <CAST> { s = span(); }
+ ( <CAST> { f = SqlStdOperatorTable.CAST; }
+ | <SAFE_CAST> { f = SqlLibraryOperators.SAFE_CAST; }
+ )
+ { s = span(); }
<LPAREN> AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
<AS>
(
@@ -6011,7 +6023,7 @@
<INTERVAL> e = IntervalQualifier() { args.add(e); }
)
<RPAREN> {
- return SqlStdOperatorTable.CAST.createCall(s.end(this), args);
+ return f.createCall(s.end(this), args);
}
|
<EXTRACT> { s = span(); }
@@ -6039,11 +6051,38 @@
|
<CONVERT> { s = span(); }
<LPAREN>
- AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
- <USING> name = SimpleIdentifier() { args.add(name); }
- <RPAREN> {
- return SqlStdOperatorTable.CONVERT.createCall(s.end(this), args);
- }
+ (
+ // CONVERT in the form of CONVERT(x USING y)
+
+ // "AddExpression" matches INTERVAL,
+ // which can also be 1st token in args of MSSQL CONVERT
+ // So lookahead another token (to match <USING> vs. <COMMA>)
+ LOOKAHEAD(2)
+ AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
+ <USING> name = SimpleIdentifier() { args.add(name); }
+ <RPAREN> {
+ return SqlStdOperatorTable.CONVERT.createCall(s.end(this), args);
+ }
+ | // mssql CONVERT(type, val [,style])
+ (
+ dt = DataType() { args.add(dt); }
+ |
+ <INTERVAL> e = IntervalQualifier() { args.add(e); }
+ )
+ <COMMA>
+ AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)
+ [
+ <COMMA>
+ (
+ style = UnsignedNumericLiteral() { args.add(style); }
+ |
+ <NULL> { args.add(SqlLiteral.createNull(getPos())); }
+ )
+ ]
+ <RPAREN> {
+ return SqlLibraryOperators.MSSQL_CONVERT.createCall(s.end(this), args);
+ }
+ )
|
<TRANSLATE> { s = span(); }
<LPAREN>
@@ -7727,6 +7766,8 @@
| < DATETIME_INTERVAL_CODE: "DATETIME_INTERVAL_CODE" >
| < DATETIME_INTERVAL_PRECISION: "DATETIME_INTERVAL_PRECISION" >
| < DAY: "DAY" >
+| < DAYOFWEEK: "DAYOFWEEK" >
+| < DAYOFYEAR: "DAYOFYEAR" >
| < DAYS: "DAYS" >
| < DEALLOCATE: "DEALLOCATE" >
| < DEC: "DEC" >
@@ -8076,6 +8117,7 @@
| < ROW_NUMBER: "ROW_NUMBER" >
| < ROWS: "ROWS" >
| < RUNNING: "RUNNING" >
+| < SAFE_CAST: "SAFE_CAST" >
| < SATURDAY: "SATURDAY" >
| < SAVEPOINT: "SAVEPOINT" >
| < SCALAR: "SCALAR" >
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/conversion/DrillRexBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/conversion/DrillRexBuilder.java
index 299859c..7c232ec 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/conversion/DrillRexBuilder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/conversion/DrillRexBuilder.java
@@ -65,9 +65,9 @@
* @return Call to CAST operator
*/
@Override
- public RexNode makeCast(RelDataType type, RexNode exp, boolean matchNullability) {
+ public RexNode makeCast(RelDataType type, RexNode exp, boolean matchNullability, boolean safe) {
if (matchNullability) {
- return makeAbstractCast(type, exp);
+ return makeAbstractCast(type, exp, safe);
}
// for the case when BigDecimal literal has a scale or precision
// that differs from the value from specified RelDataType, cast cannot be removed
@@ -81,11 +81,11 @@
BigDecimal bigDecimal = (BigDecimal) value;
DecimalUtility.checkValueOverflow(bigDecimal, precision, scale);
if (bigDecimal.precision() != precision || bigDecimal.scale() != scale) {
- return makeAbstractCast(type, exp);
+ return makeAbstractCast(type, exp, safe);
}
}
}
- return super.makeCast(type, exp, false);
+ return super.makeCast(type, exp, false, safe);
}
private void validatePrecisionAndScale(int precision, int scale) {
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestCastFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestCastFunctions.java
index 73853fe..0644c2c 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestCastFunctions.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestCastFunctions.java
@@ -667,10 +667,10 @@
@Test
public void testCastFloatDecimalOverflow() throws Exception {
- String query = "select cast(i1 as DECIMAL(4, 0)) as s1 from (select cast(123456.123 as float) as i1)";
+ String query = "select cast(i1 as DECIMAL(4, 0)) as s1 from (select cast(12345.123 as float) as i1)";
thrown.expect(UserRemoteException.class);
- thrown.expectMessage(containsString("VALIDATION ERROR: Value 123456.123 overflows specified precision 4 with scale 0"));
+ thrown.expectMessage(containsString("VALIDATION ERROR: Value 12345.123 overflows specified precision 4 with scale 0"));
run(query);
}
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewDateFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewDateFunctions.java
index 626b6d1..6d51430 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewDateFunctions.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewDateFunctions.java
@@ -153,6 +153,26 @@
}
@Test
+ public void testDayOfYear() throws Exception {
+ testBuilder()
+ .sqlQuery("SELECT EXTRACT(DOY FROM date '2023-04-17') AS col1, EXTRACT(DAYOFYEAR FROM date '2023-04-17') as col2")
+ .unOrdered()
+ .baselineColumns("col1", "col2")
+ .baselineValues(107L, 107L)
+ .go();
+ }
+
+ @Test
+ public void testDayOfWeek() throws Exception {
+ testBuilder()
+ .sqlQuery("SELECT EXTRACT(DOW FROM date '2023-04-17') AS col1, EXTRACT(DAYOFWEEK FROM date '2023-04-17') as col2")
+ .unOrdered()
+ .baselineColumns("col1", "col2")
+ .baselineValues(1L, 1L)
+ .go();
+ }
+
+ @Test
public void testLocalTimestamp() throws Exception {
testBuilder()
.sqlQuery("select extract(day from localtimestamp) = extract(day from current_date) as col from cp.`employee.json` limit 1")
diff --git a/pom.xml b/pom.xml
index 375124e..503ee3a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -338,7 +338,7 @@
<plugin>
<groupId>org.apache.rat</groupId>
<artifactId>apache-rat-plugin</artifactId>
- <version>0.13</version>
+ <version>0.15</version>
<executions>
<execution>
<id>rat-checks</id>