fix expression plan type inference to correctly handle complex types (#12857)

This commit is contained in:
Clint Wylie 2022-08-04 02:56:05 -07:00 committed by GitHub
parent a618458bf0
commit 73cfc4e5d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 0 deletions

View File

@ -230,6 +230,10 @@ public class ExpressionPlan
if (outputType != null) { if (outputType != null) {
final ColumnType inferredValueType = ExpressionType.toColumnType(outputType); final ColumnType inferredValueType = ExpressionType.toColumnType(outputType);
if (inferredValueType.is(ValueType.COMPLEX)) {
return ColumnCapabilitiesImpl.createDefault().setHasNulls(true).setType(inferredValueType);
}
if (inferredValueType.isNumeric()) { if (inferredValueType.isNumeric()) {
// if float was explicitly specified preserve it, because it will currently never be the computed output type // if float was explicitly specified preserve it, because it will currently never be the computed output type
// since there is no float expression type // since there is no float expression type

View File

@ -23,12 +23,14 @@ import com.google.common.collect.ImmutableMap;
import org.apache.druid.common.config.NullHandling; import org.apache.druid.common.config.NullHandling;
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.NestedDataExpressions;
import org.apache.druid.query.expression.TestExprMacroTable; import org.apache.druid.query.expression.TestExprMacroTable;
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;
import org.apache.druid.segment.column.ColumnType; import org.apache.druid.segment.column.ColumnType;
import org.apache.druid.segment.column.ValueType; import org.apache.druid.segment.column.ValueType;
import org.apache.druid.segment.nested.NestedDataComplexTypeSerde;
import org.apache.druid.testing.InitializedNullHandlingTest; import org.apache.druid.testing.InitializedNullHandlingTest;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Rule; import org.junit.Rule;
@ -807,6 +809,36 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest
Assert.assertEquals(ExpressionType.STRING_ARRAY, thePlan.getOutputType()); Assert.assertEquals(ExpressionType.STRING_ARRAY, thePlan.getOutputType());
} }
@Test
public void testNestedColumnExpression()
{
ExpressionPlan thePlan = plan("json_object('long1', long1, 'long2', long2)");
Assert.assertFalse(
thePlan.is(
ExpressionPlan.Trait.NON_SCALAR_OUTPUT,
ExpressionPlan.Trait.SINGLE_INPUT_SCALAR,
ExpressionPlan.Trait.SINGLE_INPUT_MAPPABLE,
ExpressionPlan.Trait.UNKNOWN_INPUTS,
ExpressionPlan.Trait.INCOMPLETE_INPUTS,
ExpressionPlan.Trait.NEEDS_APPLIED,
ExpressionPlan.Trait.NON_SCALAR_INPUTS,
ExpressionPlan.Trait.VECTORIZABLE
)
);
Assert.assertEquals(NestedDataExpressions.TYPE, thePlan.getOutputType());
ColumnCapabilities inferred = thePlan.inferColumnCapabilities(
ExpressionType.toColumnType(thePlan.getOutputType())
);
Assert.assertEquals(
NestedDataComplexTypeSerde.TYPE.getType(),
inferred.getType()
);
Assert.assertEquals(
NestedDataExpressions.TYPE.getComplexTypeName(),
inferred.getComplexTypeName()
);
}
private static ExpressionPlan plan(String expression) private static ExpressionPlan plan(String expression)
{ {
return ExpressionPlanner.plan(SYNTHETIC_INSPECTOR, Parser.parse(expression, TestExprMacroTable.INSTANCE)); return ExpressionPlanner.plan(SYNTHETIC_INSPECTOR, Parser.parse(expression, TestExprMacroTable.INSTANCE));