Package dev.frostlake.executor
Class SqlIdentifiers
java.lang.Object
dev.frostlake.executor.SqlIdentifiers
Canonical form of a SQL identifier, matching Snowflake's identifier resolution:
- an unquoted identifier folds to UPPERCASE (
site→SITE, so it lands in the catalog, INFORMATION_SCHEMA, SHOW output and result-set column labels the same way Snowflake stores it); - a "double-quoted" identifier keeps its exact case (the surrounding quotes are stripped);
- a
$npositional parameter becomesCOLUMNn.
Name resolution is already case-insensitive (storage keys are upper-cased and column lookups use
equalsIgnoreCase), so folding changes only the canonical/display name, never whether a name
resolves. Every identifier-name extraction point routes through here so the behaviour is uniform.
-
Method Summary
Modifier and TypeMethodDescriptionstatic Stringstatic StringcanonicalText(String text) static String[]canonicalTextParts(String text) The canonical PARTS of a runtime-string object name —canonicalText(java.lang.String)without the rejoin, for callers that resolve per level: a double-quoted part containing a dot survives as ONE part here, where the joined spelling can no longer show where its dots came from.static String[]The canonical parts of anIDENTIFIER(...)argument's value:canonicalTextParts(java.lang.String), with an empty middle part ('db..t') read as the PUBLIC schema, as the account reads it.static StringidentifierReferenceParts(java.lang.String), joined the waycanonicalText(java.lang.String)joins.static booleanisIdentifierReference(String text) Whether a runtime string reads as an identifier reference, the way IDENTIFIER() reads its argument.static StringAn ALREADY-CANONICAL dotted name spelled back, part by part, without canonicalising it again.static StringspellAsWritten(String rawToken) One name part spelled the way live ECHOES it in a refusal: a quoted token stays verbatim, quotes and case intact, and an unquoted one folds to upper case.static StringspellCanonical(String name) A CANONICAL name spelled the way a refusal prints it: bare when it could have been written without quotes, quoted otherwise.static StringspellCanonicalPath(String path) static StringThe identifier EXACTLY as written — quotes stripped, but no case folding.
-
Method Details
-
verbatim
The identifier EXACTLY as written — quotes stripped, but no case folding. Structured-type field names are the one place Snowflake does not fold: live-verified,CAST(OBJECT_CONSTRUCT('x','a') AS OBJECT(x VARCHAR))yields{"x":"a"}while the same cast toOBJECT(X VARCHAR)FAILS "Typed object schema mismatch in conversion" — the unquotedXstayed upper case and did not match the keyx. -
canonical
-
spellAsWritten
One name part spelled the way live ECHOES it in a refusal: a quoted token stays verbatim, quotes and case intact, and an unquoted one folds to upper case."a"andaname different columns, so the two cannot be printed alike. -
spellCanonical
A CANONICAL name spelled the way a refusal prints it: bare when it could have been written without quotes, quoted otherwise. The same rulespellAsWritten(java.lang.String)applies to a raw token, for callers that hold a name already resolved — an object's stored identity, a folded function name, the relation and column of the grouped sentence.- Parameters:
name- the canonical name- Returns:
- the name as a refusal spells it
-
spellAlreadyCanonicalPath
An ALREADY-CANONICAL dotted name spelled back, part by part, without canonicalising it again.The distinction from
spellCanonicalPath(java.lang.String)is the whole point: that one canonicalises first, which is right for text as the user WROTE it and wrong for a name that has already been through the mill. A canonical name has had its quotes removed and its case kept, so a second pass sees an unquotedtest_schema, finds no quotes to protect it, and folds it — which is howTEST_DB."test_schema"came back asTEST_DB.TEST_SCHEMA.- Parameters:
path- the already-canonical name, parts separated by dots- Returns:
- the name spelled with quotes only where a part needs them
-
spellCanonicalPath
-
isIdentifierReference
Whether a runtime string reads as an identifier reference, the way IDENTIFIER() reads its argument. Once trimmed, each dotted part is a closed double-quoted identifier or an unquoted one: a letter or an underscore, then letters, digits, underscores and dollars. An empty part stands for the default database or schema (a..b), but the empty string names nothing (live-verified).- Parameters:
text- the evaluated argument- Returns:
- true when every part is an identifier
-
canonicalText
-
identifierReferenceParts
The canonical parts of anIDENTIFIER(...)argument's value:canonicalTextParts(java.lang.String), with an empty middle part ('db..t') read as the PUBLIC schema, as the account reads it. -
identifierReferenceText
identifierReferenceParts(java.lang.String), joined the waycanonicalText(java.lang.String)joins. -
canonicalTextParts
The canonical PARTS of a runtime-string object name —canonicalText(java.lang.String)without the rejoin, for callers that resolve per level: a double-quoted part containing a dot survives as ONE part here, where the joined spelling can no longer show where its dots came from. The same not-already-canonicalised caveat ascanonicalText(java.lang.String)applies.
-