From 9e6cddc6255a6ec820a5489d3523c07927bba8e2 Mon Sep 17 00:00:00 2001 From: Misha Date: Tue, 10 Feb 2026 15:28:28 +0100 Subject: [PATCH 1/2] introduced configurable index disabling for virtual columns --- docs/querying/query-context-reference.md | 1 + .../org/apache/druid/query/QueryContext.java | 5 + .../org/apache/druid/query/QueryContexts.java | 3 + .../segment/QueryableIndexCursorHolder.java | 15 ++- ...ualColumnBitmapDisablingIndexSelector.java | 126 ++++++++++++++++++ ...ilterBundleVCBitmapIndexDisablingTest.java | 108 +++++++++++++++ ...olumnBitmapDisablingIndexSelectorTest.java | 90 +++++++++++++ .../VcBitmapIndexDisablingSqlTest.java | 88 ++++++++++++ 8 files changed, 433 insertions(+), 3 deletions(-) create mode 100644 processing/src/main/java/org/apache/druid/segment/VirtualColumnBitmapDisablingIndexSelector.java create mode 100644 processing/src/test/java/org/apache/druid/segment/filter/FilterBundleVCBitmapIndexDisablingTest.java create mode 100644 processing/src/test/java/org/apache/druid/segment/filter/VirtualColumnBitmapDisablingIndexSelectorTest.java create mode 100644 sql/src/test/java/org/apache/druid/sql/calcite/VcBitmapIndexDisablingSqlTest.java diff --git a/docs/querying/query-context-reference.md b/docs/querying/query-context-reference.md index a7532b265d01..43c98ac3281d 100644 --- a/docs/querying/query-context-reference.md +++ b/docs/querying/query-context-reference.md @@ -72,6 +72,7 @@ Unless otherwise noted, the following parameters apply to all query types, and t |`sqlPlannerBloat`|`1000`|Calcite parameter which controls whether to merge two Project operators when inlining expressions causes complexity to increase. Implemented as a workaround to exception `There are not enough rules to produce a node with desired properties: convention=DRUID, sort=[]` thrown after rejecting the merge of two projects.| |`cloneQueryMode`|`excludeClones`| Indicates whether clone Historicals should be queried by brokers. Clone servers are created by the `cloneServers` Coordinator dynamic configuration. Possible values are `excludeClones`, `includeClones` and `preferClones`. `excludeClones` means that clone Historicals are not queried by the broker. `preferClones` indicates that when given a choice between the clone Historical and the original Historical which is being cloned, the broker chooses the clones. Historicals which are not involved in the cloning process will still be queried. `includeClones` means that broker queries any Historical without regarding clone status. This parameter only affects native queries. MSQ does not query Historicals directly.| |`realtimeSegmentsOnly` |`false`| When set to true, only query realtime segments. Historical segments are excluded. | +|`maxVirtualColumnsForBitmapIndexing`|`Integer.MAX_VALUE`| Sets the virtual-column count threshold beyond which Druid stops using bitmap indexes for filters on virtual columns.| ## Parameters by query type diff --git a/processing/src/main/java/org/apache/druid/query/QueryContext.java b/processing/src/main/java/org/apache/druid/query/QueryContext.java index 42ed66978ffa..b13f606f6f56 100644 --- a/processing/src/main/java/org/apache/druid/query/QueryContext.java +++ b/processing/src/main/java/org/apache/druid/query/QueryContext.java @@ -777,4 +777,9 @@ public boolean isRealtimeSegmentsOnly() { return getBoolean(QueryContexts.REALTIME_SEGMENTS_ONLY, QueryContexts.DEFAULT_REALTIME_SEGMENTS_ONLY); } + + public int getMaxVirtualColumnsForBitmapIndexing() + { + return getInt(QueryContexts.CTX_MAX_VIRTUAL_COLUMNS_FOR_BITMAP, QueryContexts.DEFAULT_MAX_VIRTUAL_COLUMNS_FOR_BITMAP); + } } diff --git a/processing/src/main/java/org/apache/druid/query/QueryContexts.java b/processing/src/main/java/org/apache/druid/query/QueryContexts.java index 6df392d95714..b5416b64d293 100644 --- a/processing/src/main/java/org/apache/druid/query/QueryContexts.java +++ b/processing/src/main/java/org/apache/druid/query/QueryContexts.java @@ -142,6 +142,8 @@ public class QueryContexts public static final boolean DEFAULT_REALTIME_SEGMENTS_ONLY = false; public static final String CTX_PREPLANNED = "prePlanned"; + public static final String CTX_MAX_VIRTUAL_COLUMNS_FOR_BITMAP = "maxVirtualColumnsForBitmapIndexing"; + public static final boolean DEFAULT_PREPLANNED = true; // Defaults @@ -177,6 +179,7 @@ public class QueryContexts public static final boolean DEFAULT_USE_NESTED_FOR_UNKNOWN_TYPE_IN_SUBQUERY = false; public static final boolean DEFAULT_EXTENDED_FILTERED_SUM_REWRITE_ENABLED = true; public static final boolean DEFAULT_CTX_FULL_REPORT = false; + public static final int DEFAULT_MAX_VIRTUAL_COLUMNS_FOR_BITMAP = Integer.MAX_VALUE; @SuppressWarnings("unused") // Used by Jackson serialization diff --git a/processing/src/main/java/org/apache/druid/segment/QueryableIndexCursorHolder.java b/processing/src/main/java/org/apache/druid/segment/QueryableIndexCursorHolder.java index 3470ed2ca43c..883f5e2d6158 100644 --- a/processing/src/main/java/org/apache/druid/segment/QueryableIndexCursorHolder.java +++ b/processing/src/main/java/org/apache/druid/segment/QueryableIndexCursorHolder.java @@ -84,6 +84,7 @@ public class QueryableIndexCursorHolder implements CursorHolder private final QueryContext queryContext; private final int vectorSize; private final Supplier resourcesSupplier; + private final boolean disableVirtualColumnBitmapIndexes; public QueryableIndexCursorHolder( QueryableIndex index, @@ -108,6 +109,8 @@ public QueryableIndexCursorHolder( this.queryContext = cursorBuildSpec.getQueryContext(); this.vectorSize = cursorBuildSpec.getQueryContext().getVectorSize(); this.metrics = cursorBuildSpec.getQueryMetrics(); + this.disableVirtualColumnBitmapIndexes = queryContext.getMaxVirtualColumnsForBitmapIndexing() + < virtualColumns.getColumnNames().size(); this.resourcesSupplier = Suppliers.memoize( () -> new CursorResources( index, @@ -117,7 +120,8 @@ public QueryableIndexCursorHolder( interval, filter, cursorBuildSpec.getQueryContext().getBoolean(QueryContexts.CURSOR_AUTO_ARRANGE_FILTERS, true), - metrics + metrics, + disableVirtualColumnBitmapIndexes ) ); } @@ -672,7 +676,8 @@ private CursorResources( Interval interval, @Nullable Filter filter, boolean cursorAutoArrangeFilters, - @Nullable QueryMetrics> metrics + @Nullable QueryMetrics> metrics, + boolean disableVirtualColumnBitmapIndexes ) { this.closer = Closer.create(); @@ -680,6 +685,10 @@ private CursorResources( this.timeBoundaryInspector = timeBoundaryInspector; try { this.numRows = index.getNumRows(); + final ColumnIndexSelector indexSelectorForFilters = + disableVirtualColumnBitmapIndexes + ? new VirtualColumnBitmapDisablingIndexSelector(columnCache, virtualColumns) + : columnCache; this.filterBundle = makeFilterBundle( computeFilterWithIntervalIfNeeded( timeBoundaryInspector, @@ -688,7 +697,7 @@ private CursorResources( filter ), cursorAutoArrangeFilters, - columnCache, + indexSelectorForFilters, numRows, metrics ); diff --git a/processing/src/main/java/org/apache/druid/segment/VirtualColumnBitmapDisablingIndexSelector.java b/processing/src/main/java/org/apache/druid/segment/VirtualColumnBitmapDisablingIndexSelector.java new file mode 100644 index 000000000000..12de337fae52 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/segment/VirtualColumnBitmapDisablingIndexSelector.java @@ -0,0 +1,126 @@ +/* + * 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.segment; + +import org.apache.druid.collections.bitmap.BitmapFactory; +import org.apache.druid.query.filter.ColumnIndexSelector; +import org.apache.druid.segment.column.ColumnCapabilities; +import org.apache.druid.segment.column.ColumnHolder; +import org.apache.druid.segment.column.ColumnIndexSupplier; +import org.apache.druid.segment.column.SelectableColumn; +import org.apache.druid.segment.selector.settable.SettableColumnValueSelector; +import org.apache.druid.segment.serde.NoIndexesColumnIndexSupplier; + +import javax.annotation.Nullable; +import java.util.Objects; + +public final class VirtualColumnBitmapDisablingIndexSelector implements ColumnIndexSelector +{ + private static final ColumnIndexSupplier NO_INDEXES = NoIndexesColumnIndexSupplier.getInstance(); + private final ColumnIndexSelector delegate; + private final VirtualColumns virtualColumns; + + + public VirtualColumnBitmapDisablingIndexSelector( + final ColumnIndexSelector delegate, + final VirtualColumns virtualColumns + ) + { + this.delegate = Objects.requireNonNull(delegate, "delegate"); + this.virtualColumns = Objects.requireNonNull(virtualColumns, "virtualColumns"); + } + + @Override + public int getNumRows() + { + return delegate.getNumRows(); + } + + @Override + public BitmapFactory getBitmapFactory() + { + return delegate.getBitmapFactory(); + } + + @Override + @Nullable + public ColumnHolder getColumnHolder(final String columnName) + { + final ColumnHolder holder = delegate.getColumnHolder(columnName); + if (holder == null || !isVirtual(columnName)) { + return holder; + } + + // force no indexes even if callers go via getColumnHolder(). + return new ColumnHolder() + { + @Override + public ColumnCapabilities getCapabilities() + { + return holder.getCapabilities(); + } + + @Override + public int getLength() + { + return holder.getLength(); + } + + @Override + public SelectableColumn getColumn() + { + return holder.getColumn(); + } + + @Override + public ColumnIndexSupplier getIndexSupplier() + { + return NO_INDEXES; + } + + @Override + public SettableColumnValueSelector makeNewSettableColumnValueSelector() + { + return holder.makeNewSettableColumnValueSelector(); + } + }; + } + + @Override + @Nullable + public ColumnIndexSupplier getIndexSupplier(final String column) + { + if (column.isEmpty()) { + return null; + } + + // Only disable indexes for virtual columns + if (isVirtual(column)) { + return NO_INDEXES; + } + return delegate.getIndexSupplier(column); + } + + + private boolean isVirtual(final String columnName) + { + return virtualColumns.getVirtualColumn(columnName) != null; + } +} diff --git a/processing/src/test/java/org/apache/druid/segment/filter/FilterBundleVCBitmapIndexDisablingTest.java b/processing/src/test/java/org/apache/druid/segment/filter/FilterBundleVCBitmapIndexDisablingTest.java new file mode 100644 index 000000000000..d1a321cf7041 --- /dev/null +++ b/processing/src/test/java/org/apache/druid/segment/filter/FilterBundleVCBitmapIndexDisablingTest.java @@ -0,0 +1,108 @@ +/* + * 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.segment.filter; + +import com.google.common.collect.ImmutableList; +import org.apache.druid.collections.bitmap.BitmapFactory; +import org.apache.druid.java.util.common.io.Closer; +import org.apache.druid.math.expr.ExprMacroTable; +import org.apache.druid.query.DefaultBitmapResultFactory; +import org.apache.druid.query.filter.ColumnIndexSelector; +import org.apache.druid.query.filter.EqualityFilter; +import org.apache.druid.query.filter.Filter; +import org.apache.druid.query.filter.FilterBundle; +import org.apache.druid.segment.ColumnCache; +import org.apache.druid.segment.QueryableIndex; +import org.apache.druid.segment.TestIndex; +import org.apache.druid.segment.VirtualColumnBitmapDisablingIndexSelector; +import org.apache.druid.segment.VirtualColumns; +import org.apache.druid.segment.column.ColumnType; +import org.apache.druid.segment.virtual.ExpressionVirtualColumn; +import org.apache.druid.testing.InitializedNullHandlingTest; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public class FilterBundleVCBitmapIndexDisablingTest extends InitializedNullHandlingTest +{ + + @Test + public void testVCBitmapIndexEnabled() + { + final VirtualColumns virtualColumns = VirtualColumns.create(ImmutableList.of( + new ExpressionVirtualColumn("v1", + "countryName", ColumnType.STRING, + ExprMacroTable.nil() + ) + )); + final QueryableIndex index = TestIndex.getMMappedWikipediaIndex(); + BitmapFactory bitmapFactory = index.getBitmapFactoryForDimensions(); + + try (Closer closer = Closer.create()) { + ColumnCache columnCache = new ColumnCache(index, virtualColumns, closer); + VirtualColumnBitmapDisablingIndexSelector selector = new VirtualColumnBitmapDisablingIndexSelector(columnCache, + virtualColumns + ); + + final FilterBundle filterBundleIndexEnabled = makeFilterBundle(new AndFilter(ImmutableList.of( + new EqualityFilter("v1", ColumnType.STRING, "United States", null), + new EqualityFilter("countryName", + ColumnType.STRING, + "United States", + null + ) + )), columnCache, bitmapFactory); + + final FilterBundle filterBundleIndexDisabled = makeFilterBundle(new AndFilter(ImmutableList.of( + new EqualityFilter("v1", ColumnType.STRING, "United States", null), + new EqualityFilter("countryName", + ColumnType.STRING, + "United States", + null + ) + )), selector, bitmapFactory); + + Assert.assertEquals(2, filterBundleIndexEnabled.getIndex().getIndexInfo().getIndexes().size()); + Assert.assertEquals("v1 = United States", filterBundleIndexEnabled.getIndex().getIndexInfo().getIndexes().get(0).getFilter()); + Assert.assertEquals("countryName = United States", filterBundleIndexEnabled.getIndex().getIndexInfo().getIndexes().get(1).getFilter()); + + Assert.assertNull(filterBundleIndexDisabled.getIndex().getIndexInfo().getIndexes()); + Assert.assertEquals("countryName = United States", filterBundleIndexDisabled.getIndex().getIndexInfo().getFilter()); + } + catch (IOException e) { + throw new RuntimeException(e); + } + + } + + protected FilterBundle makeFilterBundle( + final Filter filter, + ColumnIndexSelector selector, + BitmapFactory bitmapFactory + ) + { + return new FilterBundle.Builder(filter, selector, false).build(new DefaultBitmapResultFactory(bitmapFactory), + selector.getNumRows(), + selector.getNumRows(), + false + ); + } +} diff --git a/processing/src/test/java/org/apache/druid/segment/filter/VirtualColumnBitmapDisablingIndexSelectorTest.java b/processing/src/test/java/org/apache/druid/segment/filter/VirtualColumnBitmapDisablingIndexSelectorTest.java new file mode 100644 index 000000000000..afc9aaa596e0 --- /dev/null +++ b/processing/src/test/java/org/apache/druid/segment/filter/VirtualColumnBitmapDisablingIndexSelectorTest.java @@ -0,0 +1,90 @@ +/* + * 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.segment.filter; + +import com.google.common.collect.ImmutableList; +import org.apache.druid.java.util.common.io.Closer; +import org.apache.druid.math.expr.ExprMacroTable; +import org.apache.druid.query.filter.ColumnIndexSelector; +import org.apache.druid.segment.ColumnCache; +import org.apache.druid.segment.QueryableIndex; +import org.apache.druid.segment.TestIndex; +import org.apache.druid.segment.VirtualColumnBitmapDisablingIndexSelector; +import org.apache.druid.segment.VirtualColumns; +import org.apache.druid.segment.column.ColumnType; +import org.apache.druid.segment.serde.NoIndexesColumnIndexSupplier; +import org.apache.druid.segment.serde.StringUtf8ColumnIndexSupplier; +import org.apache.druid.segment.virtual.ExpressionVirtualColumn; +import org.apache.druid.testing.InitializedNullHandlingTest; +import org.junit.Test; + +import java.util.Objects; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +public class VirtualColumnBitmapDisablingIndexSelectorTest extends InitializedNullHandlingTest +{ + @Test + public void testNative_disablesIndexSupplierForVirtualColumnsOnly() throws Exception + { + final QueryableIndex index = TestIndex.getMMappedWikipediaIndex(); + + final VirtualColumns virtualColumns = VirtualColumns.create(ImmutableList.of(new ExpressionVirtualColumn( + "v0", + "countryName", + ColumnType.STRING, + ExprMacroTable.nil() + ), + new ExpressionVirtualColumn("v1", + "cityName", + ColumnType.STRING, + ExprMacroTable.nil() + ) + )); + + try (Closer closer = Closer.create()) { + final ColumnCache columnCache = new ColumnCache(index, virtualColumns, closer); + + assertEquals(StringUtf8ColumnIndexSupplier.class, + Objects.requireNonNull(columnCache.getIndexSupplier("v0")).getClass() + ); + assertEquals(StringUtf8ColumnIndexSupplier.class, + Objects.requireNonNull(columnCache.getIndexSupplier("v1")).getClass() + ); + + final ColumnIndexSelector vcIndexDisabled = new VirtualColumnBitmapDisablingIndexSelector(columnCache, + virtualColumns + ); + + assertSame(NoIndexesColumnIndexSupplier.getInstance(), vcIndexDisabled.getIndexSupplier("v0")); + assertSame(NoIndexesColumnIndexSupplier.getInstance(), vcIndexDisabled.getIndexSupplier("v1")); + + assertEquals( + StringUtf8ColumnIndexSupplier.class, + Objects.requireNonNull(vcIndexDisabled.getIndexSupplier("countryName")).getClass() + ); + assertEquals( + StringUtf8ColumnIndexSupplier.class, + Objects.requireNonNull(vcIndexDisabled.getIndexSupplier("cityName")).getClass() + ); + } + } +} diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/VcBitmapIndexDisablingSqlTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/VcBitmapIndexDisablingSqlTest.java new file mode 100644 index 000000000000..e0c2cad6a01e --- /dev/null +++ b/sql/src/test/java/org/apache/druid/sql/calcite/VcBitmapIndexDisablingSqlTest.java @@ -0,0 +1,88 @@ +/* + * 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.sql.calcite; + +import com.google.common.collect.ImmutableMap; +import org.apache.druid.java.util.common.io.Closer; +import org.apache.druid.query.Query; +import org.apache.druid.query.QueryContexts; +import org.apache.druid.segment.ColumnCache; +import org.apache.druid.segment.QueryableIndex; +import org.apache.druid.segment.TestIndex; +import org.apache.druid.segment.VirtualColumnBitmapDisablingIndexSelector; +import org.apache.druid.segment.VirtualColumns; +import org.apache.druid.segment.serde.NoIndexesColumnIndexSupplier; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.fail; + + +public class VcBitmapIndexDisablingSqlTest extends BaseCalciteQueryTest +{ + @Test + public void testSqlPlannedQueryVirtualColumnsHaveNoIndexSupplierWhenDisabled() + { + final Map ctx = ImmutableMap.builder() + .putAll(QUERY_CONTEXT_DEFAULT) + .put( + QueryContexts.CTX_MAX_VIRTUAL_COLUMNS_FOR_BITMAP, + 0 + ) + .build(); + + final String sql = "SELECT countryName + '' AS v0 FROM wikipedia LIMIT 1"; + + testBuilder() + .queryContext(ctx) + .sql(sql) + .expectedResults((s, queryResults) -> { + final List> planned = queryResults.recordedQueries; + Assertions.assertFalse(planned.isEmpty()); + + final QueryableIndex index = TestIndex.getMMappedWikipediaIndex(); + + for (Query q : planned) { + final VirtualColumns vcs = q.getVirtualColumns(); + if (vcs == null || vcs.isEmpty()) { + continue; + } + + try (var closer = Closer.create()) { + final var columnCache = new + ColumnCache(index, vcs, closer); + final var selector = new VirtualColumnBitmapDisablingIndexSelector(columnCache, vcs); + + Assertions.assertSame(NoIndexesColumnIndexSupplier.getInstance(), selector.getIndexSupplier("v0")); + return; + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + fail("SQL did not plan any query with virtualColumns"); + }) + .run(); + } +} From 1d280d6cda08e8092d531536c9c878efa2aa29da Mon Sep 17 00:00:00 2001 From: Misha Date: Fri, 13 Feb 2026 19:30:26 +0100 Subject: [PATCH 2/2] benchmark added --- .../benchmark/query/SqlExpressionBenchmark.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java index cc9e7b888dad..64855e48d30e 100644 --- a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java +++ b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java @@ -159,7 +159,9 @@ public class SqlExpressionBenchmark extends SqlBaseQueryBenchmark "SELECT CASE WHEN MOD(long1, 2) = 0 THEN -1 WHEN MOD(long1, 2) = 1 THEN long2 / MOD(long1, 2) ELSE long3 END FROM expressions GROUP BY 1", // cast "SELECT CAST(string1 as BIGINT) + CAST(string3 as DOUBLE) + long3, COUNT(*) FROM expressions GROUP BY 1 ORDER BY 2", - "SELECT COUNT(*), SUM(CAST(string1 as BIGINT) + CAST(string3 as BIGINT)) FROM expressions WHERE double3 < 1010.0 AND double3 > 100.0" + "SELECT COUNT(*), SUM(CAST(string1 as BIGINT) + CAST(string3 as BIGINT)) FROM expressions WHERE double3 < 1010.0 AND double3 > 100.0", + // virtual-column bitmap-index + "SELECT COUNT(*) FROM expressions WHERE __time >= TIMESTAMP '2000-01-01 00:00:00' AND __time < TIMESTAMP '2000-01-02 00:00:00' AND (UPPER(COALESCE(string3,'')) LIKE '1%' OR TRIM(UPPER(COALESCE(string3,''))) LIKE '1%' OR SUBSTRING(UPPER(COALESCE(string3,'')),1,1) IN ('1','2','3','4','5') OR ('X' || UPPER(COALESCE(string3,''))) LIKE 'X1%') AND (UPPER(COALESCE(string5,'')) LIKE '2%' OR TRIM(UPPER(COALESCE(string5,''))) LIKE '2%' OR SUBSTRING(UPPER(COALESCE(string5,'')),1,1) IN ('1','2','3','4','5') OR ('Y' || UPPER(COALESCE(string5,''))) LIKE 'Y2%') AND CAST(double4 * 1000 AS BIGINT) BETWEEN -850000000 AND 850000000" ); @Param({ @@ -233,10 +235,17 @@ public class SqlExpressionBenchmark extends SqlBaseQueryBenchmark "57", "58", "59", - "60" + "60", + "61" }) private String query; + @Param({ + "0", + "100" + }) + private String maxVirtualColumnsForBitmapIndexing; + @Override public String getQuery() { @@ -255,7 +264,8 @@ protected Map getContext() final Map context = ImmutableMap.of( QueryContexts.VECTORIZE_KEY, vectorize, QueryContexts.VECTORIZE_VIRTUAL_COLUMNS_KEY, vectorize, - GroupByQueryConfig.CTX_KEY_DEFER_EXPRESSION_DIMENSIONS, deferExpressionDimensions + GroupByQueryConfig.CTX_KEY_DEFER_EXPRESSION_DIMENSIONS, deferExpressionDimensions, + QueryContexts.CTX_MAX_VIRTUAL_COLUMNS_FOR_BITMAP, maxVirtualColumnsForBitmapIndexing ); return context; }