com.hazelcast.org.apache.calcite.sql.SqlCollectionTypeNameSpec Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.org.apache.calcite.sql;
import com.hazelcast.org.apache.calcite.rel.type.RelDataType;
import com.hazelcast.org.apache.calcite.rel.type.RelDataTypeFactory;
import com.hazelcast.org.apache.calcite.sql.parser.SqlParserPos;
import com.hazelcast.org.apache.calcite.sql.type.SqlTypeName;
import com.hazelcast.org.apache.calcite.sql.validate.SqlValidator;
import com.hazelcast.org.apache.calcite.util.Litmus;
import com.hazelcast.org.apache.calcite.util.Util;
import java.util.Objects;
/**
* A sql type name specification of collection type.
*
* The grammar definition in SQL-2011 IWD 9075-2:201?(E)
* 6.1 <collection type> is as following:
*
* <collection type> ::=
* <array type>
* | <multiset type>
*
* <array type> ::=
* <data type> ARRAY
* [ <left bracket or trigraph>
* <maximum cardinality>
* <right bracket or trigraph> ]
*
* <maximum cardinality> ::=
* <unsigned integer>
*
* <multiset type> ::=
* <data type> MULTISET
*
*
* This class is intended to describe SQL collection type. It can describe
* either simple collection type like "int array" or nested collection type like
* "int array array" or "int array multiset". For nested collection type, the element type
* name of this {@code SqlCollectionTypeNameSpec} is also a {@code SqlCollectionTypeNameSpec}.
*/
public class SqlCollectionTypeNameSpec extends SqlTypeNameSpec {
private final SqlTypeNameSpec elementTypeName;
private final SqlTypeName collectionTypeName;
/**
* Creates a {@code SqlCollectionTypeNameSpec}.
*
* @param elementTypeName Type of the collection element
* @param collectionTypeName Collection type name
* @param pos Parser position, must not be null
*/
public SqlCollectionTypeNameSpec(SqlTypeNameSpec elementTypeName,
SqlTypeName collectionTypeName,
SqlParserPos pos) {
super(new SqlIdentifier(collectionTypeName.name(), pos), pos);
this.elementTypeName = Objects.requireNonNull(elementTypeName);
this.collectionTypeName = Objects.requireNonNull(collectionTypeName);
}
public SqlTypeNameSpec getElementTypeName() {
return elementTypeName;
}
@Override public RelDataType deriveType(SqlValidator validator) {
final RelDataType type = elementTypeName.deriveType(validator);
return createCollectionType(type, validator.getTypeFactory());
}
@Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
elementTypeName.unparse(writer, leftPrec, rightPrec);
writer.keyword(collectionTypeName.name());
}
@Override public boolean equalsDeep(SqlTypeNameSpec spec, Litmus litmus) {
if (!(spec instanceof SqlCollectionTypeNameSpec)) {
return litmus.fail("{} != {}", this, spec);
}
SqlCollectionTypeNameSpec that = (SqlCollectionTypeNameSpec) spec;
if (!this.elementTypeName.equalsDeep(that.elementTypeName, litmus)) {
return litmus.fail("{} != {}", this, spec);
}
if (!Objects.equals(this.collectionTypeName, that.collectionTypeName)) {
return litmus.fail("{} != {}", this, spec);
}
return litmus.succeed();
}
//~ Tools ------------------------------------------------------------------
/**
* Create collection data type.
*
* @param elementType Type of the collection element
* @param typeFactory Type factory
* @return The collection data type, or throw exception if the collection
* type name does not belong to {@code SqlTypeName} enumerations
*/
private RelDataType createCollectionType(RelDataType elementType,
RelDataTypeFactory typeFactory) {
switch (collectionTypeName) {
case MULTISET:
return typeFactory.createMultisetType(elementType, -1);
case ARRAY:
return typeFactory.createArrayType(elementType, -1);
default:
throw Util.unexpected(collectionTypeName);
}
}
}