Skip to content

Commit 5436afb

Browse files
implicit casting for union typed field in logical plan
1 parent e006e07 commit 5436afb

File tree

8 files changed

+283
-282
lines changed

8 files changed

+283
-282
lines changed

x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/FieldExtractorTestCase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,9 @@ public void testLongIntegerConflict() throws IOException {
937937
"order of fields in error message inconsistent before 8.14",
938938
getCachedNodesVersions().stream().allMatch(v -> Version.fromString(v).onOrAfter(Version.V_8_14_0))
939939
);
940+
if (EsqlCapabilities.Cap.IMPLICIT_CASTING_UNION_TYPED_NUMERIC_AND_DATE.isEnabled()) {
941+
return;
942+
}
940943
longTest().sourceMode(SourceMode.DEFAULT).createIndex("test1", "emp_no");
941944
index("test1", """
942945
{"emp_no": 1}""");
@@ -979,6 +982,9 @@ public void testIntegerShortConflict() throws IOException {
979982
"order of fields in error message inconsistent before 8.14",
980983
getCachedNodesVersions().stream().allMatch(v -> Version.fromString(v).onOrAfter(Version.V_8_14_0))
981984
);
985+
if (EsqlCapabilities.Cap.IMPLICIT_CASTING_UNION_TYPED_NUMERIC_AND_DATE.isEnabled()) {
986+
return;
987+
}
982988
intTest().sourceMode(SourceMode.DEFAULT).createIndex("test1", "emp_no");
983989
index("test1", """
984990
{"emp_no": 1}""");

x-pack/plugin/esql/qa/testFixtures/src/main/resources/data/employees_incompatible.csv

Lines changed: 101 additions & 101 deletions
Large diffs are not rendered by default.

x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,14 +1296,3 @@ diff_sec:integer | diff_sec_m:integer | n:date_nanos
12961296
-18489600 | -18489599 | 2023-03-23T12:15:03.360103847Z
12971297
-18489600 | -18489599 | 2023-03-23T12:15:03.360103847Z
12981298
;
1299-
1300-
DateAndDateNanos
1301-
from employees,employees_incompatible
1302-
| keep emp_no, birth_date
1303-
| sort emp_no
1304-
| limit 1
1305-
;
1306-
1307-
emp_no:integer |birth_date:date
1308-
10001 |1953-09-02T00:00:00Z
1309-
;

