ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Apache Spark SQL SHOW DATABASES 命令详解:语法、正则过滤与底层实现

Apache Spark SQL SHOW DATABASES 命令详解:语法、正则过滤与底层实现 Apache Spark SQL SHOW DATABASES 命令详解语法、正则过滤与底层实现【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark导读SHOW DATABASES是 Apache Spark SQL 中用于枚举系统中全部数据库Database的命令其等价形式为SHOW SCHEMAS。本文基于 sql-ref-syntax-aux-show-databases.md 官方语法文档完整讲解该命令的语法、LIKE正则过滤规则与输出格式并结合本仓库 SparkSqlParser.scala、ShowNamespacesCommand.scala 等源码与测试用例深入剖析其解析链路、匹配算法与新旧输出 schema 的兼容行为。读完本文你将能够熟练使用该命令进行数据库清单查询与模式过滤并理解其背后Namespace 统一抽象的实现原理。一、命令概述与语法1.1 功能描述SHOW DATABASES用于列出系统中与可选正则表达式模式匹配的数据库。若未提供模式则列出系统中的全部数据库。官方文档特别强调SCHEMAS与DATABASES两个关键字可以互换使用含义完全相同。这一点在语法层面与实现层面都是一致的——两条语句最终都会解析为同一个逻辑计划节点ShowNamespacesCommand。1.2 语法SHOW { DATABASES | SCHEMAS } [ LIKE regex_pattern ]语法要点关键字DATABASES、SCHEMAS二选一等价LIKE regex_pattern为可选项用于按模式过滤结果命令不区分大小写。二、参数说明regex_patternregex_pattern是一个正则表达式模式字符串用于过滤语句的返回结果。官方文档对其语义给出三条核心规则除*与|两个特殊字符外模式按照正则表达式规则工作*单独使用可匹配 0 个或多个字符等价于正则中的.*而|用于分隔多个不同的正则表达式只要命中任意一个即可匹配模式字符串首尾的空格会在处理前被去除trim匹配过程不区分大小写case-insensitive。2.1 源码级验证StringUtils.filterPattern以上规则的实现位于 StringUtils.scala 中的filterPattern方法。该方法注释明确说明其用途是 filtering pattern in the Like of Show Tables / Functions DDL即SHOW DATABASES / TABLES / FUNCTIONS等命令共用同一套模式过滤逻辑。核心实现如下def filterPattern(names: Seq[String], pattern: String): Seq[String] { val funcNames scala.collection.mutable.SortedSet.empty[String] pattern.trim().split(\\|).foreach { subPattern try { val regex ((?i) subPattern.replaceAll(\\*, .*)).r funcNames names.filter{ name regex.pattern.matcher(name).matches() } } catch { case _: PatternSyntaxException } } funcNames.toSeq }从实现可以提炼出与文档一一对应的关键事实文档规则源码实现首尾空格被去除pattern.trim()*匹配 0 或多个字符subPattern.replaceAll(\\*, .*)匹配不区分大小写正则前缀(?i)\|分隔多个正则任一命中即可pattern.trim().split(\\|)后逐一求并集结果有序、去重使用SortedSet收集后转为序列此外注意两点实现细节匹配方式为全字符串匹配matcher.matches()即模式必须完整匹配数据库名而非部分包含若某个子模式编译失败PatternSyntaxException该子模式会被静默跳过不影响其他子模式的结果。2.2 匹配规则小结未指定LIKE时列出全部数据库模式按正则匹配*是通配符|是或分隔符大小写不敏感首尾空白自动剔除若LIKE模式不匹配任何数据库返回空结果集不报错。三、完整示例以下示例全部取自官方文档可直接在 Spark SQL CLI 或spark-sql、Spark Connect 等任意 SQL 入口中执行。3.1 准备数据库-- 创建数据库。假设系统中已存在名为 default 的数据库。 CREATE DATABASE payroll_db; CREATE DATABASE payments_db;3.2 列出全部数据库SHOW DATABASES; ------------ |databaseName| ------------ | default| | payments_db| | payroll_db| ------------3.3 使用 LIKE 模式过滤-- 列出名字以字符串模式 pay 开头的数据库 SHOW DATABASES LIKE pay*; ------------ |databaseName| ------------ | payments_db| | payroll_db| ------------3.4 SCHEMAS 与 DATABASES 互换-- 列出全部数据库。关键字 SCHEMAS 与 DATABASES 可互换。 SHOW SCHEMAS; ------------ |databaseName| ------------ | default| | payments_db| | payroll_db| ------------3.5 更多模式用法结合|与大小写不敏感规则还可以写出更复杂的过滤-- 同时匹配多个模式任一命中即返回且不区分大小写 SHOW DATABASES LIKE PAY*|DEF*; ------------ |databaseName| ------------ | default| | payments_db| | payroll_db| ------------四、底层实现解析从 SQL 文本到结果集理解SHOW DATABASES的完整执行链路有助于在实际排障与二次开发中快速定位问题。该命令在源码中走的是解析Parsing→ 逻辑计划Logical Plan→ 执行Execution的标准 Catalyst 流程。4.1 语法规则SqlBase.g4在 ANTLR 语法文件 SqlBaseParser.g4 中SHOW DATABASES与SHOW SCHEMAS统一对应到showNamespaces规则| SHOW namespaces ((FROM | IN) multipartIdentifier)? (LIKE? patternstringLit)? #showNamespaces从语法定义可以进一步确认两点文档未展开的能力SHOW NAMESPACES还支持FROM/IN限定 multipartIdentifier用于在指定 catalog 或命名空间下展示命名空间LIKE关键字本身是可选的LIKE?即使不写LIKE也可以直接跟字符串字面量作为模式。4.2 解析器visitShowNamespaces在 SparkSqlParser.scala 中visitShowNamespaces将语法树转换为逻辑计划ShowNamespacesCommandoverride def visitShowNamespaces(ctx: ShowNamespacesContext): LogicalPlan withOrigin(ctx) { val multiPart Option(ctx.multipartIdentifier).map(visitMultipartIdentifier) ShowNamespacesCommand( UnresolvedNamespace(multiPart.getOrElse(Seq.empty[String])), Option(ctx.pattern).map(x string(visitStringLit(x)))) }未指定命名空间时UnresolvedNamespace使用空序列Seq.empty[String]表示当前根命名空间。4.3 执行命令ShowNamespacesCommand核心执行逻辑位于 ShowNamespacesCommand.scala。该命令继承UnaryRunnableCommandrun方法的关键步骤为通过child即ResolvedNamespace解析出目录cat与命名空间ns调用nsCatalog.listNamespaces()列出全部命名空间若指定了上层命名空间则传入ns.toArray根据输出列名与命名空间元数决定是否添加引号见下文兼容性章节使用StringUtils.filterPattern按pattern过滤最终映射为Row输出。值得注意的是输出列定义本身也是动态的见ShowNamespacesCommand.outputdef output: Seq[AttributeReference] { Seq( if (SQLConf.get.legacyOutputSchema) { AttributeReference(databaseName, StringType, nullable false)() } else { AttributeReference(namespace, StringType, nullable false)() } ) }五、新旧行为兼容databaseName 与 namespace从源码结构可以推断Spark 在引入 V2 Catalog 的 Namespace 抽象后对SHOW DATABASES的输出 schema 做了演进同时保留了旧行为的开关5.1 输出列名差异新行为默认输出列名为namespace旧行为输出列名为databaseName文档示例中展示的即是此列名可通过配置spark.sql.legacy.keepCommandOutputSchematrue开启对应SQLConf.legacyOutputSchema。相关测试 ShowNamespacesSuiteBase.scala 中用例 SPARK-34359: keep the legacy output schema 验证了该行为withSQLConf(SQLConf.LEGACY_KEEP_COMMAND_OUTPUT_SCHEMA.key - true) { assert(sql(SHOW NAMESPACES).schema.fieldNames.toSeq Seq(databaseName)) }5.2 引号行为差异ShowNamespacesCommand.run中还有一处细节当输出列为databaseName且所有命名空间均为单段无层级时命名空间名不加反引号否则使用quoted形式带反引号。用例 SPARK-39149: keep the legacy no-quote behavior同文件第 130-142 行验证了在 legacy 模式下特殊命名空间123输出为123而新行为下输出为123。5.3 大小写与匹配语义测试用例 case sensitivity of the pattern string同文件第 144-161 行进一步验证无论全局spark.sql.caseSensitive如何设置LIKE AAA与LIKE aaa均能匹配名为AAA的命名空间——这正对应filterPattern中(?i)前缀带来的大小写不敏感匹配。六、编程接口Catalog.listDatabases除了 SQL 语句Spark 还提供等价的数据集 API。在 Catalog.scala 中listDatabases()与listDatabases(pattern: String)最终都汇聚到listDatabasesInternal其内部正是构造并执行ShowNamespacesCommandprivate def listDatabasesInternal(patternOpt: Option[String]): Dataset[Database] { val plan ShowNamespacesCommand(UnresolvedNamespace(Nil), patternOpt) val qe sparkSession.sessionState.executePlan(plan) ... }由此可以确认SQL 与 DataFrame API 共享同一套执行计划与过滤逻辑两者结果保持一致。Scala 中用法示例spark.catalog.listDatabases().show() // 列出全部数据库 spark.catalog.listDatabases(pay*).show() // 按模式过滤七、测试覆盖与使用建议7.1 测试覆盖SHOW DATABASES / SHOW NAMESPACES具有统一的测试基类 ShowNamespacesSuiteBase.scala覆盖场景包括默认命名空间展示SHOW NAMESPACES与SHOW NAMESPACES IN $catalog精确匹配LIKE ns2无匹配返回空结果LIKE non-existentdb复杂模式*db1A、*2*、*db1A|*db2B等组合通配符与多模式USE切换目录/命名空间后的展示行为legacy 输出 schemaSPARK-34359与去引号行为SPARK-39149模式字符串大小写敏感性。对应的 V1 In-Memory Catalog 测试位于 v1/ShowNamespacesSuite.scala。7.2 实战建议日常巡检用SHOW DATABASES快速确认当前系统数据库清单与DESCRIBE DATABASE配合查看库属性批量筛选利用LIKE pay*或LIKE a*|b*一次过滤多组前缀的库避免全量返回后手工筛选注意匹配语义*是通配符而非普通正则字符若需匹配字面*需转义模式需完整匹配整个库名脚本兼容若下游脚本依赖列名databaseName在升级 Spark 后需显式开启spark.sql.legacy.keepCommandOutputSchematrue或改用新的namespace列名。八、相关语句DESCRIBE DATABASECREATE DATABASEALTER DATABASE结语SHOW DATABASES虽是一条简单的元数据查询语句但透过它可以看到 Spark SQL 在 V1/V2 Catalog 演进中的兼容设计同一命令既保留了databaseName这一 legacy 输出列又统一到 Namespace 抽象之下并与StringUtils.filterPattern这套共享模式过滤工具协同工作。掌握其语法、过滤规则与底层实现能帮助你在日常开发、脚本迁移与源码排障中更加游刃有余。【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表