Search in sources :

Example 86 with RelDataTypeField

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

the class CalcitePrepareImpl method prepare2_.

<T> CalciteSignature<T> prepare2_(Context context, Query<T> query, Type elementType, long maxRowCount, CalciteCatalogReader catalogReader, RelOptPlanner planner) {
    final JavaTypeFactory typeFactory = context.getTypeFactory();
    final EnumerableRel.Prefer prefer;
    if (elementType == Object[].class) {
        prefer = EnumerableRel.Prefer.ARRAY;
    } else {
        prefer = EnumerableRel.Prefer.CUSTOM;
    }
    final Convention resultConvention = enableBindable ? BindableConvention.INSTANCE : EnumerableConvention.INSTANCE;
    final CalcitePreparingStmt preparingStmt = new CalcitePreparingStmt(this, context, catalogReader, typeFactory, context.getRootSchema(), prefer, planner, resultConvention, createConvertletTable());
    final RelDataType x;
    final Prepare.PreparedResult preparedResult;
    final Meta.StatementType statementType;
    if (query.sql != null) {
        final CalciteConnectionConfig config = context.config();
        final SqlParser.ConfigBuilder parserConfig = createParserConfig().setQuotedCasing(config.quotedCasing()).setUnquotedCasing(config.unquotedCasing()).setQuoting(config.quoting()).setConformance(config.conformance()).setCaseSensitive(config.caseSensitive());
        final SqlParserImplFactory parserFactory = config.parserFactory(SqlParserImplFactory.class, null);
        if (parserFactory != null) {
            parserConfig.setParserFactory(parserFactory);
        }
        SqlParser parser = createParser(query.sql, parserConfig);
        SqlNode sqlNode;
        try {
            sqlNode = parser.parseStmt();
            statementType = getStatementType(sqlNode.getKind());
        } catch (SqlParseException e) {
            throw new RuntimeException("parse failed: " + e.getMessage(), e);
        }
        Hook.PARSE_TREE.run(new Object[] { query.sql, sqlNode });
        if (sqlNode.getKind().belongsTo(SqlKind.DDL)) {
            executeDdl(context, sqlNode);
            return new CalciteSignature<>(query.sql, ImmutableList.<AvaticaParameter>of(), ImmutableMap.<String, Object>of(), null, ImmutableList.<ColumnMetaData>of(), Meta.CursorFactory.OBJECT, null, ImmutableList.<RelCollation>of(), -1, null, Meta.StatementType.OTHER_DDL);
        }
        final SqlValidator validator = createSqlValidator(context, catalogReader);
        validator.setIdentifierExpansion(true);
        validator.setDefaultNullCollation(config.defaultNullCollation());
        preparedResult = preparingStmt.prepareSql(sqlNode, Object.class, validator, true);
        switch(sqlNode.getKind()) {
            case INSERT:
            case DELETE:
            case UPDATE:
            case EXPLAIN:
                // FIXME: getValidatedNodeType is wrong for DML
                x = RelOptUtil.createDmlRowType(sqlNode.getKind(), typeFactory);
                break;
            default:
                x = validator.getValidatedNodeType(sqlNode);
        }
    } else if (query.queryable != null) {
        x = context.getTypeFactory().createType(elementType);
        preparedResult = preparingStmt.prepareQueryable(query.queryable, x);
        statementType = getStatementType(preparedResult);
    } else {
        assert query.rel != null;
        x = query.rel.getRowType();
        preparedResult = preparingStmt.prepareRel(query.rel);
        statementType = getStatementType(preparedResult);
    }
    final List<AvaticaParameter> parameters = new ArrayList<>();
    final RelDataType parameterRowType = preparedResult.getParameterRowType();
    for (RelDataTypeField field : parameterRowType.getFieldList()) {
        RelDataType type = field.getType();
        parameters.add(new AvaticaParameter(false, getPrecision(type), getScale(type), getTypeOrdinal(type), getTypeName(type), getClassName(type), field.getName()));
    }
    RelDataType jdbcType = makeStruct(typeFactory, x);
    final List<List<String>> originList = preparedResult.getFieldOrigins();
    final List<ColumnMetaData> columns = getColumnMetaDataList(typeFactory, x, jdbcType, originList);
    Class resultClazz = null;
    if (preparedResult instanceof Typed) {
        resultClazz = (Class) ((Typed) preparedResult).getElementType();
    }
    final Meta.CursorFactory cursorFactory = preparingStmt.resultConvention == BindableConvention.INSTANCE ? Meta.CursorFactory.ARRAY : Meta.CursorFactory.deduce(columns, resultClazz);
    // noinspection unchecked
    final Bindable<T> bindable = preparedResult.getBindable(cursorFactory);
    return new CalciteSignature<>(query.sql, parameters, preparingStmt.internalParameters, jdbcType, columns, cursorFactory, context.getRootSchema(), preparedResult instanceof Prepare.PreparedResultImpl ? ((Prepare.PreparedResultImpl) preparedResult).collations : ImmutableList.<RelCollation>of(), maxRowCount, bindable, statementType);
}
Also used : Meta(org.apache.calcite.avatica.Meta) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) AvaticaParameter(org.apache.calcite.avatica.AvaticaParameter) Typed(org.apache.calcite.runtime.Typed) SqlValidator(org.apache.calcite.sql.validate.SqlValidator) JavaTypeFactory(org.apache.calcite.adapter.java.JavaTypeFactory) CalcitePrepare(org.apache.calcite.jdbc.CalcitePrepare) SqlParserImplFactory(org.apache.calcite.sql.parser.SqlParserImplFactory) ArrayList(java.util.ArrayList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) ColumnMetaData(org.apache.calcite.avatica.ColumnMetaData) EnumerableRel(org.apache.calcite.adapter.enumerable.EnumerableRel) SqlNode(org.apache.calcite.sql.SqlNode) SqlParseException(org.apache.calcite.sql.parser.SqlParseException) CalciteConnectionConfig(org.apache.calcite.config.CalciteConnectionConfig) SqlParser(org.apache.calcite.sql.parser.SqlParser) BindableConvention(org.apache.calcite.interpreter.BindableConvention) Convention(org.apache.calcite.plan.Convention) EnumerableConvention(org.apache.calcite.adapter.enumerable.EnumerableConvention) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelCollation(org.apache.calcite.rel.RelCollation)

Example 87 with RelDataTypeField

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

the class CalcitePrepareImpl method getColumnMetaDataList.

private List<ColumnMetaData> getColumnMetaDataList(JavaTypeFactory typeFactory, RelDataType x, RelDataType jdbcType, List<List<String>> originList) {
    final List<ColumnMetaData> columns = new ArrayList<>();
    for (Ord<RelDataTypeField> pair : Ord.zip(jdbcType.getFieldList())) {
        final RelDataTypeField field = pair.e;
        final RelDataType type = field.getType();
        final RelDataType fieldType = x.isStruct() ? x.getFieldList().get(pair.i).getType() : type;
        columns.add(metaData(typeFactory, columns.size(), field.getName(), type, fieldType, originList.get(pair.i)));
    }
    return columns;
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) ColumnMetaData(org.apache.calcite.avatica.ColumnMetaData)

Example 88 with RelDataTypeField

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

the class SqlTypeUtil method sameNamedType.

/**
 * Tests whether two types have the same name and structure, possibly with
 * differing modifiers. For example, VARCHAR(1) and VARCHAR(10) are
 * considered the same, while VARCHAR(1) and CHAR(1) are considered
 * different. Likewise, VARCHAR(1) MULTISET and VARCHAR(10) MULTISET are
 * considered the same.
 *
 * @return true if types have same name and structure
 */
