| Modifier and Type | Class and Description |
|---|---|
static class |
SQLUtil.UnicodeInputStream |
| Constructor and Description |
|---|
SQLUtil() |
| Modifier and Type | Method and Description |
|---|---|
static void |
appendToFile(File file,
String string) |
static CanonKey |
canonKey(EDbVendor dbVendor,
ESQLDataObjectType objectType,
String identifier)
Canonical identity key of a single identifier segment — key equality is exactly
sameName(gudusoft.gsqlparser.EDbVendor, gudusoft.gsqlparser.sqlenv.ESQLDataObjectType, java.lang.String, java.lang.String) (see CanonKey; in-process
only, never persist). |
static boolean |
compareIdentifier(EDbVendor dbVendor,
ESQLDataObjectType sqlDataObjectType,
String identifier1,
String identifier2) |
static String |
decodeDelimitedName(EDbVendor vendor,
ESQLDataObjectType objectType,
String name)
Decode a delimited identifier spelling to the undelimited name a catalog
stores, WITHOUT case folding:
[Volgorde], "Volgorde",
`Volgorde` and the SQL Server legacy column-alias form
'Volgorde' all decode to Volgorde, and escaped delimiters
resolve ([Esc]]aped] → Esc]aped). |
static void |
deltree(File root) |
static String |
endTrim(String input) |
static void |
endTrim(StringBuilder buffer) |
static String |
formatSql(EDbVendor dbVendor,
String inputQuery) |
static String |
getFileContent(File file) |
static String |
getFileContent(String filePath) |
static String |
getIdentifierNormalColumnName(EDbVendor dbVendor,
String name)
Legacy display/normal-name form of a column reference.
|
static String |
getIdentifierNormalName(EDbVendor dbVendor,
String name,
ESQLDataObjectType sqlDataObjectType)
规范化多段限定名(Multi-Segment Qualified Name)并返回规范化后的完整限定名。
|
static String |
getIdentifierNormalTableName(EDbVendor dbVendor,
String name)
Legacy display/normal-name form of a table reference.
|
static String |
getIdentifierNormalTableName(String name)
Legacy display/normal-name form of a table reference (global analysis vendor).
|
static String |
getInputStreamContent(InputStream is,
boolean close) |
static InputStream |
getInputStreamWithoutBom(String file) |
static long |
hash64(CharSequence cs) |
static boolean |
isEmpty(String value) |
static boolean |
isTempTable(table table) |
static String |
joinNonEmpty(String... parts) |
static File[] |
listFiles(File sqlFiles) |
static File[] |
listFiles(File sqlFiles,
FileFilter filter) |
static void |
listFiles(File rootFile,
List<File> children) |
static void |
listFiles(File rootFile,
List<File> children,
FileFilter filter) |
static void |
main(String[] args)
A delimited segment is truly CLOSED only when it ends with an ODD run
of the close delimiter: every vendor whose quoted identifiers this
splitter merges escapes the close delimiter by doubling it, so a
trailing even run is escaped literal content and the segment
continues (
[a]] is an open bracket segment whose content so
far is a]; [a]]] is closed with content a]). |
static String |
mergeSegments(List<String> segments,
int index) |
static String |
normalizeIdentifier(EDbVendor dbVendor,
ESQLDataObjectType objectType,
String identifier)
Deprecated.
For equality tests use
sameName(EDbVendor, ESQLDataObjectType,
String, String) / compareIdentifier(EDbVendor, ESQLDataObjectType, String,
String) — never normalize-then-compare. For map keys use canonKey(EDbVendor,
ESQLDataObjectType, String) (or IdentifierService.keyForMap(String,
ESQLDataObjectType)); for the stored/display form use
IdentifierService.normalizeStatic(EDbVendor, ESQLDataObjectType, String).
Retained only for callers that persist the legacy normal form (e.g. dlineage
display names — see the identifier normalization guide §6). |
static List<String> |
parseNames(String nameString) |
static List<String> |
parseNames(String nameString,
EDbVendor vendor)
解析以点号分隔的 SQL 标识符或表达式,并返回各层级片段。
|
protected static List<String> |
putCache(String cacheKey,
List<String> names) |
static String |
quoteDottedName(EDbVendor vendor,
ESQLDataObjectType objectType,
String name)
Quote one name segment so its dots survive qualified-name splitting
(
parseNames(java.lang.String)), using the vendor's REAL quoted-identifier form. |
static String |
readFile(File file) |
static boolean |
sameName(EDbVendor dbVendor,
ESQLDataObjectType objectType,
String ident1,
String ident2)
Single-segment SQL identifier equality — the unified façade for
identifier-vs-identifier name comparisons (see
docs/refactor/identifier_normalization_unification_plan.md).
|
static String |
stringToMD5(String plainText) |
static String |
trimColumnStringQuote(String string) |
static String |
trimSingleQuote(String columnAlias) |
static void |
writeToFile(File file,
InputStream source,
boolean close) |
static void |
writeToFile(File file,
String string) |
public SQLUtil()
public static String getFileContent(File file)
public static String getInputStreamContent(InputStream is, boolean close)
public static String getFileContent(String filePath)
public static String quoteDottedName(EDbVendor vendor, ESQLDataObjectType objectType, String name)
parseNames(java.lang.String)), using the vendor's REAL quoted-identifier form.
This replaces the legacy
delimitedChar + trimColumnStringQuote(x) + delimitedChar
pattern, which used the OPEN delimiter on both ends and therefore
produced malformed spellings for open≠close vendors — MSSQL's
[a.b[ — that only survived via lenient first/last-char
stripping and broke parseNames(java.lang.String) segmentation
([a.b[.dbo reads as ONE unterminated segment; the repaired
[a.b].dbo reads as two).
Existing quoting on the input is removed by a REAL decode where
possible: input the vendor's codec recognizes as quoted goes through
IdentifierCodec.decodeLexical(gudusoft.gsqlparser.sqlenv.IdentifierProfile, gudusoft.gsqlparser.sqlenv.ESQLDataObjectType, java.lang.String) (so embedded escaped delimiters
like [a]]b.c] decode to a]b.c and are not re-escaped
twice); malformed or vendor-foreign wrappers fall back to the lenient
legacy strip (trimColumnStringQuote(java.lang.String)). The stored text is then
re-encoded with IdentifierCodec.encodeStored(gudusoft.gsqlparser.sqlenv.IdentifierProfile, gudusoft.gsqlparser.sqlenv.ESQLDataObjectType, java.lang.String) (proper close
delimiter and escaping).
A vendor with no quoted-identifier syntax at all (SOQL) gets the stored text back UNCHANGED — the vendor cannot express a quoted spelling, and manufacturing one here would plant strings the codec itself refuses to recognize (a trap for the U5 recognition swap). A dotted name for such a vendor is unrepresentable vendor-side; how it segments internally is not this helper's contract.
vendor - database vendorobjectType - syntactic role of the segment (catalog/schema/table/column)name - the possibly-quoted, possibly-dotted name segmentpublic static String decodeDelimitedName(EDbVendor vendor, ESQLDataObjectType objectType, String name)
[Volgorde], "Volgorde",
`Volgorde` and the SQL Server legacy column-alias form
'Volgorde' all decode to Volgorde, and escaped delimiters
resolve ([Esc]]aped] → Esc]aped).
This is the decode half of normalizeIdentifier(gudusoft.gsqlparser.EDbVendor, gudusoft.gsqlparser.sqlenv.ESQLDataObjectType, java.lang.String), split out for
callers that publish a DISPLAY name and must therefore preserve the
author's letter case — dlineage's column names, whose consumers match
them against sys.columns and other catalog assets. Recognition is
vendor- and role-aware, so a form that is not a delimiter for the vendor
is left alone (brackets are array subscripts, not delimiters, in
BigQuery).
Input that the vendor's codec does not recognize as quoted, or that
starts with a delimiter but is malformed ([a.b[), is returned
UNCHANGED — guessing a payload by stripping the first and last code units
is the fabrication this program removed.
The caller owns identifier provenance. Only pass a string that
came from an identifier token (a TObjectName part token or a
TAliasClause alias name). A SQL string literal renders as quoted
text too, and decoding one would silently corrupt the VALUE — for SQL
Server, 'literal value' is a legal column alias spelling AND a
legal string constant, and nothing in the string itself tells them apart.
vendor - database vendorobjectType - syntactic role of the name (quote rules are per-role:
the SQL Server apostrophe form is recognized for
dotColumn only)name - a single, possibly-delimited name segmentname unchanged when it is not a
well-formed delimited spelling for this vendor and rolepublic static String trimColumnStringQuote(String string)
public static List<String> parseNames(String nameString)
public static List<String> parseNames(String nameString, EDbVendor vendor)
用途:
"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)"]
nameString - 待解析的标识符或表达式字符串vendor - 数据库厂商(用于处理厂商特定定界符,如 BigQuery 的反引号),可为 nullpublic static void main(String[] args)
[a]] is an open bracket segment whose content so
far is a]; [a]]] is closed with content a]).seg - the (trimmed) piece to examinecontentFrom - index where content starts (1 for the piece that
carries the opening delimiter, 0 for merge pieces)endDelim - the close delimiterpublic static void writeToFile(File file, InputStream source, boolean close)
public static void writeToFile(File file, String string) throws IOException
IOExceptionpublic static void appendToFile(File file, String string) throws IOException
IOExceptionpublic static InputStream getInputStreamWithoutBom(String file) throws IOException
IOExceptionpublic static boolean sameName(EDbVendor dbVendor, ESQLDataObjectType objectType, String ident1, String ident2)
Both arguments must be a single name segment (no a.b qualification);
qualified names are segmented by compareIdentifier(EDbVendor,
ESQLDataObjectType, String, String), which compares segment by segment.
POLICY: CANONICAL (since P0d.2). Equality is canonical-key
equality (canonKey(gudusoft.gsqlparser.EDbVendor, gudusoft.gsqlparser.sqlenv.ESQLDataObjectType, java.lang.String)): each operand is quote-stripped and folded by its own
quote state under the vendor's identifier rules, then compared exactly. The
relation is an equivalence relation, safe as a map-key contract, and matches how
names are stored (Oracle unquoted foo ≡ quoted "FOO", never
"foo").
dbVendor - database vendor whose identifier rules applyobjectType - kind of database object the names refer toident1 - first identifier segment (may be quoted)ident2 - second identifier segment (may be quoted)public static CanonKey canonKey(EDbVendor dbVendor, ESQLDataObjectType objectType, String identifier)
sameName(gudusoft.gsqlparser.EDbVendor, gudusoft.gsqlparser.sqlenv.ESQLDataObjectType, java.lang.String, java.lang.String) (see CanonKey; in-process
only, never persist).public static boolean compareIdentifier(EDbVendor dbVendor, ESQLDataObjectType sqlDataObjectType, String identifier1, String identifier2)
@Deprecated public static String normalizeIdentifier(EDbVendor dbVendor, ESQLDataObjectType objectType, String identifier)
sameName(EDbVendor, ESQLDataObjectType,
String, String) / compareIdentifier(EDbVendor, ESQLDataObjectType, String,
String) — never normalize-then-compare. For map keys use canonKey(EDbVendor,
ESQLDataObjectType, String) (or IdentifierService.keyForMap(String,
ESQLDataObjectType)); for the stored/display form use
IdentifierService.normalizeStatic(EDbVendor, ESQLDataObjectType, String).
Retained only for callers that persist the legacy normal form (e.g. dlineage
display names — see the identifier normalization guide §6).CanonKey map-key convention. Multi-segment inputs are returned in their origin (only case-collapsed)
form.public static String getIdentifierNormalColumnName(EDbVendor dbVendor, String name)
equals/equalsIgnoreCase is the
pre-P0d bug pattern — use sameName(EDbVendor, ESQLDataObjectType, String,
String) / compareIdentifier(EDbVendor, ESQLDataObjectType, String, String)
instead.public static String getIdentifierNormalTableName(String name)
sameName(EDbVendor,
ESQLDataObjectType, String, String) / compareIdentifier(EDbVendor,
ESQLDataObjectType, String, String), never string compares on this result.public static String getIdentifierNormalTableName(EDbVendor dbVendor, String name)
sameName(EDbVendor, ESQLDataObjectType, String, String) /
compareIdentifier(EDbVendor, ESQLDataObjectType, String, String).public static String getIdentifierNormalName(EDbVendor dbVendor, String name, ESQLDataObjectType sqlDataObjectType)
本方法是 SQL 标识符规范化的多段名处理版本,接受包含多段(catalog.schema.table.column)的限定名, 根据数据库厂商特性、层级支持能力和对象类型,智能解析和规范化每个段,最后返回用点号连接的完整规范化名称。
"db..table" → "db.dbo.table"parseNames(String) 将限定名按点号分割成段列表sqlDataObjectType)normalizeIdentifier(EDbVendor, ESQLDataObjectType, String),
应用厂商特定的大小写规则、引号处理等假设数据库同时支持 catalog 和 schema,目标类型为 dotTable:
"a.b.c" → 解析为 catalog.schema.table"a.b" → 解析为 schema.table"a" → 解析为 table假设数据库仅支持 catalog(如 MySQL),目标类型为 dotTable:
"a.b" → 解析为 catalog.table"a" → 解析为 table假设数据库仅支持 schema(如 PostgreSQL),目标类型为 dotTable:
"a.b" → 解析为 schema.table"a" → 解析为 table列名可能有4段(catalog.schema.table.column),方法会根据实际段数自动调整解析策略:
"db.sch.tbl.col" → catalog.schema.table.column"sch.tbl.col" → schema.table.column"tbl.col" → table.column"col" → column当段数超过标准层级时(如表名有4段或更多),方法会使用 mergeSegments(List, int)
将多余的尾部段合并为单个段(保留点号),然后作为最后一段进行规范化。
示例:5段列名 "db.sch.tbl.nested.col" → 合并后4段处理:
"db.sch.tbl.nested.col" (最后两段合并为 "nested.col")
normalizeIdentifier(EDbVendor, ESQLDataObjectType, String):
单段规范化,不解析限定名,直接处理引号和大小写,返回单段名IdentifierService.keyForMap(String, ESQLDataObjectType):
仅接受单段名,用于生成 Map 的 key,会抛出异常如果输入是多段名IdentifierService.normalizeQualifiedName(String, ESQLDataObjectType):
新架构中的等价方法,提供相同的多段名规范化功能dbVendor - 数据库厂商类型(决定层级支持、引号风格、大小写规则)name - 原始标识符或多段限定名(可能包含引号/反引号;可能包含 catalog/schema 前缀;
可能包含厂商特定语法如 MSSQL 的 "..")sqlDataObjectType - 期望的对象类型(例如 dotTable, dotColumn, dotSchema, dotCatalog),
用于指导段类型推断和规范化规则应用null,返回 null;
如果输入为空字符串或无法解析,返回空字符串
等价性警告(equality warning):本方法产出的是显示/存储用的规范名,
不是等价比较原语。判断两个名字是否指向同一数据库对象,请使用
compareIdentifier(EDbVendor, ESQLDataObjectType, String, String)(多段限定名)
或 sameName(EDbVendor, ESQLDataObjectType, String, String)(单段),
不要对两个规范名的返回值做 equals/equalsIgnoreCase 比较 —— 那是 P0d
统一化之前的 bug 模式。详见 gsp_java_core/doc/user_guide/identifier_normalization_guide.md。
单段规范化方法,
多段名解析方法,
段合并工具方法,
TSQLEnv.normalizeIdentifier(EDbVendor, ESQLDataObjectType, String),
Phase 0 新架构中的等价方法public static String mergeSegments(List<String> segments, int index)
public static boolean isTempTable(table table)
public static File[] listFiles(File sqlFiles, FileFilter filter)
public static void listFiles(File rootFile, List<File> children, FileFilter filter)
public static String stringToMD5(String plainText)
public static String trimSingleQuote(String columnAlias)
public static void endTrim(StringBuilder buffer)
public static String joinNonEmpty(String... parts)
public static long hash64(CharSequence cs)