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

org.apache.flink.table.planner.calcite.CalciteConfig.scala 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 org.apache.flink.table.planner.calcite

import org.apache.flink.table.api.PlannerConfig
import org.apache.flink.table.planner.plan.optimize.program.{BatchOptimizeContext, FlinkChainedProgram, StreamOptimizeContext}
import org.apache.flink.util.Preconditions

import org.apache.calcite.config.{CalciteConnectionConfig, CalciteConnectionConfigImpl, CalciteConnectionProperty}
import org.apache.calcite.sql.SqlOperatorTable
import org.apache.calcite.sql.parser.SqlParser
import org.apache.calcite.sql.util.SqlOperatorTables
import org.apache.calcite.sql2rel.SqlToRelConverter

import java.util.Properties

/**
  * Builder for creating a Calcite configuration.
  */
class CalciteConfigBuilder {

  /**
    * Defines the optimize program for batch table plan.
    */
  private var batchProgram: Option[FlinkChainedProgram[BatchOptimizeContext]] = None

  /**
    * Defines the optimize program for stream table plan.
    */
  private var streamProgram: Option[FlinkChainedProgram[StreamOptimizeContext]] = None

  /**
    * Defines the SQL operator tables.
    */
  private var replaceOperatorTable: Boolean = false
  private var operatorTables: List[SqlOperatorTable] = Nil

  /**
    * Defines a SQL parser configuration.
    */
  private var replaceSqlParserConfig: Option[SqlParser.Config] = None

  /**
    * Defines a configuration for SqlToRelConverter.
    */
  private var replaceSqlToRelConverterConfig: Option[SqlToRelConverter.Config] = None

  /**
    * Replaces the default batch table optimize program with the given program.
    */
  def replaceBatchProgram(
      program: FlinkChainedProgram[BatchOptimizeContext]): CalciteConfigBuilder = {
    Preconditions.checkNotNull(program)
    batchProgram = Some(program)
    this
  }

  /**
    * Replaces the default stream table optimize program with the given program.
    */
  def replaceStreamProgram(
      program: FlinkChainedProgram[StreamOptimizeContext]): CalciteConfigBuilder = {
    Preconditions.checkNotNull(program)
    streamProgram = Some(program)
    this
  }

  /**
    * Replaces the built-in SQL operator table with the given table.
    */
  def replaceSqlOperatorTable(replaceSqlOperatorTable: SqlOperatorTable): CalciteConfigBuilder = {
    Preconditions.checkNotNull(replaceSqlOperatorTable)
    operatorTables = List(replaceSqlOperatorTable)
    replaceOperatorTable = true
    this
  }

  /**
    * Appends the given table to the built-in SQL operator table.
    */
  def addSqlOperatorTable(addedSqlOperatorTable: SqlOperatorTable): CalciteConfigBuilder = {
    Preconditions.checkNotNull(addedSqlOperatorTable)
    this.operatorTables = addedSqlOperatorTable :: this.operatorTables
    this
  }

  /**
    * Replaces the built-in SQL parser configuration with the given configuration.
    */
  def replaceSqlParserConfig(sqlParserConfig: SqlParser.Config): CalciteConfigBuilder = {
    Preconditions.checkNotNull(sqlParserConfig)
    replaceSqlParserConfig = Some(sqlParserConfig)
    this
  }

  def replaceSqlToRelConverterConfig(config: SqlToRelConverter.Config): CalciteConfigBuilder = {
    Preconditions.checkNotNull(config)
    replaceSqlToRelConverterConfig = Some(config)
    this
  }

  private class CalciteConfigImpl(
      val getBatchProgram: Option[FlinkChainedProgram[BatchOptimizeContext]],
      val getStreamProgram: Option[FlinkChainedProgram[StreamOptimizeContext]],
      val getSqlOperatorTable: Option[SqlOperatorTable],
      val replacesSqlOperatorTable: Boolean,
      val getSqlParserConfig: Option[SqlParser.Config],
      val getSqlToRelConverterConfig: Option[SqlToRelConverter.Config])
    extends CalciteConfig {

  }

  /**
    * Builds a new [[CalciteConfig]].
    */
  def build(): CalciteConfig = new CalciteConfigImpl(
    batchProgram,
    streamProgram,
    operatorTables match {
      case Nil => None
      case h :: Nil => Some(h)
      case _ =>
        // chain operator tables
        Some(operatorTables.reduce((x, y) => SqlOperatorTables.chain(x, y)))
    },
    this.replaceOperatorTable,
    replaceSqlParserConfig,
    replaceSqlToRelConverterConfig)
}

/**
  * Calcite configuration for defining a custom Calcite configuration for Table and SQL API.
  */
trait CalciteConfig extends PlannerConfig {

  /**
    * Returns a custom batch table optimize program
    */
  def getBatchProgram: Option[FlinkChainedProgram[BatchOptimizeContext]]

  /**
    * Returns a custom stream table optimize program.
    */
  def getStreamProgram: Option[FlinkChainedProgram[StreamOptimizeContext]]

  /**
    * Returns whether this configuration replaces the built-in SQL operator table.
    */
  def replacesSqlOperatorTable: Boolean

  /**
    * Returns a custom SQL operator table.
    */
  def getSqlOperatorTable: Option[SqlOperatorTable]

  /**
    * Returns a custom SQL parser configuration.
    */
  def getSqlParserConfig: Option[SqlParser.Config]

  /**
    * Returns a custom configuration for SqlToRelConverter.
    */
  def getSqlToRelConverterConfig: Option[SqlToRelConverter.Config]
}

object CalciteConfig {

  val DEFAULT: CalciteConfig = createBuilder().build()

  /**
    * Creates a new builder for constructing a [[CalciteConfig]].
    */
  def createBuilder(): CalciteConfigBuilder = {
    new CalciteConfigBuilder
  }

  /**
    * Creates a new builder for constructing a [[CalciteConfig]] based on a given [[CalciteConfig]].
    */
  def createBuilder(calciteConfig: CalciteConfig): CalciteConfigBuilder = {
    val builder = new CalciteConfigBuilder
    if (calciteConfig.getBatchProgram.isDefined) {
      builder.replaceBatchProgram(calciteConfig.getBatchProgram.get)
    }
    if (calciteConfig.getStreamProgram.isDefined) {
      builder.replaceStreamProgram(calciteConfig.getStreamProgram.get)
    }
    if (calciteConfig.getSqlOperatorTable.isDefined) {
      if (calciteConfig.replacesSqlOperatorTable) {
        builder.replaceSqlOperatorTable(calciteConfig.getSqlOperatorTable.get)
      } else {
        builder.addSqlOperatorTable(calciteConfig.getSqlOperatorTable.get)
      }
    }
    if (calciteConfig.getSqlParserConfig.isDefined) {
      builder.replaceSqlParserConfig(calciteConfig.getSqlParserConfig.get)
    }
    if (calciteConfig.getSqlToRelConverterConfig.isDefined) {
      builder.replaceSqlToRelConverterConfig(calciteConfig.getSqlToRelConverterConfig.get)
    }

    builder
  }

  def connectionConfig(parserConfig: SqlParser.Config): CalciteConnectionConfig = {
    val prop = new Properties()
    prop.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName,
      String.valueOf(parserConfig.caseSensitive))
    new CalciteConnectionConfigImpl(prop)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy