mirror of https://github.com/apache/druid.git
fix vector grouping expression deferred evaluation to only consider dictionary encoded strings as fixed width (#16666)
This commit is contained in:
parent
4401c9d138
commit
d86f25c74a
|
@ -71,7 +71,7 @@ public enum DeferExpressionDimensions
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!capabilities.isNumeric() && !capabilities.isDictionaryEncoded().isTrue()) {
|
if (!capabilities.isNumeric() && !isDictionaryEncodedScalarString(capabilities)) {
|
||||||
// Not fixed-width.
|
// Not fixed-width.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ public enum DeferExpressionDimensions
|
||||||
|
|
||||||
allNumericInputs = allNumericInputs && capabilities.isNumeric();
|
allNumericInputs = allNumericInputs && capabilities.isNumeric();
|
||||||
|
|
||||||
if (!capabilities.isNumeric() && !capabilities.isDictionaryEncoded().isTrue()) {
|
if (!capabilities.isNumeric() && !isDictionaryEncodedScalarString(capabilities)) {
|
||||||
// Not fixed-width.
|
// Not fixed-width.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -162,6 +162,25 @@ public enum DeferExpressionDimensions
|
||||||
return jsonName;
|
return jsonName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link VectorColumnSelectorFactory} currently can only make dictionary encoded selectors for string types, so
|
||||||
|
* we can only consider them as fixed width. Additionally, to err on the side of safety, multi-value string columns
|
||||||
|
* are also not considered fixed width because expressions process multi-value dimensions as single rows, so we would
|
||||||
|
* need all dictionary ids to be present in the combined key.
|
||||||
|
*
|
||||||
|
* At the time of this javadoc, vector group by does not support multi-value dimensions anyway, so this isn't really
|
||||||
|
* a problem, but if it did, we could consider allowing them if we ensure that all multi-value inputs are used as
|
||||||
|
* scalars and so the expression can be applied separately to each individual dictionary id (e.g. the equivalent of
|
||||||
|
* {@link ExpressionPlan.Trait#SINGLE_INPUT_MAPPABLE} but for all multi-value string inputs of the expression).
|
||||||
|
*/
|
||||||
|
private static boolean isDictionaryEncodedScalarString(ColumnCapabilities capabilities)
|
||||||
|
{
|
||||||
|
return capabilities.isDictionaryEncoded().isTrue() &&
|
||||||
|
capabilities.is(ValueType.STRING) &&
|
||||||
|
capabilities.hasMultipleValues().isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the given expression can be deferred innately by the selector created by
|
* Whether the given expression can be deferred innately by the selector created by
|
||||||
* {@link ExpressionVirtualColumn#makeSingleValueVectorDimensionSelector(DimensionSpec, VectorColumnSelectorFactory)}.
|
* {@link ExpressionVirtualColumn#makeSingleValueVectorDimensionSelector(DimensionSpec, VectorColumnSelectorFactory)}.
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.druid.math.expr.ExprMacroTable;
|
||||||
import org.apache.druid.math.expr.ExpressionType;
|
import org.apache.druid.math.expr.ExpressionType;
|
||||||
import org.apache.druid.math.expr.Parser;
|
import org.apache.druid.math.expr.Parser;
|
||||||
import org.apache.druid.query.expression.TestExprMacroTable;
|
import org.apache.druid.query.expression.TestExprMacroTable;
|
||||||
|
import org.apache.druid.query.groupby.DeferExpressionDimensions;
|
||||||
import org.apache.druid.segment.ColumnInspector;
|
import org.apache.druid.segment.ColumnInspector;
|
||||||
import org.apache.druid.segment.column.ColumnCapabilities;
|
import org.apache.druid.segment.column.ColumnCapabilities;
|
||||||
import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
|
import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
|
||||||
|
@ -234,6 +235,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertNull(thePlan.getOutputType());
|
Assert.assertNull(thePlan.getOutputType());
|
||||||
Assert.assertNull(thePlan.inferColumnCapabilities(null));
|
Assert.assertNull(thePlan.inferColumnCapabilities(null));
|
||||||
// no we cannot
|
// no we cannot
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -269,6 +292,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertFalse(inferred.hasMultipleValues().isMaybeTrue());
|
Assert.assertFalse(inferred.hasMultipleValues().isMaybeTrue());
|
||||||
Assert.assertFalse(inferred.hasBitmapIndexes());
|
Assert.assertFalse(inferred.hasBitmapIndexes());
|
||||||
Assert.assertFalse(inferred.hasSpatialIndexes());
|
Assert.assertFalse(inferred.hasSpatialIndexes());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -348,6 +393,27 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertFalse(inferred.hasMultipleValues().isMaybeTrue());
|
Assert.assertFalse(inferred.hasMultipleValues().isMaybeTrue());
|
||||||
Assert.assertFalse(inferred.hasBitmapIndexes());
|
Assert.assertFalse(inferred.hasBitmapIndexes());
|
||||||
Assert.assertFalse(inferred.hasSpatialIndexes());
|
Assert.assertFalse(inferred.hasSpatialIndexes());
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertTrue(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -387,6 +453,30 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertTrue(inferred.hasBitmapIndexes());
|
Assert.assertTrue(inferred.hasBitmapIndexes());
|
||||||
Assert.assertFalse(inferred.hasSpatialIndexes());
|
Assert.assertFalse(inferred.hasSpatialIndexes());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// innately deferrable
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// multiple input columns
|
// multiple input columns
|
||||||
thePlan = plan("concat(scalar_dictionary_string, scalar_dictionary_string_nonunique)");
|
thePlan = plan("concat(scalar_dictionary_string, scalar_dictionary_string_nonunique)");
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
@ -430,6 +520,29 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertFalse(inferred.hasBitmapIndexes());
|
Assert.assertFalse(inferred.hasBitmapIndexes());
|
||||||
Assert.assertFalse(inferred.hasSpatialIndexes());
|
Assert.assertFalse(inferred.hasSpatialIndexes());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertTrue(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertTrue(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// array output of dictionary encoded string are not considered single scalar/mappable, nor vectorizable
|
// array output of dictionary encoded string are not considered single scalar/mappable, nor vectorizable
|
||||||
thePlan = plan("array(scalar_dictionary_string)");
|
thePlan = plan("array(scalar_dictionary_string)");
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
@ -448,6 +561,27 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
ExpressionPlan.Trait.VECTORIZABLE
|
ExpressionPlan.Trait.VECTORIZABLE
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertTrue(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertTrue(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -481,6 +615,29 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertTrue(inferred.hasBitmapIndexes());
|
Assert.assertTrue(inferred.hasBitmapIndexes());
|
||||||
Assert.assertFalse(inferred.hasSpatialIndexes());
|
Assert.assertFalse(inferred.hasSpatialIndexes());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
thePlan = plan("concat(scalar_string, multi_dictionary_string_nonunique)");
|
thePlan = plan("concat(scalar_string, multi_dictionary_string_nonunique)");
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
thePlan.is(
|
thePlan.is(
|
||||||
|
@ -510,6 +667,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertEquals(ValueType.STRING, inferred.getType());
|
Assert.assertEquals(ValueType.STRING, inferred.getType());
|
||||||
Assert.assertTrue(inferred.hasMultipleValues().isTrue());
|
Assert.assertTrue(inferred.hasMultipleValues().isTrue());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
thePlan = plan("concat(multi_dictionary_string, multi_dictionary_string_nonunique)");
|
thePlan = plan("concat(multi_dictionary_string, multi_dictionary_string_nonunique)");
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
thePlan.is(
|
thePlan.is(
|
||||||
|
@ -541,6 +720,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertEquals(ValueType.STRING, inferred.getType());
|
Assert.assertEquals(ValueType.STRING, inferred.getType());
|
||||||
Assert.assertTrue(inferred.hasMultipleValues().isTrue());
|
Assert.assertTrue(inferred.hasMultipleValues().isTrue());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
thePlan = plan("array_append(multi_dictionary_string, 'foo')");
|
thePlan = plan("array_append(multi_dictionary_string, 'foo')");
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
thePlan.is(
|
thePlan.is(
|
||||||
|
@ -556,6 +757,27 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
ExpressionPlan.Trait.VECTORIZABLE
|
ExpressionPlan.Trait.VECTORIZABLE
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -582,6 +804,27 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
Assert.assertEquals(ExpressionType.STRING, thePlan.getOutputType());
|
Assert.assertEquals(ExpressionType.STRING, thePlan.getOutputType());
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
thePlan = plan("concat(multi_dictionary_string, multi_dictionary_string_nonunique)");
|
thePlan = plan("concat(multi_dictionary_string, multi_dictionary_string_nonunique)");
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
@ -631,6 +874,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
// incomplete and unknown skip output type since we don't reliably know
|
// incomplete and unknown skip output type since we don't reliably know
|
||||||
Assert.assertNull(thePlan.getOutputType());
|
Assert.assertNull(thePlan.getOutputType());
|
||||||
Assert.assertNull(thePlan.inferColumnCapabilities(null));
|
Assert.assertNull(thePlan.inferColumnCapabilities(null));
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -667,14 +932,78 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
Assert.assertEquals("array_append(\"scalar_string\", 'x')", thePlan.getAppliedFoldExpression("__acc").stringify());
|
Assert.assertEquals("array_append(\"scalar_string\", 'x')", thePlan.getAppliedFoldExpression("__acc").stringify());
|
||||||
Assert.assertEquals(ExpressionType.STRING_ARRAY, thePlan.getOutputType());
|
Assert.assertEquals(ExpressionType.STRING_ARRAY, thePlan.getOutputType());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// multi-valued are cool too
|
// multi-valued are cool too
|
||||||
thePlan = plan("array_append(multi_dictionary_string, 'x')");
|
thePlan = plan("array_append(multi_dictionary_string, 'x')");
|
||||||
assertArrayInAndOut(thePlan);
|
assertArrayInAndOut(thePlan);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// what about incomplete inputs with arrays? they are not reported as incomplete because they are treated as arrays
|
// what about incomplete inputs with arrays? they are not reported as incomplete because they are treated as arrays
|
||||||
thePlan = plan("array_append(string_unknown, 'x')");
|
thePlan = plan("array_append(string_unknown, 'x')");
|
||||||
assertArrayInAndOut(thePlan);
|
assertArrayInAndOut(thePlan);
|
||||||
Assert.assertEquals(ExpressionType.STRING_ARRAY, thePlan.getOutputType());
|
Assert.assertEquals(ExpressionType.STRING_ARRAY, thePlan.getOutputType());
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// what about if it is the scalar argument? there it is
|
// what about if it is the scalar argument? there it is
|
||||||
thePlan = plan("array_append(multi_dictionary_string, string_unknown)");
|
thePlan = plan("array_append(multi_dictionary_string, string_unknown)");
|
||||||
|
@ -696,13 +1025,76 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
);
|
);
|
||||||
// incomplete and unknown skip output type since we don't reliably know
|
// incomplete and unknown skip output type since we don't reliably know
|
||||||
Assert.assertNull(thePlan.getOutputType());
|
Assert.assertNull(thePlan.getOutputType());
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// array types are cool too
|
// array types are cool too
|
||||||
thePlan = plan("array_append(string_array_1, 'x')");
|
thePlan = plan("array_append(string_array_1, 'x')");
|
||||||
assertArrayInAndOut(thePlan);
|
assertArrayInAndOut(thePlan);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
thePlan = plan("array_append(string_array_1, 'x')");
|
thePlan = plan("array_append(string_array_1, 'x')");
|
||||||
assertArrayInAndOut(thePlan);
|
assertArrayInAndOut(thePlan);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -732,6 +1124,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
);
|
);
|
||||||
Assert.assertEquals(ExpressionType.STRING, thePlan.getOutputType());
|
Assert.assertEquals(ExpressionType.STRING, thePlan.getOutputType());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// what about a multi-valued input
|
// what about a multi-valued input
|
||||||
thePlan = plan("array_to_string(array_append(scalar_string, multi_dictionary_string), ',')");
|
thePlan = plan("array_to_string(array_append(scalar_string, multi_dictionary_string), ',')");
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
@ -761,6 +1175,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
);
|
);
|
||||||
// why is this null
|
// why is this null
|
||||||
Assert.assertEquals(ExpressionType.STRING, thePlan.getOutputType());
|
Assert.assertEquals(ExpressionType.STRING, thePlan.getOutputType());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -864,6 +1300,29 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
ColumnType.NESTED_DATA.getComplexTypeName(),
|
ColumnType.NESTED_DATA.getComplexTypeName(),
|
||||||
inferred.getComplexTypeName()
|
inferred.getComplexTypeName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// all numeric inputs so these are true
|
||||||
|
Assert.assertTrue(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertTrue(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -895,6 +1354,28 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
|
||||||
inferred.getType()
|
inferred.getType()
|
||||||
);
|
);
|
||||||
Assert.assertFalse(inferred.isDictionaryEncoded().isMaybeTrue());
|
Assert.assertFalse(inferred.isDictionaryEncoded().isMaybeTrue());
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.SINGLE_STRING.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH_NON_NUMERIC.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Assert.assertFalse(
|
||||||
|
DeferExpressionDimensions.FIXED_WIDTH.useDeferredGroupBySelector(
|
||||||
|
thePlan,
|
||||||
|
thePlan.getAnalysis().getRequiredBindingsList(),
|
||||||
|
SYNTHETIC_INSPECTOR
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ExpressionPlan plan(String expression)
|
private static ExpressionPlan plan(String expression)
|
||||||
|
|
Loading…
Reference in New Issue