Liking cljdoc? Tell your friends :D

datahike.pg.sql

SQL → Datahike Datalog translator.

Parses SQL strings using JSqlParser and translates the AST into Datahike Datalog queries that can be executed by datahike.api/q.

The core mapping: attribute namespace prefixes become virtual table names. :person/name → table 'person', column 'name' :person/age → table 'person', column 'age'

Main entry points: (parse-sql sql schema) → {:type :select :query {...} :args [...]} | {:type :insert :tx-data [...]} | {:type :system :result QueryResult} | {:type :error :message str}

SQL → Datahike Datalog translator.

Parses SQL strings using JSqlParser and translates the AST into Datahike
Datalog queries that can be executed by `datahike.api/q`.

The core mapping: attribute namespace prefixes become virtual table names.
  :person/name  → table 'person', column 'name'
  :person/age   → table 'person', column 'age'

Main entry points:
  (parse-sql sql schema)  → {:type :select :query {...} :args [...]}
                           | {:type :insert :tx-data [...]}
                           | {:type :system :result QueryResult}
                           | {:type :error :message str}
raw docstring

*ast-cache*clj

Server-wide JSqlParser AST cache, keyed on the preprocessed SQL string. Tests can rebind to an isolated map; nil disables caching.

Server-wide JSqlParser AST cache, keyed on the preprocessed SQL
string. Tests can rebind to an isolated map; nil disables caching.
sourceraw docstring

*catalog-cache*clj

Tests can rebind this to an isolated java.util.Map to keep their data from polluting the global cache (or vice versa). Nil disables caching entirely. Defaults to the server-wide cache.

Tests can rebind this to an isolated `java.util.Map` to keep their
data from polluting the global cache (or vice versa). Nil disables
caching entirely. Defaults to the server-wide cache.
sourceraw docstring

*parse-cache*clj

Server-wide cache for parse-sql results. Tests can rebind to an isolated map; nil disables caching entirely.

Server-wide cache for parse-sql results. Tests can rebind to an
isolated map; nil disables caching entirely.
sourceraw docstring

cached-resultclj

(cached-result k f)

The value of (f), kept in the parse-sql result cache under k, with the same LRU bound and the same clearing on DDL. k must hold everything the value depends on. A result of :type :error, or one that reads a session value, is not kept.

The value of (f), kept in the parse-sql result cache under `k`, with
the same LRU bound and the same clearing on DDL. `k` must hold
everything the value depends on. A result of :type :error, or one
that reads a session value, is not kept.
sourceraw docstring

catalog-basis-ofclj

(catalog-basis-of db)

The exact catalog/schema comparison value of db, as the parse cache's own key takes it: what a cached translation is valid for.

The exact catalog/schema comparison value of `db`, as the parse cache's
own key takes it: what a cached translation is valid for.
sourceraw docstring

cte-namespaceclj

(cte-namespace n cte-name)

The synthetic storage namespace for the nth CTE named cte-name.

Deterministic — a pure function of the SQL text — because the parse caches key on [sql (hash schema)], and a gensym/nanoTime namespace would change the enriched schema on every parse and turn every CTE query into a total cache miss.

The __cte prefix is reserved: datahike.pg.schema/internal-attr? filters it so a CTE can never surface as a table in pg_class or information_schema.

The synthetic storage namespace for the `n`th CTE named `cte-name`.

Deterministic — a pure function of the SQL text — because the parse
caches key on `[sql (hash schema)]`, and a gensym/nanoTime namespace
would change the enriched schema on every parse and turn every CTE
query into a total cache miss.

The `__cte` prefix is reserved: `datahike.pg.schema/internal-attr?`
filters it so a CTE can never surface as a table in pg_class or
information_schema.
sourceraw docstring

enrich-db-with-catalogsclj

(enrich-db-with-catalogs db schema catalog-names)

Materialise the given catalog tables' schema + data on top of db, returning the enriched db (its :schema carries the catalog attrs). Returns db unchanged when catalog-names is empty.

Only catalog schema fragments are cached. Catalog rows are derived from this exact input DB and materialized on top of it on every call. Thus a catalog join cannot accidentally inherit another call's user rows. schema is db's user schema.

Materialise the given catalog tables' schema + data on top of `db`,
returning the enriched db (its `:schema` carries the catalog attrs).
Returns `db` unchanged when `catalog-names` is empty.

Only catalog schema fragments are cached. Catalog rows are derived from
this exact input DB and materialized on top of it on every call. Thus a
catalog join cannot accidentally inherit another call's user rows.
`schema` is `db`'s user schema.
sourceraw docstring

invalidate-catalog-cache!clj

(invalidate-catalog-cache!)

Clear cached catalog schema fragments. Rows and enriched database snapshots are not cached: catalog extensions may read arbitrary current user data.

Clear cached catalog schema fragments. Rows and enriched database snapshots
are not cached: catalog extensions may read arbitrary current user data.
sourceraw docstring

invalidate-parse-cache!clj

