This is an automated email from the ASF dual-hosted git repository.
abhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new b95035f183e Fix VirtualColumn related issues in window expressions
(#15119)
b95035f183e is described below
commit b95035f183e193f24ceee57cc41d295918fe87ac
Author: Zoltan Haindrich <[email protected]>
AuthorDate: Mon Oct 23 10:35:59 2023 +0200
Fix VirtualColumn related issues in window expressions (#15119)
for some exotic queries like:
SELECT
'_'||dim1,
MIN(cast(0 as double)) OVER (),
MIN(cast((cnt||cnt) as bigint)) OVER ()
FROM foo
the compilation have resulted in NPE -s mostly because VirtualColumn -s
were not handled properly
---
.../frame/write/columnar/FrameColumnWriters.java | 5 +-
.../druid/query/operator/OperatorFactory.java | 1 +
.../druid/query/operator/WindowOperatorQuery.java | 14 +++-
.../WindowOperatorQueryQueryToolChest.java | 10 ++-
.../rowsandcols/LazilyDecoratedRowsAndColumns.java | 45 +++++++++--
.../rowsandcols/concrete/FrameRowsAndColumns.java | 8 ++
.../DefaultColumnSelectorFactoryMaker.java | 14 +++-
.../org/apache/druid/segment/VirtualColumns.java | 17 ++++
.../apache/druid/error/DruidExceptionMatcher.java | 9 +++
.../query/operator/WindowOperatorQueryTest.java | 21 +++++
.../query/rowsandcols/RowsAndColumnsTestBase.java | 5 +-
.../concrete/FrameRowsAndColumnsTest.java | 47 +++++++++++
.../semantic/CombinedSemanticInterfacesTest.java | 30 +++++++
...tVirtualColumnEvaluationRowsAndColumnsTest.java | 92 ++++++++++++++++++++++
.../virtual/ExpressionVirtualColumnTest.java | 4 +-
.../druid/segment/virtual/VirtualColumnsTest.java | 24 ++++++
.../apache/druid/sql/calcite/rel/DruidQuery.java | 25 +++++-
.../sql/calcite/rel/VirtualColumnRegistry.java | 27 +++++++
.../apache/druid/sql/calcite/rel/Windowing.java | 6 +-
.../druid/sql/calcite/BaseCalciteQueryTest.java | 3 +-
.../druid/sql/calcite/DrillWindowQueryTest.java | 68 ++++++++--------
.../apache/druid/sql/calcite/NotYetSupported.java | 2 +-
.../calcite/tests/window/virtualColumns.sqlTest | 33 ++++++++
23 files changed, 449 insertions(+), 61 deletions(-)
diff --git
a/processing/src/main/java/org/apache/druid/frame/write/columnar/FrameColumnWriters.java
b/processing/src/main/java/org/apache/druid/frame/write/columnar/FrameColumnWriters.java
index bc1180cb8e3..596fa77646f 100644
---
a/processing/src/main/java/org/apache/druid/frame/write/columnar/FrameColumnWriters.java
+++
b/processing/src/main/java/org/apache/druid/frame/write/columnar/FrameColumnWriters.java
@@ -19,7 +19,6 @@
package org.apache.druid.frame.write.columnar;
-import org.apache.druid.common.config.NullHandling;
import org.apache.druid.frame.allocation.MemoryAllocator;
import org.apache.druid.frame.write.UnsupportedColumnTypeException;
import org.apache.druid.java.util.common.ISE;
@@ -167,9 +166,7 @@ public class FrameColumnWriters
private static boolean hasNullsForNumericWriter(final ColumnCapabilities
capabilities)
{
- if (NullHandling.replaceWithDefault()) {
- return false;
- } else if (capabilities == null) {
+ if (capabilities == null) {
return true;
} else if (capabilities.getType().isNumeric()) {
return capabilities.hasNulls().isMaybeTrue();
diff --git
a/processing/src/main/java/org/apache/druid/query/operator/OperatorFactory.java
b/processing/src/main/java/org/apache/druid/query/operator/OperatorFactory.java
index 90bd30862c9..a97c332505c 100644
---
a/processing/src/main/java/org/apache/druid/query/operator/OperatorFactory.java
+++
b/processing/src/main/java/org/apache/druid/query/operator/OperatorFactory.java
@@ -33,6 +33,7 @@ import
org.apache.druid.query.operator.window.WindowOperatorFactory;
@JsonSubTypes.Type(name = "naivePartition", value =
NaivePartitioningOperatorFactory.class),
@JsonSubTypes.Type(name = "naiveSort", value =
NaiveSortOperatorFactory.class),
@JsonSubTypes.Type(name = "window", value = WindowOperatorFactory.class),
+ @JsonSubTypes.Type(name = "scan", value = ScanOperatorFactory.class),
})
public interface OperatorFactory
{
diff --git
a/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQuery.java
b/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQuery.java
index a07bad0d082..5ecba3f2242 100644
---
a/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQuery.java
+++
b/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQuery.java
@@ -196,7 +196,7 @@ public class WindowOperatorQuery extends
BaseQuery<RowsAndColumns>
{
return new WindowOperatorQuery(
getDataSource(),
- getQuerySegmentSpec(),
+ spec,
getContext(),
rowSignature,
operators,
@@ -217,6 +217,18 @@ public class WindowOperatorQuery extends
BaseQuery<RowsAndColumns>
);
}
+ public Query<RowsAndColumns> withOperators(List<OperatorFactory> operators)
+ {
+ return new WindowOperatorQuery(
+ getDataSource(),
+ getQuerySegmentSpec(),
+ getContext(),
+ rowSignature,
+ operators,
+ leafOperators
+ );
+ }
+
@Override
public boolean equals(Object o)
{
diff --git
a/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQueryQueryToolChest.java
b/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQueryQueryToolChest.java
index 650bd0ae452..bec529eedef 100644
---
a/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQueryQueryToolChest.java
+++
b/processing/src/main/java/org/apache/druid/query/operator/WindowOperatorQueryQueryToolChest.java
@@ -54,9 +54,17 @@ public class WindowOperatorQueryQueryToolChest extends
QueryToolChest<RowsAndCol
(queryPlus, responseContext) -> {
final WindowOperatorQuery query = (WindowOperatorQuery)
queryPlus.getQuery();
final List<OperatorFactory> opFactories = query.getOperators();
+ if (opFactories.isEmpty()) {
+ return runner.run(queryPlus, responseContext);
+ }
Supplier<Operator> opSupplier = () -> {
- Operator retVal = new SequenceOperator(runner.run(queryPlus,
responseContext));
+ Operator retVal = new SequenceOperator(
+ runner.run(
+ queryPlus.withQuery(query.withOperators(new
ArrayList<OperatorFactory>())),
+ responseContext
+ )
+ );
for (OperatorFactory operatorFactory : opFactories) {
retVal = operatorFactory.wrap(retVal);
}
diff --git
a/processing/src/main/java/org/apache/druid/query/rowsandcols/LazilyDecoratedRowsAndColumns.java
b/processing/src/main/java/org/apache/druid/query/rowsandcols/LazilyDecoratedRowsAndColumns.java
index c1a13c50441..79505dcdd41 100644
---
a/processing/src/main/java/org/apache/druid/query/rowsandcols/LazilyDecoratedRowsAndColumns.java
+++
b/processing/src/main/java/org/apache/druid/query/rowsandcols/LazilyDecoratedRowsAndColumns.java
@@ -19,6 +19,7 @@
package org.apache.druid.query.rowsandcols;
+import com.google.common.collect.ImmutableList;
import org.apache.druid.frame.Frame;
import org.apache.druid.frame.FrameType;
import org.apache.druid.frame.allocation.ArenaMemoryAllocatorFactory;
@@ -101,6 +102,11 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
return viewableColumns == null ? base.getColumnNames() : viewableColumns;
}
+ public RowsAndColumns getBase()
+ {
+ return base;
+ }
+
@Override
public int numRows()
{
@@ -115,7 +121,6 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
if (viewableColumns != null && !viewableColumns.contains(name)) {
return null;
}
-
maybeMaterialize();
return base.findColumn(name);
}
@@ -158,7 +163,7 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
private void maybeMaterialize()
{
- if (!(interval == null && filter == null && limit == -1 && ordering ==
null)) {
+ if (needsMaterialization()) {
final Pair<byte[], RowSignature> thePair = materialize();
if (thePair == null) {
reset(new EmptyRowsAndColumns());
@@ -168,6 +173,11 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
}
}
+ private boolean needsMaterialization()
+ {
+ return interval != null || filter != null || limit != -1 || ordering !=
null || virtualColumns != null;
+ }
+
private Pair<byte[], RowSignature> materialize()
{
if (ordering != null) {
@@ -180,7 +190,6 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
} else {
return materializeStorageAdapter(as);
}
-
}
private void reset(RowsAndColumns rac)
@@ -200,13 +209,26 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
final Sequence<Cursor> cursors = as.makeCursors(
filter,
interval == null ? Intervals.ETERNITY : interval,
- virtualColumns,
+ virtualColumns == null ? VirtualColumns.EMPTY : virtualColumns,
Granularities.ALL,
false,
null
);
- Collection<String> cols = viewableColumns == null ? base.getColumnNames()
: viewableColumns;
+
+ final Collection<String> cols;
+ if (viewableColumns != null) {
+ cols = viewableColumns;
+ } else {
+ if (virtualColumns == null) {
+ cols = base.getColumnNames();
+ } else {
+ cols = ImmutableList.<String>builder()
+ .addAll(base.getColumnNames())
+ .addAll(virtualColumns.getColumnNames())
+ .build();
+ }
+ }
AtomicReference<RowSignature> siggy = new AtomicReference<>(null);
FrameWriter writer = cursors.accumulate(null, (accumulated, in) -> {
@@ -222,9 +244,18 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
final RowSignature.Builder sigBob = RowSignature.builder();
for (String col : cols) {
- final ColumnCapabilities capabilities =
columnSelectorFactory.getColumnCapabilities(col);
+ ColumnCapabilities capabilities;
+ capabilities = columnSelectorFactory.getColumnCapabilities(col);
if (capabilities != null) {
sigBob.add(col, capabilities.toColumnType());
+ continue;
+ }
+ if (virtualColumns != null) {
+ capabilities =
virtualColumns.getColumnCapabilities(columnSelectorFactory, col);
+ if (capabilities != null) {
+ sigBob.add(col, capabilities.toColumnType());
+ continue;
+ }
}
}
final RowSignature signature = sigBob.build();
@@ -350,12 +381,12 @@ public class LazilyDecoratedRowsAndColumns implements
RowsAndColumns
final RowSignature.Builder sigBob = RowSignature.builder();
final ArenaMemoryAllocatorFactory memFactory = new
ArenaMemoryAllocatorFactory(200 << 20);
+
for (String column : columnsToGenerate) {
final Column racColumn = rac.findColumn(column);
if (racColumn == null) {
continue;
}
-
sigBob.add(column, racColumn.toAccessor().getType());
}
diff --git
a/processing/src/main/java/org/apache/druid/query/rowsandcols/concrete/FrameRowsAndColumns.java
b/processing/src/main/java/org/apache/druid/query/rowsandcols/concrete/FrameRowsAndColumns.java
index 0eefa288df2..59a97f12bf5 100644
---
a/processing/src/main/java/org/apache/druid/query/rowsandcols/concrete/FrameRowsAndColumns.java
+++
b/processing/src/main/java/org/apache/druid/query/rowsandcols/concrete/FrameRowsAndColumns.java
@@ -21,10 +21,14 @@ package org.apache.druid.query.rowsandcols.concrete;
import org.apache.druid.frame.Frame;
import org.apache.druid.frame.FrameType;
+import org.apache.druid.frame.read.FrameReader;
import org.apache.druid.frame.read.columnar.FrameColumnReaders;
+import org.apache.druid.frame.segment.FrameStorageAdapter;
import org.apache.druid.java.util.common.ISE;
+import org.apache.druid.java.util.common.Intervals;
import org.apache.druid.query.rowsandcols.RowsAndColumns;
import org.apache.druid.query.rowsandcols.column.Column;
+import org.apache.druid.segment.StorageAdapter;
import org.apache.druid.segment.column.ColumnType;
import org.apache.druid.segment.column.RowSignature;
@@ -77,10 +81,14 @@ public class FrameRowsAndColumns implements RowsAndColumns
}
+ @SuppressWarnings("unchecked")
@Nullable
@Override
public <T> T as(Class<T> clazz)
{
+ if (StorageAdapter.class.equals(clazz)) {
+ return (T) new FrameStorageAdapter(frame, FrameReader.create(signature),
Intervals.ETERNITY);
+ }
return null;
}
}
diff --git
a/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultColumnSelectorFactoryMaker.java
b/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultColumnSelectorFactoryMaker.java
index a8f3570b9ad..4611280ce89 100644
---
a/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultColumnSelectorFactoryMaker.java
+++
b/processing/src/main/java/org/apache/druid/query/rowsandcols/semantic/DefaultColumnSelectorFactoryMaker.java
@@ -141,7 +141,7 @@ public class DefaultColumnSelectorFactoryMaker implements
ColumnSelectorFactoryM
{
return withColumnAccessor(columnName, columnAccessor -> {
if (columnAccessor == null) {
- return DimensionSelector.constant(null);
+ return DimensionSelector.nilSelector();
} else {
final ColumnType type = columnAccessor.getType();
switch (type.getType()) {
@@ -160,16 +160,22 @@ public class DefaultColumnSelectorFactoryMaker implements
ColumnSelectorFactoryM
@Override
public ColumnCapabilities getColumnCapabilities(String column)
{
- return withColumnAccessor(column, columnAccessor ->
- new ColumnCapabilitiesImpl()
+ return withColumnAccessor(column, columnAccessor -> {
+ if (columnAccessor == null) {
+ return null;
+ } else {
+ return new ColumnCapabilitiesImpl()
.setType(columnAccessor.getType())
.setHasMultipleValues(false)
.setDictionaryEncoded(false)
- .setHasBitmapIndexes(false));
+ .setHasBitmapIndexes(false);
+ }
+ });
}
private <T> T withColumnAccessor(String column, Function<ColumnAccessor,
T> fn)
{
+ @Nullable
ColumnAccessor retVal = accessorCache.get(column);
if (retVal == null) {
Column racColumn = rac.findColumn(column);
diff --git
a/processing/src/main/java/org/apache/druid/segment/VirtualColumns.java
b/processing/src/main/java/org/apache/druid/segment/VirtualColumns.java
index f26e297684b..be877566262 100644
--- a/processing/src/main/java/org/apache/druid/segment/VirtualColumns.java
+++ b/processing/src/main/java/org/apache/druid/segment/VirtualColumns.java
@@ -48,10 +48,12 @@ import
org.apache.druid.segment.virtual.VirtualizedColumnSelectorFactory;
import javax.annotation.Nullable;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* Class allowing lookup and usage of virtual columns.
@@ -112,6 +114,11 @@ public class VirtualColumns implements Cacheable
return new VirtualColumns(ImmutableList.copyOf(virtualColumns),
withDotSupport, withoutDotSupport);
}
+ public static VirtualColumns create(VirtualColumn... virtualColumns)
+ {
+ return create(Arrays.asList(virtualColumns));
+ }
+
public static VirtualColumns nullToEmpty(@Nullable VirtualColumns
virtualColumns)
{
return virtualColumns == null ? EMPTY : virtualColumns;
@@ -519,4 +526,14 @@ public class VirtualColumns implements Cacheable
((VirtualColumns) obj).virtualColumns.isEmpty();
}
}
+
+ public boolean isEmpty()
+ {
+ return virtualColumns.isEmpty();
+ }
+
+ public List<String> getColumnNames()
+ {
+ return virtualColumns.stream().map(v ->
v.getOutputName()).collect(Collectors.toList());
+ }
}
diff --git
a/processing/src/test/java/org/apache/druid/error/DruidExceptionMatcher.java
b/processing/src/test/java/org/apache/druid/error/DruidExceptionMatcher.java
index d3d4e057c5e..75166543f55 100644
--- a/processing/src/test/java/org/apache/druid/error/DruidExceptionMatcher.java
+++ b/processing/src/test/java/org/apache/druid/error/DruidExceptionMatcher.java
@@ -45,6 +45,15 @@ public class DruidExceptionMatcher extends
DiagnosingMatcher<Throwable>
return invalidInput().expectContext("sourceType", "sql");
}
+ public static DruidExceptionMatcher defensive()
+ {
+ return new DruidExceptionMatcher(
+ DruidException.Persona.DEVELOPER,
+ DruidException.Category.DEFENSIVE,
+ "general"
+ );
+ }
+
private final AllOf<DruidException> delegate;
private final ArrayList<Matcher<? super DruidException>> matcherList;
diff --git
a/processing/src/test/java/org/apache/druid/query/operator/WindowOperatorQueryTest.java
b/processing/src/test/java/org/apache/druid/query/operator/WindowOperatorQueryTest.java
index 69712c06493..dcd969e57fa 100644
---
a/processing/src/test/java/org/apache/druid/query/operator/WindowOperatorQueryTest.java
+++
b/processing/src/test/java/org/apache/druid/query/operator/WindowOperatorQueryTest.java
@@ -19,18 +19,23 @@
package org.apache.druid.query.operator;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.druid.java.util.common.Intervals;
import org.apache.druid.query.InlineDataSource;
import org.apache.druid.query.QueryContext;
import org.apache.druid.query.TableDataSource;
import org.apache.druid.query.spec.LegacySegmentSpec;
+import org.apache.druid.query.spec.MultipleIntervalSegmentSpec;
+import org.apache.druid.query.spec.QuerySegmentSpec;
import org.apache.druid.segment.column.RowSignature;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Set;
/**
@@ -107,6 +112,22 @@ public class WindowOperatorQueryTest
Assert.assertSame(newDs, query.withDataSource(newDs).getDataSource());
}
+ @Test
+ public void withQuerySpec()
+ {
+ QuerySegmentSpec spec = new
MultipleIntervalSegmentSpec(Collections.emptyList());
+ Assert.assertSame(spec, ((WindowOperatorQuery)
query.withQuerySegmentSpec(spec)).getQuerySegmentSpec());
+ }
+
+ @Test
+ public void withOperators()
+ {
+ List<OperatorFactory> operators = ImmutableList.<OperatorFactory>builder()
+ .add(new
NaivePartitioningOperatorFactory(Collections.singletonList("some")))
+ .build();
+ Assert.assertSame(operators, ((WindowOperatorQuery)
query.withOperators(operators)).getOperators());
+ }
+
@Test
public void testEquals()
{
diff --git
a/processing/src/test/java/org/apache/druid/query/rowsandcols/RowsAndColumnsTestBase.java
b/processing/src/test/java/org/apache/druid/query/rowsandcols/RowsAndColumnsTestBase.java
index 36a621ff8c8..16b84f82728 100644
---
a/processing/src/test/java/org/apache/druid/query/rowsandcols/RowsAndColumnsTestBase.java
+++
b/processing/src/test/java/org/apache/druid/query/rowsandcols/RowsAndColumnsTestBase.java
@@ -22,6 +22,8 @@ package org.apache.druid.query.rowsandcols;
import com.google.common.collect.Lists;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.java.util.common.ISE;
+import org.apache.druid.query.rowsandcols.concrete.FrameRowsAndColumns;
+import org.apache.druid.query.rowsandcols.concrete.FrameRowsAndColumnsTest;
import org.junit.Assert;
import org.junit.Test;
@@ -63,7 +65,8 @@ public abstract class RowsAndColumnsTestBase
new Object[]{MapOfColumnsRowsAndColumns.class, Function.identity()},
new Object[]{ArrayListRowsAndColumns.class,
ArrayListRowsAndColumnsTest.MAKER},
new Object[]{ConcatRowsAndColumns.class,
ConcatRowsAndColumnsTest.MAKER},
- new Object[]{RearrangedRowsAndColumns.class,
RearrangedRowsAndColumnsTest.MAKER}
+ new Object[]{RearrangedRowsAndColumns.class,
RearrangedRowsAndColumnsTest.MAKER},
+ new Object[]{FrameRowsAndColumns.class, FrameRowsAndColumnsTest.MAKER}
);
}
diff --git
a/processing/src/test/java/org/apache/druid/query/rowsandcols/concrete/FrameRowsAndColumnsTest.java
b/processing/src/test/java/org/apache/druid/query/rowsandcols/concrete/FrameRowsAndColumnsTest.java
new file mode 100644
index 00000000000..837e30185e2
--- /dev/null
+++
b/processing/src/test/java/org/apache/druid/query/rowsandcols/concrete/FrameRowsAndColumnsTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.rowsandcols.concrete;
+
+import org.apache.druid.query.rowsandcols.LazilyDecoratedRowsAndColumns;
+import org.apache.druid.query.rowsandcols.MapOfColumnsRowsAndColumns;
+import org.apache.druid.query.rowsandcols.RowsAndColumnsTestBase;
+import java.util.function.Function;
+
+public class FrameRowsAndColumnsTest extends RowsAndColumnsTestBase
+{
+ public FrameRowsAndColumnsTest()
+ {
+ super(FrameRowsAndColumns.class);
+ }
+
+ public static Function<MapOfColumnsRowsAndColumns, FrameRowsAndColumns>
MAKER = input -> {
+
+ return buildFrame(input);
+ };
+
+ private static FrameRowsAndColumns buildFrame(MapOfColumnsRowsAndColumns
input)
+ {
+ LazilyDecoratedRowsAndColumns rac = new
LazilyDecoratedRowsAndColumns(input, null, null, null, Integer.MAX_VALUE, null,
null);
+
+ rac.numRows(); // materialize
+
+ return (FrameRowsAndColumns) rac.getBase();
+ }
+}
diff --git
a/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/CombinedSemanticInterfacesTest.java
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/CombinedSemanticInterfacesTest.java
index 9a5bce17c58..b7c91b854e4 100644
---
a/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/CombinedSemanticInterfacesTest.java
+++
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/CombinedSemanticInterfacesTest.java
@@ -30,6 +30,8 @@ import org.apache.druid.query.rowsandcols.RowsAndColumns;
import org.apache.druid.query.rowsandcols.column.ColumnAccessor;
import org.apache.druid.query.rowsandcols.column.IntArrayColumn;
import org.apache.druid.query.rowsandcols.column.ObjectArrayColumn;
+import org.apache.druid.segment.ColumnSelectorFactory;
+import org.apache.druid.segment.DimensionSelector;
import org.apache.druid.segment.column.ColumnType;
import org.junit.Assert;
import org.junit.Test;
@@ -38,8 +40,12 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
/**
* Place where tests can live that are testing the interactions of multiple
semantic interfaces
*/
@@ -54,6 +60,30 @@ public class CombinedSemanticInterfacesTest extends
SemanticTestBase
super(name, fn);
}
+ @Test
+ public void
testColumnSelectorFactoryMakeColumnValueSelectorNonExistentColumn()
+ {
+ RowsAndColumns rac = make(MapOfColumnsRowsAndColumns.fromMap(
+ ImmutableMap.of(
+ "some", new IntArrayColumn(new int[] {3, 54, 21, 1, 5, 54, 2, 3,
92}))));
+ AtomicInteger currRow = new AtomicInteger();
+ ColumnSelectorFactory csfm =
ColumnSelectorFactoryMaker.fromRAC(rac).make(currRow);
+
+ assertEquals(DimensionSelector.nilSelector(),
csfm.makeColumnValueSelector("nonexistent"));
+ }
+
+ @Test
+ public void testColumnSelectorFactoryGetColumnCapabilitiesNonExistentColumn()
+ {
+ RowsAndColumns rac = make(MapOfColumnsRowsAndColumns.fromMap(
+ ImmutableMap.of(
+ "some", new IntArrayColumn(new int[] {3, 54, 21, 1, 5, 54, 2, 3,
92}))));
+ AtomicInteger currRow = new AtomicInteger();
+ ColumnSelectorFactory csfm =
ColumnSelectorFactoryMaker.fromRAC(rac).make(currRow);
+
+ assertNull(csfm.getColumnCapabilities("nonexistent"));
+ }
+
/**
* Tests a relatively common series of operations for window functions:
partition -> aggregate -> sort
*/
diff --git
a/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/TestVirtualColumnEvaluationRowsAndColumnsTest.java
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/TestVirtualColumnEvaluationRowsAndColumnsTest.java
new file mode 100644
index 00000000000..e53850bccc9
--- /dev/null
+++
b/processing/src/test/java/org/apache/druid/query/rowsandcols/semantic/TestVirtualColumnEvaluationRowsAndColumnsTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.rowsandcols.semantic;
+
+import com.google.common.collect.Lists;
+import org.apache.druid.query.expression.TestExprMacroTable;
+import org.apache.druid.query.operator.window.RowsAndColumnsHelper;
+import org.apache.druid.query.rowsandcols.LazilyDecoratedRowsAndColumns;
+import org.apache.druid.query.rowsandcols.MapOfColumnsRowsAndColumns;
+import org.apache.druid.query.rowsandcols.RowsAndColumns;
+import org.apache.druid.segment.StorageAdapter;
+import org.apache.druid.segment.VirtualColumns;
+import org.apache.druid.segment.column.ColumnType;
+import org.apache.druid.segment.column.RowSignature;
+import org.apache.druid.segment.virtual.ExpressionVirtualColumn;
+import org.junit.Test;
+
+import java.util.function.Function;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeNotNull;
+
+public class TestVirtualColumnEvaluationRowsAndColumnsTest extends
SemanticTestBase
+{
+ public TestVirtualColumnEvaluationRowsAndColumnsTest(String name,
Function<MapOfColumnsRowsAndColumns, RowsAndColumns> fn)
+ {
+ super(name, fn);
+ }
+
+ @Test
+ public void testMaterializeVirtualColumns()
+ {
+ Object[][] vals = new Object[][] {
+ {1L, "a", 123L, 0L},
+ {2L, "a", 456L, 1L},
+ {3L, "b", 789L, 2L},
+ {4L, "b", 123L, 3L},
+ };
+
+ RowSignature siggy = RowSignature.builder()
+ .add("__time", ColumnType.LONG)
+ .add("dim", ColumnType.STRING)
+ .add("val", ColumnType.LONG)
+ .add("arrayIndex", ColumnType.LONG)
+ .build();
+
+ final RowsAndColumns base =
make(MapOfColumnsRowsAndColumns.fromRowObjects(vals, siggy));
+
+ assumeNotNull("skipping: StorageAdapter not supported",
base.as(StorageAdapter.class));
+
+ LazilyDecoratedRowsAndColumns ras = new LazilyDecoratedRowsAndColumns(
+ base,
+ null,
+ null,
+ VirtualColumns.create(new ExpressionVirtualColumn(
+ "expr",
+ "val * 2",
+ ColumnType.LONG,
+ TestExprMacroTable.INSTANCE)),
+ Integer.MAX_VALUE,
+ null,
+ null);
+
+ // do the materialziation
+ ras.numRows();
+
+ assertEquals(Lists.newArrayList("__time", "dim", "val", "arrayIndex",
"expr"), ras.getColumnNames());
+
+ new RowsAndColumnsHelper()
+ .expectColumn("expr", new long[] {123 * 2, 456L * 2, 789 * 2, 123 * 2})
+ .validate(ras);
+
+ }
+
+}
diff --git
a/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionVirtualColumnTest.java
b/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionVirtualColumnTest.java
index c8fd92a1079..9d35e6025ff 100644
---
a/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionVirtualColumnTest.java
+++
b/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionVirtualColumnTest.java
@@ -716,8 +716,8 @@ public class ExpressionVirtualColumnTest extends
InitializedNullHandlingTest
CURRENT_ROW.set(ROW0);
Assert.assertEquals(DateTimes.of("2000-01-01").getMillis(),
selector.getLong());
- Assert.assertEquals((float) DateTimes.of("2000-01-01").getMillis(),
selector.getFloat(), 0.0f);
- Assert.assertEquals((double) DateTimes.of("2000-01-01").getMillis(),
selector.getDouble(), 0.0d);
+ Assert.assertEquals(DateTimes.of("2000-01-01").getMillis(),
selector.getFloat(), 0.0f);
+ Assert.assertEquals(DateTimes.of("2000-01-01").getMillis(),
selector.getDouble(), 0.0d);
Assert.assertEquals(DateTimes.of("2000-01-01").getMillis(),
selector.getObject());
CURRENT_ROW.set(ROW1);
diff --git
a/processing/src/test/java/org/apache/druid/segment/virtual/VirtualColumnsTest.java
b/processing/src/test/java/org/apache/druid/segment/virtual/VirtualColumnsTest.java
index fbf3b1c3aee..e13807e07e2 100644
---
a/processing/src/test/java/org/apache/druid/segment/virtual/VirtualColumnsTest.java
+++
b/processing/src/test/java/org/apache/druid/segment/virtual/VirtualColumnsTest.java
@@ -64,8 +64,12 @@ import org.mockito.quality.Strictness;
import javax.annotation.Nullable;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
public class VirtualColumnsTest extends InitializedNullHandlingTest
{
private static final String REAL_COLUMN_NAME = "real_column";
@@ -90,6 +94,26 @@ public class VirtualColumnsTest extends
InitializedNullHandlingTest
Assert.assertFalse(virtualColumns.exists("bar"));
}
+ @Test
+ public void testIsEmpty()
+ {
+ assertTrue(VirtualColumns.EMPTY.isEmpty());
+ assertTrue(VirtualColumns.create(Collections.emptyList()).isEmpty());
+ }
+
+ @Test
+ public void testGetColumnNames()
+ {
+ final VirtualColumns virtualColumns = makeVirtualColumns();
+ List<String> colNames = ImmutableList.<String>builder()
+ .add("expr")
+ .add("expr2i")
+ .add("expr2")
+ .add("foo")
+ .build();
+ assertEquals(colNames, virtualColumns.getColumnNames());
+ }
+
@Test
public void testGetColumnCapabilitiesNilBase()
{
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
index 1cf79b6dc12..b670d682222 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
@@ -67,6 +67,8 @@ import org.apache.druid.query.groupby.GroupByQuery;
import org.apache.druid.query.groupby.having.DimFilterHavingSpec;
import org.apache.druid.query.groupby.orderby.DefaultLimitSpec;
import org.apache.druid.query.groupby.orderby.OrderByColumnSpec;
+import org.apache.druid.query.operator.OperatorFactory;
+import org.apache.druid.query.operator.ScanOperatorFactory;
import org.apache.druid.query.operator.WindowOperatorQuery;
import org.apache.druid.query.ordering.StringComparator;
import org.apache.druid.query.scan.ScanQuery;
@@ -282,7 +284,8 @@ public class DruidQuery
partialQuery,
plannerContext,
sourceRowSignature, // Plans immediately after Scan, so safe
to use the row signature from scan
- rexBuilder
+ rexBuilder,
+ virtualColumnRegistry
)
);
} else {
@@ -1442,12 +1445,30 @@ public class DruidQuery
return null;
}
+ // all virtual cols are needed - these columns are only referenced from
the aggregates
+ VirtualColumns virtualColumns =
virtualColumnRegistry.build(Collections.emptySet());
+ final List<OperatorFactory> operators;
+
+ if (virtualColumns.isEmpty()) {
+ operators = windowing.getOperators();
+ } else {
+ operators = ImmutableList.<OperatorFactory>builder()
+ .add(new ScanOperatorFactory(
+ null,
+ null,
+ null,
+ null,
+ virtualColumns,
+ null))
+ .addAll(windowing.getOperators())
+ .build();
+ }
return new WindowOperatorQuery(
dataSource,
new LegacySegmentSpec(Intervals.ETERNITY),
plannerContext.queryContextMap(),
windowing.getSignature(),
- windowing.getOperators(),
+ operators,
null
);
}
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java
b/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java
index b44be8b4389..3503838d6fd 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java
@@ -22,6 +22,7 @@ package org.apache.druid.sql.calcite.rel;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.druid.segment.VirtualColumn;
+import org.apache.druid.segment.VirtualColumns;
import org.apache.druid.segment.column.ColumnCapabilities;
import org.apache.druid.segment.column.ColumnType;
import org.apache.druid.segment.column.RowSignature;
@@ -32,13 +33,17 @@ import org.apache.druid.sql.calcite.planner.PlannerContext;
import javax.annotation.Nullable;
import java.util.ArrayDeque;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
+import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -88,6 +93,11 @@ public class VirtualColumnRegistry
);
}
+ public boolean isEmpty()
+ {
+ return virtualColumnsByExpression.isEmpty();
+ }
+
/**
* Check if a {@link VirtualColumn} is defined by column name
*/
@@ -350,4 +360,21 @@ public class VirtualColumnRegistry
return Objects.hash(expression, typeHint);
}
}
+
+ public VirtualColumns build(Set<String> exclude)
+ {
+ List<VirtualColumn> columns = new ArrayList<>();
+ if (virtualColumnsByName == null) {
+ return VirtualColumns.EMPTY;
+ }
+
+ for (Entry<String, ExpressionAndTypeHint> entry :
virtualColumnsByName.entrySet()) {
+ if (exclude.contains(entry.getKey())) {
+ continue;
+ }
+ columns.add(getVirtualColumn(entry.getKey()));
+ }
+ columns.sort(Comparator.comparing(VirtualColumn::getOutputName));
+ return VirtualColumns.create(columns);
+ }
}
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java
b/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java
index 4039ca8914a..9f8d3d091b5 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/Windowing.java
@@ -115,7 +115,8 @@ public class Windowing
final PartialDruidQuery partialQuery,
final PlannerContext plannerContext,
final RowSignature sourceRowSignature,
- final RexBuilder rexBuilder
+ final RexBuilder rexBuilder,
+ final VirtualColumnRegistry virtualColumnRegistry
)
{
final Window window = Preconditions.checkNotNull(partialQuery.getWindow(),
"window");
@@ -172,10 +173,11 @@ public class Windowing
ProcessorMaker maker =
KNOWN_WINDOW_FNS.get(aggregateCall.getAggregation().getName());
if (maker == null) {
+
final Aggregation aggregation = GroupByRules.translateAggregateCall(
plannerContext,
sourceRowSignature,
- null,
+ virtualColumnRegistry,
rexBuilder,
InputAccessor.buildFor(
rexBuilder,
diff --git
a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
index 1527e75fa38..6b2d12c6cce 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
@@ -1335,8 +1335,7 @@ public class BaseCalciteQueryTest extends CalciteTestBase
return queryJsonMapper.treeToValue(newQueryNode, Query.class);
}
catch (Exception e) {
- Assert.fail(e.getMessage());
- return null;
+ throw new RuntimeException(e);
}
}
diff --git
a/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java
b/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java
index 8a737eca035..7a2b9b70f1a 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/DrillWindowQueryTest.java
@@ -4691,7 +4691,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("aggregates/winFnQry_12")
@Test
public void test_aggregates_winFnQry_12()
@@ -4699,7 +4699,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("aggregates/winFnQry_13")
@Test
public void test_aggregates_winFnQry_13()
@@ -4707,7 +4707,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("aggregates/winFnQry_20")
@Test
public void test_aggregates_winFnQry_20()
@@ -4715,7 +4715,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("aggregates/winFnQry_21")
@Test
public void test_aggregates_winFnQry_21()
@@ -4731,7 +4731,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/defaultFrame/RBUPACR_chr_1")
@Test
public void test_frameclause_defaultFrame_RBUPACR_chr_1()
@@ -4739,7 +4739,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/defaultFrame/RBUPACR_chr_2")
@Test
public void test_frameclause_defaultFrame_RBUPACR_chr_2()
@@ -4747,7 +4747,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/defaultFrame/RBUPACR_vchr_1")
@Test
public void test_frameclause_defaultFrame_RBUPACR_vchr_1()
@@ -4755,7 +4755,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/defaultFrame/RBUPACR_vchr_2")
@Test
public void test_frameclause_defaultFrame_RBUPACR_vchr_2()
@@ -4763,7 +4763,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/multipl_wnwds/max_mulwds")
@Test
public void test_frameclause_multipl_wnwds_max_mulwds()
@@ -4771,7 +4771,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/multipl_wnwds/min_mulwds")
@Test
public void test_frameclause_multipl_wnwds_min_mulwds()
@@ -4779,7 +4779,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBCRACR/RBCRACR_char_1")
@Test
public void test_frameclause_RBCRACR_RBCRACR_char_1()
@@ -4787,7 +4787,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBCRACR/RBCRACR_char_2")
@Test
public void test_frameclause_RBCRACR_RBCRACR_char_2()
@@ -4795,7 +4795,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBCRACR/RBCRACR_vchar_1")
@Test
public void test_frameclause_RBCRACR_RBCRACR_vchar_1()
@@ -4803,7 +4803,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBCRACR/RBCRACR_vchar_2")
@Test
public void test_frameclause_RBCRACR_RBCRACR_vchar_2()
@@ -4811,7 +4811,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPACR/RBUPACR_chr_1")
@Test
public void test_frameclause_RBUPACR_RBUPACR_chr_1()
@@ -4819,7 +4819,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPACR/RBUPACR_chr_2")
@Test
public void test_frameclause_RBUPACR_RBUPACR_chr_2()
@@ -4827,7 +4827,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPACR/RBUPACR_vchr_1")
@Test
public void test_frameclause_RBUPACR_RBUPACR_vchr_1()
@@ -4835,7 +4835,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPACR/RBUPACR_vchr_2")
@Test
public void test_frameclause_RBUPACR_RBUPACR_vchr_2()
@@ -4843,7 +4843,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPAUF/RBUPAUF_char_1")
@Test
public void test_frameclause_RBUPAUF_RBUPAUF_char_1()
@@ -4851,7 +4851,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPAUF/RBUPAUF_char_2")
@Test
public void test_frameclause_RBUPAUF_RBUPAUF_char_2()
@@ -4859,7 +4859,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPAUF/RBUPAUF_vchar_1")
@Test
public void test_frameclause_RBUPAUF_RBUPAUF_vchar_1()
@@ -4867,7 +4867,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/RBUPAUF/RBUPAUF_vchar_2")
@Test
public void test_frameclause_RBUPAUF_RBUPAUF_vchar_2()
@@ -4875,7 +4875,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_22")
@Test
public void test_frameclause_subQueries_frmInSubQry_22()
@@ -4883,7 +4883,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_23")
@Test
public void test_frameclause_subQueries_frmInSubQry_23()
@@ -4891,7 +4891,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_24")
@Test
public void test_frameclause_subQueries_frmInSubQry_24()
@@ -4899,7 +4899,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_41")
@Test
public void test_frameclause_subQueries_frmInSubQry_41()
@@ -4907,7 +4907,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_42")
@Test
public void test_frameclause_subQueries_frmInSubQry_42()
@@ -4915,7 +4915,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_43")
@Test
public void test_frameclause_subQueries_frmInSubQry_43()
@@ -4923,7 +4923,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_44")
@Test
public void test_frameclause_subQueries_frmInSubQry_44()
@@ -4931,7 +4931,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_45")
@Test
public void test_frameclause_subQueries_frmInSubQry_45()
@@ -4939,7 +4939,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("frameclause/subQueries/frmInSubQry_46")
@Test
public void test_frameclause_subQueries_frmInSubQry_46()
@@ -4963,7 +4963,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("nestedAggs/basic_10")
@Test
public void test_nestedAggs_basic_10()
@@ -4971,7 +4971,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE)
+ @NotYetSupported(Modes.AGGREGATION_NOT_SUPPORT_TYPE)
@DrillTest("nestedAggs/cte_win_01")
@Test
public void test_nestedAggs_cte_win_01()
@@ -4979,7 +4979,7 @@ public class DrillWindowQueryTest extends
BaseCalciteQueryTest
windowQueryTest();
}
- @NotYetSupported(Modes.NPE_PLAIN)
+ @NotYetSupported(Modes.RESULT_MISMATCH)
@DrillTest("aggregates/winFnQry_7")
@Test
public void test_aggregates_winFnQry_7()
diff --git
a/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java
b/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java
index 933359e96bf..86e5c41d6de 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/NotYetSupported.java
@@ -79,7 +79,7 @@ public @interface NotYetSupported
BIGINT_TO_DATE(DruidException.class, "BIGINT to type (DATE|TIME)"),
NPE_PLAIN(NullPointerException.class, "java.lang.NullPointerException"),
NPE(DruidException.class, "java.lang.NullPointerException"),
- AGGREGATION_NOT_SUPPORT_TYPE(DruidException.class, "Aggregation
\\[(MIN|MAX)\\] does not support type"),
+ AGGREGATION_NOT_SUPPORT_TYPE(DruidException.class, "Aggregation
\\[(MIN|MAX)\\] does not support type \\[STRING\\]"),
CANNOT_APPLY_VIRTUAL_COL(UOE.class, "apply virtual columns"),
MISSING_DESC(DruidException.class, "function signature DESC"),
RESULT_COUNT_MISMATCH(AssertionError.class, "result count:"),
diff --git a/sql/src/test/resources/calcite/tests/window/virtualColumns.sqlTest
b/sql/src/test/resources/calcite/tests/window/virtualColumns.sqlTest
new file mode 100644
index 00000000000..0a86a691e26
--- /dev/null
+++ b/sql/src/test/resources/calcite/tests/window/virtualColumns.sqlTest
@@ -0,0 +1,33 @@
+type: "operatorValidation"
+
+sql: |
+ SELECT
+ '_'||dim1,
+ MIN(cast(42 as double)) OVER (),
+ MIN(cast((cnt||cnt) as bigint)) OVER ()
+ FROM foo
+
+expectedOperators:
+ - type: "scan"
+ limit: -1
+ virtualColumns:
+ - type: "expression"
+ name: "_v0"
+ expression: "42.0"
+ outputType: "DOUBLE"
+ - { type: "naivePartition", partitionColumns: [ ] }
+ - type: "window"
+ processor:
+ type: "framedAgg"
+ frame: { peerType: "ROWS", lowUnbounded: true, lowOffset: 0,
uppUnbounded: true, uppOffset: 0 }
+ aggregations:
+ - { type: "doubleMin", name: "w0", fieldName: "_v0" }
+ - { type: "longMin", name: "w1", fieldName: "v1" }
+
+expectedResults:
+ - ["_",42.0,11]
+ - ["_10.1",42.0,11]
+ - ["_2",42.0,11]
+ - ["_1",42.0,11]
+ - ["_def",42.0,11]
+ - ["_abc",42.0,11]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]