diff --git a/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionPlan.java b/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionPlan.java index 86dbbd78267..3a35859b41f 100644 --- a/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionPlan.java +++ b/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionPlan.java @@ -230,6 +230,10 @@ public class ExpressionPlan if (outputType != null) { final ColumnType inferredValueType = ExpressionType.toColumnType(outputType); + if (inferredValueType.is(ValueType.COMPLEX)) { + return ColumnCapabilitiesImpl.createDefault().setHasNulls(true).setType(inferredValueType); + } + if (inferredValueType.isNumeric()) { // if float was explicitly specified preserve it, because it will currently never be the computed output type // since there is no float expression type diff --git a/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionPlannerTest.java b/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionPlannerTest.java index ad7f1daab1f..37a09a10af6 100644 --- a/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionPlannerTest.java +++ b/processing/src/test/java/org/apache/druid/segment/virtual/ExpressionPlannerTest.java @@ -23,12 +23,14 @@ import com.google.common.collect.ImmutableMap; import org.apache.druid.common.config.NullHandling; import org.apache.druid.math.expr.ExpressionType; 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.segment.ColumnInspector; import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilitiesImpl; import org.apache.druid.segment.column.ColumnType; import org.apache.druid.segment.column.ValueType; +import org.apache.druid.segment.nested.NestedDataComplexTypeSerde; import org.apache.druid.testing.InitializedNullHandlingTest; import org.junit.Assert; import org.junit.Rule; @@ -807,6 +809,36 @@ public class ExpressionPlannerTest extends InitializedNullHandlingTest 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) { return ExpressionPlanner.plan(SYNTHETIC_INSPECTOR, Parser.parse(expression, TestExprMacroTable.INSTANCE));