Skip to content

Commit

Permalink
Allow Double & null values in sql type array through dynamic params (a…
Browse files Browse the repository at this point in the history
  • Loading branch information
sreemanamala authored Apr 15, 2024
1 parent 3df00ae commit 5247059
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,19 @@ private SqlNode createArrayLiteral(Object value, int posn)
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]",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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;
Expand Down Expand Up @@ -70,6 +71,7 @@
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;

Expand Down Expand Up @@ -933,6 +935,40 @@ public void testArrayOverlapFilterArrayDoubleColumns()
);
}

@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()
{
Expand Down Expand Up @@ -1270,6 +1306,39 @@ public void testArrayContainsConstantNull()
);
}

@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()
{
Expand Down

0 comments on commit 5247059

Please sign in to comment.