From 4746fa6b050349294d271e3ea20e14354c66052c Mon Sep 17 00:00:00 2001 From: wangjunbo Date: Fri, 29 Dec 2023 09:49:23 +0800 Subject: [PATCH 1/2] [KYUUBI #5797] Support to describe engine with command in current session --- .../apache/kyuubi/sql/KyuubiSqlBaseLexer.g4 | 2 + .../apache/kyuubi/sql/KyuubiSqlBaseParser.g4 | 1 + .../sql/parser/server/KyuubiAstBuilder.scala | 7 +- .../sql/plan/command/DescribeEngine.scala | 64 +++++++++++++++++++ .../sql/plan/command/DescribeSession.scala | 6 +- .../parser/DescribeEngineSuite.scala | 35 ++++++++++ .../parser/DescribeSessionSuite.scala | 18 +++--- .../kyuubi/parser/KyuubiParserSuite.scala | 9 ++- 8 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala create mode 100644 kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeEngineSuite.scala diff --git a/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseLexer.g4 b/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseLexer.g4 index 7e7dee0e371..c6fd6676b86 100644 --- a/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseLexer.g4 +++ b/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseLexer.g4 @@ -51,6 +51,8 @@ KYUUBIADMIN: 'KYUUBIADMIN'; SESSION: 'SESSION'; +ENGINE: 'ENGINE'; + BACKQUOTED_IDENTIFIER : '`' ( ~'`' | '``' )* '`' ; diff --git a/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseParser.g4 b/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseParser.g4 index 7360c8410ae..67bb7e35a7f 100644 --- a/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseParser.g4 +++ b/kyuubi-server/src/main/antlr4/org/apache/kyuubi/sql/KyuubiSqlBaseParser.g4 @@ -30,4 +30,5 @@ statement runnableCommand : (DESC | DESCRIBE) SESSION #describeSession + | (DESC | DESCRIBE) ENGINE #describeEngine ; diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/parser/server/KyuubiAstBuilder.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/parser/server/KyuubiAstBuilder.scala index 6c5f6a395f3..b29b57cbd2d 100644 --- a/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/parser/server/KyuubiAstBuilder.scala +++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/parser/server/KyuubiAstBuilder.scala @@ -20,7 +20,7 @@ package org.apache.kyuubi.sql.parser.server import org.apache.kyuubi.sql.{KyuubiSqlBaseParser, KyuubiSqlBaseParserBaseVisitor} import org.apache.kyuubi.sql.KyuubiSqlBaseParser.SingleStatementContext import org.apache.kyuubi.sql.plan.{KyuubiTreeNode, PassThroughNode} -import org.apache.kyuubi.sql.plan.command.{DescribeSession, RunnableCommand} +import org.apache.kyuubi.sql.plan.command.{DescribeEngine, DescribeSession, RunnableCommand} class KyuubiAstBuilder extends KyuubiSqlBaseParserBaseVisitor[AnyRef] { @@ -44,4 +44,9 @@ class KyuubiAstBuilder extends KyuubiSqlBaseParserBaseVisitor[AnyRef] { : RunnableCommand = { DescribeSession() } + + override def visitDescribeEngine(ctx: KyuubiSqlBaseParser.DescribeEngineContext) + : RunnableCommand = { + DescribeEngine() + } } diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala new file mode 100644 index 00000000000..d20feebc7a8 --- /dev/null +++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala @@ -0,0 +1,64 @@ +/* + * 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.kyuubi.sql.plan.command + +import scala.collection.mutable.ListBuffer + +import org.apache.kyuubi.operation.IterableFetchIterator +import org.apache.kyuubi.session.{KyuubiSession, KyuubiSessionImpl} +import org.apache.kyuubi.shaded.hive.service.rpc.thrift.TTypeId +import org.apache.kyuubi.sql.schema.{Column, Row, Schema} + +/** + * A runnable node for description the current session. + * + * The syntax of using this command in SQL is: + * {{{ + * [DESC|DESCRIBE] ENGINE; + * }}} + */ +case class DescribeEngine() extends RunnableCommand { + + override def run(kyuubiSession: KyuubiSession): Unit = { + val rows = Seq(kyuubiSession).map { session => + lazy val client = session.asInstanceOf[KyuubiSessionImpl].client + val values = new ListBuffer[String]() + values += client.engineId.getOrElse("") + values += client.engineName.getOrElse("") + values += client.engineUrl.getOrElse("") + Row(values.toList) + } + iter = new IterableFetchIterator(rows) + } + + override def resultSchema: Schema = { + Schema(DescribeEngine.outputCols().toList) + } + + override def name(): String = "Describe Engine Node" +} + +object DescribeEngine { + + def outputCols(): Seq[Column] = { + Seq( + Column("ENGINE_ID", TTypeId.STRING_TYPE, Some("Kyuubi engine identify")), + Column("ENGINE_NAME", TTypeId.STRING_TYPE, Some("Kyuubi engine name")), + Column("ENGINE_URL", TTypeId.STRING_TYPE, Some("Kyuubi engine url"))) + } +} diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeSession.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeSession.scala index e1d77f296e7..8abe93e17d0 100644 --- a/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeSession.scala +++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeSession.scala @@ -56,8 +56,8 @@ object DescribeSession { def outputCols(): Seq[Column] = { Seq( - Column("id", TTypeId.STRING_TYPE, Some("Kyuubi session identify")), - Column("user", TTypeId.STRING_TYPE, Some("Kyuubi session user")), - Column("type", TTypeId.STRING_TYPE, Some("Kyuubi session type"))) + Column("SESSION_ID", TTypeId.STRING_TYPE, Some("Kyuubi session identify")), + Column("SESSION_USER", TTypeId.STRING_TYPE, Some("Kyuubi session user")), + Column("SESSION_TYPE", TTypeId.STRING_TYPE, Some("Kyuubi session type"))) } } diff --git a/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeEngineSuite.scala b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeEngineSuite.scala new file mode 100644 index 00000000000..d9488abd62f --- /dev/null +++ b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeEngineSuite.scala @@ -0,0 +1,35 @@ +/* + * 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.kyuubi.operation.parser + +class DescribeEngineSuite extends ExecutedCommandExecSuite { + + test("desc/describe kyuubi engine") { + Seq("DESC", "DESCRIBE").foreach { desc => + withJdbcStatement() { statement => + val resultSet = statement.executeQuery(s"KYUUBI $desc ENGINE") + assert(resultSet.next()) + + assert(resultSet.getMetaData.getColumnCount == 3) + assert(resultSet.getMetaData.getColumnName(1) == "ENGINE_ID") + assert(resultSet.getMetaData.getColumnName(2) == "ENGINE_NAME") + assert(resultSet.getMetaData.getColumnName(3) == "ENGINE_URL") + } + } + } +} diff --git a/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeSessionSuite.scala b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeSessionSuite.scala index e6f42ed6231..b4eb0893d85 100644 --- a/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeSessionSuite.scala +++ b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/parser/DescribeSessionSuite.scala @@ -19,15 +19,17 @@ package org.apache.kyuubi.operation.parser class DescribeSessionSuite extends ExecutedCommandExecSuite { - test("desc kyuubi session") { - withJdbcStatement() { statement => - val resultSet = statement.executeQuery("KYUUBI DESC SESSION") - assert(resultSet.next()) + test("desc/describe kyuubi session") { + Seq("DESC", "DESCRIBE").foreach { desc => + withJdbcStatement() { statement => + val resultSet = statement.executeQuery(s"KYUUBI $desc SESSION") + assert(resultSet.next()) - assert(resultSet.getMetaData.getColumnCount == 3) - assert(resultSet.getMetaData.getColumnName(1) == "id") - assert(resultSet.getMetaData.getColumnName(2) == "user") - assert(resultSet.getMetaData.getColumnName(3) == "type") + assert(resultSet.getMetaData.getColumnCount == 3) + assert(resultSet.getMetaData.getColumnName(1) == "SESSION_ID") + assert(resultSet.getMetaData.getColumnName(2) == "SESSION_USER") + assert(resultSet.getMetaData.getColumnName(3) == "SESSION_TYPE") + } } } } diff --git a/kyuubi-server/src/test/scala/org/apache/kyuubi/parser/KyuubiParserSuite.scala b/kyuubi-server/src/test/scala/org/apache/kyuubi/parser/KyuubiParserSuite.scala index 6858ea0c041..b2ddfdfcdfa 100644 --- a/kyuubi-server/src/test/scala/org/apache/kyuubi/parser/KyuubiParserSuite.scala +++ b/kyuubi-server/src/test/scala/org/apache/kyuubi/parser/KyuubiParserSuite.scala @@ -20,7 +20,7 @@ package org.apache.kyuubi.parser import org.apache.kyuubi.KyuubiFunSuite import org.apache.kyuubi.sql.parser.server.KyuubiParser import org.apache.kyuubi.sql.plan.PassThroughNode -import org.apache.kyuubi.sql.plan.command.DescribeSession +import org.apache.kyuubi.sql.plan.command.{DescribeEngine, DescribeSession} class KyuubiParserSuite extends KyuubiFunSuite { @@ -51,4 +51,11 @@ class KyuubiParserSuite extends KyuubiFunSuite { assert(node.isInstanceOf[DescribeSession]) assert(node.name() == "Describe Session Node") } + + test("Describe session engine") { + val node = parser.parsePlan("KYUUBI DESC ENGINE") + + assert(node.isInstanceOf[DescribeEngine]) + assert(node.name() == "Describe Engine Node") + } } From f768fb5adc98a25a4adad1d288b812071188b7e0 Mon Sep 17 00:00:00 2001 From: wangjunbo Date: Tue, 2 Jan 2024 19:42:32 +0800 Subject: [PATCH 2/2] [KYUUBI #5797] fix --- .../org/apache/kyuubi/sql/plan/command/DescribeEngine.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala index d20feebc7a8..85ec536853a 100644 --- a/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala +++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/sql/plan/command/DescribeEngine.scala @@ -25,7 +25,7 @@ import org.apache.kyuubi.shaded.hive.service.rpc.thrift.TTypeId import org.apache.kyuubi.sql.schema.{Column, Row, Schema} /** - * A runnable node for description the current session. + * A runnable node for description the current session engine. * * The syntax of using this command in SQL is: * {{{