#[non_exhaustive]pub struct OrderByClause {
pub field: String,
pub direction: OrderDirection,
pub field_type: ScalarFieldType,
pub native_column: Option<String>,
pub vector: Option<VectorDistanceOrder>,
pub relevance: Option<RelevanceOrder>,
pub identity: bool,
}Expand description
ORDER BY clause with optional type and native column information.
The SQL generator uses field_type to emit the correct type cast for
JSONB-extracted values, and native_column to bypass JSONB extraction
entirely when the view exposes a dedicated typed column.
§Sort correctness by source
| Source | Text fields | Numeric fields | Date fields |
|---|---|---|---|
| JSONB (no cast) | Correct | Wrong (lexicographic) | Correct (ISO-8601) |
| JSONB (with cast) | Correct | Correct | Correct |
| Native column | Correct | Correct | Correct + indexable |
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.field: StringField to order by (GraphQL camelCase name).
direction: OrderDirectionSort direction.
field_type: ScalarFieldTypeField type for SQL cast generation. Text (default) means no cast.
native_column: Option<String>Native column name if the view exposes this field as a typed column. When set, ORDER BY uses this column directly instead of JSONB extraction, enabling index support and correct typing without casts.
vector: Option<VectorDistanceOrder>Vector-distance ordering (#386): when set, this clause orders by
{column} {operator} '{query_vector}'::vector — the pgvector ANN shape.
Requires native_column (a JSONB-extracted text
value would defeat every vector index and re-parse per row).
relevance: Option<RelevanceOrder>Full-text relevance ordering (#1284): when set, this clause orders by
ts_rank(to_tsvector(document), websearch_to_tsquery($n)), where the
document is built from the searchable fields the same ?search=
predicate matched on.
field is not read for such a clause — there is no
single field a relevance rank belongs to — and is empty by construction.
identity: boolThis clause is the entity identity, whatever it is spelled as (#1303).
Set only by identity, which the runtime uses to lower
the compiled pagination_order into an ordering. Read only by the
tie-breaker, which appends nothing to an ordering that already carries one.
A flag rather than a name comparison because the identity is a schema
fact: it may be data->>'id', a native id, or pk_user, and this module
cannot tell the last from any other column. Without the flag the renderer
would append its own data->>'id' on top of a pk_user ordering — a
second, redundant sort key on every paged read of every Trinity view.
Implementations§
Source§impl OrderByClause
impl OrderByClause
Sourcepub fn new(field: String, direction: OrderDirection) -> OrderByClause
pub fn new(field: String, direction: OrderDirection) -> OrderByClause
Create a new OrderByClause with default field type (text) and no native column.
Sourcepub const fn identity(
field: String,
native_column: Option<String>,
) -> OrderByClause
pub const fn identity( field: String, native_column: Option<String>, ) -> OrderByClause
A clause that orders by the entity identity, ascending (#1303).
native_column when the relation exposes the identity as a column
(id, pk_user), None for the JSONB extraction data->>'id'. Which
one is a compile-time decision recorded in QueryDefinition::pagination_order;
this is its lowering.
ASC unconditionally. A total order is all this has to be, and which of two otherwise-tied rows comes first is not a property any client asked about. Matching a requested clause’s direction would suggest it is.
Sourcepub fn by_relevance(relevance: RelevanceOrder) -> OrderByClause
pub fn by_relevance(relevance: RelevanceOrder) -> OrderByClause
A clause that orders by full-text relevance, most relevant first (#1284).
field is left empty deliberately. A relevance rank is
computed over several fields at once, so naming one of them would be a
lie, and naming a sentinel like _relevance would put the sort kind back
into a string — which is the defect this constructor exists to replace:
[{"_relevance": "desc"}] type-checked at every layer that touched it
and failed only in the ORDER BY parser, three layers below the handler
that wrote it.
Sourcepub const fn binds_parameter(&self) -> bool
pub const fn binds_parameter(&self) -> bool
Whether rendering this clause binds a SQL parameter.
True only for full-text relevance (#1284), whose operand is arbitrary
client text and is therefore bound rather than interpolated. A SQL
builder that assembles ORDER BY as a bare string — the relay keyset
query, the fraiseql-wire adapter — asks this before rendering, so that
“this ordering cannot be expressed here” is a named refusal instead of a
dropped sort or an escaped literal.
Sourcepub fn storage_key(&self) -> String
pub fn storage_key(&self) -> String
Convert the GraphQL camelCase field name to the JSONB snake_case storage key.
§Examples
use fraiseql_db::OrderByClause;
use fraiseql_db::OrderDirection;
let clause = OrderByClause::new("createdAt".to_string(), OrderDirection::Asc);
assert_eq!(clause.storage_key(), "created_at");Sourcepub fn validate_field_name(field: &str) -> Result<(), FraiseQLError>
pub fn validate_field_name(field: &str) -> Result<(), FraiseQLError>
Validate that a field name matches the GraphQL identifier pattern [_A-Za-z][_0-9A-Za-z]*.
This is a security boundary: field names are interpolated into SQL data->>'field'
expressions. Any character outside the GraphQL identifier set must be rejected before
the OrderByClause is constructed.
§Errors
Returns FraiseQLError::Validation if the field contains invalid characters.
Sourcepub fn from_graphql_json(
value: &Value,
) -> Result<Vec<OrderByClause>, FraiseQLError>
pub fn from_graphql_json( value: &Value, ) -> Result<Vec<OrderByClause>, FraiseQLError>
Parse orderBy from a GraphQL variables JSON value.
Accepts two formats:
- Object:
{ "name": "DESC", "created_at": "ASC" } - Array:
[{ "field": "name", "direction": "DESC" }]
Direction strings are case-insensitive.
§Errors
Returns FraiseQLError::Validation for invalid structure or direction values.
Trait Implementations§
Source§impl Clone for OrderByClause
impl Clone for OrderByClause
Source§fn clone(&self) -> OrderByClause
fn clone(&self) -> OrderByClause
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for OrderByClause
impl Debug for OrderByClause
Source§impl<'de> Deserialize<'de> for OrderByClause
impl<'de> Deserialize<'de> for OrderByClause
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<OrderByClause, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<OrderByClause, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for OrderByClause
Source§impl PartialEq for OrderByClause
impl PartialEq for OrderByClause
Source§impl Serialize for OrderByClause
impl Serialize for OrderByClause
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for OrderByClause
Auto Trait Implementations§
impl Freeze for OrderByClause
impl RefUnwindSafe for OrderByClause
impl Send for OrderByClause
impl Sync for OrderByClause
impl Unpin for OrderByClause
impl UnsafeUnpin for OrderByClause
impl UnwindSafe for OrderByClause
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.