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 use LIKE, 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.

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
  • HasNextPage must 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.

All chapters of the specification