Search in sources :

Example 16 with RelDataTypeFieldImpl

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

the class RelBuilder method project.

/**
 * Creates a {@link org.apache.calcite.rel.core.Project} of the given list
 * of expressions, using the given names.
 *
 * <p>Names are deduced as follows:
 * <ul>
 *   <li>If the length of {@code fieldNames} is greater than the index of
 *     the current entry in {@code nodes}, and the entry in
 *     {@code fieldNames} is not null, uses it; otherwise
 *   <li>If an expression projects an input field,
 *     or is a cast an input field,
 *     uses the input field name; otherwise
 *   <li>If an expression is a call to
 *     {@link org.apache.calcite.sql.fun.SqlStdOperatorTable#AS}
 *     (see {@link #alias}), removes the call but uses the intended alias.
 * </ul>
 *
 * <p>After the field names have been inferred, makes the
 * field names unique by appending numeric suffixes.
 *
 * @param nodes Expressions
 * @param fieldNames Suggested field names
 * @param force create project even if it is identity
 */
public RelBuilder project(Iterable<? extends RexNode> nodes, Iterable<String> fieldNames, boolean force) {
    final List<String> names = new ArrayList<>();
    final List<RexNode> exprList = new ArrayList<>();
    final Iterator<String> nameIterator = fieldNames.iterator();
    for (RexNode node : nodes) {
        if (simplify) {
            node = simplifier.simplifyPreservingType(node);
        }
        exprList.add(node);
        String name = nameIterator.hasNext() ? nameIterator.next() : null;
        names.add(name != null ? name : inferAlias(exprList, node));
    }
    final Frame frame = stack.peek();
    final ImmutableList.Builder<Field> fields = ImmutableList.builder();
    final Set<String> uniqueNameList = getTypeFactory().getTypeSystem().isSchemaCaseSensitive() ? new HashSet<String>() : new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
    // calculate final names and build field list
    for (int i = 0; i < names.size(); ++i) {
        RexNode node = exprList.get(i);
        String name = names.get(i);
        Field field;
        if (name == null || uniqueNameList.contains(name)) {
            int j = 0;
            if (name == null) {
                j = i;
            }
            do {
                name = SqlValidatorUtil.F_SUGGESTER.apply(name, j, j++);
            } while (uniqueNameList.contains(name));
            names.set(i, name);
        }
        RelDataTypeField fieldType = new RelDataTypeFieldImpl(name, i, node.getType());
        switch(node.getKind()) {
            case INPUT_REF:
                // preserve rel aliases for INPUT_REF fields
                final int index = ((RexInputRef) node).getIndex();
                field = new Field(frame.fields.get(index).left, fieldType);
                break;
            default:
                field = new Field(ImmutableSet.<String>of(), fieldType);
                break;
        }
        uniqueNameList.add(name);
        fields.add(field);
    }
    final RelDataType inputRowType = peek().getRowType();
    if (!force && RexUtil.isIdentity(exprList, inputRowType)) {
        if (names.equals(inputRowType.getFieldNames())) {
            // Do not create an identity project if it does not rename any fields
            return this;
        } else {
            // create "virtual" row type for project only rename fields
            stack.pop();
            stack.push(new Frame(frame.rel, fields.build()));
            return this;
        }
    }
    final RelNode project = projectFactory.createProject(frame.rel, ImmutableList.copyOf(exprList), names);
    stack.pop();
    stack.push(new Frame(project, fields.build()));
    return this;
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataTypeFieldImpl(org.apache.calcite.rel.type.RelDataTypeFieldImpl) RexNode(org.apache.calcite.rex.RexNode)

Example 17 with RelDataTypeFieldImpl

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

the class RelBuilder method aggregate.

/**
 * Creates an {@link org.apache.calcite.rel.core.Aggregate} with a list of
 * calls.
 */
public RelBuilder aggregate(GroupKey groupKey, Iterable<AggCall> aggCalls) {
    final Registrar registrar = new Registrar();
    registrar.extraNodes.addAll(fields());
    registrar.names.addAll(peek().getRowType().getFieldNames());
    final GroupKeyImpl groupKey_ = (GroupKeyImpl) groupKey;
    final ImmutableBitSet groupSet = ImmutableBitSet.of(registrar.registerExpressions(groupKey_.nodes));
    label: if (Iterables.isEmpty(aggCalls) && !groupKey_.indicator) {
        final RelMetadataQuery mq = peek().getCluster().getMetadataQuery();
        if (groupSet.isEmpty()) {
            final Double minRowCount = mq.getMinRowCount(peek());
            if (minRowCount == null || minRowCount < 1D) {
                // empty.
                break label;
            }
        }
        if (registrar.extraNodes.size() == fields().size()) {
            final Boolean unique = mq.areColumnsUnique(peek(), groupSet);
            if (unique != null && unique) {
                // Rel is already unique.
                return project(fields(groupSet.asList()));
            }
        }
        final Double maxRowCount = mq.getMaxRowCount(peek());
        if (maxRowCount != null && maxRowCount <= 1D) {
            // If there is at most one row, rel is already unique.
            return this;
        }
    }
    final ImmutableList<ImmutableBitSet> groupSets;
    if (groupKey_.nodeLists != null) {
        final int sizeBefore = registrar.extraNodes.size();
        final SortedSet<ImmutableBitSet> groupSetSet = new TreeSet<>(ImmutableBitSet.ORDERING);
        for (ImmutableList<RexNode> nodeList : groupKey_.nodeLists) {
            final ImmutableBitSet groupSet2 = ImmutableBitSet.of(registrar.registerExpressions(nodeList));
            if (!groupSet.contains(groupSet2)) {
                throw new IllegalArgumentException("group set element " + nodeList + " must be a subset of group key");
            }
            groupSetSet.add(groupSet2);
        }
        groupSets = ImmutableList.copyOf(groupSetSet);
        if (registrar.extraNodes.size() > sizeBefore) {
            throw new IllegalArgumentException("group sets contained expressions not in group key: " + registrar.extraNodes.subList(sizeBefore, registrar.extraNodes.size()));
        }
    } else {
        groupSets = ImmutableList.of(groupSet);
    }
    for (AggCall aggCall : aggCalls) {
        if (aggCall instanceof AggCallImpl) {
            final AggCallImpl aggCall1 = (AggCallImpl) aggCall;
            registrar.registerExpressions(aggCall1.operands);
            if (aggCall1.filter != null) {
                registrar.registerExpression(aggCall1.filter);
            }
        }
    }
    project(registrar.extraNodes);
    rename(registrar.names);
    final Frame frame = stack.pop();
    final RelNode r = frame.rel;
    final List<AggregateCall> aggregateCalls = new ArrayList<>();
    for (AggCall aggCall : aggCalls) {
        final AggregateCall aggregateCall;
        if (aggCall instanceof AggCallImpl) {
            final AggCallImpl aggCall1 = (AggCallImpl) aggCall;
            final List<Integer> args = registrar.registerExpressions(aggCall1.operands);
            final int filterArg = aggCall1.filter == null ? -1 : registrar.registerExpression(aggCall1.filter);
            if (aggCall1.distinct && !aggCall1.aggFunction.isQuantifierAllowed()) {
                throw new IllegalArgumentException("DISTINCT not allowed");
            }
            if (aggCall1.filter != null && !aggCall1.aggFunction.allowsFilter()) {
                throw new IllegalArgumentException("FILTER not allowed");
            }
            aggregateCall = AggregateCall.create(aggCall1.aggFunction, aggCall1.distinct, aggCall1.approximate, args, filterArg, groupSet.cardinality(), r, null, aggCall1.alias);
        } else {
            aggregateCall = ((AggCallImpl2) aggCall).aggregateCall;
        }
        aggregateCalls.add(aggregateCall);
    }
    assert ImmutableBitSet.ORDERING.isStrictlyOrdered(groupSets) : groupSets;
    for (ImmutableBitSet set : groupSets) {
        assert groupSet.contains(set);
    }
    RelNode aggregate = aggregateFactory.createAggregate(r, groupKey_.indicator, groupSet, groupSets, aggregateCalls);
    // build field list
    final ImmutableList.Builder<Field> fields = ImmutableList.builder();
    final List<RelDataTypeField> aggregateFields = aggregate.getRowType().getFieldList();
    int i = 0;
    // first, group fields
    for (Integer groupField : groupSet.asList()) {
        RexNode node = registrar.extraNodes.get(groupField);
        final SqlKind kind = node.getKind();
        switch(kind) {
            case INPUT_REF:
                fields.add(frame.fields.get(((RexInputRef) node).getIndex()));
                break;
            default:
                String name = aggregateFields.get(i).getName();
                RelDataTypeField fieldType = new RelDataTypeFieldImpl(name, i, node.getType());
                fields.add(new Field(ImmutableSet.<String>of(), fieldType));
                break;
        }
        i++;
    }
    // second, indicator fields (copy from aggregate rel type)
    if (groupKey_.indicator) {
        for (int j = 0; j < groupSet.cardinality(); ++j) {
            final RelDataTypeField field = aggregateFields.get(i);
            final RelDataTypeField fieldType = new RelDataTypeFieldImpl(field.getName(), i, field.getType());
            fields.add(new Field(ImmutableSet.<String>of(), fieldType));
            i++;
        }
    }
    // third, aggregate fields. retain `i' as field index
    for (int j = 0; j < aggregateCalls.size(); ++j) {
        final AggregateCall call = aggregateCalls.get(j);
        final RelDataTypeField fieldType = new RelDataTypeFieldImpl(aggregateFields.get(i + j).getName(), i + j, call.getType());
        fields.add(new Field(ImmutableSet.<String>of(), fieldType));
    }
    stack.push(new Frame(aggregate, fields.build()));
    return this;
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) NlsString(org.apache.calcite.util.NlsString) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) TreeSet(java.util.TreeSet) RelDataTypeFieldImpl(org.apache.calcite.rel.type.RelDataTypeFieldImpl) SqlKind(org.apache.calcite.sql.SqlKind) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 18 with RelDataTypeFieldImpl

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

the class SqlValidatorUtil method getExtendedColumns.

/**
 * Gets a list of extended columns with field indices to the underlying table.
 */
public static List<RelDataTypeField> getExtendedColumns(RelDataTypeFactory typeFactory, SqlValidatorTable table, SqlNodeList extendedColumns) {
    final ImmutableList.Builder<RelDataTypeField> extendedFields = ImmutableList.builder();
    final ExtensibleTable extTable = table.unwrap(ExtensibleTable.class);
    int extendedFieldOffset = extTable == null ? table.getRowType().getFieldCount() : extTable.getExtendedColumnOffset();
    for (final Pair<SqlIdentifier, SqlDataTypeSpec> pair : pairs(extendedColumns)) {
        final SqlIdentifier identifier = pair.left;
        final SqlDataTypeSpec type = pair.right;
        extendedFields.add(new RelDataTypeFieldImpl(identifier.toString(), extendedFieldOffset++, type.deriveType(typeFactory)));
    }
    return extendedFields.build();
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) ImmutableList(com.google.common.collect.ImmutableList) SqlDataTypeSpec(org.apache.calcite.sql.SqlDataTypeSpec) RelDataTypeFieldImpl(org.apache.calcite.rel.type.RelDataTypeFieldImpl) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) ExtensibleTable(org.apache.calcite.schema.ExtensibleTable)

Example 19 with RelDataTypeFieldImpl

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

the class JavaTypeFactoryExtImpl method createPdxType.

public RelDataType createPdxType(PdxInstance pdxInstance) {
    final List<RelDataTypeField> list = new ArrayList<>();
    for (String fieldName : pdxInstance.getFieldNames()) {
        Object field = pdxInstance.getField(fieldName);
        Type fieldType;
        if (field == null) {
            fieldType = String.class;
        } else if (field instanceof PdxInstance) {
            // Map Nested PDX structures as String. This relates with
            // GeodeUtils.convert case when clazz is Null.
            fieldType = Map.class;
        // RelDataType boza = createPdxType((PdxInstance) field);
        } else {
            fieldType = field.getClass();
        }
        list.add(new RelDataTypeFieldImpl(fieldName, list.size(), createType(fieldType)));
    }
    return canonize(new RelRecordType(list));
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType) RelRecordType(org.apache.calcite.rel.type.RelRecordType) Type(java.lang.reflect.Type) JavaRecordType(org.apache.calcite.jdbc.JavaRecordType) PdxInstance(org.apache.geode.pdx.PdxInstance) ArrayList(java.util.ArrayList) RelDataTypeFieldImpl(org.apache.calcite.rel.type.RelDataTypeFieldImpl) Map(java.util.Map) RelRecordType(org.apache.calcite.rel.type.RelRecordType)

Example 20 with RelDataTypeFieldImpl

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

the class JavaTypeFactoryExtImpl method recursiveCreatePdxType.

private void recursiveCreatePdxType(PdxInstance pdxInstance, List<RelDataTypeField> list, String fieldNamePrefix) {
    for (String fieldName : pdxInstance.getFieldNames()) {
        Object field = pdxInstance.getField(fieldName);
        final Type fieldType = field.getClass();
        if (fieldType instanceof PdxInstance) {
            recursiveCreatePdxType((PdxInstance) field, list, fieldNamePrefix + fieldName + ".");
        } else {
            list.add(new RelDataTypeFieldImpl(fieldNamePrefix + fieldName, list.size(), createType(fieldType)));
        }
    }
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType) RelRecordType(org.apache.calcite.rel.type.RelRecordType) Type(java.lang.reflect.Type) JavaRecordType(org.apache.calcite.jdbc.JavaRecordType) PdxInstance(org.apache.geode.pdx.PdxInstance) RelDataTypeFieldImpl(org.apache.calcite.rel.type.RelDataTypeFieldImpl)

Aggregations

RelDataTypeFieldImpl (org.apache.calcite.rel.type.RelDataTypeFieldImpl)27 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)26 ArrayList (java.util.ArrayList)15 RelRecordType (org.apache.calcite.rel.type.RelRecordType)15 RelDataType (org.apache.calcite.rel.type.RelDataType)9 RexNode (org.apache.calcite.rex.RexNode)8 RelNode (org.apache.calcite.rel.RelNode)6 Type (java.lang.reflect.Type)4 RexInputRef (org.apache.calcite.rex.RexInputRef)4 ImmutableList (com.google.common.collect.ImmutableList)3 JavaRecordType (org.apache.calcite.jdbc.JavaRecordType)3 Field (java.lang.reflect.Field)2 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)2 SqlTypeName (org.apache.calcite.sql.type.SqlTypeName)2 NlsString (org.apache.calcite.util.NlsString)2 LogicalExpression (org.apache.drill.common.expression.LogicalExpression)2 SchemaPath (org.apache.drill.common.expression.SchemaPath)2 NamedExpression (org.apache.drill.common.logical.data.NamedExpression)2 DbGroupScan (org.apache.drill.exec.physical.base.DbGroupScan)2 Prel (org.apache.drill.exec.planner.physical.Prel)2