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);
}
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;
}
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();
}
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;
}
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);
}
Aggregations