Class SQLUtil

Object
gudusoft.gsqlparser.util.SQLUtil

public class SQLUtil extends Object
  • Constructor Details

  • Method Details

    • formatSql

      public static String formatSql(EDbVendor dbVendor, String inputQuery)
    • isEmpty

      public static boolean isEmpty(String value)
    • getFileContent

      public static String getFileContent(File file)
    • getInputStreamContent

      public static String getInputStreamContent(InputStream is, boolean close)
    • getFileContent

      public static String getFileContent(String filePath)
    • trimColumnStringQuote

      public static String trimColumnStringQuote(String string)
    • parseNames

      public static List<String> parseNames(String nameString)
    • parseNames

      public static List<String> parseNames(String nameString, EDbVendor vendor)
      解析以点号分隔的 SQL 标识符或表达式,并返回各层级片段。

      用途:

      • 将类似 catalog.schema.table.column 的全限定名拆分为有序片段;
      • 在拆分时识别并保留引号/括号内的点号,不做误分割;
      • 根据不同数据库厂商(如 BigQuery)的定界符规则进行处理。
      工作机制:
      1. 按「可选空格 + '.' + 可选空格」初步切分;
      2. 对以下情况进行片段合并直至遇到闭合符号:
        • 单引号字符串:'...'
        • 双引号定界标识符:"..."
        • 反引号定界标识符:`...`
        • 方括号定界标识符:[...]
        • 函数/表达式括号:(...)
      3. BigQuery(vendor == dbvbigquery)且包含反引号时,会先去除反引号再进行切分。
      4. 入参为 null 返回空列表;发生异常时返回仅包含原始字符串的列表。
      示例:
        "dbo.Employee.Name"                    -> ["dbo", "Employee", "Name"]
        "[Sales DB].[Employee].[Name]"        -> ["[Sales DB]", "[Employee]", "[Name]"]
        "\"My.Schema\".\"My.Table\""       -> ["\"My.Schema\"", "\"My.Table\""]
        "`project.dataset.table`" (BigQuery)  -> ["project", "dataset", "table"]
        "OPENJSON(aptd.test.ActiviteTypeIDs)" -> ["OPENJSON(aptd.test.ActiviteTypeIDs)"]
       
      Parameters:
      nameString - 待解析的标识符或表达式字符串
      vendor - 数据库厂商(用于处理厂商特定定界符,如 BigQuery 的反引号),可为 null
      Returns:
      解析后的片段列表;顺序与层级一致
    • putCache

      protected static List<String> putCache(String cacheKey, List<String> names)
    • main

      public static void main(String[] args)
    • writeToFile

      public static void writeToFile(File file, InputStream source, boolean close)
    • writeToFile

      public static void writeToFile(File file, String string) throws IOException
      Throws:
      IOException
    • appendToFile

      public static void appendToFile(File file, String string) throws IOException
      Throws:
      IOException
    • deltree

      public static void deltree(File root)
    • getInputStreamWithoutBom

      Throws:
      IOException
    • compareIdentifier

      public static boolean compareIdentifier(EDbVendor dbVendor, ESQLDataObjectType sqlDataObjectType, String identifier1, String identifier2)
    • normalizeIdentifier

      public static String normalizeIdentifier(EDbVendor dbVendor, ESQLDataObjectType objectType, String identifier)
    • getIdentifierNormalColumnName

      public static String getIdentifierNormalColumnName(EDbVendor dbVendor, String name)
    • getIdentifierNormalTableName

    • getIdentifierNormalTableName

      public static String getIdentifierNormalTableName(EDbVendor dbVendor, String name)
    • getIdentifierNormalName

      public static String getIdentifierNormalName(EDbVendor dbVendor, String name, ESQLDataObjectType sqlDataObjectType)
      规范化多段限定名(Multi-Segment Qualified Name)并返回规范化后的完整限定名。

      核心功能

      本方法是 SQL 标识符规范化的多段名处理版本,接受包含多段(catalog.schema.table.column)的限定名, 根据数据库厂商特性、层级支持能力和对象类型,智能解析和规范化每个段,最后返回用点号连接的完整规范化名称。

      处理流程

      1. 厂商特定语法展开
        • MSSQL/Azure SQL: 将 ".." 语法展开为 ".dbo." 或全局配置的 schema
        • 示例:"db..table""db.dbo.table"
      2. 解析多段名:使用 parseNames(String) 将限定名按点号分割成段列表
      3. 智能段类型推断:根据以下因素决定每段的实际类型:
        • 数据库厂商的层级支持能力(supportCatalog/supportSchema)
        • 目标对象类型(sqlDataObjectType
        • 实际段数
      4. 逐段规范化:对每段调用 normalizeIdentifier(EDbVendor, ESQLDataObjectType, String), 应用厂商特定的大小写规则、引号处理等
      5. 重组限定名:用点号连接所有规范化后的段,返回完整的规范化限定名

      智能段类型推断示例

      假设数据库同时支持 catalog 和 schema,目标类型为 dotTable

      • 3段名 "a.b.c" → 解析为 catalog.schema.table
      • 2段名 "a.b" → 解析为 schema.table
      • 1段名 "a" → 解析为 table

      假设数据库仅支持 catalog(如 MySQL),目标类型为 dotTable

      • 2段名 "a.b" → 解析为 catalog.table
      • 1段名 "a" → 解析为 table

      假设数据库仅支持 schema(如 PostgreSQL),目标类型为 dotTable

      • 2段名 "a.b" → 解析为 schema.table
      • 1段名 "a" → 解析为 table

      对于 dotColumn 类型的特殊处理

      列名可能有4段(catalog.schema.table.column),方法会根据实际段数自动调整解析策略:

      • 4段名 "db.sch.tbl.col"catalog.schema.table.column
      • 3段名 "sch.tbl.col"schema.table.column
      • 2段名 "tbl.col"table.column
      • 1段名 "col"column

      处理超长限定名

      当段数超过标准层级时(如表名有4段或更多),方法会使用 mergeSegments(List, int) 将多余的尾部段合并为单个段(保留点号),然后作为最后一段进行规范化。

      示例:5段列名 "db.sch.tbl.nested.col" → 合并后4段处理: "db.sch.tbl.nested.col" (最后两段合并为 "nested.col")

      方法目的与使用场景

      • 目的:为多段限定名提供统一的规范化接口,生成可用于比较、索引和查找的标准化名称
      • 输出特性:返回多段名(用点号连接),保留层级结构信息
      • 使用场景
        • 环境层(TSQLEnv)处理完整限定名
        • 名称比较和匹配(需要保留层级信息)
        • 快速索引查找(NameKey 构造)

      与相关方法的区别

      • normalizeIdentifier(EDbVendor, ESQLDataObjectType, String): 单段规范化,不解析限定名,直接处理引号和大小写,返回单段名
      • IdentifierService.keyForMap(String, ESQLDataObjectType): 仅接受单段名,用于生成 Map 的 key,会抛出异常如果输入是多段名
      • IdentifierService.normalizeQualifiedName(String, ESQLDataObjectType): 新架构中的等价方法,提供相同的多段名规范化功能

      厂商特定行为

      • MySQL: 仅支持 catalog(即 database),反引号引用,大小写根据系统变量决定
      • PostgreSQL: 仅支持 schema,双引号引用,未加引号的标识符转小写
      • SQL Server: 支持 catalog+schema,方括号或双引号引用,".." 展开为 ".dbo."
      • Oracle: 仅支持 schema,双引号引用,未加引号的标识符转大写
      • Snowflake: 支持 catalog+schema,双引号引用,大小写保留但匹配不敏感
      • BigQuery: 支持 catalog+schema(项目+数据集),反引号引用,大小写不敏感,可能内部转小写
      Parameters:
      dbVendor - 数据库厂商类型(决定层级支持、引号风格、大小写规则)
      name - 原始标识符或多段限定名(可能包含引号/反引号;可能包含 catalog/schema 前缀; 可能包含厂商特定语法如 MSSQL 的 "..")
      sqlDataObjectType - 期望的对象类型(例如 dotTable, dotColumn, dotSchema, dotCatalog), 用于指导段类型推断和规范化规则应用
      Returns:
      规范化后的完整限定名,用点号连接各段;如果输入为 null,返回 null; 如果输入为空字符串或无法解析,返回空字符串
      Since:
      3.1.0.8
      See Also:
    • mergeSegments

      public static String mergeSegments(List<String> segments, int index)
    • isTempTable

      public static boolean isTempTable(table table)
    • listFiles

      public static File[] listFiles(File sqlFiles)
    • listFiles

      public static File[] listFiles(File sqlFiles, FileFilter filter)
    • listFiles

      public static void listFiles(File rootFile, List<File> children)
    • listFiles

      public static void listFiles(File rootFile, List<File> children, FileFilter filter)
    • readFile

      public static String readFile(File file)
    • stringToMD5

      public static String stringToMD5(String plainText)
    • trimSingleQuote

      public static String trimSingleQuote(String columnAlias)
    • endTrim

      public static String endTrim(String input)
    • endTrim

      public static void endTrim(StringBuilder buffer)