Apache Calcite Code for Dialect Conversion

  • 2021-08-31 10:01:54
  • OfStack

Definition

Calcite can realize the unification of Sql by parsing Sql into SqlNode, and then transforming SqlNode into dialect of specific database.

Realization

The main class for dialect conversion in Calcite is the SqlDialect base class, whose specific variable meanings are as follows:


public class SqlDialect {

BUILT_IN_OPERATORS_LIST:  Supported built-in defined functions or operators (for example: abs and.. ) 

//  Column   Identifier of the table 
String identifierQuoteString:     Start symbol of identifier 
String identifierEndQuoteString:  End symbol of identifier 
String identifierEscapedQuote:  (I don't know what this is doing yet, like an escape character in a string?) 

//  Identifier of constant 
String literalQuoteString:     Start symbol of constant 
String literalEndQuoteString:  End symbol of constant 
String literalEscapedQuote: (I don't know what this is doing yet, like an escape character in a string?) 

DatabaseProduct databaseProduct:  Database products to which you belong 
NullCollation nullCollation:  In order to sort the query, the return order of null values 
RelDataTypeSystem dataTypeSystem:  Data type 

//  And analytically related 
Casing unquotedCasing:  Case conversion 
Casing quotedCasing:  Case conversion 
boolean caseSensitive:  Is it case sensitive ( Column name   Indicate   Function name, etc )
}

//  Method area (different data sources implement custom replication methods according to different details) 
allowsAs
configureParser
configureParser
containsNonAscii
create
defaultNullDirection
emptyContext
emulateJoinTypeForCrossJoin
emulateNullDirection
emulateNullDirectionWithIsNull
getCalendarPolicy
getCastSpec
getConformance
getDatabaseProduct
getNullCollation
getProduct
getQuotedCasing
getQuoting
getSingleRowTableName
getTypeSystem
getUnquotedCasing
hasImplicitTableAlias
identifierNeedsQuote
isCaseSensitive
quoteIdentifier
quoteIdentifier
quoteIdentifier
quoteStringLiteral
quoteStringLiteral
quoteStringLiteralUnicode
quoteTimestampLiteral
requiresAliasForFromItems
rewriteSingleValueExpr
supportsAggregateFunction
supportsAliasedValues
supportsCharSet
supportsDataType
supportsFunction
supportsGroupByWithCube
supportsGroupByWithRollup
supportsImplicitTypeCoercion
supportsNestedAggregations
supportsOffsetFetch
supportsWindowFunctions
unparseCall
unparseDateTimeLiteral
unparseFetchUsingAnsi
unparseFetchUsingLimit
unparseLimit
unparseOffset
unparseOffsetFetch
unparseSqlDatetimeArithmetic
unparseSqlIntervalLiteral
unparseSqlIntervalQualifier
unparseTopN
unquoteStringLiteral

Usage Demo


/** Returns SqlNode for type in "cast(column as type)", which might be
  * different between databases by type name, precision etc.
  *
  * <p>If this method returns null, the cast will be omitted. In the default
  * implementation, this is the case for the NULL type, and therefore
  * {@code CAST(NULL AS <nulltype>)} is rendered as {@code NULL}. */
  public SqlNode getCastSpec(RelDataType type)

   This method can be converted according to the data type of a specific data source, for example: 

  @Override public SqlNode getCastSpec(RelDataType type) {
    switch (type.getSqlTypeName()) {
    case VARCHAR:
      // MySQL doesn't have a VARCHAR type, only CHAR.
      int vcMaxPrecision = this.getTypeSystem().getMaxPrecision(SqlTypeName.CHAR);
      int precision = type.getPrecision();
      if (vcMaxPrecision > 0 && precision > vcMaxPrecision) {
        precision = vcMaxPrecision;
      }
      return new SqlDataTypeSpec(
          new SqlBasicTypeNameSpec(SqlTypeName.CHAR, precision, SqlParserPos.ZERO),
          SqlParserPos.ZERO);
    }
    return super.getCastSpec(type);
  }

   You can pass through Sql In Cast Statement Cast For a specific type: 

  final String query = "select cast(\"product_id\" as varchar(50)), \"product_id\" "
       + "from \"product\" ";
   final String expected = "SELECT CAST(`product_id` AS CHAR(50)), `product_id`\n"
       + "FROM `foodmart`.`product`";

//  Analyzed SqlNode
sqlNode.toSqlString(CalciteSqlDialect.DEFAULT).getSql();

Related articles: