blob: 3a534b2eb8cebad9481da13cbb54d6ea13b797ba [file] [log] [blame]
/*
* 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.spark.sql.catalyst.plans.logical
import org.apache.spark.sql.catalyst.analysis.ViewType
import org.apache.spark.sql.catalyst.catalog.{BucketSpec, FunctionResource}
import org.apache.spark.sql.catalyst.catalog.CatalogTypes.TablePartitionSpec
import org.apache.spark.sql.catalyst.expressions.Attribute
import org.apache.spark.sql.connector.catalog.TableChange.ColumnPosition
import org.apache.spark.sql.connector.expressions.Transform
import org.apache.spark.sql.types.{DataType, StructType}
/**
* A logical plan node that contains exactly what was parsed from SQL.
*
* This is used to hold information parsed from SQL when there are multiple implementations of a
* query or command. For example, CREATE TABLE may be implemented by different nodes for v1 and v2.
* Instead of parsing directly to a v1 CreateTable that keeps metadata in CatalogTable, and then
* converting that v1 metadata to the v2 equivalent, the sql [[CreateTableStatement]] plan is
* produced by the parser and converted once into both implementations.
*
* Parsed logical plans are not resolved because they must be converted to concrete logical plans.
*
* Parsed logical plans are located in Catalyst so that as much SQL parsing logic as possible is be
* kept in a [[org.apache.spark.sql.catalyst.parser.AbstractSqlParser]].
*/
abstract class ParsedStatement extends LogicalPlan {
// Redact properties and options when parsed nodes are used by generic methods like toString
override def productIterator: Iterator[Any] = super.productIterator.map {
case mapArg: Map[_, _] => conf.redactOptions(mapArg)
case other => other
}
override def output: Seq[Attribute] = Seq.empty
override def children: Seq[LogicalPlan] = Seq.empty
final override lazy val resolved = false
}
/**
* A CREATE TABLE command, as parsed from SQL.
*
* This is a metadata-only command and is not used to write data to the created table.
*/
case class CreateTableStatement(
tableName: Seq[String],
tableSchema: StructType,
partitioning: Seq[Transform],
bucketSpec: Option[BucketSpec],
properties: Map[String, String],
provider: Option[String],
options: Map[String, String],
location: Option[String],
comment: Option[String],
ifNotExists: Boolean) extends ParsedStatement
/**
* A CREATE TABLE AS SELECT command, as parsed from SQL.
*/
case class CreateTableAsSelectStatement(
tableName: Seq[String],
asSelect: LogicalPlan,
partitioning: Seq[Transform],
bucketSpec: Option[BucketSpec],
properties: Map[String, String],
provider: Option[String],
options: Map[String, String],
location: Option[String],
comment: Option[String],
writeOptions: Map[String, String],
ifNotExists: Boolean) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(asSelect)
}
/**
* A CREATE VIEW statement, as parsed from SQL.
*/
case class CreateViewStatement(
viewName: Seq[String],
userSpecifiedColumns: Seq[(String, Option[String])],
comment: Option[String],
properties: Map[String, String],
originalText: Option[String],
child: LogicalPlan,
allowExisting: Boolean,
replace: Boolean,
viewType: ViewType) extends ParsedStatement
/**
* A REPLACE TABLE command, as parsed from SQL.
*
* If the table exists prior to running this command, executing this statement
* will replace the table's metadata and clear the underlying rows from the table.
*/
case class ReplaceTableStatement(
tableName: Seq[String],
tableSchema: StructType,
partitioning: Seq[Transform],
bucketSpec: Option[BucketSpec],
properties: Map[String, String],
provider: Option[String],
options: Map[String, String],
location: Option[String],
comment: Option[String],
orCreate: Boolean) extends ParsedStatement
/**
* A REPLACE TABLE AS SELECT command, as parsed from SQL.
*/
case class ReplaceTableAsSelectStatement(
tableName: Seq[String],
asSelect: LogicalPlan,
partitioning: Seq[Transform],
bucketSpec: Option[BucketSpec],
properties: Map[String, String],
provider: Option[String],
options: Map[String, String],
location: Option[String],
comment: Option[String],
writeOptions: Map[String, String],
orCreate: Boolean) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(asSelect)
}
/**
* Column data as parsed by ALTER TABLE ... ADD COLUMNS.
*/
case class QualifiedColType(
name: Seq[String],
dataType: DataType,
nullable: Boolean,
comment: Option[String],
position: Option[ColumnPosition])
/**
* ALTER TABLE ... ADD COLUMNS command, as parsed from SQL.
*/
case class AlterTableAddColumnsStatement(
tableName: Seq[String],
columnsToAdd: Seq[QualifiedColType]) extends ParsedStatement
case class AlterTableReplaceColumnsStatement(
tableName: Seq[String],
columnsToAdd: Seq[QualifiedColType]) extends ParsedStatement
/**
* ALTER TABLE ... CHANGE COLUMN command, as parsed from SQL.
*/
case class AlterTableAlterColumnStatement(
tableName: Seq[String],
column: Seq[String],
dataType: Option[DataType],
nullable: Option[Boolean],
comment: Option[String],
position: Option[ColumnPosition]) extends ParsedStatement
/**
* ALTER TABLE ... RENAME COLUMN command, as parsed from SQL.
*/
case class AlterTableRenameColumnStatement(
tableName: Seq[String],
column: Seq[String],
newName: String) extends ParsedStatement
/**
* ALTER TABLE ... DROP COLUMNS command, as parsed from SQL.
*/
case class AlterTableDropColumnsStatement(
tableName: Seq[String],
columnsToDrop: Seq[Seq[String]]) extends ParsedStatement
/**
* ALTER TABLE ... SET TBLPROPERTIES command, as parsed from SQL.
*/
case class AlterTableSetPropertiesStatement(
tableName: Seq[String],
properties: Map[String, String]) extends ParsedStatement
/**
* ALTER TABLE ... UNSET TBLPROPERTIES command, as parsed from SQL.
*/
case class AlterTableUnsetPropertiesStatement(
tableName: Seq[String],
propertyKeys: Seq[String],
ifExists: Boolean) extends ParsedStatement
/**
* ALTER TABLE ... SET LOCATION command, as parsed from SQL.
*/
case class AlterTableSetLocationStatement(
tableName: Seq[String],
partitionSpec: Option[TablePartitionSpec],
location: String) extends ParsedStatement
/**
* ALTER TABLE ... RECOVER PARTITIONS command, as parsed from SQL.
*/
case class AlterTableRecoverPartitionsStatement(
tableName: Seq[String]) extends ParsedStatement
/**
* ALTER TABLE ... ADD PARTITION command, as parsed from SQL
*/
case class AlterTableAddPartitionStatement(
tableName: Seq[String],
partitionSpecsAndLocs: Seq[(TablePartitionSpec, Option[String])],
ifNotExists: Boolean) extends ParsedStatement
/**
* ALTER TABLE ... RENAME PARTITION command, as parsed from SQL.
*/
case class AlterTableRenamePartitionStatement(
tableName: Seq[String],
from: TablePartitionSpec,
to: TablePartitionSpec) extends ParsedStatement
/**
* ALTER TABLE ... DROP PARTITION command, as parsed from SQL
*/
case class AlterTableDropPartitionStatement(
tableName: Seq[String],
specs: Seq[TablePartitionSpec],
ifExists: Boolean,
purge: Boolean,
retainData: Boolean) extends ParsedStatement
/**
* ALTER TABLE ... SERDEPROPERTIES command, as parsed from SQL
*/
case class AlterTableSerDePropertiesStatement(
tableName: Seq[String],
serdeClassName: Option[String],
serdeProperties: Option[Map[String, String]],
partitionSpec: Option[TablePartitionSpec]) extends ParsedStatement
/**
* ALTER VIEW ... SET TBLPROPERTIES command, as parsed from SQL.
*/
case class AlterViewSetPropertiesStatement(
viewName: Seq[String],
properties: Map[String, String]) extends ParsedStatement
/**
* ALTER VIEW ... UNSET TBLPROPERTIES command, as parsed from SQL.
*/
case class AlterViewUnsetPropertiesStatement(
viewName: Seq[String],
propertyKeys: Seq[String],
ifExists: Boolean) extends ParsedStatement
/**
* ALTER VIEW ... Query command, as parsed from SQL.
*/
case class AlterViewAsStatement(
viewName: Seq[String],
originalText: String,
query: LogicalPlan) extends ParsedStatement
/**
* ALTER TABLE ... RENAME TO command, as parsed from SQL.
*/
case class RenameTableStatement(
oldName: Seq[String],
newName: Seq[String],
isView: Boolean) extends ParsedStatement
/**
* A DROP VIEW statement, as parsed from SQL.
*/
case class DropViewStatement(
viewName: Seq[String],
ifExists: Boolean) extends ParsedStatement
/**
* An INSERT INTO statement, as parsed from SQL.
*
* @param table the logical plan representing the table.
* @param query the logical plan representing data to write to.
* @param overwrite overwrite existing table or partitions.
* @param partitionSpec a map from the partition key to the partition value (optional).
* If the value is missing, dynamic partition insert will be performed.
* As an example, `INSERT INTO tbl PARTITION (a=1, b=2) AS` would have
* Map('a' -> Some('1'), 'b' -> Some('2')),
* and `INSERT INTO tbl PARTITION (a=1, b) AS ...`
* would have Map('a' -> Some('1'), 'b' -> None).
* @param ifPartitionNotExists If true, only write if the partition does not exist.
* Only valid for static partitions.
*/
case class InsertIntoStatement(
table: LogicalPlan,
partitionSpec: Map[String, Option[String]],
query: LogicalPlan,
overwrite: Boolean,
ifPartitionNotExists: Boolean) extends ParsedStatement {
require(overwrite || !ifPartitionNotExists,
"IF NOT EXISTS is only valid in INSERT OVERWRITE")
require(partitionSpec.values.forall(_.nonEmpty) || !ifPartitionNotExists,
"IF NOT EXISTS is only valid with static partitions")
override def children: Seq[LogicalPlan] = query :: Nil
}
/**
* A SHOW TABLE EXTENDED statement, as parsed from SQL.
*/
case class ShowTableStatement(
namespace: Option[Seq[String]],
pattern: String,
partitionSpec: Option[TablePartitionSpec])
extends ParsedStatement
/**
* A CREATE NAMESPACE statement, as parsed from SQL.
*/
case class CreateNamespaceStatement(
namespace: Seq[String],
ifNotExists: Boolean,
properties: Map[String, String]) extends ParsedStatement
/**
* A USE statement, as parsed from SQL.
*/
case class UseStatement(isNamespaceSet: Boolean, nameParts: Seq[String]) extends ParsedStatement
/**
* An ANALYZE TABLE statement, as parsed from SQL.
*/
case class AnalyzeTableStatement(
tableName: Seq[String],
partitionSpec: Map[String, Option[String]],
noScan: Boolean) extends ParsedStatement
/**
* An ANALYZE TABLE FOR COLUMNS statement, as parsed from SQL.
*/
case class AnalyzeColumnStatement(
tableName: Seq[String],
columnNames: Option[Seq[String]],
allColumns: Boolean) extends ParsedStatement {
require(columnNames.isDefined ^ allColumns, "Parameter `columnNames` or `allColumns` are " +
"mutually exclusive. Only one of them should be specified.")
}
/**
* A REPAIR TABLE statement, as parsed from SQL
*/
case class RepairTableStatement(tableName: Seq[String]) extends ParsedStatement
/**
* A LOAD DATA INTO TABLE statement, as parsed from SQL
*/
case class LoadDataStatement(
tableName: Seq[String],
path: String,
isLocal: Boolean,
isOverwrite: Boolean,
partition: Option[TablePartitionSpec]) extends ParsedStatement
/**
* A SHOW CREATE TABLE statement, as parsed from SQL.
*/
case class ShowCreateTableStatement(
tableName: Seq[String],
asSerde: Boolean = false) extends ParsedStatement
/**
* A CACHE TABLE statement, as parsed from SQL
*/
case class CacheTableStatement(
tableName: Seq[String],
plan: Option[LogicalPlan],
isLazy: Boolean,
options: Map[String, String]) extends ParsedStatement
/**
* An UNCACHE TABLE statement, as parsed from SQL
*/
case class UncacheTableStatement(
tableName: Seq[String],
ifExists: Boolean) extends ParsedStatement
/**
* A TRUNCATE TABLE statement, as parsed from SQL
*/
case class TruncateTableStatement(
tableName: Seq[String],
partitionSpec: Option[TablePartitionSpec]) extends ParsedStatement
/**
* A SHOW PARTITIONS statement, as parsed from SQL
*/
case class ShowPartitionsStatement(
tableName: Seq[String],
partitionSpec: Option[TablePartitionSpec]) extends ParsedStatement
/**
* A SHOW COLUMNS statement, as parsed from SQL
*/
case class ShowColumnsStatement(
table: Seq[String],
namespace: Option[Seq[String]]) extends ParsedStatement
/**
* A SHOW CURRENT NAMESPACE statement, as parsed from SQL
*/
case class ShowCurrentNamespaceStatement() extends ParsedStatement
/**
* CREATE FUNCTION statement, as parsed from SQL
*/
case class CreateFunctionStatement(
functionName: Seq[String],
className: String,
resources: Seq[FunctionResource],
isTemp: Boolean,
ignoreIfExists: Boolean,
replace: Boolean) extends ParsedStatement