mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 01:12:56 +03:00
Change order_by to accept a list (#298)
V3_GIT_ORIGIN_REV_ID: 603f6ae4ab8c6505a5484d6b71042b0a7e5aaa8c
This commit is contained in:
parent
486249902a
commit
f65d67bd10
@ -1,7 +1,9 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use gdc::models::PathElement;
|
||||
|
||||
use lang_graphql::normalized_ast::{self as normalized_ast, InputField};
|
||||
|
||||
use ndc_client as gdc;
|
||||
use serde::Serialize;
|
||||
|
||||
@ -29,19 +31,43 @@ pub(crate) fn build_ndc_order_by<'s>(
|
||||
usage_counts: &mut UsagesCounts,
|
||||
) -> Result<ResolvedOrderBy<'s>, error::Error> {
|
||||
match &args_field.value {
|
||||
normalized_ast::Value::Object(arguments) => {
|
||||
normalized_ast::Value::List(arguments) => {
|
||||
let mut ndc_order_elements = Vec::new();
|
||||
let mut relationships = BTreeMap::new();
|
||||
// TODO: use argument.values?
|
||||
for argument in arguments.values() {
|
||||
let relationship_paths = Vec::new();
|
||||
let order_by_element = build_ndc_order_by_element(
|
||||
argument,
|
||||
relationship_paths,
|
||||
&mut relationships,
|
||||
usage_counts,
|
||||
)?;
|
||||
ndc_order_elements.extend(order_by_element);
|
||||
|
||||
for v in arguments.iter() {
|
||||
match v {
|
||||
normalized_ast::Value::Object(arguments) => {
|
||||
// Check if the input object contains exactly one key-value pair.
|
||||
// This is done because the users might provide multiple key-value pairs
|
||||
// in a single input object and the server might interpret it arbitrarily
|
||||
// since input objects values are unordered key-value pair lists.
|
||||
if arguments.len() != 1 {
|
||||
Err(error::Error::ValidationFailed(
|
||||
lang_graphql::validation::Error::OrderByObjectShouldExactlyHaveOneKeyValuePair,
|
||||
))?
|
||||
} else {
|
||||
let argument = arguments
|
||||
.first()
|
||||
.ok_or(error::InternalEngineError::InternalGeneric {
|
||||
description: "unexpected: could not find the first key-value pair of arguments"
|
||||
.into(),
|
||||
})?
|
||||
.1;
|
||||
let relationship_paths = Vec::new();
|
||||
let order_by_element = build_ndc_order_by_element(
|
||||
argument,
|
||||
relationship_paths,
|
||||
&mut relationships,
|
||||
usage_counts,
|
||||
)?;
|
||||
ndc_order_elements.extend(order_by_element);
|
||||
}
|
||||
}
|
||||
_ => Err(error::InternalEngineError::InternalGeneric {
|
||||
description: "Expected list of input objects value for order_by".into(),
|
||||
})?,
|
||||
}
|
||||
}
|
||||
Ok(ResolvedOrderBy {
|
||||
order_by: gdc::models::OrderBy {
|
||||
@ -51,7 +77,7 @@ pub(crate) fn build_ndc_order_by<'s>(
|
||||
})
|
||||
}
|
||||
_ => Err(error::InternalEngineError::InternalGeneric {
|
||||
description: "Expected object value for model arguments".into(),
|
||||
description: "Expected list of input objects value for order_by".into(),
|
||||
})?,
|
||||
}
|
||||
}
|
||||
|
@ -89,12 +89,12 @@ pub fn get_order_by_expression_input_field(
|
||||
types::Annotation::Input(types::InputAnnotation::Model(
|
||||
types::ModelInputAnnotation::ModelOrderByExpression,
|
||||
)),
|
||||
ast::TypeContainer::named_null(builder.register_type(
|
||||
ast::TypeContainer::list_null(ast::TypeContainer::named_non_null(builder.register_type(
|
||||
types::TypeId::ModelOrderByExpression {
|
||||
model_name,
|
||||
graphql_type_name: order_by_expression_info.order_by_type_name.clone(),
|
||||
},
|
||||
)),
|
||||
))),
|
||||
None,
|
||||
gql_schema::DeprecationStatus::NotDeprecated,
|
||||
)
|
||||
|
@ -1,9 +1,9 @@
|
||||
query {
|
||||
AuthorMany(order_by: {first_name: Asc}) {
|
||||
AuthorMany(order_by: [{first_name: Asc}]) {
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
a1: AuthorMany(order_by: {first_name: Asc}, limit: 1, offset: 1) {
|
||||
a1: AuthorMany(order_by: [{first_name: Asc}], limit: 1, offset: 1) {
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
query MyQuery {
|
||||
Track(
|
||||
order_by: {AlbumId: Asc, TrackId: Desc}
|
||||
order_by: [{AlbumId: Asc}, {TrackId: Desc}]
|
||||
where: {_or: [{AlbumId: {_eq: 1}}, {AlbumId: {_eq: 4}}]}
|
||||
) {
|
||||
Name
|
||||
|
@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"data": null,
|
||||
"errors": [
|
||||
{
|
||||
"message": "validation failed: order_by expects a list of input objects with exactly one key-value pair per input object. Please split the input object with multiple key-value pairs into a list of single key-value pair objects."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": null,
|
||||
"errors": [
|
||||
{
|
||||
"message": "validation failed: order_by expects a list of input objects with exactly one key-value pair per input object. Please split the input object with multiple key-value pairs into a list of single key-value pair objects."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": null,
|
||||
"errors": [
|
||||
{
|
||||
"message": "validation failed: order_by expects a list of input objects with exactly one key-value pair per input object. Please split the input object with multiple key-value pairs into a list of single key-value pair objects."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -0,0 +1,235 @@
|
||||
{
|
||||
"version": "v2",
|
||||
"subgraphs": [
|
||||
{
|
||||
"name": "default",
|
||||
"objects": [
|
||||
{
|
||||
"kind": "DataConnectorScalarRepresentation",
|
||||
"version": "v1",
|
||||
"definition": {
|
||||
"dataConnectorName": "db",
|
||||
"dataConnectorScalarType": "String",
|
||||
"representation": "String",
|
||||
"graphql": {
|
||||
"comparisonExpressionTypeName": "String_Comparison_Exp"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "DataConnectorScalarRepresentation",
|
||||
"version": "v1",
|
||||
"definition": {
|
||||
"dataConnectorName": "db",
|
||||
"dataConnectorScalarType": "Int",
|
||||
"representation": "Int",
|
||||
"graphql": {
|
||||
"comparisonExpressionTypeName": "Int_comparison"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"name": "Track",
|
||||
"fields": [
|
||||
{
|
||||
"name": "TrackId",
|
||||
"type": "Int"
|
||||
},
|
||||
{
|
||||
"name": "Name",
|
||||
"type": "String"
|
||||
},
|
||||
{
|
||||
"name": "AlbumId",
|
||||
"type": "Int"
|
||||
}
|
||||
],
|
||||
"graphql": {
|
||||
"typeName": "Track"
|
||||
}
|
||||
},
|
||||
"version": "v1",
|
||||
"kind": "ObjectType"
|
||||
},
|
||||
{
|
||||
"definition": {
|
||||
"name": "Tracks",
|
||||
"objectType": "Track",
|
||||
"source": {
|
||||
"dataConnectorName": "db",
|
||||
"collection": "Track",
|
||||
"typeMapping": {
|
||||
"Track": {
|
||||
"fieldMapping": {
|
||||
"TrackId": {
|
||||
"column": "TrackId"
|
||||
},
|
||||
"Name": {
|
||||
"column": "Name"
|
||||
},
|
||||
"AlbumId": {
|
||||
"column": "AlbumId"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"graphql": {
|
||||
"selectUniques": [
|
||||
{
|
||||
"queryRootField": "TrackByID",
|
||||
"uniqueIdentifier": [
|
||||
"TrackId"
|
||||
]
|
||||
}
|
||||
],
|
||||
"selectMany": {
|
||||
"queryRootField": "Track"
|
||||
},
|
||||
"filterExpressionType": "Track_Where_Exp",
|
||||
"orderByExpressionType": "Track_Order_By"
|
||||
},
|
||||
"filterableFields": [
|
||||
{
|
||||
"fieldName": "TrackId",
|
||||
"operators": {
|
||||
"enableAll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldName": "Name",
|
||||
"operators": {
|
||||
"enableAll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldName": "AlbumId",
|
||||
"operators": {
|
||||
"enableAll": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"orderableFields": [
|
||||
{
|
||||
"fieldName": "TrackId",
|
||||
"orderByDirections": {
|
||||
"enableAll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldName": "Name",
|
||||
"orderByDirections": {
|
||||
"enableAll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldName": "AlbumId",
|
||||
"orderByDirections": {
|
||||
"enableAll": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": "v1",
|
||||
"kind": "Model"
|
||||
},
|
||||
{
|
||||
"kind": "TypePermissions",
|
||||
"version": "v1",
|
||||
"definition": {
|
||||
"typeName": "Track",
|
||||
"permissions": [
|
||||
{
|
||||
"role": "admin",
|
||||
"output": {
|
||||
"allowedFields": [
|
||||
"TrackId",
|
||||
"Name",
|
||||
"AlbumId"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"role": "user_1",
|
||||
"output": {
|
||||
"allowedFields": [
|
||||
"TrackId",
|
||||
"Name",
|
||||
"AlbumId"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"role": "user_2",
|
||||
"output": {
|
||||
"allowedFields": [
|
||||
"TrackId",
|
||||
"Name",
|
||||
"AlbumId"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "ModelPermissions",
|
||||
"version": "v1",
|
||||
"definition": {
|
||||
"modelName": "Tracks",
|
||||
"permissions": [
|
||||
{
|
||||
"role": "admin",
|
||||
"select": {
|
||||
"filter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"role": "user_1",
|
||||
"select": {
|
||||
"filter": {
|
||||
"fieldComparison": {
|
||||
"field": "AlbumId",
|
||||
"operator": "_eq",
|
||||
"value": {
|
||||
"sessionVariable": "x-hasura-user-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"role": "user_2",
|
||||
"select": {
|
||||
"filter": {
|
||||
"and": [
|
||||
{
|
||||
"fieldComparison": {
|
||||
"field": "Name",
|
||||
"operator": "_like",
|
||||
"value": {
|
||||
"literal": "%Overdose%"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldComparison": {
|
||||
"field": "AlbumId",
|
||||
"operator": "_eq",
|
||||
"value": {
|
||||
"sessionVariable": "x-hasura-user-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
query MyQuery {
|
||||
Track(
|
||||
order_by: [{AlbumId: Asc, TrackId: Desc}]
|
||||
|
||||
) {
|
||||
Name
|
||||
TrackId
|
||||
AlbumId
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
[
|
||||
{"x-hasura-role": "admin"},
|
||||
{"x-hasura-role": "user_1", "x-hasura-user-id": "1"},
|
||||
{"x-hasura-role": "user_2", "x-hasura-user-id": "4"}
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
query MyQuery {
|
||||
Track(order_by: {Album: {Artist: {ArtistId: Asc}, AlbumId: Asc}}, limit: 15) {
|
||||
Track(order_by: [{Album: {Artist: {ArtistId: Asc}}}, {AlbumId: Asc}], limit: 15) {
|
||||
Album {
|
||||
AlbumId
|
||||
Artist {
|
||||
@ -9,7 +9,7 @@ query MyQuery {
|
||||
}
|
||||
}
|
||||
TrackOrderByWithFilter: Track(
|
||||
order_by: {Album: {Artist: {ArtistId: Desc}, AlbumId: Asc}}
|
||||
order_by: [{Album: {Artist: {ArtistId: Desc}}}, {AlbumId: Asc}]
|
||||
where: {AlbumId: {_eq: 2}}
|
||||
limit: 15
|
||||
) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
query MyQuery {
|
||||
Track(order_by: {Album: {ArtistId: Desc}}, limit: 3) {
|
||||
Track(order_by: [{Album: {ArtistId: Desc}}], limit: 3) {
|
||||
Album {
|
||||
ArtistId
|
||||
Title
|
||||
}
|
||||
}
|
||||
TrackOrderByWithFilter: Track(
|
||||
order_by: {Album: {ArtistId: Asc}, TrackId: Desc}
|
||||
order_by: [{Album: {ArtistId: Asc}}, {TrackId: Desc}]
|
||||
where: {Album: {Artist: {ArtistId: {_eq: 2}}}}
|
||||
) {
|
||||
TrackId
|
||||
|
@ -1,12 +1,12 @@
|
||||
query MyQuery {
|
||||
AuthorMany(order_by: {first_name: Asc}) {
|
||||
AuthorMany(order_by: [{first_name: Asc}]) {
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
ArticlesByAuthorMany(args: {author_id: 2}, order_by: {article_id: Desc}) {
|
||||
ArticlesByAuthorMany(args: {author_id: 2}, order_by: [{article_id: Desc}]) {
|
||||
article_id
|
||||
}
|
||||
a1: AuthorMany(order_by: {first_name: Desc}, offset: 1, limit: 1) {
|
||||
a1: AuthorMany(order_by: [{first_name: Desc}], offset: 1, limit: 1) {
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
query MyQuery {
|
||||
AuthorMany(order_by_custom: {first_name: Asc_custom}) {
|
||||
AuthorMany(order_by_custom: [{first_name: Asc_custom}]) {
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
ArticlesByAuthorMany(args_custom: {author_id: 2}, order_by_custom: {article_id: Desc_custom}) {
|
||||
ArticlesByAuthorMany(args_custom: {author_id: 2}, order_by_custom: [{article_id: Desc_custom}]) {
|
||||
article_id
|
||||
}
|
||||
a1: AuthorMany(order_by_custom: {first_name: Desc_custom}, offset_custom: 1, limit_custom: 1) {
|
||||
a1: AuthorMany(order_by_custom: [{first_name: Desc_custom}], offset_custom: 1, limit_custom: 1) {
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ query MyQuery {
|
||||
TrackId
|
||||
}
|
||||
}
|
||||
AlbumPredicateOrderBy: Album(limit: 2, order_by: {AlbumId: Desc}) {
|
||||
AlbumPredicateOrderBy: Album(limit: 2, order_by: [{AlbumId: Desc}]) {
|
||||
AlbumId
|
||||
Title
|
||||
ArtistId
|
||||
|
@ -282,9 +282,17 @@
|
||||
"name": "order_by",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "Authors_order_by",
|
||||
"ofType": null
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "Authors_order_by",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
|
@ -306,9 +306,17 @@
|
||||
"name": "order_by_custom",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "Authors_order_by",
|
||||
"ofType": null
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "Authors_order_by",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
query MyQuery {
|
||||
AuthorMany(order_by: {first_name: Asc}) {
|
||||
AuthorMany(order_by: [{first_name: Asc}]) {
|
||||
author_id
|
||||
last_name
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ query {
|
||||
}
|
||||
}
|
||||
|
||||
AuthorMany(order_by: {author_id: Desc}){
|
||||
AuthorMany(order_by: [{author_id: Desc}]){
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ query {
|
||||
}
|
||||
}
|
||||
|
||||
AuthorMany(order_by: {author_id: Desc}){
|
||||
AuthorMany(order_by: [{author_id: Desc}]){
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ query {
|
||||
}
|
||||
}
|
||||
|
||||
AuthorMany(order_by: {author_id: Desc}){
|
||||
AuthorMany(order_by: [{author_id: Desc}]){
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ query {
|
||||
}
|
||||
}
|
||||
|
||||
AuthorMany(order_by: {author_id: Desc}){
|
||||
AuthorMany(order_by: [{author_id: Desc}]){
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ query MyQuery {
|
||||
AuthorMany {
|
||||
first_name
|
||||
author_id
|
||||
Articles(limit: 2, offset: 1, order_by: {title: Asc}) {
|
||||
Articles(limit: 2, offset: 1, order_by: [{title: Asc}]) {
|
||||
title
|
||||
article_id
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ query MyQuery {
|
||||
AuthorMany {
|
||||
first_name
|
||||
author_id
|
||||
Articles(limit_custom: 2, offset_custom: 1, order_by_custom: {title: Asc_custom}, where_custom: {title: {_is_null_custom: false}}) {
|
||||
Articles(limit_custom: 2, offset_custom: 1, order_by_custom: [{title: Asc_custom}], where_custom: {title: {_is_null_custom: false}}) {
|
||||
title
|
||||
article_id
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ query MyQuery {
|
||||
AuthorMany {
|
||||
first_name
|
||||
author_id
|
||||
Articles(limit: 2, offset: 1, order_by: {title: Asc}) {
|
||||
Articles(limit: 2, offset: 1, order_by: [{title: Asc}]) {
|
||||
title
|
||||
article_id
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ query RemoteJoinsCandidateQuery2 {
|
||||
id
|
||||
title
|
||||
rating
|
||||
Analytics(limit: 5, order_by: {analytics_id: Asc}) {
|
||||
Analytics(limit: 5, order_by: [{analytics_id: Asc}]) {
|
||||
id
|
||||
num_users_faved
|
||||
num_views_day
|
||||
|
@ -117,6 +117,13 @@ fn test_model_select_many_order_by_multiple_columns() {
|
||||
common::test_execution_expectation(test_path_string, &[common_metadata_path_string]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_model_select_many_order_by_multiple_columns_validation_check() {
|
||||
let test_path_string = "execute/models/select_many/order_by/order_by_validation_check";
|
||||
let common_metadata_path_string = "execute/common_metadata/postgres_connector_schema.json";
|
||||
common::test_execution_expectation(test_path_string, &[common_metadata_path_string]);
|
||||
}
|
||||
|
||||
// Type Permissions
|
||||
#[test]
|
||||
fn test_model_select_many_type_permission_order_by() {
|
||||
|
@ -3,7 +3,7 @@
|
||||
name
|
||||
}
|
||||
|
||||
AuthorMany(order_by: {author_id: Desc}){
|
||||
AuthorMany(order_by: [{author_id: Desc}]){
|
||||
author_id
|
||||
first_name
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ query GetUser($gameID: smallint!, $id: Int, $link: String, $steamID: Int) {
|
||||
lastActivity: last_activity
|
||||
createdAt: created_at
|
||||
friendsCount: friends_count
|
||||
friends(where: {state: {_eq: "ACCEPTED"}}, order_by: {date: desc}, limit: 5) {
|
||||
friends(where: {state: {_eq: "ACCEPTED"}}, order_by: [{date: desc}], limit: 5) {
|
||||
...Friend
|
||||
__typename
|
||||
}
|
||||
@ -66,7 +66,7 @@ query GetUser($gameID: smallint!, $id: Int, $link: String, $steamID: Int) {
|
||||
type
|
||||
readiness_passed
|
||||
game_status
|
||||
teams(order_by: {id: asc}) {
|
||||
teams(order_by: [{id: asc}]) {
|
||||
size
|
||||
score
|
||||
__typename
|
||||
@ -74,7 +74,7 @@ query GetUser($gameID: smallint!, $id: Int, $link: String, $steamID: Int) {
|
||||
created_at
|
||||
started_at
|
||||
best_of
|
||||
maps(order_by: {number: asc}) {
|
||||
maps(order_by: [{number: asc}]) {
|
||||
map {
|
||||
id
|
||||
name
|
||||
@ -173,7 +173,7 @@ fragment UserStats on users {
|
||||
fragment UserBan on users {
|
||||
bans(
|
||||
where: {active: {_eq: true}, game_id: {_eq: $gameID}}
|
||||
order_by: {until: desc}
|
||||
order_by: [{until: desc}]
|
||||
) {
|
||||
id
|
||||
since
|
||||
@ -224,7 +224,7 @@ fragment Friend on friends {
|
||||
fragment UserLastActiveBan on users {
|
||||
bans(
|
||||
where: {active: {_eq: true}, game_id: {_eq: $gameID}}
|
||||
order_by: {length_minutes: desc}
|
||||
order_by: [{length_minutes: desc}]
|
||||
limit: 1
|
||||
) {
|
||||
id
|
||||
|
@ -178,4 +178,6 @@ pub enum Error {
|
||||
field_name: ast::Name,
|
||||
argument_name: ast::Name,
|
||||
},
|
||||
#[error("order_by expects a list of input objects with exactly one key-value pair per input object. Please split the input object with multiple key-value pairs into a list of single key-value pair objects.")]
|
||||
OrderByObjectShouldExactlyHaveOneKeyValuePair,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user