Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -730,6 +730,11 @@ class Analyzer(
case class ResolveNamespace(catalogManager: CatalogManager)
extends Rule[LogicalPlan] with LookupCatalog {
def apply(plan: LogicalPlan): LogicalPlan = plan resolveOperators {
case s @ ShowTablesStatement(UnresolvedNamespace(Seq()), _) =>
s.copy(namespace =
ResolvedNamespace(currentCatalog.asNamespaceCatalog, catalogManager.currentNamespace))
case UnresolvedNamespace(Seq()) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

We can move this logic to CatalogAndNamespace, but I'm fine with what it is now.

ResolvedNamespace(currentCatalog.asNamespaceCatalog, Seq.empty[String])
case UnresolvedNamespace(CatalogAndNamespace(catalog, ns)) =>
ResolvedNamespace(catalog.asNamespaceCatalog, ns)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ class ResolveCatalogs(val catalogManager: CatalogManager)

case AlterNamespaceSetPropertiesStatement(
NonSessionCatalogAndNamespace(catalog, ns), properties) =>
AlterNamespaceSetProperties(catalog.asNamespaceCatalog, ns, properties)
AlterNamespaceSetProperties(catalog, ns, properties)

case AlterNamespaceSetLocationStatement(
NonSessionCatalogAndNamespace(catalog, ns), location) =>
AlterNamespaceSetProperties(catalog.asNamespaceCatalog, ns,
AlterNamespaceSetProperties(catalog, ns,
Map(SupportsNamespaces.PROP_LOCATION -> location))

case RenameTableStatement(NonSessionCatalogAndTable(catalog, oldName), newNameParts, isView) =>
Expand Down Expand Up @@ -190,28 +190,22 @@ class ResolveCatalogs(val catalogManager: CatalogManager)
s"Can not specify catalog `${catalog.name}` for view ${viewName.quoted} " +
s"because view support in catalog has not been implemented yet")

case c @ CreateNamespaceStatement(NonSessionCatalogAndNamespace(catalog, ns), _, _) =>
case c @ CreateNamespaceStatement(CatalogAndNamespace(catalog, ns), _, _)
if !isSessionCatalog(catalog) =>
CreateNamespace(catalog.asNamespaceCatalog, ns, c.ifNotExists, c.properties)

case DropNamespaceStatement(NonSessionCatalogAndNamespace(catalog, ns), ifExists, cascade) =>
DropNamespace(catalog, ns, ifExists, cascade)

case DescribeNamespaceStatement(NonSessionCatalogAndNamespace(catalog, ns), extended) =>
DescribeNamespace(catalog.asNamespaceCatalog, ns, extended)
DescribeNamespace(catalog, ns, extended)

case ShowNamespacesStatement(Some(CatalogAndNamespace(catalog, ns)), pattern) =>
val namespace = if (ns.nonEmpty) Some(ns) else None
ShowNamespaces(catalog.asNamespaceCatalog, namespace, pattern)
case ShowNamespacesStatement(NonSessionCatalogAndNamespace(catalog, ns), pattern) =>
ShowNamespaces(catalog, ns, pattern)

case ShowNamespacesStatement(None, pattern) =>
ShowNamespaces(currentCatalog.asNamespaceCatalog, None, pattern)

case ShowTablesStatement(Some(NonSessionCatalogAndNamespace(catalog, ns)), pattern) =>
case ShowTablesStatement(NonSessionCatalogAndNamespace(catalog, ns), pattern) =>
ShowTables(catalog.asTableCatalog, ns, pattern)

case ShowTablesStatement(None, pattern) if !isSessionCatalog(currentCatalog) =>
ShowTables(currentCatalog.asTableCatalog, catalogManager.currentNamespace, pattern)

case UseStatement(isNamespaceSet, nameParts) =>
if (isNamespaceSet) {
SetCatalogAndNamespace(catalogManager, None, Some(nameParts))
Expand Down Expand Up @@ -239,10 +233,11 @@ class ResolveCatalogs(val catalogManager: CatalogManager)
}

object NonSessionCatalogAndNamespace {
def unapply(nameParts: Seq[String]): Option[(CatalogPlugin, Seq[String])] = nameParts match {
case CatalogAndNamespace(catalog, ns) if !isSessionCatalog(catalog) =>
Some(catalog -> ns)
case _ => None
}
def unapply(resolved: ResolvedNamespace): Option[(SupportsNamespaces, Seq[String])] =
if (!isSessionCatalog(resolved.catalog)) {
Some(resolved.catalog -> resolved.namespace)
} else {
None
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2548,7 +2548,7 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
*/
override def visitDropNamespace(ctx: DropNamespaceContext): LogicalPlan = withOrigin(ctx) {
DropNamespaceStatement(
visitMultipartIdentifier(ctx.multipartIdentifier),
UnresolvedNamespace(visitMultipartIdentifier(ctx.multipartIdentifier)),
ctx.EXISTS != null,
ctx.CASCADE != null)
}
Expand All @@ -2565,7 +2565,7 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
override def visitSetNamespaceProperties(ctx: SetNamespacePropertiesContext): LogicalPlan = {
withOrigin(ctx) {
AlterNamespaceSetPropertiesStatement(
visitMultipartIdentifier(ctx.multipartIdentifier),
UnresolvedNamespace(visitMultipartIdentifier(ctx.multipartIdentifier)),
visitPropertyKeyValues(ctx.tablePropertyList))
}
}
Expand All @@ -2581,7 +2581,7 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
override def visitSetNamespaceLocation(ctx: SetNamespaceLocationContext): LogicalPlan = {
withOrigin(ctx) {
AlterNamespaceSetLocationStatement(
visitMultipartIdentifier(ctx.multipartIdentifier),
UnresolvedNamespace(visitMultipartIdentifier(ctx.multipartIdentifier)),
visitLocationSpec(ctx.locationSpec))
}
}
Expand All @@ -2594,8 +2594,9 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
throw new ParseException(s"FROM/IN operator is not allowed in SHOW DATABASES", ctx)
}

val multiPart = Option(ctx.multipartIdentifier).map(visitMultipartIdentifier)
ShowNamespacesStatement(
Option(ctx.multipartIdentifier).map(visitMultipartIdentifier),
UnresolvedNamespace(multiPart.getOrElse(Seq.empty[String])),
Option(ctx.pattern).map(string))
}

Expand All @@ -2610,7 +2611,7 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
override def visitDescribeNamespace(ctx: DescribeNamespaceContext): LogicalPlan =
withOrigin(ctx) {
DescribeNamespaceStatement(
visitMultipartIdentifier(ctx.multipartIdentifier()),
UnresolvedNamespace(visitMultipartIdentifier(ctx.multipartIdentifier())),
ctx.EXTENDED != null)
}

Expand Down Expand Up @@ -2780,8 +2781,9 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
* Create a [[ShowTablesStatement]] command.
*/
override def visitShowTables(ctx: ShowTablesContext): LogicalPlan = withOrigin(ctx) {
val multiPart = Option(ctx.multipartIdentifier).map(visitMultipartIdentifier)
ShowTablesStatement(
Option(ctx.multipartIdentifier).map(visitMultipartIdentifier),
UnresolvedNamespace(multiPart.getOrElse(Seq.empty[String])),
Option(ctx.pattern).map(string))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,10 @@ case class DescribeTableStatement(
* A DESCRIBE NAMESPACE statement, as parsed from SQL.
*/
case class DescribeNamespaceStatement(
namespace: Seq[String],
extended: Boolean) extends ParsedStatement
namespace: LogicalPlan,
extended: Boolean) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(namespace)
}

/**
* A DESCRIBE TABLE tbl_name col_name statement, as parsed from SQL.
Expand Down Expand Up @@ -346,8 +348,11 @@ case class InsertIntoStatement(
/**
* A SHOW TABLES statement, as parsed from SQL.
*/
case class ShowTablesStatement(namespace: Option[Seq[String]], pattern: Option[String])
extends ParsedStatement
case class ShowTablesStatement(
namespace: LogicalPlan,
pattern: Option[String]) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(namespace)
}

/**
* A SHOW TABLE EXTENDED statement, as parsed from SQL.
Expand All @@ -370,29 +375,38 @@ case class CreateNamespaceStatement(
* A DROP NAMESPACE statement, as parsed from SQL.
*/
case class DropNamespaceStatement(
namespace: Seq[String],
namespace: LogicalPlan,
ifExists: Boolean,
cascade: Boolean) extends ParsedStatement
cascade: Boolean) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(namespace)
}

/**
* ALTER (DATABASE|SCHEMA|NAMESPACE) ... SET (DBPROPERTIES|PROPERTIES) command, as parsed from SQL.
*/
case class AlterNamespaceSetPropertiesStatement(
namespace: Seq[String],
properties: Map[String, String]) extends ParsedStatement
namespace: LogicalPlan,
properties: Map[String, String]) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(namespace)
}

/**
* ALTER (DATABASE|SCHEMA|NAMESPACE) ... SET LOCATION command, as parsed from SQL.
*/
case class AlterNamespaceSetLocationStatement(
namespace: Seq[String],
location: String) extends ParsedStatement
namespace: LogicalPlan,
location: String) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(namespace)
}

/**
* A SHOW NAMESPACES statement, as parsed from SQL.
*/
case class ShowNamespacesStatement(namespace: Option[Seq[String]], pattern: Option[String])
extends ParsedStatement
case class ShowNamespacesStatement(
namespace: LogicalPlan,
pattern: Option[String]) extends ParsedStatement {
override def children: Seq[LogicalPlan] = Seq(namespace)
}

/**
* A USE statement, as parsed from SQL.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ case class AlterNamespaceSetProperties(
*/
case class ShowNamespaces(
catalog: SupportsNamespaces,
namespace: Option[Seq[String]],
namespace: Seq[String],
pattern: Option[String]) extends Command {
override val output: Seq[Attribute] = Seq(
AttributeReference("namespace", StringType, nullable = false)())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,8 +745,10 @@ class DDLParserSuite extends AnalysisTest {
test("describe database") {
val sql1 = "DESCRIBE DATABASE EXTENDED a.b"
val sql2 = "DESCRIBE DATABASE a.b"
comparePlans(parsePlan(sql1), DescribeNamespaceStatement(Seq("a", "b"), extended = true))
comparePlans(parsePlan(sql2), DescribeNamespaceStatement(Seq("a", "b"), extended = false))
comparePlans(parsePlan(sql1),
DescribeNamespaceStatement(UnresolvedNamespace(Seq("a", "b")), extended = true))
comparePlans(parsePlan(sql2),
DescribeNamespaceStatement(UnresolvedNamespace(Seq("a", "b")), extended = false))
}

test("SPARK-17328 Fix NPE with EXPLAIN DESCRIBE TABLE") {
Expand Down Expand Up @@ -1106,16 +1108,16 @@ class DDLParserSuite extends AnalysisTest {
test("show tables") {
comparePlans(
parsePlan("SHOW TABLES"),
ShowTablesStatement(None, None))
ShowTablesStatement(UnresolvedNamespace(Seq.empty[String]), None))
comparePlans(
parsePlan("SHOW TABLES FROM testcat.ns1.ns2.tbl"),
ShowTablesStatement(Some(Seq("testcat", "ns1", "ns2", "tbl")), None))
ShowTablesStatement(UnresolvedNamespace(Seq("testcat", "ns1", "ns2", "tbl")), None))
comparePlans(
parsePlan("SHOW TABLES IN testcat.ns1.ns2.tbl"),
ShowTablesStatement(Some(Seq("testcat", "ns1", "ns2", "tbl")), None))
ShowTablesStatement(UnresolvedNamespace(Seq("testcat", "ns1", "ns2", "tbl")), None))
comparePlans(
parsePlan("SHOW TABLES IN tbl LIKE '*dog*'"),
ShowTablesStatement(Some(Seq("tbl")), Some("*dog*")))
ShowTablesStatement(UnresolvedNamespace(Seq("tbl")), Some("*dog*")))
}

test("show table extended") {
Expand Down Expand Up @@ -1230,78 +1232,86 @@ class DDLParserSuite extends AnalysisTest {
test("drop namespace") {
comparePlans(
parsePlan("DROP NAMESPACE a.b.c"),
DropNamespaceStatement(Seq("a", "b", "c"), ifExists = false, cascade = false))
DropNamespaceStatement(
UnresolvedNamespace(Seq("a", "b", "c")), ifExists = false, cascade = false))

comparePlans(
parsePlan("DROP NAMESPACE IF EXISTS a.b.c"),
DropNamespaceStatement(Seq("a", "b", "c"), ifExists = true, cascade = false))
DropNamespaceStatement(
UnresolvedNamespace(Seq("a", "b", "c")), ifExists = true, cascade = false))

comparePlans(
parsePlan("DROP NAMESPACE IF EXISTS a.b.c RESTRICT"),
DropNamespaceStatement(Seq("a", "b", "c"), ifExists = true, cascade = false))
DropNamespaceStatement(
UnresolvedNamespace(Seq("a", "b", "c")), ifExists = true, cascade = false))

comparePlans(
parsePlan("DROP NAMESPACE IF EXISTS a.b.c CASCADE"),
DropNamespaceStatement(Seq("a", "b", "c"), ifExists = true, cascade = true))
DropNamespaceStatement(
UnresolvedNamespace(Seq("a", "b", "c")), ifExists = true, cascade = true))

comparePlans(
parsePlan("DROP NAMESPACE a.b.c CASCADE"),
DropNamespaceStatement(Seq("a", "b", "c"), ifExists = false, cascade = true))
DropNamespaceStatement(
UnresolvedNamespace(Seq("a", "b", "c")), ifExists = false, cascade = true))
}

test("set namespace properties") {
comparePlans(
parsePlan("ALTER DATABASE a.b.c SET PROPERTIES ('a'='a', 'b'='b', 'c'='c')"),
AlterNamespaceSetPropertiesStatement(
Seq("a", "b", "c"), Map("a" -> "a", "b" -> "b", "c" -> "c")))
UnresolvedNamespace(Seq("a", "b", "c")), Map("a" -> "a", "b" -> "b", "c" -> "c")))

comparePlans(
parsePlan("ALTER SCHEMA a.b.c SET PROPERTIES ('a'='a')"),
AlterNamespaceSetPropertiesStatement(
Seq("a", "b", "c"), Map("a" -> "a")))
UnresolvedNamespace(Seq("a", "b", "c")), Map("a" -> "a")))

comparePlans(
parsePlan("ALTER NAMESPACE a.b.c SET PROPERTIES ('b'='b')"),
AlterNamespaceSetPropertiesStatement(
Seq("a", "b", "c"), Map("b" -> "b")))
UnresolvedNamespace(Seq("a", "b", "c")), Map("b" -> "b")))

comparePlans(
parsePlan("ALTER DATABASE a.b.c SET DBPROPERTIES ('a'='a', 'b'='b', 'c'='c')"),
AlterNamespaceSetPropertiesStatement(
Seq("a", "b", "c"), Map("a" -> "a", "b" -> "b", "c" -> "c")))
UnresolvedNamespace(Seq("a", "b", "c")), Map("a" -> "a", "b" -> "b", "c" -> "c")))

comparePlans(
parsePlan("ALTER SCHEMA a.b.c SET DBPROPERTIES ('a'='a')"),
AlterNamespaceSetPropertiesStatement(
Seq("a", "b", "c"), Map("a" -> "a")))
UnresolvedNamespace(Seq("a", "b", "c")), Map("a" -> "a")))

comparePlans(
parsePlan("ALTER NAMESPACE a.b.c SET DBPROPERTIES ('b'='b')"),
AlterNamespaceSetPropertiesStatement(
Seq("a", "b", "c"), Map("b" -> "b")))
UnresolvedNamespace(Seq("a", "b", "c")), Map("b" -> "b")))
}

test("set namespace location") {
comparePlans(
parsePlan("ALTER DATABASE a.b.c SET LOCATION '/home/user/db'"),
AlterNamespaceSetLocationStatement(Seq("a", "b", "c"), "/home/user/db"))
AlterNamespaceSetLocationStatement(
UnresolvedNamespace(Seq("a", "b", "c")), "/home/user/db"))

comparePlans(
parsePlan("ALTER SCHEMA a.b.c SET LOCATION '/home/user/db'"),
AlterNamespaceSetLocationStatement(Seq("a", "b", "c"), "/home/user/db"))
AlterNamespaceSetLocationStatement(
UnresolvedNamespace(Seq("a", "b", "c")), "/home/user/db"))

comparePlans(
parsePlan("ALTER NAMESPACE a.b.c SET LOCATION '/home/user/db'"),
AlterNamespaceSetLocationStatement(Seq("a", "b", "c"), "/home/user/db"))
AlterNamespaceSetLocationStatement(
UnresolvedNamespace(Seq("a", "b", "c")), "/home/user/db"))
}

test("show databases: basic") {
comparePlans(
parsePlan("SHOW DATABASES"),
ShowNamespacesStatement(None, None))
ShowNamespacesStatement(UnresolvedNamespace(Seq.empty[String]), None))
comparePlans(
parsePlan("SHOW DATABASES LIKE 'defau*'"),
ShowNamespacesStatement(None, Some("defau*")))
ShowNamespacesStatement(UnresolvedNamespace(Seq.empty[String]), Some("defau*")))
}

test("show databases: FROM/IN operator is not allowed") {
Expand All @@ -1317,16 +1327,16 @@ class DDLParserSuite extends AnalysisTest {
test("show namespaces") {
comparePlans(
parsePlan("SHOW NAMESPACES"),
ShowNamespacesStatement(None, None))
ShowNamespacesStatement(UnresolvedNamespace(Seq.empty[String]), None))
comparePlans(
parsePlan("SHOW NAMESPACES FROM testcat.ns1.ns2"),
ShowNamespacesStatement(Some(Seq("testcat", "ns1", "ns2")), None))
ShowNamespacesStatement(UnresolvedNamespace(Seq("testcat", "ns1", "ns2")), None))
comparePlans(
parsePlan("SHOW NAMESPACES IN testcat.ns1.ns2"),
ShowNamespacesStatement(Some(Seq("testcat", "ns1", "ns2")), None))
ShowNamespacesStatement(UnresolvedNamespace(Seq("testcat", "ns1", "ns2")), None))
comparePlans(
parsePlan("SHOW NAMESPACES IN testcat.ns1 LIKE '*pattern*'"),
ShowNamespacesStatement(Some(Seq("testcat", "ns1")), Some("*pattern*")))
ShowNamespacesStatement(UnresolvedNamespace(Seq("testcat", "ns1")), Some("*pattern*")))
}

test("analyze table statistics") {
Expand Down
Loading