mirror of https://github.com/apache/druid.git
fix nested field virtual column array column element vector object selector (#14729)
Fixes a case I missed in #14688 when the return type is STRING but its coming from a top level array typed column instead of a nested array column while making a vector object selector. Also while here I noticed that the internal JSON_VALUE functions for array types were named inconsistently with the non-array functions, so I renamed them. These are not documented so it should not be disruptive in any way, since they are only used internally for rewrites while planning to make the correctly virtual column. JSON_VALUE_RETURNING_ARRAY_VARCHAR -> JSON_VALUE_ARRAY_VARCHAR JSON_VALUE_RETURNING_ARRAY_BIGINT -> JSON_VALUE_ARRAY_BIGINT JSON_VALUE_RETURNING_ARRAY_DOUBLE -> JSON_VALUE_ARRAY_DOUBLE The internal non-array functions are JSON_VALUE_VARCHAR, JSON_VALUE_BIGINT, and JSON_VALUE_DOUBLE.
This commit is contained in:
parent
c1c2435aee
commit
94fb41a4df
|
@ -535,7 +535,11 @@ public class NestedFieldVirtualColumn implements VirtualColumn
|
|||
);
|
||||
}
|
||||
final VectorObjectSelector objectSelector = complexColumn.makeVectorObjectSelector(parts, offset);
|
||||
if (leastRestrictiveType != null && leastRestrictiveType.isArray() && !expectedType.isArray()) {
|
||||
if (leastRestrictiveType != null &&
|
||||
leastRestrictiveType.isArray() &&
|
||||
expectedType != null &&
|
||||
!expectedType.isArray()
|
||||
) {
|
||||
final ExpressionType elementType = ExpressionType.fromColumnTypeStrict(leastRestrictiveType.getElementType());
|
||||
final ExpressionType castTo = ExpressionType.fromColumnTypeStrict(expectedType);
|
||||
return makeVectorArrayToScalarObjectSelector(offset, objectSelector, elementType, castTo);
|
||||
|
@ -575,6 +579,12 @@ public class NestedFieldVirtualColumn implements VirtualColumn
|
|||
|
||||
if (parts.size() == 1 && parts.get(0) instanceof NestedPathArrayElement && column instanceof VariantColumn) {
|
||||
final VariantColumn<?> arrayColumn = (VariantColumn<?>) column;
|
||||
final ExpressionType elementType = ExpressionType.fromColumnTypeStrict(
|
||||
arrayColumn.getLogicalType().isArray() ? arrayColumn.getLogicalType().getElementType() : arrayColumn.getLogicalType()
|
||||
);
|
||||
final ExpressionType castTo = expectedType == null
|
||||
? ExpressionType.STRING
|
||||
: ExpressionType.fromColumnTypeStrict(expectedType);
|
||||
VectorObjectSelector arraySelector = arrayColumn.makeVectorObjectSelector(offset);
|
||||
final int elementNumber = ((NestedPathArrayElement) parts.get(0)).getIndex();
|
||||
if (elementNumber < 0) {
|
||||
|
@ -595,7 +605,7 @@ public class NestedFieldVirtualColumn implements VirtualColumn
|
|||
if (maybeArray instanceof Object[]) {
|
||||
Object[] anArray = (Object[]) maybeArray;
|
||||
if (elementNumber < anArray.length) {
|
||||
elements[i] = anArray[elementNumber];
|
||||
elements[i] = ExprEval.ofType(elementType, anArray[elementNumber]).castTo(castTo).value();
|
||||
} else {
|
||||
elements[i] = null;
|
||||
}
|
||||
|
|
|
@ -287,6 +287,55 @@ public class NestedDataTimeseriesQueryTest extends InitializedNullHandlingTest
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterLongArrayElementFilters()
|
||||
{
|
||||
TimeseriesQuery query = Druids.newTimeseriesQueryBuilder()
|
||||
.dataSource("test_datasource")
|
||||
.intervals(Collections.singletonList(Intervals.ETERNITY))
|
||||
.filters(
|
||||
new AndDimFilter(
|
||||
NullFilter.forColumn("v0"),
|
||||
NullFilter.forColumn("v1"),
|
||||
NullFilter.forColumn("v2")
|
||||
)
|
||||
)
|
||||
.virtualColumns(
|
||||
new NestedFieldVirtualColumn(
|
||||
"arrayLongNulls",
|
||||
"$[1]",
|
||||
"v0",
|
||||
ColumnType.STRING
|
||||
),
|
||||
new NestedFieldVirtualColumn(
|
||||
"arrayLongNulls",
|
||||
"$[1]",
|
||||
"v1",
|
||||
ColumnType.LONG
|
||||
),
|
||||
new NestedFieldVirtualColumn(
|
||||
"arrayStringNulls",
|
||||
"$[1]",
|
||||
"v2",
|
||||
ColumnType.LONG
|
||||
)
|
||||
)
|
||||
.aggregators(new CountAggregatorFactory("count"))
|
||||
.context(getContext())
|
||||
.build();
|
||||
runResults(
|
||||
query,
|
||||
ImmutableList.of(
|
||||
new Result<>(
|
||||
DateTimes.of("2023-01-01T00:00:00.000Z"),
|
||||
new TimeseriesResultValue(
|
||||
ImmutableMap.of("count", 8L)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterVariantAsString()
|
||||
{
|
||||
|
|
|
@ -557,7 +557,7 @@ public class NestedDataOperatorConversions
|
|||
|
||||
public static class JsonValueReturningArrayBigIntOperatorConversion extends JsonValueReturningArrayTypeOperatorConversion
|
||||
{
|
||||
static final SqlFunction FUNCTION = buildArrayFunction("JSON_VALUE_RETURNING_ARRAY_BIGINT", SqlTypeName.BIGINT);
|
||||
static final SqlFunction FUNCTION = buildArrayFunction("JSON_VALUE_ARRAY_BIGINT", SqlTypeName.BIGINT);
|
||||
|
||||
public JsonValueReturningArrayBigIntOperatorConversion()
|
||||
{
|
||||
|
@ -567,7 +567,7 @@ public class NestedDataOperatorConversions
|
|||
|
||||
public static class JsonValueReturningArrayDoubleOperatorConversion extends JsonValueReturningArrayTypeOperatorConversion
|
||||
{
|
||||
static final SqlFunction FUNCTION = buildArrayFunction("JSON_VALUE_RETURNING_ARRAY_DOUBLE", SqlTypeName.DOUBLE);
|
||||
static final SqlFunction FUNCTION = buildArrayFunction("JSON_VALUE_ARRAY_DOUBLE", SqlTypeName.DOUBLE);
|
||||
|
||||
public JsonValueReturningArrayDoubleOperatorConversion()
|
||||
{
|
||||
|
@ -577,7 +577,7 @@ public class NestedDataOperatorConversions
|
|||
|
||||
public static class JsonValueReturningArrayVarcharOperatorConversion extends JsonValueReturningArrayTypeOperatorConversion
|
||||
{
|
||||
static final SqlFunction FUNCTION = buildArrayFunction("JSON_VALUE_RETURNING_ARRAY_VARCHAR", SqlTypeName.VARCHAR);
|
||||
static final SqlFunction FUNCTION = buildArrayFunction("JSON_VALUE_ARRAY_VARCHAR", SqlTypeName.VARCHAR);
|
||||
|
||||
public JsonValueReturningArrayVarcharOperatorConversion()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue