All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.sql.SqlBasicTypeNameSpec Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * 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 com.hazelcast.com.liance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.com.hazelcast.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.type.SqlTypeUtil;
import com.hazelcast.org.apache.calcite.sql.validate.SqlValidator;
import com.hazelcast.org.apache.calcite.util.Litmus;

import java.nio.charset.Charset;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * A sql type name specification of basic sql type.
 *
 * 

Supported basic sql types grammar: *

 *   basicSqlType:
 *         GEOMETRY
 *     |   BOOLEAN
 *     |   [ INTEGER | INT ]
 *     |   TINYINT
 *     |   SMALLINT
 *     |   BIGINT
 *     |   REAL
 *     |   DOUBLE [ PRECISION ]
 *     |   FLOAT
 *     |   BINARY [ precision ]
 *     |   [ BINARY VARYING | VARBINARY ] [ precision ]
 *     |   [ DECIMAL | DEC | NUMERIC ] [ precision [, scale] ]
 *     |   ANY [ precision [, scale] ]
 *     |   charType [ precision ] [ charSet ]
 *     |   varcharType [ precision ] [ charSet ]
 *     |   DATE
 *     |   TIME [ precision ] [ timeZone ]
 *     |   TIMESTAMP [ precision ] [ timeZone ]
 *
 *  charType:
 *         CHARACTER
 *     |   CHAR
 *
 *  varcharType:
 *         charType VARYING
 *     |   VARCHAR
 *
 *  charSet:
 *         CHARACTER SET charSetName
 *
 *  timeZone:
 *         WITHOUT TIME ZONE
 *     |   WITH LOCAL TIME ZONE
 * 
*/ public class SqlBasicTypeNameSpec extends SqlTypeNameSpec { private final SqlTypeName sqlTypeName; private int precision; private int scale; private String charSetName; /** * Create a basic sql type name specification. * * @param typeName Type name * @param precision Precision of the type name if it is allowed, default is -1 * @param scale Scale of the type name if it is allowed, default is -1 * @param charSetName Char set of the type, only works when the type * belong to CHARACTER type family * @param pos The parser position */ public SqlBasicTypeNameSpec( SqlTypeName typeName, int precision, int scale, @Nullable String charSetName, SqlParserPos pos) { super(new SqlIdentifier(typeName.name(), pos), pos); this.sqlTypeName = typeName; this.precision = precision; this.scale = scale; this.charSetName = charSetName; } public SqlBasicTypeNameSpec(SqlTypeName typeName, SqlParserPos pos) { this(typeName, -1, -1, null, pos); } public SqlBasicTypeNameSpec(SqlTypeName typeName, int precision, SqlParserPos pos) { this(typeName, precision, -1, null, pos); } public SqlBasicTypeNameSpec(SqlTypeName typeName, int precision, String charSetName, SqlParserPos pos) { this(typeName, precision, -1, charSetName, pos); } public SqlBasicTypeNameSpec(SqlTypeName typeName, int precision, int scale, SqlParserPos pos) { this(typeName, precision, scale, null, pos); } public int getScale() { return scale; } public int getPrecision() { return precision; } public String getCharSetName() { return charSetName; } @Override public boolean equalsDeep(SqlTypeNameSpec node, Litmus litmus) { if (!(node instanceof SqlBasicTypeNameSpec)) { return litmus.fail("{} != {}", this, node); } SqlBasicTypeNameSpec that = (SqlBasicTypeNameSpec) node; if (this.sqlTypeName != that.sqlTypeName) { return litmus.fail("{} != {}", this, node); } if (this.precision != that.precision) { return litmus.fail("{} != {}", this, node); } if (this.scale != that.scale) { return litmus.fail("{} != {}", this, node); } if (!Objects.equals(this.charSetName, that.charSetName)) { return litmus.fail("{} != {}", this, node); } return litmus.succeed(); } @Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { // Unparse the builtin type name. // For some type name with extra definitions, unparse it specifically // instead of direct unparsing with enum name. // i.e. TIME_WITH_LOCAL_TIME_ZONE(3) // would be unparsed as "time(3) with local time zone". final boolean isWithLocalTimeZone = isWithLocalTimeZoneDef(sqlTypeName); if (isWithLocalTimeZone) { writer.keyword(stripLocalTimeZoneDef(sqlTypeName).name()); } else { writer.keyword(getTypeName().getSimple()); } if (sqlTypeName.allowsPrec() && (precision >= 0)) { final SqlWriter.Frame frame = writer.startList(SqlWriter.FrameTypeEnum.FUN_CALL, "(", ")"); writer.print(precision); if (sqlTypeName.allowsScale() && (scale >= 0)) { writer.sep(",", true); writer.print(scale); } writer.endList(frame); } if (isWithLocalTimeZone) { writer.keyword("WITH LOCAL TIME ZONE"); } if (charSetName != null) { writer.keyword("CHARACTER SET"); writer.identifier(charSetName, true); } } @Override public RelDataType deriveType(SqlValidator validator) { final RelDataTypeFactory typeFactory = validator.getTypeFactory(); if (sqlTypeName == null) { return null; } RelDataType type; // NOTE jvs 15-Jan-2009: earlier validation is supposed to // have caught these, which is why it's OK for them // to be assertions rather than user-level exceptions. if ((precision >= 0) && (scale >= 0)) { assert sqlTypeName.allowsPrecScale(true, true); type = typeFactory.createSqlType(sqlTypeName, precision, scale); } else if (precision >= 0) { assert sqlTypeName.allowsPrecNoScale(); type = typeFactory.createSqlType(sqlTypeName, precision); } else { assert sqlTypeName.allowsNoPrecNoScale(); type = typeFactory.createSqlType(sqlTypeName); } if (SqlTypeUtil.inCharFamily(type)) { // Applying Syntax rule 10 from SQL:99 spec section 6.22 "If TD is a // fixed-length, variable-length or large object character string, // then the collating sequence of the result of the is the default collating sequence for the // character repertoire of TD and the result of the has the Coercible coercibility characteristic." SqlCollation collation = SqlCollation.COERCIBLE; Charset charset; if (null == this.charSetName) { charset = typeFactory.getDefaultCharset(); } else { String javaCharSetName = Objects.requireNonNull( SqlUtil.translateCharacterSetName(charSetName), charSetName); charset = Charset.forName(javaCharSetName); } type = typeFactory.createTypeWithCharsetAndCollation( type, charset, collation); } return type; } //~ Tools ------------------------------------------------------------------ /** * @return true if this type name has "local time zone" definition. */ private static boolean isWithLocalTimeZoneDef(SqlTypeName typeName) { switch (typeName) { case TIME_WITH_LOCAL_TIME_ZONE: case TIMESTAMP_WITH_LOCAL_TIME_ZONE: return true; default: return false; } } /** * Remove the local time zone definition of the {@code typeName}. * * @param typeName Type name * @return new type name without local time zone definition */ private SqlTypeName stripLocalTimeZoneDef(SqlTypeName typeName) { switch (typeName) { case TIME_WITH_LOCAL_TIME_ZONE: return SqlTypeName.TIME; case TIMESTAMP_WITH_LOCAL_TIME_ZONE: return SqlTypeName.TIMESTAMP; default: throw new AssertionError(typeName); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy