Java Code Examples for org.apache.calcite.rel.type.RelDataType#isStruct()

The following examples show how to use org.apache.calcite.rel.type.RelDataType#isStruct() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: Bats   File: RelStructuredTypeFlattener.java    License: Apache License 2.0 6 votes vote down vote up
private int calculateFlattenedOffset(RelDataType rowType, int ordinal) {
    int offset = 0;
    if (SqlTypeUtil.needsNullIndicator(rowType)) {
        // skip null indicator
        ++offset;
    }
    List<RelDataTypeField> oldFields = rowType.getFieldList();
    for (int i = 0; i < ordinal; ++i) {
        RelDataType oldFieldType = oldFields.get(i).getType();
        if (oldFieldType.isStruct()) {
            // TODO jvs 10-Feb-2005: this isn't terribly efficient;
            // keep a mapping somewhere
            RelDataType flattened = SqlTypeUtil.flattenRecordType(rexBuilder.getTypeFactory(), oldFieldType, null);
            final List<RelDataTypeField> fields = flattened.getFieldList();
            offset += fields.size();
        } else {
            ++offset;
        }
    }
    return offset;
}
 
Example 2
Source Project: Bats   File: AbstractNamespace.java    License: Apache License 2.0 6 votes vote down vote up
protected RelDataType convertToStruct(RelDataType type) {
  // "MULTISET [<expr>, ...]" needs to be wrapped in a record if
  // <expr> has a scalar type.
  // For example, "MULTISET [8, 9]" has type
  // "RECORD(INTEGER EXPR$0 NOT NULL) NOT NULL MULTISET NOT NULL".
  final RelDataType componentType = type.getComponentType();
  if (componentType == null || componentType.isStruct()) {
    return type;
  }
  final RelDataTypeFactory typeFactory = validator.getTypeFactory();
  final RelDataType structType = toStruct(componentType, getNode());
  final RelDataType collectionType;
  switch (type.getSqlTypeName()) {
  case ARRAY:
    collectionType = typeFactory.createArrayType(structType, -1);
    break;
  case MULTISET:
    collectionType = typeFactory.createMultisetType(structType, -1);
    break;
  default:
    throw new AssertionError(type);
  }
  return typeFactory.createTypeWithNullability(collectionType,
      type.isNullable());
}
 
Example 3
public void rewriteRel(Sort rel) {
  RelCollation oldCollation = rel.getCollation();
  final RelNode oldChild = rel.getInput();
  final RelNode newChild = getNewForOldRel(oldChild);
  final Mappings.TargetMapping mapping =
      getNewForOldInputMapping(oldChild);

  // validate
  for (RelFieldCollation field : oldCollation.getFieldCollations()) {
    int oldInput = field.getFieldIndex();
    RelDataType sortFieldType =
        oldChild.getRowType().getFieldList().get(oldInput).getType();
    if (sortFieldType.isStruct()) {
      // TODO jvs 10-Feb-2005
      throw Util.needToImplement("sorting on structured types");
    }
  }
  RelCollation newCollation = RexUtil.apply(mapping, oldCollation);
  Sort newRel =
      LogicalSort.create(newChild, newCollation, rel.offset, rel.fetch);
  setNewForOldRel(rel, newRel);
}
 
Example 4
public static Class getSchemaForRelDataType(TupleSchemaRegistry registry, String schemaName, RelDataType rowType)
{
  if (rowType.isStruct()) {
    TupleSchemaRegistry.Schema newSchema = registry.createNewSchema(schemaName);
    for (RelDataTypeField field : rowType.getFieldList()) {
      RelDataType type = field.getType();
      newSchema.addField(OperatorUtils.getValidFieldName(field), convertPrimitiveToSqlType(type));
    }
    try {
      newSchema.generateBean();
    } catch (IOException | JSONException e) {
      throw new RuntimeException("Failed to generate schema", e);
    }
    return newSchema.beanClass;
  } else {
    throw new UnsupportedOperationException("Non-struct row type is not implemented.");
  }
}
 
Example 5
Source Project: calcite   File: AbstractNamespace.java    License: Apache License 2.0 6 votes vote down vote up
protected RelDataType convertToStruct(RelDataType type) {
  // "MULTISET [<expr>, ...]" needs to be wrapped in a record if
  // <expr> has a scalar type.
  // For example, "MULTISET [8, 9]" has type
  // "RECORD(INTEGER EXPR$0 NOT NULL) NOT NULL MULTISET NOT NULL".
  final RelDataType componentType = type.getComponentType();
  if (componentType == null || componentType.isStruct()) {
    return type;
  }
  final RelDataTypeFactory typeFactory = validator.getTypeFactory();
  final RelDataType structType = toStruct(componentType, getNode());
  final RelDataType collectionType;
  switch (type.getSqlTypeName()) {
  case ARRAY:
    collectionType = typeFactory.createArrayType(structType, -1);
    break;
  case MULTISET:
    collectionType = typeFactory.createMultisetType(structType, -1);
    break;
  default:
    throw new AssertionError(type);
  }
  return typeFactory.createTypeWithNullability(collectionType,
      type.isNullable());
}
 
Example 6
Source Project: Bats   File: StarColumnHelper.java    License: Apache License 2.0 6 votes vote down vote up
public static boolean containsStarColumnInProject(RelDataType inputRowType, List<RexNode> projExprs) {
  if (!inputRowType.isStruct()) {
    return false;
  }

  for (RexNode expr : projExprs) {
    if (expr instanceof RexInputRef) {
      String name = inputRowType.getFieldNames().get(((RexInputRef) expr).getIndex());

      if (SchemaPath.DYNAMIC_STAR.equals(name)) {
        return true;
      }
    }
  }

  return false;
}
 
Example 7
Source Project: calcite   File: PigRelBuilder.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Checks if two relational data types are compatible.
 *
 * @param t1 first type
 * @param t2 second type
 * @return true if t1 is compatible with t2
 */
public static boolean compatibleType(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 (!compatibleType(
          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 (!compatibleType(comp1, comp2)) {
      return false;
    }
  }
  return t1.getSqlTypeName().getFamily() == t2.getSqlTypeName().getFamily();
}
 
Example 8
Source Project: Bats   File: RelStructuredTypeFlattener.java    License: Apache License 2.0 5 votes vote down vote up
public void rewriteRel(LogicalCorrelate rel) {
    ImmutableBitSet.Builder newPos = ImmutableBitSet.builder();
    for (int pos : rel.getRequiredColumns()) {
        RelDataType corrFieldType = rel.getLeft().getRowType().getFieldList().get(pos).getType();
        if (corrFieldType.isStruct()) {
            throw Util.needToImplement("correlation on structured type");
        }
        newPos.set(getNewForOldInput(pos));
    }
    LogicalCorrelate newRel = LogicalCorrelate.create(getNewForOldRel(rel.getLeft()),
            getNewForOldRel(rel.getRight()), rel.getCorrelationId(), newPos.build(), rel.getJoinType());
    setNewForOldRel(rel, newRel);
}
 
Example 9
Source Project: calcite   File: SqlTypeUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Promotes a type to a row type (does nothing if it already is one).
 *
 * @param type      type to be promoted
 * @param fieldName name to give field in row type; null for default of
 *                  "ROW_VALUE"
 * @return row type
 */
public static RelDataType promoteToRowType(
    RelDataTypeFactory typeFactory,
    RelDataType type,
    String fieldName) {
  if (!type.isStruct()) {
    if (fieldName == null) {
      fieldName = "ROW_VALUE";
    }
    type = typeFactory.builder().add(fieldName, type).build();
  }
  return type;
}
 
Example 10
Source Project: calcite   File: CalcitePrepareImpl.java    License: Apache License 2.0 5 votes vote down vote up
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;
}
 
Example 11
Source Project: calcite   File: PigRelBuilder.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Builds the projection expressions for a data type on top of an input data type.
 * For any field in output type, if there is no matching input field, we build
 * the literal null expression with the corresponding output field type.
 *
 * @param inputType The input data type
 * @param outputType The output data type that defines the types of projection expressions
 * @return List of projection expressions
 */
private List<RexNode> projects(RelDataType inputType, RelDataType outputType) {
  final List<RelDataTypeField> outputFields = outputType.getFieldList();
  final List<RelDataTypeField> inputFields = inputType.getFieldList();
  final List<RexNode> projectionExprs = new ArrayList<>();

  for (RelDataTypeField outputField : outputFields) {
    RelDataTypeField matchInputField = null;
    // First find the matching input field
    for (RelDataTypeField inputField : inputFields) {
      if (inputField.getName().equals(outputField.getName())) {
        // Matched if same name
        matchInputField = inputField;
        break;
      }
    }
    if (matchInputField != null) {
      RexNode fieldProject = field(matchInputField.getIndex());
      if (matchInputField.getType().equals(outputField.getType())) {
        // If found and on same type, just project the field
        projectionExprs.add(fieldProject);
      } else {
        // Different types, CAST is required
        projectionExprs.add(getRexBuilder().makeCast(outputField.getType(), fieldProject));
      }
    } else {
      final RelDataType columnType = outputField.getType();
      if (!columnType.isStruct() && columnType.getComponentType() == null) {
        // If not, project the null Literal with the same basic type
        projectionExprs.add(getRexBuilder().makeNullLiteral(outputField.getType()));
      } else {
        // If Record or Multiset just project a constant null
        projectionExprs.add(literal(null));
      }
    }
  }
  return projectionExprs;
}
 
Example 12
Source Project: Bats   File: SqlTypeUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * 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<>();
  boolean nested =
      flattenFields(
          typeFactory,
          recordType,
          fieldList,
          flatteningMap);
  if (!nested) {
    return recordType;
  }
  List<RelDataType> types = new ArrayList<>();
  List<String> fieldNames = new ArrayList<>();
  int i = -1;
  for (RelDataTypeField field : fieldList) {
    ++i;
    types.add(field.getType());
    fieldNames.add(field.getName() + "_" + i);
  }
  return typeFactory.createStructType(types, fieldNames);
}
 
Example 13
Source Project: calcite   File: SqlTypeUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * 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();
}
 
Example 14
Source Project: calcite   File: CalcitePrepareImpl.java    License: Apache License 2.0 5 votes vote down vote up
private static RelDataType makeStruct(
    RelDataTypeFactory typeFactory,
    RelDataType type) {
  if (type.isStruct()) {
    return type;
  }
  return typeFactory.builder().add("$0", type).build();
}
 
Example 15
Source Project: calcite   File: SqlTypeUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Determines whether a type or any of its fields (if a structured type) are
 * nullable.
 */
public static boolean containsNullable(RelDataType type) {
  if (type.isNullable()) {
    return true;
  }
  if (!type.isStruct()) {
    return false;
  }
  for (RelDataTypeField field : type.getFieldList()) {
    if (containsNullable(field.getType())) {
      return true;
    }
  }
  return false;
}
 
Example 16
Source Project: calcite   File: PhysTypeImpl.java    License: Apache License 2.0 5 votes vote down vote up
private RelDataType toStruct(RelDataType type) {
  if (type.isStruct()) {
    return type;
  }
  return typeFactory.builder()
      .add(SqlUtil.deriveAliasFromOrdinal(0), type)
      .build();
}
 
