Skip to main content

Queries — overview

A query in Liberty is a named SQL statement attached to a connector (which itself points at a pool, i.e. a database). Screens, dashboards, charts, dictionary lookups, dictionary sequences and the AI assistant all consume queries — so adding a query is the most common change you'll make in the Settings UI.

The page that manages queries is Settings → Connectors. This overview maps it; the next pages walk through each "add" path.


The Connectors page at a glance

Settings · Connectors+ ConnectorDiscardSaveAPPS▣ crm▣ nomajde▣ nomasx1DATA SOURCES⛁ default⛁ jdedwards⛁ reporting[connectors.crm] · sqlSettingsTablesUnclassifiedSequencesLookups+ TablecustomersPortfolio customersGETPUTPOSDELdealsOpen dealsGETPUTPOSDELactivitiesNotes and callsGETPUTPOSDEL

Three regions:

RegionWhat it carries
Top toolbarGlobal actions — + Connector, Discard, Save. The Save button writes the connector file and triggers a hot reload — no process restart needed.
Left navigationTwo groups: Apps (connectors that have a menu — these are the apps users see in the top switcher) and Data sources (connectors that supply data but don't appear in the switcher). Click a name to open it on the right.
Right paneThe editor for the selected connector. A mode bar across the top picks one of five views — Settings, Tables, Unclassified, Sequences, Lookups.

The four kinds of queries

Every query carries a type that tells the page which tab it belongs to:

TabtypeWhat lives here
TablestableQueries that follow the CRUD naming convention — <base>_get, <base>_put, <base>_post, <base>_delete. The page groups them by base name and shows a row per table with four slot badges (GET / PUT / POS / DEL).
UnclassifiedcustomStandalone queries not tied to a table CRUD set — bulk operations, business queries, reports. Example: monthly_revenue, purge_old_logs.
SequencessequenceQueries that generate the next value for a dictionary [sequences.*] rule. Typical body: SELECT COALESCE(MAX(<col>), 0) + 1 FROM <table>.
LookupslookupQueries that supply value + label pairs for a dictionary [lookups.*] rule. Typical body: SELECT <value>, <label> FROM <table>.

The tab the query falls into is decided by its type — not by its name. A query named customer_balance typed custom lives in Unclassified; the same name typed lookup lives in Lookups.


The add buttons — one per tab

The Add affordance is per tab, because each kind has its own creation flow.

TabAdd buttonWhat opens
Tables+ Add tableA choice modal: Generate from DB (the CRUD Wizard — introspects the pool, generates all four queries) or Empty stub (prompts a base name, creates a blank <base>_get stub).
Unclassified+ Add queryA name prompt — creates a blank custom query you fill in by hand.
Sequences+ Add sequenceThe Scaffold modal — pick a table, pick a key column, get a live SQL preview, save (writes the query and the matching dictionary entry).
Lookups+ Add lookupThe Scaffold modal — pick a table, pick a value column and a label column, optional WHERE filter, save (writes the query and the dictionary entry).

The next pages walk through each path.


What a query carries

The editor form (Unclassified / Sequences / Lookups tabs) reflects the QueryDef shape:

FieldRequiredWhat it does
nameYesUnique inside the connector. The permission string for this query is sql:<connector>:<name>. Read-only in the editor — use the Rename button (cross-file rename).
typeNotable / custom / sequence / lookup — drives which tab the query appears on. Empty falls back to a name-based guess.
sqlYesThe SQL statement with :placeholder parameters. Can be a single string, or a per-dialect map { default = "…", oracle = "…" }. The default variant is required when using a map.
writableNo (default false)When false, only SELECT is allowed. Flip to true for INSERT / UPDATE / DELETE / CALL.
paramsNoList of declared parameters (name, label, default) — gives each :placeholder a form input.
labelNoShort name shown in dropdowns and listings.
descriptionNoLonger text — shown on the Tables list under the base name. Use it to explain what the query returns.

Save and reload — what a click does

Saving on this page is atomic across two files when needed:

Action you tookWhat gets written
Created or edited a query under Tables / UnclassifiedThe connector file.
Used the Scaffold for a sequence or lookupThe connector file and the dictionary file (the new entry under [connectors.<name>.sequences] or [connectors.<name>.lookups]).
Cloned a connector (whole app)A cross-file write that copies the dictionary overlay, screens, menu, charts and dashboards under the new name. Goes through a dedicated endpoint.
Renamed a connector, a query or a tableA cross-file update that touches every reference (screens, menus, dictionary, charts, dashboards). Refuses to run when local edits aren't saved.

After every save the framework runs a hot reload automatically. The new query is callable immediately — no restart, no logout.


What you actually do — quick map

GoalRead
Generate the four CRUD queries from a real database table.Create from a database table — the wizard path, recommended when the table exists.
Write a custom query (standalone, hand-written).Create a custom query.
Make a copy of an existing query or of a whole application.Clone a query or a connector.
Add a sequence (next id) or a lookup (dropdown source).Sequences and lookups.
Pass values to a query — both literal and bound (#LOGIN_USER#, source columns…).Parameter binding.
Ship different SQL for Postgres vs Oracle.Per-dialect SQL variants.

What's next