Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a005713
[SPARK-30214][SQL] Support COMMENT ON syntax
yaooqinn Dec 11, 2019
7c45c9b
naming
yaooqinn Dec 11, 2019
024ab39
Merge branch 'master' into SPARK-30214
yaooqinn Dec 11, 2019
e489e62
fix tests
yaooqinn Dec 11, 2019
9b272b6
comments
yaooqinn Dec 11, 2019
85617cd
impl UnresolvedNamespace
yaooqinn Dec 17, 2019
e33a200
megre master
yaooqinn Dec 17, 2019
3e37941
impl UnresolvedV2Table
yaooqinn Dec 17, 2019
7df9407
Merge branch 'master' into SPARK-30214
yaooqinn Dec 17, 2019
57c83fc
rm parent node
yaooqinn Dec 19, 2019
ccc4702
create namespace
yaooqinn Dec 19, 2019
72c01a9
drop namespace
yaooqinn Dec 20, 2019
1a7c800
set namespace props
yaooqinn Dec 20, 2019
415de11
set namespace location
yaooqinn Dec 20, 2019
6ab2228
desc namespace
yaooqinn Dec 20, 2019
56037ff
show current namespace
yaooqinn Dec 20, 2019
6675e7f
Revert "show current namespace"
yaooqinn Dec 20, 2019
a42e12e
Revert "desc namespace"
yaooqinn Dec 20, 2019
2c458f0
Revert "set namespace location"
yaooqinn Dec 20, 2019
573a66e
Revert "set namespace props"
yaooqinn Dec 20, 2019
f6e742b
Revert "drop namespace"
yaooqinn Dec 20, 2019
0754656
Revert "create namespace"
yaooqinn Dec 20, 2019
a868420
ident -> NamedRelation
yaooqinn Dec 20, 2019
5a6aa2a
add ident
yaooqinn Dec 20, 2019
0b89d3a
resovledtable should lookup view => v2 -> v1
yaooqinn Dec 20, 2019
a41acc5
ref
yaooqinn Dec 27, 2019
de054c7
add DataSourceV1Relation
yaooqinn Dec 27, 2019
e0836f6
Revert "add DataSourceV1Relation"
yaooqinn Dec 27, 2019
fc555be
handle view in analyzer
yaooqinn Dec 27, 2019
7b4f3e3
nit in tests
yaooqinn Dec 27, 2019
9f2159f
Merge branch 'master' into SPARK-30214
yaooqinn Dec 30, 2019
70028dd
update
yaooqinn Dec 30, 2019
9d10239
nit
yaooqinn Dec 31, 2019
c391212
fix test
yaooqinn Dec 31, 2019
d20b1b2
Merge branch 'master' into SPARK-30214
yaooqinn Jan 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ statement
| (DESC | DESCRIBE) TABLE? option=(EXTENDED | FORMATTED)?
multipartIdentifier partitionSpec? describeColName? #describeTable
| (DESC | DESCRIBE) QUERY? query #describeQuery
| COMMENT ON (database | NAMESPACE) multipartIdentifier IS

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not related to this PR, but I have seen (database | NAMESPACE) too many times.

Maybe we should have a

namespace: DATABASE | SCHEME | NAMESPACE

and use namespace directly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created #27027 for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! merged

commennt=(STRING | NULL) #commentNamespace
| COMMENT ON TABLE multipartIdentifier IS commennt=(STRING | NULL) #commentTable
| REFRESH TABLE multipartIdentifier #refreshTable
| REFRESH (STRING | .*?) #refreshResource
| CACHE LAZY? TABLE multipartIdentifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class Analyzer(
new SubstituteUnresolvedOrdinals(conf)),
Batch("Resolution", fixedPoint,
ResolveTableValuedFunctions ::
ResolveCatalogsToV2(catalogManager) ::
new ResolveCatalogs(catalogManager) ::
ResolveInsertInto ::
ResolveRelations ::
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.analysis

import org.apache.spark.sql.catalyst.expressions.Attribute
import org.apache.spark.sql.catalyst.plans.logical.LeafNode
import org.apache.spark.sql.connector.catalog.SupportsNamespaces

trait NamespaceNode extends LeafNode {
Comment thread
yaooqinn marked this conversation as resolved.
Outdated
override def output: Seq[Attribute] = Nil
def catalog: SupportsNamespaces
def namespace: Seq[String]
}

case class ResolvedNamespace(catalog: SupportsNamespaces, namespace: Seq[String])
extends NamespaceNode

case class UnresolvedNamespace(multipartIdentifier: Seq[String]) extends NamespaceNode {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, we should give nice error message in CheckAnalysis when we hit UnresolvedNamespace and UnresolvedV2Table.

override lazy val resolved: Boolean = false

override def catalog: SupportsNamespaces = throw new UnresolvedException(this, "catalog")

override def namespace: Seq[String] = throw new UnresolvedException(this, "namespace")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.analysis

import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
import org.apache.spark.sql.catalyst.rules.Rule
import org.apache.spark.sql.connector.catalog.{CatalogManager, CatalogV2Util, LookupCatalog}
import org.apache.spark.sql.connector.catalog.CatalogV2Implicits._

case class ResolveCatalogsToV2(catalogManager: CatalogManager)

@cloud-fan cloud-fan Dec 18, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about ResolveNamespaceAndTable

extends Rule[LogicalPlan] with LookupCatalog {
override def apply(plan: LogicalPlan): LogicalPlan = plan resolveOperators {
case UnresolvedNamespace(CatalogAndNamespace(catalog, ns)) =>
ResolvedNamespace(catalog.asNamespaceCatalog, ns)

case u @ UnresolvedV2Table(CatalogAndIdentifier(catalog, ident)) =>
CatalogV2Util.loadRelation(catalog, ident).map { _ =>
ResolvedV2Table(catalog.asTableCatalog, ident)
}.getOrElse(u)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.analysis

import org.apache.spark.sql.catalyst.expressions.Attribute
import org.apache.spark.sql.catalyst.plans.logical.LeafNode
import org.apache.spark.sql.connector.catalog.{Identifier, TableCatalog}

trait TableNode extends LeafNode {
Comment thread
yaooqinn marked this conversation as resolved.
Outdated
override def output: Seq[Attribute] = Nil
def catalog: TableCatalog
def tableIdentifier: Identifier
}

case class ResolvedV2Table(catalog: TableCatalog, tableIdentifier: Identifier)
Comment thread
yaooqinn marked this conversation as resolved.
Outdated
extends TableNode

case class UnresolvedV2Table(multipartIdentifier: Seq[String]) extends TableNode {
override lazy val resolved: Boolean = false

override def catalog: TableCatalog = throw new UnresolvedException(this, "catalog")

override def tableIdentifier: Identifier = throw new UnresolvedException(this, "tableIdentifier")
}
Original file line number Diff line number Diff line change
Expand Up @@ -3410,4 +3410,21 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
ctx.EXISTS != null,
ctx.TEMPORARY != null)
}

override def visitCommentNamespace(ctx: CommentNamespaceContext): LogicalPlan = withOrigin(ctx) {
val comment = ctx.commennt.getType match {
case SqlBaseParser.NULL => ""
Comment thread
cloud-fan marked this conversation as resolved.
case _ => string(ctx.STRING)
}
CommentOnNamespace(UnresolvedNamespace(visitMultipartIdentifier(ctx.multipartIdentifier)),
Comment thread
yaooqinn marked this conversation as resolved.
Outdated
comment)
}

override def visitCommentTable(ctx: CommentTableContext): LogicalPlan = withOrigin(ctx) {
val comment = ctx.commennt.getType match {
case SqlBaseParser.NULL => ""
case _ => string(ctx.STRING)
}
CommentOnTable(UnresolvedV2Table(visitMultipartIdentifier(ctx.multipartIdentifier)), comment)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package org.apache.spark.sql.catalyst.plans.logical

import org.apache.spark.sql.catalyst.analysis.{NamedRelation, Star, UnresolvedException}
import org.apache.spark.sql.catalyst.analysis.{NamedRelation, NamespaceNode, Star, TableNode, UnresolvedException}
import org.apache.spark.sql.catalyst.expressions.{Attribute, AttributeReference, Expression, Unevaluable}
import org.apache.spark.sql.catalyst.plans.DescribeTableSchema
import org.apache.spark.sql.connector.catalog.{CatalogManager, CatalogPlugin, Identifier, SupportsNamespaces, TableCatalog, TableChange}
Expand Down Expand Up @@ -454,3 +454,31 @@ case class ShowTableProperties(
AttributeReference("key", StringType, nullable = false)(),
AttributeReference("value", StringType, nullable = false)())
}

/**
* The logical plan that defines or changes the comment of an NAMESPACE for v2 catalogs.
*
* {{{
* COMMENT ON (DATABASE|SCHEMA|NAMESPACE) namespaceIdentifier IS ('text' | NULL)
* }}}
*
* where the `text` is the new comment written as a string literal; or `NULL` to drop the comment.
*
*/
case class CommentOnNamespace(child: NamespaceNode, comment: String) extends Command {
Comment thread
yaooqinn marked this conversation as resolved.
Outdated
override def children: Seq[LogicalPlan] = child :: Nil
}

/**
* The logical plan that defines or changes the comment of an TABLE for v2 catalogs.
*
* {{{
* COMMENT ON TABLE tableIdentifier IS ('text' | NULL)
* }}}
*
* where the `text` is the new comment written as a string literal; or `NULL` to drop the comment.
*
*/
case class CommentOnTable(child: TableNode, comment: String) extends Command {
override def children: Seq[LogicalPlan] = child :: Nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ package org.apache.spark.sql.catalyst.parser
import java.util.Locale

import org.apache.spark.sql.AnalysisException
import org.apache.spark.sql.catalyst.analysis.{AnalysisTest, GlobalTempView, LocalTempView, PersistedView, UnresolvedAttribute, UnresolvedRelation, UnresolvedStar}
import org.apache.spark.sql.catalyst.analysis.{AnalysisTest, GlobalTempView, LocalTempView, PersistedView, UnresolvedAttribute, UnresolvedNamespace, UnresolvedRelation, UnresolvedStar, UnresolvedV2Table}
import org.apache.spark.sql.catalyst.catalog.BucketSpec
import org.apache.spark.sql.catalyst.expressions.{EqualTo, Literal}
import org.apache.spark.sql.catalyst.plans.logical._
import org.apache.spark.sql.connector.catalog.TableChange.ColumnPosition.{after, first}
import org.apache.spark.sql.connector.expressions.{ApplyTransform, BucketTransform, DaysTransform, FieldReference, HoursTransform, IdentityTransform, LiteralValue, MonthsTransform, Transform, YearsTransform}
import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.types.{IntegerType, LongType, StringType, StructType, TimestampType}
import org.apache.spark.unsafe.types.UTF8String

Expand Down Expand Up @@ -1943,4 +1942,22 @@ class DDLParserSuite extends AnalysisTest {
}
}
}

test("comment on") {
comparePlans(
parsePlan("COMMENT ON DATABASE a.b.c IS NULL"),
CommentOnNamespace(UnresolvedNamespace(Seq("a", "b", "c")), ""))

comparePlans(
parsePlan("COMMENT ON DATABASE a.b.c IS 'NULL'"),
CommentOnNamespace(UnresolvedNamespace(Seq("a", "b", "c")), "NULL"))

comparePlans(
parsePlan("COMMENT ON NAMESPACE a.b.c IS ''"),
CommentOnNamespace(UnresolvedNamespace(Seq("a", "b", "c")), ""))

comparePlans(
parsePlan("COMMENT ON TABLE a.b.c IS 'xYz'"),
CommentOnTable(UnresolvedV2Table(Seq("a", "b", "c")), "xYz"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import scala.collection.JavaConverters._
import org.apache.spark.sql.{AnalysisException, Strategy}
import org.apache.spark.sql.catalyst.expressions.{And, PredicateHelper, SubqueryExpression}
import org.apache.spark.sql.catalyst.planning.PhysicalOperation
import org.apache.spark.sql.catalyst.plans.logical.{AlterNamespaceSetProperties, AlterTable, AppendData, CreateNamespace, CreateTableAsSelect, CreateV2Table, DeleteFromTable, DescribeNamespace, DescribeTable, DropNamespace, DropTable, LogicalPlan, OverwriteByExpression, OverwritePartitionsDynamic, RefreshTable, RenameTable, Repartition, ReplaceTable, ReplaceTableAsSelect, SetCatalogAndNamespace, ShowCurrentNamespace, ShowNamespaces, ShowTableProperties, ShowTables}
import org.apache.spark.sql.connector.catalog.{StagingTableCatalog, TableCapability}
import org.apache.spark.sql.catalyst.plans.logical.{AlterNamespaceSetProperties, AlterTable, AppendData, CommentOnNamespace, CommentOnTable, CreateNamespace, CreateTableAsSelect, CreateV2Table, DeleteFromTable, DescribeNamespace, DescribeTable, DropNamespace, DropTable, LogicalPlan, OverwriteByExpression, OverwritePartitionsDynamic, RefreshTable, RenameTable, Repartition, ReplaceTable, ReplaceTableAsSelect, SetCatalogAndNamespace, ShowCurrentNamespace, ShowNamespaces, ShowTableProperties, ShowTables}
import org.apache.spark.sql.connector.catalog.{StagingTableCatalog, SupportsNamespaces, TableCapability, TableCatalog, TableChange}
import org.apache.spark.sql.connector.read.streaming.{ContinuousStream, MicroBatchStream}
import org.apache.spark.sql.execution.{FilterExec, ProjectExec, SparkPlan}
import org.apache.spark.sql.execution.datasources.DataSourceStrategy
Expand Down Expand Up @@ -210,6 +210,16 @@ object DataSourceV2Strategy extends Strategy with PredicateHelper {
case AlterNamespaceSetProperties(catalog, namespace, properties) =>
AlterNamespaceSetPropertiesExec(catalog, namespace, properties) :: Nil

case CommentOnNamespace(namespace, comment) =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can match case CommentOnNamespace(ResolveNamespace ...), to avoid introducing that parent node.

AlterNamespaceSetPropertiesExec(
namespace.catalog,
namespace.namespace,
Map(SupportsNamespaces.PROP_COMMENT -> comment)) :: Nil
Comment thread
cloud-fan marked this conversation as resolved.

case CommentOnTable(table, comment) =>
val changes = TableChange.setProperty(TableCatalog.PROP_COMMENT, comment)
AlterTableExec(table.catalog, table.tableIdentifier, Seq(changes)) :: Nil

case CreateNamespace(catalog, namespace, ifNotExists, properties) =>
CreateNamespaceExec(catalog, namespace, ifNotExists, properties) :: Nil

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ class V2SessionCatalog(catalog: SessionCatalog, conf: SQLConf)

val properties = CatalogV2Util.applyPropertiesChanges(catalogTable.properties, changes)
val schema = CatalogV2Util.applySchemaChanges(catalogTable.schema, changes)
val comment = properties.get(TableCatalog.PROP_COMMENT)

try {
catalog.alterTable(catalogTable.copy(properties = properties, schema = schema))
catalog.alterTable(
catalogTable.copy(properties = properties, schema = schema, comment = comment))
} catch {
case _: NoSuchTableException =>
throw new NoSuchTableException(ident)
Expand Down
Loading