Example 17
Source Project: calcite   File: RelOptUtil.java    License: Apache License 2.0 5 votes vote down vote up
void accept(RelDataType type) {
  if (type.isStruct()) {
    final List<RelDataTypeField> fields = type.getFieldList();

    // RECORD (
    //   I INTEGER NOT NULL,
    //   J VARCHAR(240))
    pw.println("RECORD (");
    String prevIndent = indent;
    String extraIndent = "  ";
    this.indent = indent + extraIndent;
    acceptFields(fields);
    this.indent = prevIndent;
    pw.print(")");
    if (!type.isNullable()) {
      pw.print(" NOT NULL");
    }
  } else if (type instanceof MultisetSqlType) {
    // E.g. "INTEGER NOT NULL MULTISET NOT NULL"
    accept(type.getComponentType());
    pw.print(" MULTISET");
    if (!type.isNullable()) {
      pw.print(" NOT NULL");
    }
  } else {
    // E.g. "INTEGER" E.g. "VARCHAR(240) CHARACTER SET "ISO-8859-1"
    // COLLATE "ISO-8859-1$en_US$primary" NOT NULL"
    pw.print(type.getFullTypeString());
  }
}
 
Example 18
Source Project: calcite   File: SqlTypeUtil.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * 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;
  }

  final RelDataTypeFamily family1 = family(type1);
  final RelDataTypeFamily family2 = family(type2);
  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;
}
 
Example 19
Source Project: Bats   File: SqlTypeUtil.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * 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;
  }

  final RelDataTypeFamily family1 = family(type1);
  final RelDataTypeFamily family2 = family(type2);
  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;
}
 
Example 20
Source Project: calcite   File: EnumerableUncollect.java    License: Apache License 2.0 4 votes vote down vote up
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
  final BlockBuilder builder = new BlockBuilder();
  final EnumerableRel child = (EnumerableRel) getInput();
  final Result result = implementor.visitChild(this, 0, child, pref);
  final PhysType physType =
      PhysTypeImpl.of(
          implementor.getTypeFactory(),
          getRowType(),
          JavaRowFormat.LIST);

  // final Enumerable<List<Employee>> child = <<child adapter>>;
  // return child.selectMany(FLAT_PRODUCT);
  final Expression child_ =
      builder.append(
          "child", result.block);

  final List<Integer> fieldCounts = new ArrayList<>();
  final List<FlatProductInputType> inputTypes = new ArrayList<>();

  Expression lambdaForStructWithSingleItem = null;
  for (RelDataTypeField field : child.getRowType().getFieldList()) {
    final RelDataType type = field.getType();
    if (type instanceof MapSqlType) {
      fieldCounts.add(2);
      inputTypes.add(FlatProductInputType.MAP);
    } else {
      final RelDataType elementType = type.getComponentType();
      if (elementType.isStruct()) {
        if (elementType.getFieldCount() == 1 && child.getRowType().getFieldList().size() == 1
            && !withOrdinality) {
          // Solves CALCITE-4063: if we are processing a single field, which is a struct with a
          // single item inside, and no ordinality; the result must be a scalar, hence use a
          // special lambda that does not return lists, but the (single) items within those lists
          lambdaForStructWithSingleItem = Expressions.call(BuiltInMethod.FLAT_LIST.method);
        } else {
          fieldCounts.add(elementType.getFieldCount());
          inputTypes.add(FlatProductInputType.LIST);
        }
      } else {
        fieldCounts.add(-1);
        inputTypes.add(FlatProductInputType.SCALAR);
      }
    }
  }

  final Expression lambda = lambdaForStructWithSingleItem != null
      ? lambdaForStructWithSingleItem
      : Expressions.call(BuiltInMethod.FLAT_PRODUCT.method,
          Expressions.constant(Ints.toArray(fieldCounts)),
          Expressions.constant(withOrdinality),
          Expressions.constant(
              inputTypes.toArray(new FlatProductInputType[0])));
  builder.add(
      Expressions.return_(null,
          Expressions.call(child_,
              BuiltInMethod.SELECT_MANY.method,
              lambda)));
  return implementor.result(physType, builder.toBlock());
}