The ARX specification
04 Queries
A **query** (`ArxQueryExpression`) names an entity and has criteria, columns, an order, links, aggregates and paging.
Criteria
The criteria are a filter: conditions joined by AND or OR, and nested filters. A condition is an attribute, an operator and its values. Every value is a parameter; a condition's attribute is a name and passes the name rules of chapter 07.
The truth table
"Present" means the record has the attribute and its value isn't null. These are the semantics every provider must
have, whatever its database does with nulls; vectors/conditions.json holds the cases.
| Operator | Matches when |
|---|---|
| Equal | present and equal to the value |
| NotEqual | present and not equal (a null or missing attribute never matches) |
| GreaterThan, GreaterEqual, LessThan, LessEqual | present and the comparison holds (numbers by value, text by the database's collation, dates in time order) |
| In | present and equal to one of the values (at least one value; a null among them is ARX1001) |
| NotIn | present and equal to none of the values |
| Between | present and from ≤ value ≤ to (both included) |
| NotBetween | present and below from or above to |
| Null | the value is null or the attribute is missing |
| NotNull | present |
| Contains, BeginsWith, EndsWith | present text containing, starting or ending with the given text, ignoring case; the value is text, never a pattern (% and _ in it are themselves) |
| DoesNotContain, DoesNotBeginWith, DoesNotEndWith | present text that doesn't |
| Like, NotLike | present text matching (or not) a pattern: % any text, _ one character, ignoring case |
- A condition with the wrong number of values is ARX1001 before the database.
- Case: PostgreSQL compares with
ILIKE, MongoDB with case-insensitive expressions; SQL Server and MySQL useLIKE, which ignores case under their default collations (a case-sensitive column collation makes it case-sensitive: the database's own setting). A provider that can only compare with case (DynamoDB) must refuse these operators (capability LikeOperators not declared) unless the caller opts into case-sensitive matching. - Full-text search conditions only where capability FullTextSearch is declared.
Columns
The columns asked for are read, and always the id. An empty column set reads all columns. A column that doesn't exist is the database's ARX5002 UndefinedAttribute (or ARX1018 in Strict mode, before the database).
Order
Order by one or more attributes, ascending or descending. Records equal on every order key come in no specified order: order by a unique attribute last for a stable order. A provider that can order only by a key (DynamoDB: the sort key) must refuse any other order with ARX8001.
Links
A link joins another entity (AddLink(entity, fromAttribute, toAttribute, join)): inner or left; its columns come
back as alias.column, and conditions may name the alias. Capability Joins; a right join where the database has none
is ARX8001.
Aggregates
Count, CountDistinct, Min, Max, Sum, Avg and the statistical ones, with grouping (capability Aggregates). The result is one record per group, holding the aggregates under their aliases and the group-by columns under their names, whether or not the column set names them (from 0.1.0-preview.4; the conformance suite checks it).
Paging
| Way | How | Capability |
|---|---|---|
| By page number | PageInfo { Count, PageNumber } |
OffsetPaging |
| By cookie | PageInfo { Count, PagingCookie }: pass the previous page's cookie unchanged, null for the first page |
TokenPaging |
| The total | PageInfo.ReturnTotalRecordCount: the number of matching records, from the same round trip where the database allows |
TotalCount |
HasNextPagemust be exact: true only when another record follows.- A cookie belongs to one provider and one query (its entity, filter and order): any other cookie is ARX1001 (chapter 09). A provider without TokenPaging returns no cookie and refuses one with ARX8001.
- A page size or page number below 1 is ARX1001.
- Pages are stable: paged rows are ordered by the query's order, then by the record id where the provider knows it, so no row appears on two pages or on none. A page-number query with no order and no id the provider can add (no catalog, a table without an id column, a grouped or distinct query) is ARX1001.