public static boolean sameNamedType(RelDataType t1, RelDataType t2) {
    if (t1.isStruct() || t2.isStruct()) {
        if (!t1.isStruct() || !t2.isStruct()) {
            return false;
        }
        if (t1.getFieldCount() != t2.getFieldCount()) {
            return false;
        }
        List<RelDataTypeField> fields1 = t1.getFieldList();
        List<RelDataTypeField> fields2 = t2.getFieldList();
        for (int i = 0; i < fields1.size(); ++i) {
            if (!sameNamedType(fields1.get(i).getType(), fields2.get(i).getType())) {
                return false;
            }
        }
        return true;
    }
    RelDataType comp1 = t1.getComponentType();
    RelDataType comp2 = t2.getComponentType();
    if ((comp1 != null) || (comp2 != null)) {
        if ((comp1 == null) || (comp2 == null)) {
            return false;
        }
        if (!sameNamedType(comp1, comp2)) {
            return false;
        }
    }
    return t1.getSqlTypeName() == t2.getSqlTypeName();
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 89 with RelDataTypeField

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

the class SqlTypeUtil method flattenFields.

private static boolean flattenFields(RelDataTypeFactory typeFactory, RelDataType type, List<RelDataTypeField> list, int[] flatteningMap) {
    boolean nested = false;
    if (needsNullIndicator(type)) {
        // NOTE jvs 9-Mar-2005:  other code
        // (e.g. RelStructuredTypeFlattener) relies on the
        // null indicator field coming first.
        RelDataType indicatorType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
        if (type.isNullable()) {
            indicatorType = typeFactory.createTypeWithNullability(indicatorType, true);
        }
        RelDataTypeField nullIndicatorField = new RelDataTypeFieldImpl("NULL_VALUE", 0, indicatorType);
        list.add(nullIndicatorField);
        nested = true;
    }
    for (RelDataTypeField field : type.getFieldList()) {
        if (flatteningMap != null) {
            flatteningMap[field.getIndex()] = list.size();
        }
        if (field.getType().isStruct()) {
            nested = true;
            flattenFields(typeFactory, field.getType(), list, null);
        } else if (field.getType().getComponentType() != null) {
            nested = true;
            // TODO jvs 14-Feb-2005:  generalize to any kind of
            // collection type
            RelDataType flattenedCollectionType = typeFactory.createMultisetType(flattenRecordType(typeFactory, field.getType().getComponentType(), null), -1);
            field = new RelDataTypeFieldImpl(field.getName(), field.getIndex(), flattenedCollectionType);
            list.add(field);
        } else {
            list.add(field);
        }
    }
    return nested;
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeFieldImpl(org.apache.calcite.rel.type.RelDataTypeFieldImpl)

Example 90 with RelDataTypeField

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

the class SqlTypeUtil method flattenRecordType.

/**
 * Flattens a record type by recursively expanding any fields which are
 * themselves record types. For each record type, a representative null
 * value field is also prepended (with state NULL for a null value and FALSE
 * for non-null), and all component types are asserted to be nullable, since
 * SQL doesn't allow NOT NULL to be specified on attributes.
 *
 * @param typeFactory   factory which should produced flattened type
 * @param recordType    type with possible nesting
 * @param flatteningMap if non-null, receives map from unflattened ordinal
 *                      to flattened ordinal (must have length at least
 *                      recordType.getFieldList().size())
 * @return flattened equivalent
 */
public static RelDataType flattenRecordType(RelDataTypeFactory typeFactory, RelDataType recordType, int[] flatteningMap) {
    if (!recordType.isStruct()) {
        return recordType;
    }
    List<RelDataTypeField> fieldList = new ArrayList<RelDataTypeField>();
    boolean nested = flattenFields(typeFactory, recordType, fieldList, flatteningMap);
    if (!nested) {
        return recordType;
    }
    List<RelDataType> types = new ArrayList<RelDataType>();
    List<String> fieldNames = new ArrayList<String>();
    int i = -1;
    for (RelDataTypeField field : fieldList) {
        ++i;
        types.add(field.getType());
        fieldNames.add(field.getName() + "_" + i);
    }
    return typeFactory.createStructType(types, fieldNames);
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType)

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