(invalidate-parse-cache!)

Clear the server-wide parse-sql result cache. Called from every DDL exec branch (via server/invalidate-schema-cache!). Exact cache keys also detect native catalog changes. The AST cache is untouched: JSqlParser output depends only on SQL text.

Clear the server-wide parse-sql result cache. Called from every DDL
exec branch (via server/invalidate-schema-cache!). Exact cache keys also
detect native catalog changes. The AST cache is untouched: JSqlParser
output depends only on SQL text.
sourceraw docstring

parse-sqlclj

(parse-sql sql schema)
(parse-sql sql schema db)

Parse a SQL statement and return a translation result.

Returns one of: {:type :select :query <datalog-map> :find-aliases [...] ...} {:type :insert :tx-data [...] :count N} {:type :update :table str :ns str :assignments [...] :where-expr expr} {:type :delete :table str :ns str :where-expr expr} {:type :ddl-create :tx-data [...]} {:type :system :system-type keyword} {:type :error :message str}

Optional db parameter enables subquery execution during translation.

Three cache levels stack:

  • Result cache (*parse-cache*) — for SQL strings re-issued verbatim (pgjdbc unnamed prepared statements, ORM select-by-id).
  • Lexical INSERT-VALUES templating + AST cache — for INSERT INTO t [(cols)] VALUES (lit, …) shapes the literals are captured, the SQL is normalised to (? , …), and the resulting AST is reused across all rows of the same shape. Translation still runs per row with *bound-params* bound so JdbcParameter nodes resolve to concrete values inline (no ParamRef closure captures).
  • AST cache (*ast-cache*) — covers everything else that hits JSqlParser, repeated or not.
Parse a SQL statement and return a translation result.

Returns one of:
  {:type :select :query <datalog-map> :find-aliases [...] ...}
  {:type :insert :tx-data [...] :count N}
  {:type :update :table str :ns str :assignments [...] :where-expr expr}
  {:type :delete :table str :ns str :where-expr expr}
  {:type :ddl-create :tx-data [...]}
  {:type :system :system-type keyword}
  {:type :error :message str}

Optional db parameter enables subquery execution during translation.

Three cache levels stack:
  - **Result cache** (`*parse-cache*`) — for SQL strings re-issued
    verbatim (pgjdbc unnamed prepared statements, ORM select-by-id).
  - **Lexical INSERT-VALUES templating** + AST cache — for `INSERT
    INTO t [(cols)] VALUES (lit, …)` shapes the literals are
    captured, the SQL is normalised to `(? , …)`, and the resulting
    AST is reused across all rows of the same shape. Translation
    still runs per row with `*bound-params*` bound so JdbcParameter
    nodes resolve to concrete values inline (no ParamRef closure
    captures).
  - **AST cache** (`*ast-cache*`) — covers everything else that
    hits JSqlParser, repeated or not.
sourceraw docstring

simple-query-param-errorclj

(simple-query-param-error sql)

An {:type :error} map when sql uses a $N placeholder in the SIMPLE query protocol, else nil.

Simple Query has no Bind step, so there is nothing a placeholder could refer to and PostgreSQL raises 42P02. We used to translate the statement anyway and let the unresolved placeholder reach the client: SELECT $1 answered with the internal ParamRef record rendered as {"idx":1} — leaking a representation detail as if it were data.

Only reachable from the simple path; the extended path resolves placeholders at Bind. Gated on an indexOf so statements without a $ never pay for tokenising, and driven off the tokeniser's :param classification so a $ inside a string, a dollar-quoted body or a quoted identifier doesn't count.

An `{:type :error}` map when `sql` uses a `$N` placeholder in the
SIMPLE query protocol, else nil.

Simple Query has no Bind step, so there is nothing a placeholder
could refer to and PostgreSQL raises 42P02. We used to translate the
statement anyway and let the unresolved placeholder reach the client:
`SELECT $1` answered with the internal ParamRef record rendered as
`{"idx":1}` — leaking a representation detail as if it were data.

Only reachable from the simple path; the extended path resolves
placeholders at Bind. Gated on an indexOf so statements without a
`$` never pay for tokenising, and driven off the tokeniser's `:param`
classification so a `$` inside a string, a dollar-quoted body or a
quoted identifier doesn't count.
sourceraw docstring

translation-contextclj

(translation-context)

What a translation depends on besides its SQL, schema and catalog: the declared parameter types, the session's temp tables, whether the SQL is nested in a statement (see params/nested-parse?), search_path and the database. The cache is server-wide and its keys compare by value, so two databases built by the same DDL have equal schemas and an equal catalog basis; without the name they would share a plan.

What a translation depends on besides its SQL, schema and catalog: the
declared parameter types, the session's temp tables, whether the SQL is
nested in a statement (see params/*nested-parse?*), search_path and the
database. The cache is server-wide and its keys compare by value, so two
databases built by the same DDL have equal schemas and an equal catalog
basis; without the name they would share a plan.
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