Documentation
¶
Overview ¶
Package sqlident reads postgres identifiers out of SQL text.
forge reads migration DDL as text wherever no postgres is at hand: `forge project shapes`, `forge map`, the migration-context reader behind entity births, the read-only-fields and column-markers lints, and the unscoped_auth audit. Each used to spell its own identifier pattern, and each spelled only the bare case, `tasks`. pg_dump writes `CREATE TABLE public.tasks`; hand-written DDL writes `"public"."tasks"` or `public."Tasks"`. A pattern that stops at the first `.` read all of those as a table named `public`, and one that stops at a `"` missed the statement outright.
This package is the one place that knows the grammar. A name is one to three parts separated by `.` (catalog.schema.name), with optional whitespace around each dot. A part is either unquoted — a letter or `_`, then letters, digits, `_` or `$` — which postgres folds to lower case, or double-quoted — any characters, `""` standing for one quote — which postgres keeps verbatim. Normalizing the same way postgres resolves the name is what lets a textual reader agree with the applied schema.
Index ¶
Constants ¶
const Part = `(?:"(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_$]*)`
Part is a regexp fragment matching one identifier part, quoted or not. It has no capture group, so it composes into a caller's pattern without renumbering that pattern's groups.
const Qualified = `(?:` + Part + `\s*\.\s*){0,2}` + Part
Qualified is a regexp fragment matching a name of one to three parts (`tasks`, `public.tasks`, `"public"."Tasks"`, `public.tasks.owner_id`). No capture group, like Part. The repetition is greedy, so a caller that captures it gets the whole qualified name; pass the capture to Parts or Last to read it.
Variables ¶
This section is empty.
Functions ¶
func Last ¶
Last returns the normalized last part of a name: the object's own name, with any schema (and catalog) qualification dropped. `public.tasks`, `"public"."tasks"` and `tasks` all return "tasks".
func Parts ¶
Parts splits a name matched by Qualified into its parts, each normalized as postgres resolves it: an unquoted part folded to lower case, a quoted one unquoted verbatim. `public."Tasks"` is ["public", "Tasks"]. Text that is not a name yields whatever parts precede the first character that cannot continue one.
Types ¶
This section is empty.