mirror of https://github.com/apache/druid.git
Allow Double & null values in sql type array through dynamic params (#16274)
This commit is contained in:
parent
3df00aef9d
commit
5247059d2f
|
@ -129,18 +129,19 @@ public class SqlParameterizerShuttle extends SqlShuttle
|
|||
List<SqlNode> args = new ArrayList<>(list.size());
|
||||
for (int i = 0, listSize = list.size(); i < listSize; i++) {
|
||||
Object element = list.get(i);
|
||||
if (element == null) {
|
||||
throw InvalidSqlInput.exception("parameter [%d] is an array, with an illegal null at index [%d]", posn + 1, i);
|
||||
}
|
||||
SqlNode node;
|
||||
if (element instanceof String) {
|
||||
if (element == null) {
|
||||
node = SqlLiteral.createNull(SqlParserPos.ZERO);
|
||||
} else if (element instanceof String) {
|
||||
node = SqlLiteral.createCharString((String) element, SqlParserPos.ZERO);
|
||||
} else if (element instanceof Integer || element instanceof Long) {
|
||||
// No direct way to create a literal from an Integer or Long, have
|
||||
// to parse a string, sadly.
|
||||
node = SqlLiteral.createExactNumeric(element.toString(), SqlParserPos.ZERO);
|
||||
} else if (element instanceof Double || element instanceof Float) {
|
||||
node = SqlLiteral.createApproxNumeric(element.toString(), SqlParserPos.ZERO);
|
||||
} else if (element instanceof Boolean) {
|
||||
node = SqlLiteral.createBoolean((Boolean) value, SqlParserPos.ZERO);
|
||||
node = SqlLiteral.createBoolean((Boolean) element, SqlParserPos.ZERO);
|
||||
} else {
|
||||
throw InvalidSqlInput.exception(
|
||||
"parameter [%d] is an array, with an illegal value of type [%s] at index [%d]",
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.apache.druid.sql.calcite;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.apache.calcite.avatica.SqlType;
|
||||
import org.apache.druid.common.config.NullHandling;
|
||||
import org.apache.druid.guice.DruidInjectorBuilder;
|
||||
import org.apache.druid.guice.NestedDataModule;
|
||||
|
@ -70,6 +71,7 @@ import org.apache.druid.segment.join.JoinType;
|
|||
import org.apache.druid.segment.virtual.ExpressionVirtualColumn;
|
||||
import org.apache.druid.sql.calcite.filtration.Filtration;
|
||||
import org.apache.druid.sql.calcite.util.CalciteTests;
|
||||
import org.apache.druid.sql.http.SqlParameter;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -933,6 +935,40 @@ public class CalciteArraysQueryTest extends BaseCalciteQueryTest
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayOverlapFilterWithDynamicParameter()
|
||||
{
|
||||
Druids.ScanQueryBuilder builder = newScanQueryBuilder()
|
||||
.dataSource(CalciteTests.DATASOURCE3)
|
||||
.intervals(querySegmentSpec(Filtration.eternity()))
|
||||
.filters(expressionFilter("array_overlap(array(1.0,1.7,null),array(\"d1\"))"))
|
||||
.columns("dim3")
|
||||
.resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST)
|
||||
.limit(5)
|
||||
.context(QUERY_CONTEXT_DEFAULT);
|
||||
|
||||
testQuery(
|
||||
PLANNER_CONFIG_DEFAULT,
|
||||
QUERY_CONTEXT_DEFAULT,
|
||||
ImmutableList.of(
|
||||
new SqlParameter(SqlType.ARRAY, Arrays.asList(1.0, 1.7, null))
|
||||
),
|
||||
"SELECT dim3 FROM druid.numfoo WHERE ARRAY_OVERLAP(?, ARRAY[d1]) LIMIT 5",
|
||||
CalciteTests.REGULAR_USER_AUTH_RESULT,
|
||||
ImmutableList.of(builder.build()),
|
||||
NullHandling.sqlCompatible() ? ImmutableList.of(
|
||||
new Object[]{"[\"a\",\"b\"]"},
|
||||
new Object[]{"[\"b\",\"c\"]"},
|
||||
new Object[]{""},
|
||||
new Object[]{null},
|
||||
new Object[]{null}
|
||||
) : ImmutableList.of(
|
||||
new Object[]{"[\"a\",\"b\"]"},
|
||||
new Object[]{"[\"b\",\"c\"]"}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayContainsFilter()
|
||||
{
|
||||
|
@ -1270,6 +1306,39 @@ public class CalciteArraysQueryTest extends BaseCalciteQueryTest
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayContainsFilterWithDynamicParameter()
|
||||
{
|
||||
Druids.ScanQueryBuilder builder = newScanQueryBuilder()
|
||||
.dataSource(CalciteTests.DATASOURCE3)
|
||||
.intervals(querySegmentSpec(Filtration.eternity()))
|
||||
.filters(expressionFilter("array_contains(array(1,null),array((\"d1\" > 1)))"))
|
||||
.columns("dim3")
|
||||
.resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST)
|
||||
.limit(5)
|
||||
.context(QUERY_CONTEXT_DEFAULT);
|
||||
|
||||
testQuery(
|
||||
PLANNER_CONFIG_DEFAULT,
|
||||
QUERY_CONTEXT_DEFAULT,
|
||||
ImmutableList.of(
|
||||
new SqlParameter(SqlType.ARRAY, Arrays.asList(true, null))
|
||||
),
|
||||
"SELECT dim3 FROM druid.numfoo WHERE ARRAY_CONTAINS(?, ARRAY[d1>1]) LIMIT 5",
|
||||
CalciteTests.REGULAR_USER_AUTH_RESULT,
|
||||
ImmutableList.of(builder.build()),
|
||||
NullHandling.sqlCompatible() ? ImmutableList.of(
|
||||
new Object[]{"[\"b\",\"c\"]"},
|
||||
new Object[]{""},
|
||||
new Object[]{null},
|
||||
new Object[]{null}
|
||||
) : ImmutableList.of(
|
||||
new Object[]{"[\"b\",\"c\"]"}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testArraySlice()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue