Java源码示例:org.apache.calcite.sql.type.SqlTypeFamily

示例1
private SqlSingleOperandTypeChecker getChecker(RelDataType operandType) {
  switch (operandType.getSqlTypeName()) {
  case ARRAY:
    return OperandTypes.family(SqlTypeFamily.INTEGER);
  case MAP:
    return OperandTypes.family(
        operandType.getKeyType().getSqlTypeName().getFamily());
  case ANY:
  case DYNAMIC_STAR:
    return OperandTypes.or(
        OperandTypes.family(SqlTypeFamily.INTEGER),
        OperandTypes.family(SqlTypeFamily.CHARACTER));
  default:
    throw new AssertionError(operandType.getSqlTypeName());
  }
}
 
示例2
/**
 * Given a {@link SqlTypeName} and nullability, create a RelDataType from the RelDataTypeFactory
 *
 * @param typeFactory RelDataTypeFactory used to create the RelDataType
 * @param sqlTypeName the given SqlTypeName
 * @param isNullable  the nullability of the created RelDataType
 * @return RelDataType Type of call
 */
public static RelDataType createCalciteTypeWithNullability(RelDataTypeFactory typeFactory,
                                                           SqlTypeName sqlTypeName,
                                                           boolean isNullable) {
  RelDataType type;
  if (sqlTypeName.getFamily() == SqlTypeFamily.INTERVAL_DAY_TIME) {
    type = typeFactory.createSqlIntervalType(
        new SqlIntervalQualifier(
            TimeUnit.DAY,
            TimeUnit.MINUTE,
            SqlParserPos.ZERO));
  } else if (sqlTypeName.getFamily() == SqlTypeFamily.INTERVAL_YEAR_MONTH) {
    type = typeFactory.createSqlIntervalType(
        new SqlIntervalQualifier(
            TimeUnit.YEAR,
            TimeUnit.MONTH,
            SqlParserPos.ZERO));
  } else if (sqlTypeName == SqlTypeName.VARCHAR) {
    type = typeFactory.createSqlType(sqlTypeName, Types.MAX_VARCHAR_LENGTH);
  } else {
    type = typeFactory.createSqlType(sqlTypeName);
  }
  return typeFactory.createTypeWithNullability(type, isNullable);
}
 
示例3
public SqlDatePartOperator() {
  super(
      "DATE_PART",
      SqlKind.OTHER_FUNCTION,
      ReturnTypes.BIGINT_NULLABLE,
      null,
      OperandTypes.sequence(
          "<PERIOD LITERAL>, <DATE or TIMESTAMP or INTERVAL>",
          new EnumeratedListChecker(VALID_PERIODS.keySet()),
          OperandTypes.or(
              OperandTypes.family(SqlTypeFamily.DATE),
              OperandTypes.family(SqlTypeFamily.TIMESTAMP),
              OperandTypes.family(SqlTypeFamily.DATETIME),
              OperandTypes.family(SqlTypeFamily.DATETIME_INTERVAL),
              OperandTypes.family(SqlTypeFamily.INTERVAL_DAY_TIME),
              OperandTypes.family(SqlTypeFamily.INTERVAL_YEAR_MONTH))
          ),
          SqlFunctionCategory.SYSTEM);
}
 
示例4
public static List<MeasureType> validate(String fieldName, RelDataTypeFamily dataTypeFamily, List<MeasureType> measures) {
  TypeHandler handle = null;
  if(dataTypeFamily instanceof SqlTypeFamily) {
    handle = TYPE_ALLOWANCES.get(dataTypeFamily);
  }

  if(handle == null) {
    throw UserException.validationError()
    .message("Unable to configure reflection on field %s because it was type %s.",
        fieldName,
        dataTypeFamily
      ).build(logger);
  }

  return handle.validate(fieldName, measures);
}
 
