Liking cljdoc? Tell your friends :D

datahike.pg.sql.ddl

DDL translation: CREATE TABLE, CREATE SEQUENCE, constraint extraction.

Produces Datahike tx-data that installs schema attributes (:db/ident, :db/valueType, :db/cardinality, :db/unique, :pg/type, and the pgwire-specific :pg/* constraint metadata).

The predicate helpers (identity-column?, column-is-primary-key?, column-is-unique?, column-is-not-null?, specs-contain-seq?, column-check-expr-text, column-default-spec) walk JSqlParser's ColumnDefinition.getColumnSpecs lists, which are raw strings — so each predicate is a case-insensitive token matcher.

Entry points:

  • translate-create-table — main; returns {:type :ddl :tx-data [...]}
  • translate-create-sequence — CREATE SEQUENCE name [...]

Helpers:

  • extract-ddl-constraints — CHECK / NOT NULL / UNIQUE / FK clauses
  • extract-inherits — PostgreSQL INHERITS
DDL translation: CREATE TABLE, CREATE SEQUENCE, constraint extraction.

Produces Datahike tx-data that installs schema attributes (`:db/ident`,
`:db/valueType`, `:db/cardinality`, `:db/unique`, `:pg/type`, and the
pgwire-specific `:pg/*` constraint metadata).

The predicate helpers (`identity-column?`, `column-is-primary-key?`,
`column-is-unique?`, `column-is-not-null?`, `specs-contain-seq?`,
`column-check-expr-text`, `column-default-spec`) walk JSqlParser's
`ColumnDefinition.getColumnSpecs` lists, which are raw strings — so
each predicate is a case-insensitive token matcher.

Entry points:
  - translate-create-table    — main; returns {:type :ddl :tx-data [...]}
  - translate-create-sequence — CREATE SEQUENCE name [...]

Helpers:
  - extract-ddl-constraints — CHECK / NOT NULL / UNIQUE / FK clauses
  - extract-inherits        — PostgreSQL INHERITS
raw docstring

column-check-expr-textclj

(column-check-expr-text col)

Extract the text of an inline CHECK (…) constraint from a ColumnDefinition's ColumnSpecs, or nil if none.

JSqlParser emits inline CHECK as two tokens: CHECK and a second token that's the entire parenthesized expression, e.g. ["CHECK" "(x > 0)"]. We keep the inner text.

Also tolerate the tokenized form PG dialect dumps sometimes produce — CHECK followed by (, individual tokens, ) — by paren-matching across the remaining specs.

Extract the text of an inline `CHECK (…)` constraint from a
ColumnDefinition's ColumnSpecs, or nil if none.

JSqlParser emits inline CHECK as two tokens: `CHECK` and a second
token that's the entire parenthesized expression, e.g.
`["CHECK" "(x > 0)"]`. We keep the inner text.

Also tolerate the tokenized form PG dialect dumps sometimes
produce — CHECK followed by `(`, individual tokens, `)` — by
paren-matching across the remaining specs.
sourceraw docstring

column-default-specclj

(column-default-spec col)

If the column spec list carries DEFAULT <expr>, return a map describing the default so translate-create-table can attach it to the schema entity. Shape:

{:kind :literal :value <long|double|string|boolean|nil>} {:kind :fn :value <canonical fn name string>} {:kind :nextval :value <sequence name string>} {:kind :unsupported :raw <original SQL text>}

The literal branch handles numbers, single-quoted strings, boolean keywords, and NULL. The :fn branch covers the stateless current-* functions PG users rely on. :nextval is the only stateful default we support and it ties into our existing sequence infrastructure. Unknown expressions land in :unsupported so CREATE TABLE can raise loudly instead of silently dropping the constraint.

Walks the ColumnSpecs as whitespace-separated tokens; tolerant of parens (e.g. DEFAULT (now())).

If the column spec list carries `DEFAULT <expr>`, return a map
describing the default so translate-create-table can attach it to
the schema entity. Shape:

  {:kind :literal  :value <long|double|string|boolean|nil>}
  {:kind :fn       :value <canonical fn name string>}
  {:kind :nextval  :value <sequence name string>}
  {:kind :unsupported :raw <original SQL text>}

The literal branch handles numbers, single-quoted strings, boolean
keywords, and NULL. The :fn branch covers the stateless current-*
functions PG users rely on. :nextval is the only stateful default
we support and it ties into our existing sequence infrastructure.
Unknown expressions land in :unsupported so CREATE TABLE can
raise loudly instead of silently dropping the constraint.

Walks the ColumnSpecs as whitespace-separated tokens; tolerant of
parens (e.g. `DEFAULT (now())`).
sourceraw docstring

column-is-not-null?clj

(column-is-not-null? col)

True when the column-spec list carries NOT NULL. PK columns are implicitly NOT NULL in PG; callers should combine this with column-is-primary-key? to avoid double-flagging.

True when the column-spec list carries `NOT NULL`. PK columns are
implicitly NOT NULL in PG; callers should combine this with
column-is-primary-key? to avoid double-flagging.
sourceraw docstring

column-is-primary-key?clj

(column-is-primary-key? col)

True when a column has inline PRIMARY KEY in its column specs.

True when a column has inline PRIMARY KEY in its column specs.
sourceraw docstring

column-is-unique?clj

(column-is-unique? col)

True when a column has inline UNIQUE in its column specs (not part of PRIMARY KEY, which we handle separately).

True when a column has inline UNIQUE in its column specs (not part of
PRIMARY KEY, which we handle separately).
sourceraw docstring

extract-ddl-constraintsclj

(extract-ddl-constraints ct)

Collect PRIMARY KEY and UNIQUE constraints from a CreateTable into a normalized shape. Merges column-level specs (id INT PRIMARY KEY) with table-level indexes (PRIMARY KEY (a,b), UNIQUE (c)).

Returns a map: :pk-cols — vector of column names in the PK (empty if none) :pk-name — explicit constraint name for the PK, or nil :uniques — vector of {:cols [str...] :name str-or-nil} each an independent UNIQUE constraint Column names are the raw SQL idents (unquoted), not namespaced keywords. The caller owns the :t/col namespace mapping.

Collect PRIMARY KEY and UNIQUE constraints from a CreateTable into a
normalized shape. Merges column-level specs (`id INT PRIMARY KEY`) with
table-level indexes (`PRIMARY KEY (a,b), UNIQUE (c)`).

Returns a map:
  :pk-cols       — vector of column names in the PK (empty if none)
  :pk-name       — explicit constraint name for the PK, or nil
  :uniques       — vector of {:cols [str...] :name str-or-nil}
                   each an independent UNIQUE constraint
Column names are the raw SQL idents (unquoted), not namespaced keywords.
The caller owns the :t/col namespace mapping.
sourceraw docstring

extract-inheritsclj

(extract-inherits ct)

Extract parent table name from INHERITS clause in CREATE TABLE options.

Extract parent table name from INHERITS clause in CREATE TABLE options.
sourceraw docstring

identity-column?clj

(identity-column? col)

Check if a JSqlParser ColumnDefinition has GENERATED BY DEFAULT AS IDENTITY or uses a SERIAL type (which implies auto-increment).

Check if a JSqlParser ColumnDefinition has GENERATED BY DEFAULT AS IDENTITY
or uses a SERIAL type (which implies auto-increment).
sourceraw docstring

pg-type-hintclj

(pg-type-hint base-type array?)

The :pg/type a column of SQL type base-type should record, or nil when the storage valueType already implies the right OID.

Datahike collapses whole families onto one carrier — every integer is :db.type/long, every temporal is :db.type/instant, jsonb and bit are :db.type/string — so this hint is the ONLY thing that lets the catalog report date rather than timestamp, or int4 rather than int8. Drivers pick codecs off those OIDs.

Extracted so ALTER TABLE ... ADD COLUMN records the same hints CREATE TABLE does. It previously recorded them only for json/jsonb, so a column added by ALTER as date or smallint reported the storage type forever after.

array? suppresses the scalar hints: an int[] column has base-type "int" too and its array :pg/type ("_int4") is set elsewhere.

The `:pg/type` a column of SQL type `base-type` should record, or nil
when the storage valueType already implies the right OID.

Datahike collapses whole families onto one carrier — every integer is
:db.type/long, every temporal is :db.type/instant, jsonb and bit are
:db.type/string — so this hint is the ONLY thing that lets the
catalog report `date` rather than `timestamp`, or `int4` rather than
`int8`. Drivers pick codecs off those OIDs.

Extracted so `ALTER TABLE ... ADD COLUMN` records the same hints
CREATE TABLE does. It previously recorded them only for json/jsonb,
so a column added by ALTER as `date` or `smallint` reported the
storage type forever after.

`array?` suppresses the scalar hints: an `int[]` column has base-type
"int" too and its array `:pg/type` ("_int4") is set elsewhere.
sourceraw docstring

sequence-entityclj

(sequence-entity seq-name
                 {:keys [increment minvalue maxvalue start cache cycle? type]})

The stored entity for a sequence with the given resolved params.

:__seq__/value holds the last value HANDED OUT, so a fresh sequence stores start - increment and the first advance lands exactly on start. (PG models this as last_value + is_called=false; the offset encoding is equivalent for a single-value-at-a-time nextval and is what the IDENTITY path in translate-create-table already assumes.)

The stored entity for a sequence with the given resolved params.

`:__seq__/value` holds the last value HANDED OUT, so a fresh sequence
stores `start - increment` and the first advance lands exactly on
start. (PG models this as last_value + is_called=false; the offset
encoding is equivalent for a single-value-at-a-time nextval and is
what the IDENTITY path in translate-create-table already assumes.)
sourceraw docstring

sequence-paramsclj

(sequence-params opts {:keys [existing]})

Resolve a classifier option list into concrete sequence parameters, applying PG's defaults and raising PG's errors.

Mirrors init_params (postgres src/backend/commands/sequence.c:1260) including its ORDER, because a statement with more than one problem must report the same one PG reports: duplicate detection, then AS, INCREMENT, CYCLE, MAXVALUE, MINVALUE, the min/max crosscheck, START, RESTART, CACHE.

existing is the current parameter map for ALTER (nil for CREATE); options left unspecified keep their existing values on ALTER and take the defaults on CREATE.

Returns {:type :increment :minvalue :maxvalue :start :cache :cycle? :restart :owned-by}.

Resolve a classifier option list into concrete sequence parameters,
applying PG's defaults and raising PG's errors.

Mirrors `init_params` (postgres src/backend/commands/sequence.c:1260)
including its ORDER, because a statement with more than one problem
must report the same one PG reports: duplicate detection, then AS,
INCREMENT, CYCLE, MAXVALUE, MINVALUE, the min/max crosscheck, START,
RESTART, CACHE.

`existing` is the current parameter map for ALTER (nil for CREATE);
options left unspecified keep their existing values on ALTER and take
the defaults on CREATE.

Returns {:type :increment :minvalue :maxvalue :start :cache :cycle?
         :restart :owned-by}.
sourceraw docstring

sequence-schemaclj

Schema attributes backing a sequence entity. Idempotent — re-transacted on every CREATE SEQUENCE.

Schema attributes backing a sequence entity. Idempotent — re-transacted
on every CREATE SEQUENCE.
sourceraw docstring

specs-contain-seq?clj

(specs-contain-seq? specs tokens)

True when the whitespace-split column-spec list contains the given token sequence contiguously, case-insensitive. Used to detect PRIMARY KEY (two tokens) and UNIQUE (one token) inline on a ColumnDefinition.

True when the whitespace-split column-spec list contains the given token
sequence contiguously, case-insensitive. Used to detect PRIMARY KEY
(two tokens) and UNIQUE (one token) inline on a ColumnDefinition.
sourceraw docstring

translate-create-sequenceclj

(translate-create-sequence {:keys [seq-name seq-opts if-not-exists?]})

Translate a classified CREATE SEQUENCE into schema + initial entity.

Consumes the token classifier's :seq-opts rather than JSqlParser's AST: the grammar there covers only a subset of PG's option list, and the values used to be recovered by regex over the re-rendered SQL (increment\s+by\s+(\d+)), which could not see a negative increment and silently dropped MINVALUE/MAXVALUE/CACHE/CYCLE. See issue #21.

Translate a classified CREATE SEQUENCE into schema + initial entity.

Consumes the token classifier's `:seq-opts` rather than JSqlParser's
AST: the grammar there covers only a subset of PG's option list, and
the values used to be recovered by regex over the re-rendered SQL
(`increment\s+by\s+(\d+)`), which could not see a negative increment
and silently dropped MINVALUE/MAXVALUE/CACHE/CYCLE. See issue #21.
sourceraw docstring

translate-create-tableclj

(translate-create-table ct db)

Translate a CREATE TABLE statement to Datahike schema transaction data. Also returns :table-name, :column-order, :identity-cols, and :inherits.

Translate a CREATE TABLE statement to Datahike schema transaction data.
Also returns :table-name, :column-order, :identity-cols, and :inherits.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close