Dwrite commented on code in PR #4877:
URL: https://github.com/apache/calcite/pull/4877#discussion_r3141273585
##########
core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java:
##########
@@ -651,41 +651,113 @@ private boolean coalesceCoercion(SqlCallBinding
callBinding) {
*/
@Override public boolean quantifyOperationCoercion(SqlCallBinding binding) {
final RelDataType type1 = binding.getOperandType(0);
- final RelDataType collectionType = binding.getOperandType(1);
- final RelDataType type2 = collectionType.getComponentType();
- requireNonNull(type2, "type2");
- final SqlCall sqlCall = binding.getCall();
- final SqlValidatorScope scope = binding.getScope();
+ final RelDataType type2 = binding.getOperandType(1);
final SqlNode node1 = binding.operand(0);
final SqlNode node2 = binding.operand(1);
- RelDataType widenType = commonTypeForBinaryComparison(type1, type2);
- if (widenType == null) {
- widenType = getTightestCommonType(type1, type2);
- }
- if (widenType == null) {
+ final SqlValidatorScope scope = binding.getScope();
+
+ // Check column counts match for struct types, consistent with
inOperationCoercion.
+ if (type1.isStruct()
+ && type2.isStruct()
+ && type1.getFieldCount() != type2.getFieldCount()) {
return false;
}
- final RelDataType leftWidenType =
- binding.getTypeFactory().enforceTypeWithNullability(widenType,
type1.isNullable());
- boolean coercedLeft =
- coerceOperandType(scope, sqlCall, 0, leftWidenType);
- if (coercedLeft) {
- updateInferredType(node1, leftWidenType);
+
+ int colCount = type1.isStruct() ? type1.getFieldCount() : 1;
+ RelDataType[] argTypes = new RelDataType[2];
+ argTypes[0] = type1;
+ final boolean isSubQuery = node2 instanceof SqlSelect;
+ // For subquery, use the row type directly.
+ // For collection, use the component type for comparison, not the array
type.
+ if (isSubQuery) {
+ argTypes[1] = type2;
+ } else {
+ RelDataType componentType = type2.getComponentType();
+ if (componentType == null) {
+ return false;
+ }
+ argTypes[1] = componentType;
+ }
+ boolean coerced = false;
+
+ // Find the common types for RHS and LHS columns,
+ // following the same rules as inOperationCoercion.
+ List<RelDataType> widenTypes = new ArrayList<>();
+ for (int i = 0; i < colCount; i++) {
+ final int i2 = i;
+ List<RelDataType> columnIthTypes = new AbstractList<RelDataType>() {
+ @Override public RelDataType get(int index) {
+ return argTypes[index].isStruct()
+ ? argTypes[index].getFieldList().get(i2).getType()
+ : argTypes[index];
+ }
+
+ @Override public int size() {
+ return argTypes.length;
+ }
+ };
+
+ RelDataType widenType =
+ commonTypeForBinaryComparison(columnIthTypes.get(0),
columnIthTypes.get(1));
+ if (widenType == null) {
+ widenType = getTightestCommonType(columnIthTypes.get(0),
columnIthTypes.get(1));
Review Comment:
yeah. This logic is derived from the IN operator
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]