fix vectorized query engine numeric filter matchers against null values (#9063)

* fix druid-sql issue with filtering numeric columns by null values

* fix vector numeric column matchers to check null vector for null matches
This commit is contained in:
Clint Wylie 2019-12-20 13:15:48 -08:00 committed by Jonathan Wei
parent 60d896a67c
commit 8ccce9857a
5 changed files with 52 additions and 6 deletions

View File

@ -19,6 +19,7 @@
package org.apache.druid.query.filter.vector;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.query.filter.DruidDoublePredicate;
import org.apache.druid.query.filter.DruidPredicateFactory;
import org.apache.druid.segment.DimensionHandlerUtils;
@ -29,6 +30,7 @@ import javax.annotation.Nullable;
public class DoubleVectorValueMatcher implements VectorValueMatcherFactory
{
private final VectorValueSelector selector;
private final boolean canHaveNulls = !NullHandling.replaceWithDefault();
public DoubleVectorValueMatcher(final VectorValueSelector selector)
{
@ -38,6 +40,10 @@ public class DoubleVectorValueMatcher implements VectorValueMatcherFactory
@Override
public VectorValueMatcher makeMatcher(@Nullable final String value)
{
if (value == null && canHaveNulls) {
return makeNullValueMatcher(selector);
}
final Double matchVal = DimensionHandlerUtils.convertObjectToDouble(value);
if (matchVal == null) {

View File

@ -19,6 +19,7 @@
package org.apache.druid.query.filter.vector;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.query.filter.DruidFloatPredicate;
import org.apache.druid.query.filter.DruidPredicateFactory;
import org.apache.druid.segment.DimensionHandlerUtils;
@ -29,6 +30,7 @@ import javax.annotation.Nullable;
public class FloatVectorValueMatcher implements VectorValueMatcherFactory
{
private final VectorValueSelector selector;
private final boolean canHaveNulls = !NullHandling.replaceWithDefault();
public FloatVectorValueMatcher(final VectorValueSelector selector)
{
@ -38,6 +40,10 @@ public class FloatVectorValueMatcher implements VectorValueMatcherFactory
@Override
public VectorValueMatcher makeMatcher(@Nullable final String value)
{
if (value == null && canHaveNulls) {
return makeNullValueMatcher(selector);
}
final Float matchVal = DimensionHandlerUtils.convertObjectToFloat(value);
if (matchVal == null) {

View File

@ -19,6 +19,7 @@
package org.apache.druid.query.filter.vector;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.query.filter.DruidLongPredicate;
import org.apache.druid.query.filter.DruidPredicateFactory;
import org.apache.druid.segment.DimensionHandlerUtils;
@ -29,6 +30,7 @@ import javax.annotation.Nullable;
public class LongVectorValueMatcher implements VectorValueMatcherFactory
{
private final VectorValueSelector selector;
private final boolean canHaveNulls = !NullHandling.replaceWithDefault();
public LongVectorValueMatcher(final VectorValueSelector selector)
{
@ -38,6 +40,10 @@ public class LongVectorValueMatcher implements VectorValueMatcherFactory
@Override
public VectorValueMatcher makeMatcher(@Nullable final String value)
{
if (value == null && canHaveNulls) {
return makeNullValueMatcher(selector);
}
final Long matchVal = DimensionHandlerUtils.convertObjectToLong(value);
if (matchVal == null) {

View File

@ -20,6 +20,7 @@
package org.apache.druid.query.filter.vector;
import org.apache.druid.query.filter.DruidPredicateFactory;
import org.apache.druid.segment.vector.VectorValueSelector;
import javax.annotation.Nullable;
@ -28,4 +29,37 @@ public interface VectorValueMatcherFactory
VectorValueMatcher makeMatcher(@Nullable String value);
VectorValueMatcher makeMatcher(DruidPredicateFactory predicateFactory);
default VectorValueMatcher makeNullValueMatcher(VectorValueSelector selector)
{
return new BaseVectorValueMatcher(selector)
{
final VectorMatch match = VectorMatch.wrap(new int[selector.getMaxVectorSize()]);
@Override
public ReadableVectorMatch match(final ReadableVectorMatch mask)
{
final boolean[] nullVector = selector.getNullVector();
if (nullVector == null) {
return VectorMatch.allFalse();
}
final int[] selection = match.getSelection();
int numRows = 0;
for (int i = 0; i < mask.getSelectionSize(); i++) {
final int rowNum = mask.getSelection()[i];
if (nullVector[rowNum]) {
selection[numRows++] = rowNum;
}
}
match.setSelectionSize(numRows);
assert match.isValid(mask);
return match;
}
};
}
}

View File

@ -2277,8 +2277,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
@Test
public void testNullLongFilter() throws Exception
{
// bug https://github.com/apache/incubator-druid/issues/9062 prevents this test from passing
skipVectorize();
testQuery(
"SELECT COUNT(*)\n"
+ "FROM druid.numfoo\n"
@ -2302,8 +2300,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
@Test
public void testNullDoubleFilter() throws Exception
{
// bug https://github.com/apache/incubator-druid/issues/9062 prevents this test from passing
skipVectorize();
testQuery(
"SELECT COUNT(*)\n"
+ "FROM druid.numfoo\n"
@ -2328,8 +2324,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
@Test
public void testNullFloatFilter() throws Exception
{
// bug https://github.com/apache/incubator-druid/issues/9062 prevents this test from passing
skipVectorize();
testQuery(
"SELECT COUNT(*)\n"
+ "FROM druid.numfoo\n"