A query defines a reusable object-selection contract in Jetstack. It tells the platform which records should be returned, how they may be filtered or ordered, and whether the result set is intended for views, property selectors, permission evaluation, or saved user-facing query templates.
Queries are one of the main reuse mechanisms in the platform. The same query can shape:
That makes query design architectural, not just presentational.
This chapter explains:
Use it together with:
Keep these three layers separate:
This distinction is especially important for fixed parameters:
Jetstack defines four query roles:
ViewPropertyPermissionUser templateThe code explicitly describes this as categorization of the query by its primary intended use.
ViewUse this role for queries whose main purpose is to feed views.
This is the default query role.
Typical uses:
What it means in the platform:
View.relevant_queriesChoose View when the query is primarily about presenting or navigating a result set.
PropertyUse this role for queries whose main purpose is to provide selectable options to a property.
Typical uses:
What it means in the platform:
query_type = QT_PROPERTY in the property-type runtimeoptions_query, title_property, value_switch, and conditional selector behaviorChoose Property when the query exists primarily to populate a field, not to serve as a user-facing list.
PermissionUse this role for queries whose main purpose is to define access scope.
Typical uses:
What it means in the platform:
query_type = PermissionChoose Permission when the result set defines who may access what.
User templateUse this role for saved user-facing query states.
Typical uses:
What it means in the platform:
query_type = User templateChoose User template when the query is primarily a saved slice of a list experience, not a core implementation asset.
The fields below come from the query resource definition and the query create/edit flow.
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
query_name |
Main name of the query. | Enter a stable, descriptive name such as Active customers for selector, Contracts editable by owner, or Open invoices board. |
This is the title-role field and the most important identifier used by implementers. |
query_title |
Optional display title of the query. | Enter a friendlier or more presentation-oriented title if needed. | If left null, the runtime falls back to query_name. |
query_description |
Description of the query's purpose. | Describe what the query returns and why it exists. | This is especially valuable for permission and property queries where intent is not obvious from conditions alone. |
query_type |
Primary intended role of the query. | Choose one of View, Property, Permission, or User template. |
This is required. It is a categorization field, but it also matters because several parts of the platform filter or create queries by this role. |
owner |
Owning user for personal/private query scenarios. | Set this when the query should belong to a specific user. | This field comes from the broader system-resource surface and matters especially for private and user-template queries. |
publicity |
Reuse and visibility level of the query. | Choose System, Private, or Public. |
Use this to decide whether the query is an internal platform asset, a private user asset, or a reusable shared one. |
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
object_type |
Type of objects returned by the query. | Select the target type the query should operate on. | This is required. Almost every other query behavior depends on this. |
is_custom_query |
Whether the query uses custom SQL rather than only configured query parameters. | Enable when the standard configured-query model is not sufficient. | When this is enabled, the custom SQL fields become relevant. |
custom_query |
SQL text used for a custom query. | Enter the SQL in the custom query editor. | Visible only when is_custom_query is enabled. Use this only when the configured query model cannot express the needed behavior. |
custom_query_available_params |
Declared parameter contract for a custom query. | Define the available parameters as a struct/array. | This makes custom SQL reusable and parameterized instead of hard-coded. |
These fields store the baseline query state. They are mostly internal in the resource definition, but they are important because they represent what the query builder persists.
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
parameters |
Full stored query parameter payload. | Usually configured through the query builder, filters UI, or query runtime state rather than manual direct editing. | This is the most important stored state field for configured queries. |
conditions |
Stored low-level conditions for the query object. | Usually created by the query builder or query methods rather than hand-edited. | Think of this as internal query structure rather than business-facing configuration. |
order |
Stored ordering rules. | Set through sorting configuration in the query builder or runtime parameter flow. | Ordering may also be supplemented later by runtime sort parameters. |
page_length |
Baseline items-per-page value. | Set through pagination-related parameter editing. | This is part of stored query state and may also be fixed. |
groups |
Stored grouping configuration. | Set through grouping controls in the query builder. | Grouping is part of parameter state and can also be fixed. |
merges |
Stored merge or GROUP BY-like configuration. | Set through merge/grouping builder controls. | Merging has its own parameter family and is separate from ordinary grouping. |
show_cols |
Stored columns to show. | Usually configured through visible-column selection in the query/view builder. | These are baseline display columns, not necessarily the final runtime columns after user overrides. |
hide_cols |
Stored columns to hide. | Usually configured through hide-column controls. | Useful when a baseline query should intentionally suppress some available columns. |
select_cols |
Stored explicit select-column set. | Used when the query should explicitly select a known set of columns. | More internal and lower-level than ordinary display-column selection. |
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
relevant_views |
Views that are associated with this query. | The relationship is managed through view/query linking. | This is a virtual relationship from View.relevant_queries. It helps explain where the query is expected to be used. |
query_nameThis should describe both the data set and the reason it exists.
Good examples:
Open invoices for finance boardAssignable consultants for project formContracts visible to regional managerAvoid vague names like:
Test queryCustomer list 2Permission thingThe more strategic the query role, the more important clear naming becomes.
query_typeThis is one of the most important fields on the query because it tells future implementers how to reason about the query.
Use it as an explicit statement of design intent:
View: presentation-oriented reusable data setProperty: selector backing setPermission: access-scoping setUser template: saved end-user or view-state setIf a query could be used in multiple places, choose the role that best describes why it was created in the first place.
publicityAvailable values:
SystemPrivatePublicUse them like this:
System: platform-owned or implementation-owned query. Best for durable shared logic.Private: personal or owner-scoped query that should not be treated as general reusable infrastructure.Public: reusable shared query available as a tenant-level asset.This matters especially for user templates and shared view presets.
object_typeThis is the target model of the query.
It determines:
Changing object_type after a query is already in use is usually disruptive, because the entire parameter surface is type-dependent.
is_custom_queryEnable this only when the configured query model is not enough.
Good reasons:
Bad reasons:
custom_queryThis stores SQL text and is shown in a code editor when custom-query mode is enabled.
Use it with care:
Important runtime behavior:
That means custom queries are not just "configured queries with extra freedom." They follow a meaningfully different runtime path.
custom_query_available_paramsThis is the declared parameter contract for a custom SQL query.
The resource description says it is an array where:
"pX [default]"The query runtime also supports array-style parameter definitions with richer structure.
Supported shapes:
":status:Status" => "pText [active]"
This is parsed as:
{
":status:Status": {
"type": "pSelect",
"default": "active",
"select_options": {
"active": "Active",
"archived": "Archived"
}
}
}
The runtime resolves each declared parameter into:
nametitletypedefaultselect_optionsParameter-name behavior:
:, the runtime treats it as a named parameter definition: can contain both machine name and title, separated by another ::, the runtime treats it as a positional parameter title and assigns a numeric parameter nameThis is how custom SQL stays reusable instead of becoming hard-coded per use.
A configured query is primarily driven by stored query parameters:
Use configured queries when:
A custom query is primarily driven by SQL text and declared custom parameters.
Use custom queries when:
Configured queries are usually better for:
Custom queries are usually better for:
This is one of the most important distinctions in the query system.
Regular query parameters are ordinary stored parameter values, such as:
They define the baseline state of the query.
At runtime, those parameters may later be supplemented or overridden by:
Fixed query parameters are query parameters that are also marked as locked.
They are still represented through the same parameter families, but the system additionally stores fixed-parameter metadata in pfix_* fields such as:
pfix__filterspfix__columnspfix__hideColumnspfix__sortingpfix__groupingspfix__mergingspfix__calculationspfix__tagspfix__pagepfix__itemsPerPageWhat that means in runtime:
fixedParameters objectIn plain terms:
There are two important paths:
Some query helper methods explicitly allow a fixed flag:
setParam_grouping(..., fixed: true)setParam_displayCols(..., fixed: true)setParam_hideCols(..., fixed: true)setParam_tags(..., fixed: true, ...)When you pass fixed: true, the query writes both:
pfix__... metadataThe query builder exposes a dedicated fixed-parameters form where implementers can mark:
as fixed.
This is how most implementers will encounter the feature.
When a view loads a query:
viewQueryParametersuserQueryParametersfixedParameters objectThis is why fixed parameters are the right tool when a query must enforce:
This is also why fixed parameters are not the right tool when you only want a helpful default.
Use:
query_type = ViewThis is the standard list/query pattern.
Use:
query_type = PropertyThis query should optimize for option quality, not for list exploration.
Use:
query_type = PermissionThis query is part of the access-control model.
Use:
query_type = User templateThis is a saved slice of a list experience, not usually a core model asset.
Property queries for selectors so their intent is obvious.Permission queries as policy statements, not generic data sets.custom_query_available_params as a stable contract when other builders or integrations depend on the query.