fix issue with SQL boolean constants not respecting nulls when strict booleans and sql compatible null handling are enabled (#15135)

This commit is contained in:
Clint Wylie 2023-10-12 01:23:24 -07:00 committed by GitHub
parent d0f64608eb
commit a0fd9ec55c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 0 deletions

View File

@ -25,7 +25,9 @@ import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall; import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.rel.logical.LogicalValues; import org.apache.calcite.rel.logical.LogicalValues;
import org.apache.calcite.rex.RexLiteral; import org.apache.calcite.rex.RexLiteral;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.error.InvalidSqlInput; import org.apache.druid.error.InvalidSqlInput;
import org.apache.druid.math.expr.ExpressionProcessing;
import org.apache.druid.query.InlineDataSource; import org.apache.druid.query.InlineDataSource;
import org.apache.druid.segment.column.RowSignature; import org.apache.druid.segment.column.RowSignature;
import org.apache.druid.sql.calcite.planner.Calcites; import org.apache.druid.sql.calcite.planner.Calcites;
@ -120,6 +122,9 @@ public class DruidLogicalValuesRule extends RelOptRule
} }
return ((Number) RexLiteral.value(literal)).longValue(); return ((Number) RexLiteral.value(literal)).longValue();
case BOOLEAN: case BOOLEAN:
if (ExpressionProcessing.useStrictBooleans() && NullHandling.sqlCompatible() && literal.isNull()) {
return null;
}
return literal.isAlwaysTrue() ? 1L : 0L; return literal.isAlwaysTrue() ? 1L : 0L;
case TIMESTAMP: case TIMESTAMP:
case DATE: case DATE:

View File

@ -28,8 +28,10 @@ import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.DateString; import org.apache.calcite.util.DateString;
import org.apache.calcite.util.TimeString; import org.apache.calcite.util.TimeString;
import org.apache.calcite.util.TimestampString; import org.apache.calcite.util.TimestampString;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.error.DruidExceptionMatcher; import org.apache.druid.error.DruidExceptionMatcher;
import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.DateTimes;
import org.apache.druid.math.expr.ExpressionProcessing;
import org.apache.druid.sql.calcite.planner.DruidTypeSystem; import org.apache.druid.sql.calcite.planner.DruidTypeSystem;
import org.apache.druid.sql.calcite.planner.PlannerContext; import org.apache.druid.sql.calcite.planner.PlannerContext;
import org.apache.druid.testing.InitializedNullHandlingTest; import org.apache.druid.testing.InitializedNullHandlingTest;
@ -139,6 +141,21 @@ public class DruidLogicalValuesRuleTest
Assert.assertEquals(0L, fromLiteral); Assert.assertEquals(0L, fromLiteral);
} }
@Test
public void testGetValueFromNullBooleanLiteral()
{
RexLiteral literal = REX_BUILDER.makeLiteral(null, REX_BUILDER.getTypeFactory().createSqlType(SqlTypeName.BOOLEAN));
if (NullHandling.sqlCompatible() && ExpressionProcessing.useStrictBooleans()) {
final Object fromLiteral = DruidLogicalValuesRule.getValueFromLiteral(literal, DEFAULT_CONTEXT);
Assert.assertNull(fromLiteral);
} else {
final Object fromLiteralNonStrict = DruidLogicalValuesRule.getValueFromLiteral(literal, DEFAULT_CONTEXT);
Assert.assertSame(Long.class, fromLiteralNonStrict.getClass());
Assert.assertEquals(0L, fromLiteralNonStrict);
}
}
@Test @Test
public void testGetValueFromTimestampLiteral() public void testGetValueFromTimestampLiteral()
{ {