Search in sources :

Example 91 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlTypeUtil method isComparable.

/**
 * Returns whether two types are comparable. They need to be scalar types of
 * the same family, or struct types whose fields are pairwise comparable.
 *
 * @param type1 First type
 * @param type2 Second type
 * @return Whether types are comparable
 */
public static boolean isComparable(RelDataType type1, RelDataType type2) {
    if (type1.isStruct() != type2.isStruct()) {
        return false;
    }
    if (type1.isStruct()) {
        int n = type1.getFieldCount();
        if (n != type2.getFieldCount()) {
            return false;
        }
        for (Pair<RelDataTypeField, RelDataTypeField> pair : Pair.zip(type1.getFieldList(), type2.getFieldList())) {
            if (!isComparable(pair.left.getType(), pair.right.getType())) {
                return false;
            }
        }
        return true;
    }
    RelDataTypeFamily family1 = null;
    RelDataTypeFamily family2 = null;
    // the Saffron type system happy.
    if (type1.getSqlTypeName() != null) {
        family1 = type1.getSqlTypeName().getFamily();
    }
    if (type2.getSqlTypeName() != null) {
        family2 = type2.getSqlTypeName().getFamily();
    }
    if (family1 == null) {
        family1 = type1.getFamily();
    }
    if (family2 == null) {
        family2 = type2.getFamily();
    }
    if (family1 == family2) {
        return true;
    }
    // If one of the arguments is of type 'ANY', return true.
    if (family1 == SqlTypeFamily.ANY || family2 == SqlTypeFamily.ANY) {
        return true;
    }
    // If one of the arguments is of type 'NULL', return true.
    if (family1 == SqlTypeFamily.NULL || family2 == SqlTypeFamily.NULL) {
        return true;
    }
    // We can implicitly convert from character to date
    if (family1 == SqlTypeFamily.CHARACTER && canConvertStringInCompare(family2) || family2 == SqlTypeFamily.CHARACTER && canConvertStringInCompare(family1)) {
        return true;
    }
    return false;
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataTypeFamily(org.apache.calcite.rel.type.RelDataTypeFamily)

Example 92 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlTypeUtil method canCastFrom.

/**
 * Compares two types and returns true if fromType can be cast to toType.
 *
 * <p>REVIEW jvs 17-Dec-2004: the coerce param below shouldn't really be
 * necessary. We're using it as a hack because
 * {@link SqlTypeFactoryImpl#leastRestrictiveSqlType} isn't complete enough
 * yet.  Once it is, this param (and the non-coerce rules of
 * {@link SqlTypeAssignmentRules}) should go away.
 *
 * @param toType   target of assignment
 * @param fromType source of assignment
 * @param coerce   if true, the SQL rules for CAST are used; if false, the
 *                 rules are similar to Java; e.g. you can't assign short x =
 *                 (int) y, and you can't assign int x = (String) z.
 * @return true iff cast is legal
 */
public static boolean canCastFrom(RelDataType toType, RelDataType fromType, boolean coerce) {
    if (toType == fromType) {
        return true;
    }
    if (isAny(toType) || isAny(fromType)) {
        return true;
    }
    final SqlTypeName fromTypeName = fromType.getSqlTypeName();
    final SqlTypeName toTypeName = toType.getSqlTypeName();
    if (toType.isStruct() || fromType.isStruct()) {
        if (toTypeName == SqlTypeName.DISTINCT) {
            if (fromTypeName == SqlTypeName.DISTINCT) {
                // can't cast between different distinct types
                return false;
            }
            return canCastFrom(toType.getFieldList().get(0).getType(), fromType, coerce);
        } else if (fromTypeName == SqlTypeName.DISTINCT) {
            return canCastFrom(toType, fromType.getFieldList().get(0).getType(), coerce);
        } else if (toTypeName == SqlTypeName.ROW) {
            if (fromTypeName != SqlTypeName.ROW) {
                return false;
            }
            int n = toType.getFieldCount();
            if (fromType.getFieldCount() != n) {
                return false;
            }
            for (int i = 0; i < n; ++i) {
                RelDataTypeField toField = toType.getFieldList().get(i);
                RelDataTypeField fromField = fromType.getFieldList().get(i);
                if (!canCastFrom(toField.getType(), fromField.getType(), coerce)) {
                    return false;
                }
            }
            return true;
        } else if (toTypeName == SqlTypeName.MULTISET) {
            if (!fromType.isStruct()) {
                return false;
            }
            if (fromTypeName != SqlTypeName.MULTISET) {
                return false;
            }
            return canCastFrom(toType.getComponentType(), fromType.getComponentType(), coerce);
        } else if (fromTypeName == SqlTypeName.MULTISET) {
            return false;
        } else {
            return toType.getFamily() == fromType.getFamily();
        }
    }
    RelDataType c1 = toType.getComponentType();
    if (c1 != null) {
        RelDataType c2 = fromType.getComponentType();
        if (c2 == null) {
            return false;
        }
        return canCastFrom(c1, c2, coerce);
    }
    if ((isInterval(fromType) && isExactNumeric(toType)) || (isInterval(toType) && isExactNumeric(fromType))) {
        IntervalSqlType intervalType = (IntervalSqlType) (isInterval(fromType) ? fromType : toType);
        if (!intervalType.getIntervalQualifier().isSingleDatetimeField()) {
            // intervals with a single datetime field.
            return false;
        }
    }
    if (toTypeName == null || fromTypeName == null) {
        return false;
    }
    // REVIEW jvs 9-Feb-2009: we don't impose SQL rules for character sets
    // here; instead, we do that in SqlCastFunction.  The reason is that
    // this method is called from at least one place (MedJdbcNameDirectory)
    // where internally a cast across character repertoires is OK.  Should
    // probably clean that up.
    SqlTypeAssignmentRules rules = SqlTypeAssignmentRules.instance(coerce);
    return rules.canCastFrom(toTypeName, fromTypeName);
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 93 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class IdentifierNamespace method validateImpl.

public RelDataType validateImpl(RelDataType targetRowType) {
    resolvedNamespace = Preconditions.checkNotNull(resolveImpl(id));
    if (resolvedNamespace instanceof TableNamespace) {
        SqlValidatorTable table = resolvedNamespace.getTable();
        if (validator.shouldExpandIdentifiers()) {
            // TODO:  expand qualifiers for column references also
            List<String> qualifiedNames = table.getQualifiedName();
            if (qualifiedNames != null) {
                // Assign positions to the components of the fully-qualified
                // identifier, as best we can. We assume that qualification
                // adds names to the front, e.g. FOO.BAR becomes BAZ.FOO.BAR.
                List<SqlParserPos> poses = new ArrayList<>(Collections.nCopies(qualifiedNames.size(), id.getParserPosition()));
                int offset = qualifiedNames.size() - id.names.size();
                // reader.
                if (offset >= 0) {
                    for (int i = 0; i < id.names.size(); i++) {
                        poses.set(i + offset, id.getComponentParserPosition(i));
                    }
                }
                id.setNames(qualifiedNames, poses);
            }
        }
    }
    RelDataType rowType = resolvedNamespace.getRowType();
    if (extendList != null) {
        if (!(resolvedNamespace instanceof TableNamespace)) {
            throw new RuntimeException("cannot convert");
        }
        resolvedNamespace = ((TableNamespace) resolvedNamespace).extend(extendList);
        rowType = resolvedNamespace.getRowType();
    }
    // Build a list of monotonic expressions.
    final ImmutableList.Builder<Pair<SqlNode, SqlMonotonicity>> builder = ImmutableList.builder();
    List<RelDataTypeField> fields = rowType.getFieldList();
    for (RelDataTypeField field : fields) {
        final String fieldName = field.getName();
        final SqlMonotonicity monotonicity = resolvedNamespace.getMonotonicity(fieldName);
        if (monotonicity != SqlMonotonicity.NOT_MONOTONIC) {
            builder.add(Pair.of((SqlNode) new SqlIdentifier(fieldName, SqlParserPos.ZERO), monotonicity));
        }
    }
    monotonicExprs = builder.build();
    // Validation successful.
    return rowType;
}
Also used : SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) Pair(org.apache.calcite.util.Pair) SqlNode(org.apache.calcite.sql.SqlNode)

Example 94 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class ListScope method resolveColumn.

public RelDataType resolveColumn(String columnName, SqlNode ctx) {
    final SqlNameMatcher nameMatcher = validator.catalogReader.nameMatcher();
    int found = 0;
    RelDataType type = null;
    for (ScopeChild child : children) {
        SqlValidatorNamespace childNs = child.namespace;
        final RelDataType childRowType = childNs.getRowType();
        final RelDataTypeField field = nameMatcher.field(childRowType, columnName);
        if (field != null) {
            found++;
            type = field.getType();
        }
    }
    switch(found) {
        case 0:
            return null;
        case 1:
            return type;
        default:
            throw validator.newValidationError(ctx, RESOURCE.columnAmbiguous(columnName));
    }
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 95 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class AliasNamespace method validateImpl.

// ~ Methods ----------------------------------------------------------------
protected RelDataType validateImpl(RelDataType targetRowType) {
    final List<String> nameList = new ArrayList<String>();
    final List<SqlNode> operands = call.getOperandList();
    final SqlValidatorNamespace childNs = validator.getNamespace(operands.get(0));
    final RelDataType rowType = childNs.getRowTypeSansSystemColumns();
    final List<SqlNode> columnNames = Util.skip(operands, 2);
    for (final SqlNode operand : columnNames) {
        String name = ((SqlIdentifier) operand).getSimple();
        if (nameList.contains(name)) {
            throw validator.newValidationError(operand, RESOURCE.aliasListDuplicate(name));
        }
        nameList.add(name);
    }
    if (nameList.size() != rowType.getFieldCount()) {
        // Position error over all column names
        final SqlNode node = operands.size() == 3 ? operands.get(2) : new SqlNodeList(columnNames, SqlParserPos.sum(columnNames));
        throw validator.newValidationError(node, RESOURCE.aliasListDegree(rowType.getFieldCount(), getString(rowType), nameList.size()));
    }
    final List<RelDataType> typeList = new ArrayList<RelDataType>();
    for (RelDataTypeField field : rowType.getFieldList()) {
        typeList.add(field.getType());
    }
    return validator.getTypeFactory().createStructType(typeList, nameList);
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) ArrayList(java.util.ArrayList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)388 RelDataType (org.apache.calcite.rel.type.RelDataType)210 RexNode (org.apache.calcite.rex.RexNode)185 ArrayList (java.util.ArrayList)175 RelNode (org.apache.calcite.rel.RelNode)130 RexBuilder (org.apache.calcite.rex.RexBuilder)76 RexInputRef (org.apache.calcite.rex.RexInputRef)72 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)65 Pair (org.apache.calcite.util.Pair)55 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)47 HashMap (java.util.HashMap)39 Map (java.util.Map)35 AggregateCall (org.apache.calcite.rel.core.AggregateCall)35 SqlNode (org.apache.calcite.sql.SqlNode)32 ImmutableList (com.google.common.collect.ImmutableList)31 RelBuilder (org.apache.calcite.tools.RelBuilder)29 RelDataTypeFieldImpl (org.apache.calcite.rel.type.RelDataTypeFieldImpl)26 List (java.util.List)23 LinkedHashSet (java.util.LinkedHashSet)22 RelOptUtil (org.apache.calcite.plan.RelOptUtil)22