x-pack/plugin/esql/qa/testFixtures/src/main/resources/union_types.csv-spec

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,3 +1639,67 @@ id:integer | name:keyword | count:long
16391639
13 | lllll | 2
16401640
14 | mmmmm | 2
16411641
;
1642+
1643+
MultiTypedFieldsKeepDropSort
1644+
required_capability: implicit_casting_union_typed_numeric_and_date
1645+
1646+
FROM employees, employees_incompatible
1647+
| DROP salary
1648+
| KEEP emp_no, languages, hire_date, avg_worked_seconds
1649+
| SORT emp_no, hire_date
1650+
| limit 2
1651+
;
1652+
1653+
emp_no:long |languages:integer |hire_date:date_nanos |avg_worked_seconds:unsigned_long
1654+
10001 |2 |1986-06-26T00:00:00.000Z |268728049
1655+
10001 |2 |1986-06-26T00:00:00.000Z |268728049
1656+
;
1657+
1658+
MultiTypedFieldsRenameKeep
1659+
required_capability: implicit_casting_union_typed_numeric_and_date
1660+
1661+
from employees, employees_incompatible
1662+
| RENAME emp_no as new_emp_no, languages as new_languages, hire_date as new_hire_date, avg_worked_seconds as new_avg_worked_seconds
1663+
| KEEP new_emp_no, new_languages, new_hire_date, new_avg_worked_seconds
1664+
| sort new_emp_no, new_hire_date
1665+
| limit 2
1666+
;
1667+
1668+
new_emp_no:long |new_languages:integer |new_hire_date:date_nanos |new_avg_worked_seconds:unsigned_long
1669+
10001 |2 |1986-06-26T00:00:00.000Z |268728049
1670+
10001 |2 |1986-06-26T00:00:00.000Z |268728049
1671+
;
1672+
1673+
MultiTypedFieldsEvalKeepSort
1674+
required_capability: implicit_casting_union_typed_numeric_and_date
1675+
1676+
FROM employees, employees_incompatible
1677+
| DROP birth_date
1678+
| EVAL x = emp_no + 1, y = hire_date + 1 year, z = hire_date::datetime
1679+
| KEEP emp_no, x, hire_date, y, z
1680+
| SORT emp_no, hire_date
1681+
| limit 2
1682+
;
1683+
1684+
emp_no:long |x:long |hire_date:date_nanos |y:date_nanos |z:date
1685+
10001 |10002 |1986-06-26T00:00:00.000Z |1987-06-26T00:00:00.000Z |1986-06-26T00:00:00.000Z
1686+
10001 |10002 |1986-06-26T00:00:00.000Z |1987-06-26T00:00:00.000Z |1986-06-26T00:00:00.000Z
1687+
;
1688+
1689+
MultiTypedFieldsEvalFilterKeepSort
1690+
required_capability: implicit_casting_union_typed_numeric_and_date
1691+
1692+
FROM employees, employees_incompatible
1693+
| EVAL x = emp_no + 1, y = hire_date + 1 day
1694+
| WHERE emp_no > 10010 AND hire_date > "1992-01-01" AND languages < 3 AND height > 1.2
1695+
| KEEP emp_no, hire_date
1696+
| SORT emp_no, hire_date
1697+
| limit 4
1698+
;
1699+
1700+
emp_no:long |hire_date:date_nanos
1701+
10016 | 1995-01-27T00:00:00.000Z
1702+
10016 | 1995-01-27T00:00:00.000Z
1703+
10017 | 1993-08-03T00:00:00.000Z
1704+
10017 | 1993-08-03T00:00:00.000Z
1705+
;

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,12 @@ public enum Cap {
850850
/**
851851
* Allow mixed numeric types in conditional functions - case, greatest and least
852852
*/
853-
MIXED_NUMERIC_TYPES_IN_CASE_GREATEST_LEAST;
853+
MIXED_NUMERIC_TYPES_IN_CASE_GREATEST_LEAST,
854+
855+
/**
856+
* Support implicit casting for union typed numeric and date/date_nanos fields
857+
*/
858+
IMPLICIT_CASTING_UNION_TYPED_NUMERIC_AND_DATE;
854859

855860
private final boolean enabled;
856861

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java

Lines changed: 105 additions & 156 deletions
Large diffs are not rendered by default.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.elasticsearch.xpack.esql.core.capabilities.Unresolvable;
1818
import org.elasticsearch.xpack.esql.core.expression.Alias;
1919
import org.elasticsearch.xpack.esql.core.expression.Expression;
20-
import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
2120
import org.elasticsearch.xpack.esql.core.expression.TypeResolutions;
2221
import org.elasticsearch.xpack.esql.core.expression.function.Function;
2322
import org.elasticsearch.xpack.esql.core.expression.predicate.BinaryOperator;
@@ -36,7 +35,6 @@
3635
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
3736
import org.elasticsearch.xpack.esql.plan.logical.Lookup;
3837
import org.elasticsearch.xpack.esql.plan.logical.Project;
39-
import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
4038
import org.elasticsearch.xpack.esql.telemetry.FeatureMetric;
4139
import org.elasticsearch.xpack.esql.telemetry.Metrics;
4240

@@ -96,16 +94,6 @@ Collection<Failure> verify(LogicalPlan plan, BitSet partialMetrics) {
9694
return;
9795
}
9896

99-
if (p instanceof EsqlProject proj) {
100-
for (NamedExpression projection : proj.projections()) {
101-
// don't call dataType() - it will fail on UnresolvedAttribute
102-
String className = String.valueOf(projection.getClass());
103-
if (projection.resolved() == false && projection instanceof UnsupportedAttribute == false) {
104-
105-
}
106-
}
107-
}
108-
10997
planCheckers.forEach(c -> c.accept(p, failures));
11098

11199
checkOperationsOnUnsignedLong(p, failures);

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverterTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public void testCommonTypeDateTimeIntervals() {
9797
assertEqualsCommonType(dataType1, NULL, dataType1);
9898
} else if (isDateTimeOrNanosOrTemporal(dataType2)) {
9999
if ((dataType1 == DATE_NANOS && dataType2 == DATETIME) || (dataType1 == DATETIME && dataType2 == DATE_NANOS)) {
100-
assertNullCommonType(dataType1, dataType2);
100+
assertEqualsCommonType(dataType1, dataType2, DATE_NANOS);
101101
} else if (isDateTime(dataType1) || isDateTime(dataType2)) {
102102
assertEqualsCommonType(dataType1, dataType2, DATETIME);
103103
} else if (dataType1 == DATE_NANOS || dataType2 == DATE_NANOS) {

0 commit comments

Comments
 (0)