示例5
@Override
public Boolean visitCall(RexCall call) {
  if (call.getOperator() == SqlStdOperatorTable.ITEM) {
    final RexNode op0 = call.getOperands().get(0);
    final RexNode op1 = call.getOperands().get(1);

    if (op0 instanceof RexInputRef &&
        op1 instanceof RexLiteral && ((RexLiteral) op1).getTypeName().getFamily() == SqlTypeFamily.CHARACTER) {
      return true;
    } else if (op0 instanceof RexCall &&
        op1 instanceof RexLiteral && ((RexLiteral) op1).getTypeName().getFamily() == SqlTypeFamily.CHARACTER) {
      return op0.accept(this);
    }
  }

  return false;
}
 
示例6
private Stream<AggregateCall> toCalls(ReflectionMeasureField field) {
  Optional<SqlTypeFamily> typeFamily = getSqlTypeFamily(field.getName());
  if(!typeFamily.isPresent()) {
    // are we silently not measuring the field ? should we catch this during validation ?
    return Stream.of();
  }

  // for old systems, make sure we have a default measure list if one is not specificed.
  List<MeasureType> measures = field.getMeasureTypeList() == null || field.getMeasureTypeList().isEmpty() ? DEFAULT_MEASURE_LIST : field.getMeasureTypeList();
  List<AggregateCall> calls = new ArrayList<>();
  final int inputRef = getField(field.getName()).getIndex();
  int inFieldIndex = 0;
  for(MeasureType t : measures) {
    AggregateCall c = createMeasureFor(inputRef, inFieldIndex, typeFamily.get(), t);
    if(c == null) {
      continue;
    }
    calls.add(c);
  }
  return calls.stream();
}
 
示例7
/**
 * For a particular input and type family, create the request type if it is allowed.
 * @param inputRef The input of that this measure will be applied to.
 * @param index The index of this measure when the collection of measure for this input field.
 * @param family The type family of the field.
 * @param type The type of measure to generate.
 * @return An aggregate call or null if we can't create a measure of the requested type.
 */
private AggregateCall createMeasureFor(int inputRef, int index, SqlTypeFamily family, MeasureType type) {

  // skip measure columns for invalid types.
  if(!ReflectionValidator.getValidMeasures(family).contains(type)) {
    return null;
  }

  switch(type) {
  case APPROX_COUNT_DISTINCT:
    return AggregateCall.create(HyperLogLog.HLL, false, ImmutableList.of(inputRef), -1, 1, view, null, String.format("agg-%s-%s", inputRef, index));
  case COUNT:
    return AggregateCall.create(SqlStdOperatorTable.COUNT, false, ImmutableList.of(inputRef), -1, 1, view, null, String.format("agg-%s-%s", inputRef, index));
  case MAX:
    return AggregateCall.create(SqlStdOperatorTable.MAX, false, ImmutableList.of(inputRef), -1, 1, view, null, String.format("agg-%s-%s", inputRef, index));
  case MIN:
    return AggregateCall.create(SqlStdOperatorTable.MIN, false, ImmutableList.of(inputRef), -1, 1, view, null, String.format("agg-%s-%s", inputRef, index));
  case SUM:
    return AggregateCall.create(SqlStdOperatorTable.SUM, false, ImmutableList.of(inputRef), -1, 1, view, null, String.format("agg-%s-%s", inputRef, index));
  case UNKNOWN:
  default:
    throw new UnsupportedOperationException(type.name());
  }
}
 
示例8
private void validateFields(List<ReflectionField> fieldList, Map<String, ViewFieldType> schemaMap, String fieldName, Boolean mustBePrimitive) {
  if (fieldList == null) {
    return;
  }

  for (ReflectionField reflectionField : fieldList) {
    // A field must exist in the schema
    Preconditions.checkArgument(schemaMap.containsKey(reflectionField.getName()), String.format("%s field contains a field name [%s] that does not exist in the dataset", fieldName, reflectionField.getName()));

    if (mustBePrimitive) {
      ViewFieldType fieldType = schemaMap.get(reflectionField.getName());
      // We let ANY type pass primarily because pre-1.5 datasets may have valid fields marked as ANY.
      Preconditions.checkArgument(!Arrays.asList(SqlTypeFamily.ARRAY.name(), SqlTypeFamily.MAP.name()).contains(fieldType.getTypeFamily()), String.format("%s field cannot have field [%s] of type list, map or union", fieldName, reflectionField.getName()));
    }
  }
}
 
示例9
public static boolean isTemporal(final RField field) {
  final Optional<SqlTypeFamily> familyOpt = getSqlTypeFamily(field);
  if (!familyOpt.isPresent()) {
    return false;
  }

  final SqlTypeFamily family = familyOpt.get();
  switch (family) {
    case DATETIME:
    case TIMESTAMP:
    case DATE:
    case TIME:
      return true;
    default:
      return false;
  }
}
 
示例10
/** Decision method for {@link AbstractTypeCoercion#implicitCast}. */
private void shouldCast(
    RelDataType from,
    SqlTypeFamily family,
    RelDataType expected) {
  if (family == null) {
    // ROW type do not have a family.
    return;
  }
  RelDataType castedType = ((AbstractTypeCoercion) typeCoercion).implicitCast(from, family);
  boolean equals = castedType != null
      && (from.equals(castedType)
      || SqlTypeUtil.equalSansNullability(dataTypeFactory, castedType, expected)
      || expected.getSqlTypeName().getFamily().contains(castedType));
  assert equals
      : "Failed to cast from "
      + from.getSqlTypeName()
      + " to "
      + family;
}
 
示例11
/**
 * If one operand in a binary operator is a DateTime type, but the other isn't,
 * we should not push down the predicate
 * @param call current node being evaluated
 */
private static void checkForIncompatibleDateTimeOperands(RexCall call) {
  RelDataType op1 = call.getOperands().get(0).getType();
  RelDataType op2 = call.getOperands().get(1).getType();
  if ((SqlTypeFamily.DATETIME.contains(op1) && !SqlTypeFamily.DATETIME.contains(op2))
         || (SqlTypeFamily.DATETIME.contains(op2) && !SqlTypeFamily.DATETIME.contains(op1))
         || (SqlTypeFamily.DATE.contains(op1) && !SqlTypeFamily.DATE.contains(op2))
         || (SqlTypeFamily.DATE.contains(op2) && !SqlTypeFamily.DATE.contains(op1))
         || (SqlTypeFamily.TIMESTAMP.contains(op1) && !SqlTypeFamily.TIMESTAMP.contains(op2))
         || (SqlTypeFamily.TIMESTAMP.contains(op2) && !SqlTypeFamily.TIMESTAMP.contains(op1))
         || (SqlTypeFamily.TIME.contains(op1) && !SqlTypeFamily.TIME.contains(op2))
         || (SqlTypeFamily.TIME.contains(op2) && !SqlTypeFamily.TIME.contains(op1))) {
    throw new PredicateAnalyzerException("Cannot handle " + call.getKind()
        + " expression for _id field, " + call);
  }
}
 
示例12
public boolean builtinFunctionCoercion(
    SqlCallBinding binding,
    List<RelDataType> operandTypes,
    List<SqlTypeFamily> expectedFamilies) {
  assert binding.getOperandCount() == operandTypes.size();
  if (!canImplicitTypeCast(operandTypes, expectedFamilies)) {
    return false;
  }
  boolean coerced = false;
  for (int i = 0; i < operandTypes.size(); i++) {
    RelDataType implicitType = implicitCast(operandTypes.get(i), expectedFamilies.get(i));
    coerced = null != implicitType
        && operandTypes.get(i) != implicitType
        && coerceOperandType(binding.getScope(), binding.getCall(), i, implicitType)
        || coerced;
  }
  return coerced;
}
 
示例13
private SqlSingleOperandTypeChecker getChecker(SqlCallBinding callBinding) {
  final RelDataType operandType = callBinding.getOperandType(0);
  switch (operandType.getSqlTypeName()) {
  case ARRAY:
    return OperandTypes.family(SqlTypeFamily.INTEGER);
  case MAP:
    return OperandTypes.family(
        operandType.getKeyType().getSqlTypeName().getFamily());
  case ROW:
    return OperandTypes.CHARACTER;
  case ANY:
  case DYNAMIC_STAR:
    return OperandTypes.or(
        OperandTypes.family(SqlTypeFamily.INTEGER),
        OperandTypes.family(SqlTypeFamily.CHARACTER));
  default:
    throw callBinding.newValidationSignatureError();
  }
}
 
示例14
@Override
public SqlNode toSql(RexProgram program, RexNode rex) {
    if (rex.getKind() == SqlKind.LITERAL) {
        final RexLiteral literal = (RexLiteral) rex;
        if (literal.getTypeName().getFamily() == SqlTypeFamily.CHARACTER) {
            return new SqlIdentifier(RexLiteral.stringValue(literal), POS);
        }
    }
    return super.toSql(program, rex);
}
 
示例15
@Override public int getNumTypeRadix(SqlTypeName typeName) {
  if (typeName.getFamily() == SqlTypeFamily.NUMERIC
      && getDefaultPrecision(typeName) != -1) {
    return 10;
  }
  return 0;
}
 
示例16
private static RelDataType consistentType(SqlRexContext cx,
    SqlOperandTypeChecker.Consistency consistency, List<RelDataType> types) {
  switch (consistency) {
  case COMPARE:
    if (SqlTypeUtil.areSameFamily(types)) {
      // All arguments are of same family. No need for explicit casts.
      return null;
    }
    final List<RelDataType> nonCharacterTypes = new ArrayList<>();
    for (RelDataType type : types) {
      if (type.getFamily() != SqlTypeFamily.CHARACTER) {
        nonCharacterTypes.add(type);
      }
    }
    if (!nonCharacterTypes.isEmpty()) {
      final int typeCount = types.size();
      types = nonCharacterTypes;
      if (nonCharacterTypes.size() < typeCount) {
        final RelDataTypeFamily family =
            nonCharacterTypes.get(0).getFamily();
        if (family instanceof SqlTypeFamily) {
          // The character arguments might be larger than the numeric
          // argument. Give ourselves some headroom.
          switch ((SqlTypeFamily) family) {
          case INTEGER:
          case NUMERIC:
            nonCharacterTypes.add(
                cx.getTypeFactory().createSqlType(SqlTypeName.BIGINT));
          }
        }
      }
    }
    // fall through
  case LEAST_RESTRICTIVE:
    return cx.getTypeFactory().leastRestrictive(types);
  default:
    return null;
  }
}
 
示例17
/** Creates a SqlTimestampAddFunction. */
SqlTimestampAddFunction() {
  super("TIMESTAMPADD", SqlKind.TIMESTAMP_ADD, RETURN_TYPE_INFERENCE, null,
      OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER,
          SqlTypeFamily.DATETIME),
      SqlFunctionCategory.TIMEDATE);
}
 
示例18
SqlTimestampDiffFunction() {
  super("TIMESTAMPDIFF", SqlKind.TIMESTAMP_DIFF,
      RETURN_TYPE_INFERENCE, null,
      OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.DATETIME,
          SqlTypeFamily.DATETIME),
      SqlFunctionCategory.TIMEDATE);
}
 
示例19
public SqlJsonArrayAggAggFunction(SqlKind kind,
    SqlJsonConstructorNullClause nullClause) {
  super(kind + "_" + nullClause.name(), null, kind, ReturnTypes.VARCHAR_2000, null,
      OperandTypes.family(SqlTypeFamily.ANY), SqlFunctionCategory.SYSTEM,
      false, false, Optionality.OPTIONAL);
  this.nullClause = Objects.requireNonNull(nullClause);
}
 
示例20
/** Creates a SqlJsonObjectAggAggFunction. */
public SqlJsonObjectAggAggFunction(SqlKind kind,
    SqlJsonConstructorNullClause nullClause) {
  super(kind + "_" + nullClause.name(), null, kind, ReturnTypes.VARCHAR_2000, null,
      OperandTypes.family(SqlTypeFamily.CHARACTER, SqlTypeFamily.ANY),
      SqlFunctionCategory.SYSTEM, false, false, Optionality.FORBIDDEN);
  this.nullClause = Objects.requireNonNull(nullClause);
}
 
示例21
/**
 * Returns whether the conversion from {@code source} to {@code target} type
 * is a 'loss-less' cast, that is, a cast from which
 * the original value of the field can be certainly recovered.
 *
 * <p>For instance, int &rarr; bigint is loss-less (as you can cast back to
 * int without loss of information), but bigint &rarr; int is not loss-less.
 *
 * <p>The implementation of this method does not return false positives.
 * However, it is not complete.
 * @param source source type
 * @param target target type
 * @return true iff the conversion is a loss-less cast
 */
@API(since = "1.22", status = API.Status.EXPERIMENTAL)
public static boolean isLosslessCast(RelDataType source, RelDataType target) {
  final SqlTypeName sourceSqlTypeName = source.getSqlTypeName();
  final SqlTypeName targetSqlTypeName = target.getSqlTypeName();
  // 1) Both INT numeric types
  if (SqlTypeFamily.INTEGER.getTypeNames().contains(sourceSqlTypeName)
      && SqlTypeFamily.INTEGER.getTypeNames().contains(targetSqlTypeName)) {
    return targetSqlTypeName.compareTo(sourceSqlTypeName) >= 0;
  }
  // 2) Both CHARACTER types: it depends on the precision (length)
  if (SqlTypeFamily.CHARACTER.getTypeNames().contains(sourceSqlTypeName)
      && SqlTypeFamily.CHARACTER.getTypeNames().contains(targetSqlTypeName)) {
    return targetSqlTypeName.compareTo(sourceSqlTypeName) >= 0
        && source.getPrecision() <= target.getPrecision();
  }
  // 3) From NUMERIC family to CHARACTER family: it depends on the precision/scale
  if (sourceSqlTypeName.getFamily() == SqlTypeFamily.NUMERIC
      && targetSqlTypeName.getFamily() == SqlTypeFamily.CHARACTER) {
    int sourceLength = source.getPrecision() + 1; // include sign
    if (source.getScale() != -1 && source.getScale() != 0) {
      sourceLength += source.getScale() + 1; // include decimal mark
    }
    return target.getPrecision() >= sourceLength;
  }
  // Return FALSE by default
  return false;
}
 
示例22
public SqlJsonQueryFunction() {
  super("JSON_QUERY", SqlKind.OTHER_FUNCTION,
      ReturnTypes.cascade(ReturnTypes.VARCHAR_2000,
          SqlTypeTransforms.FORCE_NULLABLE),
      null,
      OperandTypes.family(SqlTypeFamily.ANY,
          SqlTypeFamily.ANY, SqlTypeFamily.ANY, SqlTypeFamily.ANY),
      SqlFunctionCategory.SYSTEM);
}
 
示例23
private SqlSingleOperandTypeChecker getChecker(RelDataType operandType) {
  switch (operandType.getSqlTypeName()) {
  case ROW:
    return OperandTypes.family(SqlTypeFamily.STRING);
  default:
    throw new AssertionError(operandType.getSqlTypeName());
  }
}
 
示例24
/** Converts a function to a {@link org.apache.calcite.sql.SqlOperator}.
 *
 * <p>The {@code typeFactory} argument is technical debt; see [CALCITE-2082]
 * Remove RelDataTypeFactory argument from SqlUserDefinedAggFunction
 * constructor. */
private static SqlOperator toOp(RelDataTypeFactory typeFactory,
    SqlIdentifier name, final Function function) {
  List<RelDataType> argTypes = new ArrayList<>();
  List<SqlTypeFamily> typeFamilies = new ArrayList<>();
  for (FunctionParameter o : function.getParameters()) {
    final RelDataType type = o.getType(typeFactory);
    argTypes.add(type);
    typeFamilies.add(
        Util.first(type.getSqlTypeName().getFamily(), SqlTypeFamily.ANY));
  }
  final FamilyOperandTypeChecker typeChecker =
      OperandTypes.family(typeFamilies, i ->
          function.getParameters().get(i).isOptional());
  final List<RelDataType> paramTypes = toSql(typeFactory, argTypes);
  if (function instanceof ScalarFunction) {
    return new SqlUserDefinedFunction(name, infer((ScalarFunction) function),
        InferTypes.explicit(argTypes), typeChecker, paramTypes, function);
  } else if (function instanceof AggregateFunction) {
    return new SqlUserDefinedAggFunction(name,
        infer((AggregateFunction) function), InferTypes.explicit(argTypes),
        typeChecker, (AggregateFunction) function, false, false,
        Optionality.FORBIDDEN, typeFactory);
  } else if (function instanceof TableMacro) {
    return new SqlUserDefinedTableMacro(name, ReturnTypes.CURSOR,
        InferTypes.explicit(argTypes), typeChecker, paramTypes,
        (TableMacro) function);
  } else if (function instanceof TableFunction) {
    return new SqlUserDefinedTableFunction(name, ReturnTypes.CURSOR,
        InferTypes.explicit(argTypes), typeChecker, paramTypes,
        (TableFunction) function);
  } else {
    throw new AssertionError("unknown function type " + function);
  }
}
 
示例25
/**
 * Returns whether the input is a 'loss-less' cast, that is, a cast from which
 * the original value of the field can be certainly recovered.
 *
 * <p>For instance, int &rarr; bigint is loss-less (as you can cast back to
 * int without loss of information), but bigint &rarr; int is not loss-less.
 *
 * <p>The implementation of this method does not return false positives.
 * However, it is not complete.
 */
public static boolean isLosslessCast(RexNode node) {
    if (!node.isA(SqlKind.CAST)) {
        return false;
    }
    final RelDataType source = ((RexCall) node).getOperands().get(0).getType();
    final SqlTypeName sourceSqlTypeName = source.getSqlTypeName();
    final RelDataType target = node.getType();
    final SqlTypeName targetSqlTypeName = target.getSqlTypeName();
    // 1) Both INT numeric types
    if (SqlTypeFamily.INTEGER.getTypeNames().contains(sourceSqlTypeName)
            && SqlTypeFamily.INTEGER.getTypeNames().contains(targetSqlTypeName)) {
        return targetSqlTypeName.compareTo(sourceSqlTypeName) >= 0;
    }
    // 2) Both CHARACTER types: it depends on the precision (length)
    if (SqlTypeFamily.CHARACTER.getTypeNames().contains(sourceSqlTypeName)
            && SqlTypeFamily.CHARACTER.getTypeNames().contains(targetSqlTypeName)) {
        return targetSqlTypeName.compareTo(sourceSqlTypeName) >= 0
                && source.getPrecision() <= target.getPrecision();
    }
    // 3) From NUMERIC family to CHARACTER family: it depends on the precision/scale
    if (sourceSqlTypeName.getFamily() == SqlTypeFamily.NUMERIC
            && targetSqlTypeName.getFamily() == SqlTypeFamily.CHARACTER) {
        int sourceLength = source.getPrecision() + 1; // include sign
        if (source.getScale() != -1 && source.getScale() != 0) {
            sourceLength += source.getScale() + 1; // include decimal mark
        }
        return target.getPrecision() >= sourceLength;
    }
    // Return FALSE by default
    return false;
}
 
示例26
public ProctimeMaterializeSqlFunction() {
	super(
		"PROCTIME_MATERIALIZE",
		SqlKind.OTHER_FUNCTION,
		ReturnTypes.cascade(
				ReturnTypes.explicit(SqlTypeName.TIMESTAMP),
				SqlTypeTransforms.TO_NULLABLE),
		InferTypes.RETURN_TYPE,
		OperandTypes.family(SqlTypeFamily.TIMESTAMP),
		SqlFunctionCategory.SYSTEM);
}
 
示例27
public StreamRecordTimestampSqlFunction() {
	super(
		"STREAMRECORD_TIMESTAMP",
		SqlKind.OTHER_FUNCTION,
		ReturnTypes.explicit(SqlTypeName.BIGINT),
		InferTypes.RETURN_TYPE,
		OperandTypes.family(SqlTypeFamily.NUMERIC),
		SqlFunctionCategory.SYSTEM);
}
 
示例28
public boolean checkSingleOperandType(
	SqlCallBinding callBinding,
	SqlNode node,
	boolean throwOnFailure) {

	if (SqlUtil.isNullLiteral(node, false)) {
		if (throwOnFailure) {
			throw callBinding.getValidator().newValidationError(node,
				RESOURCE.nullIllegal());
		} else {
			return false;
		}
	}

	RelDataType type = callBinding.getValidator().deriveType(
		callBinding.getScope(),
		node);
	SqlTypeName typeName = type.getSqlTypeName();

	// Pass type checking for operators if it's of type 'ANY'.
	if (typeName.getFamily() == SqlTypeFamily.ANY) {
		return true;
	}

	if (!family.getTypeNames().contains(typeName)) {
		if (throwOnFailure) {
			throw callBinding.newValidationSignatureError();
		}
		return false;
	}
	return true;
}
 
示例29
SqlAggFunction createCustomAggFunction(String funcName, RelDataType returnType, Class<?> customAggFuncClz) {
    RelDataTypeFactory typeFactory = getCluster().getTypeFactory();
    SqlIdentifier sqlIdentifier = new SqlIdentifier(funcName, new SqlParserPos(1, 1));
    AggregateFunction aggFunction = AggregateFunctionImpl.create(customAggFuncClz);
    List<RelDataType> argTypes = new ArrayList<RelDataType>();
    List<SqlTypeFamily> typeFamilies = new ArrayList<SqlTypeFamily>();
    for (FunctionParameter o : aggFunction.getParameters()) {
        final RelDataType type = o.getType(typeFactory);
        argTypes.add(type);
        typeFamilies.add(Util.first(type.getSqlTypeName().getFamily(), SqlTypeFamily.ANY));
    }
    return new SqlUserDefinedAggFunction(sqlIdentifier, ReturnTypes.explicit(returnType),
            InferTypes.explicit(argTypes), OperandTypes.family(typeFamilies), aggFunction, false, false,
            typeFactory);
}
 
示例30
public RelDataType getRowType(RelDataTypeFactory factory) {

    List<RelDataType> types = Lists.newArrayList();
    List<String> names = Lists.newArrayList();

    for (FieldType field : fields) {
      names.add(field.getName());
      RelDataType type;
      if (   SqlTypeFamily.INTERVAL_YEAR_MONTH == field.getType().getFamily()
          || SqlTypeFamily.INTERVAL_DAY_TIME   == field.getType().getFamily() ) {
       type = factory.createSqlIntervalType( field.getIntervalQualifier() );
      } else if (field.getType().equals(SqlTypeName.ARRAY) || field.getType().equals(SqlTypeName.MAP)) {
        type = factory.createSqlType(SqlTypeName.ANY);
      } else if (field.getPrecision() == null && field.getScale() == null) {
        type = factory.createSqlType(field.getType());
      } else if (field.getPrecision() != null && field.getScale() == null) {
        type = factory.createSqlType(field.getType(), field.getPrecision());
      } else {
        type = factory.createSqlType(field.getType(), field.getPrecision(), field.getScale());
      }

      if (field.getIsNullable()) {
        types.add(factory.createTypeWithNullability(type, true));
      } else {
        types.add(type);
      }
    }
    return factory.createStructType(types, names);
  }