fix return type inference of parse_long, which can also be null if string is not parseable into a long (#15909)

* fix return type inference of parse_long, which can also be null if string is not parseable into a long

* fix msq test
This commit is contained in:
Clint Wylie 2024-02-15 08:45:34 -08:00 committed by GitHub
parent 66f54f2066
commit fe2ba8cc28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 1 deletions

View File

@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Module;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.guice.DruidInjectorBuilder;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.msq.exec.WorkerMemoryParameters;
@ -215,4 +216,18 @@ public class CalciteSelectQueryMSQTest extends CalciteQueryTest
)
.run();
}
@Override
public void testFilterParseLongNullable()
{
// this isn't really correct in default value mode, the result should be ImmutableList.of(new Object[]{0L})
// but MSQ is missing default aggregator values in empty group results. this override can be removed when this
// is fixed
testBuilder().queryContext(QUERY_CONTEXT_DEFAULT)
.sql("select count(*) from druid.foo where parse_long(dim1, 10) is null")
.expectedResults(
NullHandling.sqlCompatible() ? ImmutableList.of(new Object[]{4L}) : ImmutableList.of()
)
.run();
}
}

View File

@ -38,7 +38,7 @@ public class ParseLongOperatorConversion implements SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder(NAME)
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.INTEGER)
.returnTypeCascadeNullable(SqlTypeName.BIGINT)
.returnTypeNullable(SqlTypeName.BIGINT)
.functionCategory(SqlFunctionCategory.STRING)
.requiredOperandCount(1)
.build();

View File

@ -15292,4 +15292,29 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
)
.run();
}
@Test
public void testFilterParseLongNullable()
{
testQuery(
"select count(*) from druid.foo where parse_long(dim1, 10) is null",
ImmutableList.of(
Druids.newTimeseriesQueryBuilder()
.dataSource(CalciteTests.DATASOURCE1)
.intervals(querySegmentSpec(Filtration.eternity()))
.virtualColumns(
expressionVirtualColumn(
"v0",
"parse_long(\"dim1\",10)",
ColumnType.LONG)
)
.filters(isNull("v0"))
.granularity(Granularities.ALL)
.aggregators(new CountAggregatorFactory("a0"))
.context(QUERY_CONTEXT_DEFAULT)
.build()
),
ImmutableList.of(new Object[]{NullHandling.sqlCompatible() ? 4L : 0L})
);
}
}