Skip to content

Commit

Permalink
Reinstate consistency checks
Browse files Browse the repository at this point in the history
Signed-off-by: Mihai Budiu <[email protected]>
  • Loading branch information
mihaibudiu committed Jan 9, 2025
1 parent 8f10f82 commit c6eee80
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 5 deletions.
40 changes: 40 additions & 0 deletions core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.MultisetSqlType;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeUtil;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.ImmutableBitSet;
Expand Down Expand Up @@ -2222,6 +2223,45 @@ public static boolean eq(
return litmus.succeed();
}

/**
* Returns whether two types are equal, perhaps ignoring nullability.
*
* @param ignoreNullability If true the types must be equal ignoring the (top-level) nullability.
* @param desc1 Description of first type
* @param type1 First type
* @param desc2 Description of second type
* @param type2 Second type
* @param litmus What to do if an error is detected (types are not equal)
* @return Whether the types are equal
*/
public static boolean eqUpToNullability(
boolean ignoreNullability,
final String desc1,
RelDataType type1,
final String desc2,
RelDataType type2,
Litmus litmus) {
// if any one of the types is ANY return true
if (type1.getSqlTypeName() == SqlTypeName.ANY
|| type2.getSqlTypeName() == SqlTypeName.ANY) {
return litmus.succeed();
}

boolean success;
if (ignoreNullability) {
success = SqlTypeUtil.equalSansNullability(type1, type2);
} else {
success = type1.equals(type2);
}

if (!success) {
return litmus.fail("type mismatch:\n{}:\n{}\n{}:\n{}",
desc1, type1.getFullTypeString(),
desc2, type2.getFullTypeString());
}
return litmus.succeed();
}

/**
* Returns whether two types are equal using
* {@link #areRowTypesEqual(RelDataType, RelDataType, boolean)}. Both types
Expand Down
18 changes: 18 additions & 0 deletions core/src/main/java/org/apache/calcite/rex/RexChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ public int getFailureCount() {
index, inputTypeList.size() - 1);
}
// Type of field and type of result can differ in nullability. See [CALCITE-6764]
if (!ref.getType().isStruct()
&& !RelOptUtil.eqUpToNullability(
ref.getType().isNullable(),
"ref", ref.getType(), "input",
inputTypeList.get(index), litmus)) {
++failCount;
return litmus.fail(null);
}
return litmus.succeed();
}

Expand Down Expand Up @@ -156,6 +164,16 @@ public int getFailureCount() {
return litmus.fail(null);
}
// Type of field may not match type of field access - they may differ in nullability
final RelDataTypeField typeField = refType.getFieldList().get(index);
if (!RelOptUtil.eqUpToNullability(
refType.isNullable(),
"type1",
typeField.getType(),
"type2",
fieldAccess.getType(), litmus)) {
++failCount;
return litmus.fail(null);
}
return litmus.succeed();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,7 @@ public class RexFieldAccess extends RexNode {
RexFieldAccess(
RexNode expr,
RelDataTypeField field) {
checkValid(expr, field);
this.expr = expr;
this.field = field;
this.digest = expr + "." + field.getName();
this.type = field.getType();
this(expr, field, field.getType());
}

RexFieldAccess(
Expand Down

0 comments on commit c6eee80

Please sign in to comment.