From e52b47bae9d27d5d1cfd87dc96e1f5585dd0a29c Mon Sep 17 00:00:00 2001 From: Dale Lakes <6843636+spitfire55@users.noreply.github.com> Date: Sun, 4 May 2025 14:27:34 -0400 Subject: [PATCH 01/15] Add support for single record queries by primary key --- src/builder.rs | 195 ++++++++ src/graphql.rs | 52 ++ src/resolve.rs | 52 ++ src/transpile.rs | 121 ++++- test/expected/function_calls.out | 447 +++++++++--------- test/expected/function_calls_unsupported.out | 176 +++---- .../function_return_row_is_selectable.out | 3 + .../function_return_view_has_pkey.out | 3 + test/expected/permissions_table_level.out | 12 + test/expected/primary_key_queries.out | 315 ++++++++++++ test/expected/resolve_graphiql_schema.out | 120 +++++ test/expected/views_integration.out | 15 + test/sql/primary_key_queries.sql | 196 ++++++++ 13 files changed, 1391 insertions(+), 316 deletions(-) create mode 100644 test/expected/primary_key_queries.out create mode 100644 test/sql/primary_key_queries.sql diff --git a/src/builder.rs b/src/builder.rs index 6baf1526..9f465b3f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1037,6 +1037,19 @@ pub struct NodeBuilder { pub selections: Vec, } +#[derive(Clone, Debug)] +pub struct NodeByPkBuilder { + // args - map of column name to value + pub pk_values: HashMap, + + pub _alias: String, + + // metadata + pub table: Arc, + + pub selections: Vec, +} + #[derive(Clone, Debug)] pub enum NodeSelection { Connection(ConnectionBuilder), @@ -2156,6 +2169,188 @@ where }) } +pub fn to_node_by_pk_builder<'a, T>( + field: &__Field, + query_field: &graphql_parser::query::Field<'a, T>, + fragment_definitions: &Vec>, + variables: &serde_json::Value, + variable_definitions: &Vec>, +) -> Result +where + T: Text<'a> + Eq + AsRef + Clone, + T::Value: Hash, +{ + let type_ = field.type_().unmodified_type(); + let alias = alias_or_name(query_field); + + match type_ { + __Type::Node(xtype) => { + let type_name = xtype + .name() + .ok_or("Encountered type without name in node_by_pk builder")?; + + let field_map = field_map(&__Type::Node(xtype.clone())); + + // Get primary key columns from the table + let pkey = xtype + .table + .primary_key() + .ok_or("Table has no primary key".to_string())?; + + // Create a map of expected field arguments based on the field's arg definitions + let mut pk_arg_map = HashMap::new(); + for arg in field.args() { + if let Some(NodeSQLType::Column(col)) = &arg.sql_type { + pk_arg_map.insert(arg.name().to_string(), col.name.clone()); + } + } + + let mut pk_values = HashMap::new(); + + // Process each argument in the query + for arg in &query_field.arguments { + let arg_name = arg.0.as_ref(); + + // Find the corresponding column name from our argument map + if let Some(col_name) = pk_arg_map.get(arg_name) { + let value = to_gson(&arg.1, variables, variable_definitions)?; + let json_value = gson::gson_to_json(&value)?; + pk_values.insert(col_name.clone(), json_value); + } + } + + // Need values for all primary key columns + if pk_values.len() != pkey.column_names.len() { + return Err("All primary key columns must be provided".to_string()); + } + + let mut builder_fields = vec![]; + let selection_fields = normalize_selection_set( + &query_field.selection_set, + fragment_definitions, + &type_name, + variables, + )?; + + for selection_field in selection_fields { + match field_map.get(selection_field.name.as_ref()) { + None => { + return Err(format!( + "Unknown field '{}' on type '{}'", + selection_field.name.as_ref(), + &type_name + )) + } + Some(f) => { + let alias = alias_or_name(&selection_field); + + let node_selection = match &f.sql_type { + Some(node_sql_type) => match node_sql_type { + NodeSQLType::Column(col) => NodeSelection::Column(ColumnBuilder { + alias, + column: Arc::clone(col), + }), + NodeSQLType::Function(func) => { + let function_selection = match &f.type_() { + __Type::Scalar(_) => FunctionSelection::ScalarSelf, + __Type::List(_) => FunctionSelection::Array, + __Type::Node(_) => { + let node_builder = to_node_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + )?; + FunctionSelection::Node(node_builder) + } + __Type::Connection(_) => { + let connection_builder = to_connection_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + )?; + FunctionSelection::Connection(connection_builder) + } + _ => { + return Err( + "invalid return type from function".to_string() + ) + } + }; + NodeSelection::Function(FunctionBuilder { + alias, + function: Arc::clone(func), + table: Arc::clone(&xtype.table), + selection: function_selection, + }) + } + NodeSQLType::NodeId(pkey_columns) => { + NodeSelection::NodeId(NodeIdBuilder { + alias, + columns: pkey_columns.clone(), + table_name: xtype.table.name.clone(), + schema_name: xtype.table.schema.clone(), + }) + } + }, + _ => match f.name().as_ref() { + "__typename" => NodeSelection::Typename { + alias: alias_or_name(&selection_field), + typename: xtype.name().expect("node type should have a name"), + }, + _ => match f.type_().unmodified_type() { + __Type::Connection(_) => { + let con_builder = to_connection_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + ); + NodeSelection::Connection(con_builder?) + } + __Type::Node(_) => { + let node_builder = to_node_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + ); + NodeSelection::Node(node_builder?) + } + _ => { + return Err(format!( + "unexpected field type on node {}", + f.name() + )); + } + }, + }, + }; + builder_fields.push(node_selection); + } + } + } + + Ok(NodeByPkBuilder { + pk_values, + _alias: alias, + table: Arc::clone(&xtype.table), + selections: builder_fields, + }) + } + _ => Err("cannot build query for non-node type".to_string()), + } +} + // Introspection #[allow(clippy::large_enum_variant)] diff --git a/src/graphql.rs b/src/graphql.rs index 1d07eeb1..b7876839 100644 --- a/src/graphql.rs +++ b/src/graphql.rs @@ -1247,6 +1247,58 @@ impl ___Type for QueryType { }; f.push(collection_entrypoint); + + // Add single record query by primary key if the table has a primary key + if let Some(primary_key) = table.primary_key() { + let node_type = NodeType { + table: Arc::clone(table), + fkey: None, + reverse_reference: None, + schema: Arc::clone(&self.schema), + }; + + // Create arguments for each primary key column + let mut pk_args = Vec::new(); + for col_name in &primary_key.column_names { + if let Some(col) = table.columns.iter().find(|c| &c.name == col_name) { + let col_type = sql_column_to_graphql_type(col, &self.schema) + .ok_or_else(|| { + format!( + "Could not determine GraphQL type for column {}", + col_name + ) + }) + .unwrap_or_else(|_| __Type::Scalar(Scalar::String(None))); + + // Use graphql_column_field_name to convert snake_case to camelCase if needed + let arg_name = self.schema.graphql_column_field_name(col); + + pk_args.push(__InputValue { + name_: arg_name, + type_: __Type::NonNull(NonNullType { + type_: Box::new(col_type), + }), + description: Some(format!("The record's `{}` value", col_name)), + default_value: None, + sql_type: Some(NodeSQLType::Column(Arc::clone(col))), + }); + } + } + + let pk_entrypoint = __Field { + name_: format!("{}ByPk", lowercase_first_letter(table_base_type_name)), + type_: __Type::Node(node_type), + args: pk_args, + description: Some(format!( + "Retrieve a record of type `{}` by its primary key", + table_base_type_name + )), + deprecation_reason: None, + sql_type: None, + }; + + f.push(pk_entrypoint); + } } } diff --git a/src/resolve.rs b/src/resolve.rs index 2f734bba..8c5d5c1d 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -257,6 +257,58 @@ where }), } } + __Type::Node(_) => { + // Determine if this is a primary key query field + let has_pk_args = !field_def.args().is_empty() + && field_def.args().iter().all(|arg| { + // All PK field args have a SQL Column type + arg.sql_type.is_some() + && matches!( + arg.sql_type.as_ref().unwrap(), + NodeSQLType::Column(_) + ) + }); + + if has_pk_args { + let node_by_pk_builder = to_node_by_pk_builder( + field_def, + selection, + &fragment_definitions, + variables, + variable_definitions, + ); + + match node_by_pk_builder { + Ok(builder) => match builder.execute() { + Ok(d) => { + res_data[alias_or_name(selection)] = d; + } + Err(msg) => res_errors.push(ErrorMessage { message: msg }), + }, + Err(msg) => res_errors.push(ErrorMessage { message: msg }), + } + } else { + // Regular node access + let node_builder = to_node_builder( + field_def, + selection, + &fragment_definitions, + variables, + &[], + variable_definitions, + ); + + match node_builder { + Ok(builder) => match builder.execute() { + Ok(d) => { + res_data[alias_or_name(selection)] = d; + } + Err(msg) => res_errors.push(ErrorMessage { message: msg }), + }, + Err(msg) => res_errors.push(ErrorMessage { message: msg }), + } + } + } __Type::__Type(_) => { let __type_builder = schema_type.to_type_builder( field_def, diff --git a/src/transpile.rs b/src/transpile.rs index aa6fbaa2..d8e3fb2c 100644 --- a/src/transpile.rs +++ b/src/transpile.rs @@ -1502,12 +1502,84 @@ impl QueryEntrypoint for NodeBuilder { let quoted_table = quote_ident(&self.table.name); let object_clause = self.to_sql("ed_block_name, param_context)?; - let node_id = self - .node_id - .as_ref() - .ok_or("Expected nodeId argument missing")?; + let where_clause = match &self.node_id { + Some(node_id) => node_id.to_sql("ed_block_name, &self.table, param_context)?, + None => "true".to_string(), + }; + + Ok(format!( + " + ( + select + {object_clause} + from + {quoted_schema}.{quoted_table} as {quoted_block_name} + where + {where_clause} + ) + " + )) + } +} - let node_id_clause = node_id.to_sql("ed_block_name, &self.table, param_context)?; +impl NodeByPkBuilder { + pub fn to_sql( + &self, + block_name: &str, + param_context: &mut ParamContext, + ) -> Result { + let mut field_clauses = vec![]; + for selection in &self.selections { + field_clauses.push(selection.to_sql(block_name, param_context)?); + } + + if field_clauses.is_empty() { + return Ok("'{}'::jsonb".to_string()); + } + + let fields_clause = field_clauses.join(", "); + Ok(format!("jsonb_build_object({fields_clause})")) + } + + pub fn to_pk_where_clause( + &self, + block_name: &str, + param_context: &mut ParamContext, + ) -> Result { + let mut conditions = Vec::new(); + + for (column_name, value) in &self.pk_values { + let value_clause = param_context.clause_for( + value, + &self + .table + .columns + .iter() + .find(|c| &c.name == column_name) + .ok_or_else(|| format!("Column {} not found", column_name))? + .type_name, + )?; + + conditions.push(format!( + "{}.{} = {}", + block_name, + quote_ident(column_name), + value_clause + )); + } + + Ok(conditions.join(" AND ")) + } +} + +impl QueryEntrypoint for NodeByPkBuilder { + fn to_sql_entrypoint(&self, param_context: &mut ParamContext) -> Result { + let quoted_block_name = rand_block_name(); + let quoted_schema = quote_ident(&self.table.schema); + let quoted_table = quote_ident(&self.table.name); + let object_clause = self.to_sql("ed_block_name, param_context)?; + + let where_clause = self.to_pk_where_clause("ed_block_name, param_context)?; Ok(format!( " @@ -1517,7 +1589,7 @@ impl QueryEntrypoint for NodeBuilder { from {quoted_schema}.{quoted_table} as {quoted_block_name} where - {node_id_clause} + {where_clause} ) " )) @@ -1539,13 +1611,38 @@ impl NodeIdInstance { )); } - let mut col_val_pairs: Vec = vec![]; - for (col, val) in table.primary_key_columns().iter().zip(self.values.iter()) { - let column_name = &col.name; - let val_clause = param_context.clause_for(val, &col.type_name)?; - col_val_pairs.push(format!("{block_name}.{column_name} = {val_clause}")) + let pkey = table + .primary_key() + .ok_or_else(|| "Found table with no primary key".to_string())?; + + if pkey.column_names.len() != self.values.len() { + return Err(format!( + "Primary key column count mismatch. Expected {}, provided {}", + pkey.column_names.len(), + self.values.len() + )); + } + + let mut conditions = vec![]; + + for (column_name, value) in pkey.column_names.iter().zip(&self.values) { + let column = table + .columns + .iter() + .find(|c| &c.name == column_name) + .ok_or(format!("Primary key column {} not found", column_name))?; + + let value_clause = param_context.clause_for(value, &column.type_name)?; + + conditions.push(format!( + "{}.{} = {}", + block_name, + quote_ident(column_name), + value_clause + )); } - Ok(col_val_pairs.join(" and ")) + + Ok(conditions.join(" AND ")) } } diff --git a/test/expected/function_calls.out b/test/expected/function_calls.out index bd2dd34d..aefeb10a 100644 --- a/test/expected/function_calls.out +++ b/test/expected/function_calls.out @@ -2042,226 +2042,233 @@ begin; } } } $$)); - jsonb_pretty ---------------------------------------------------------------------------------- - { + - "data": { + - "__schema": { + - "queryType": { + - "fields": [ + - { + - "args": [ + - { + - "name": "first", + - "type": { + - "kind": "SCALAR", + - "name": "Int", + - "ofType": null + - } + - }, + - { + - "name": "last", + - "type": { + - "kind": "SCALAR", + - "name": "Int", + - "ofType": null + - } + - }, + - { + - "name": "before", + - "type": { + - "kind": "SCALAR", + - "name": "Cursor", + - "ofType": null + - } + - }, + - { + - "name": "after", + - "type": { + - "kind": "SCALAR", + - "name": "Cursor", + - "ofType": null + - } + - }, + - { + - "name": "offset", + - "type": { + - "kind": "SCALAR", + - "name": "Int", + - "ofType": null + - } + - }, + - { + - "name": "filter", + - "type": { + - "kind": "INPUT_OBJECT", + - "name": "AccountFilter", + - "ofType": null + - } + - }, + - { + - "name": "orderBy", + - "type": { + - "kind": "LIST", + - "name": null, + - "ofType": { + - "kind": "NON_NULL", + - "name": null + - } + - } + - } + - ], + - "name": "accountCollection", + - "type": { + - "kind": "NON_NULL", + - "name": null, + - "ofType": { + - "kind": "OBJECT", + - "name": "AccountConnection" + - } + - }, + - "description": "A pagable collection of type `Account`"+ - }, + - { + - "args": [ + - { + - "name": "nodeId", + - "type": { + - "kind": "NON_NULL", + - "name": null, + - "ofType": { + - "kind": "SCALAR", + - "name": "ID" + - } + - } + - } + - ], + - "name": "node", + - "type": { + - "kind": "INTERFACE", + - "name": "Node", + - "ofType": null + - }, + - "description": "Retrieve a record by its `ID`" + - }, + - { + - "args": [ + - ], + - "name": "returnsAccount", + - "type": { + - "kind": "OBJECT", + - "name": "Account", + - "ofType": null + - }, + - "description": null + - }, + - { + - "args": [ + - { + - "name": "idToSearch", + - "type": { + - "kind": "NON_NULL", + - "name": null, + - "ofType": { + - "kind": "SCALAR", + - "name": "Int" + - } + - } + - } + - ], + - "name": "returnsAccountWithId", + - "type": { + - "kind": "OBJECT", + - "name": "Account", + - "ofType": null + - }, + - "description": null + - }, + - { + - "args": [ + - { + - "name": "top", + - "type": { + - "kind": "NON_NULL", + - "name": null, + - "ofType": { + - "kind": "SCALAR", + - "name": "Int" + - } + - } + - }, + - { + - "name": "first", + - "type": { + - "kind": "SCALAR", + - "name": "Int", + - "ofType": null + - } + - }, + - { + - "name": "last", + - "type": { + - "kind": "SCALAR", + - "name": "Int", + - "ofType": null + - } + - }, + - { + - "name": "before", + - "type": { + - "kind": "SCALAR", + - "name": "Cursor", + - "ofType": null + - } + - }, + - { + - "name": "after", + - "type": { + - "kind": "SCALAR", + - "name": "Cursor", + - "ofType": null + - } + - }, + - { + - "name": "offset", + - "type": { + - "kind": "SCALAR", + - "name": "Int", + - "ofType": null + - } + - }, + - { + - "name": "filter", + - "type": { + - "kind": "INPUT_OBJECT", + - "name": "AccountFilter", + - "ofType": null + - } + - }, + - { + - "name": "orderBy", + - "type": { + - "kind": "LIST", + - "name": null, + - "ofType": { + - "kind": "NON_NULL", + - "name": null + - } + - } + - } + - ], + - "name": "returnsSetofAccount", + - "type": { + - "kind": "OBJECT", + - "name": "AccountConnection", + - "ofType": null + - }, + - "description": null + - } + - ] + - } + - } + - } + + jsonb_pretty +------------------------------------------------------------------------------------------------- + { + + "data": { + + "__schema": { + + "queryType": { + + "fields": [ + + { + + "args": [ + + { + + "name": "id", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "NON_NULL", + + "name": null + + } + + } + + } + + ], + + "name": "accountByPk", + + "type": { + + "kind": "OBJECT" + + }, + + "description": "Retrieve a record of type `Account` by its primary key"+ + }, + + { + + "args": [ + + { + + "name": "first", + + "type": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + }, + + { + + "name": "last", + + "type": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + }, + + { + + "name": "before", + + "type": { + + "kind": "SCALAR", + + "name": "Cursor", + + "ofType": null + + } + + }, + + { + + "name": "after", + + "type": { + + "kind": "SCALAR", + + "name": "Cursor", + + "ofType": null + + } + + }, + + { + + "name": "offset", + + "type": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + }, + + { + + "name": "filter", + + "type": { + + "kind": "INPUT_OBJECT", + + "name": "AccountFilter", + + "ofType": null + + } + + }, + + { + + "name": "orderBy", + + "type": { + + "kind": "LIST", + + "name": null, + + "ofType": { + + "kind": "NON_NULL", + + "name": null + + } + + } + + } + + ], + + "name": "accountCollection", + + "type": { + + "kind": "OBJECT" + + }, + + "description": "A pagable collection of type `Account`" + + }, + + { + + "args": [ + + { + + "name": "nodeId", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "SCALAR", + + "name": "ID" + + } + + } + + } + + ], + + "name": "node", + + "type": { + + "kind": "INTERFACE" + + }, + + "description": "Retrieve a record by its `ID`" + + }, + + { + + "args": [ + + ], + + "name": "returnsAccount", + + "type": { + + "kind": "OBJECT" + + }, + + "description": null + + }, + + { + + "args": [ + + { + + "name": "idToSearch", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "SCALAR", + + "name": "Int" + + } + + } + + } + + ], + + "name": "returnsAccountWithId", + + "type": { + + "kind": "OBJECT" + + }, + + "description": null + + }, + + { + + "args": [ + + { + + "name": "top", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "SCALAR", + + "name": "Int" + + } + + } + + }, + + { + + "name": "first", + + "type": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + }, + + { + + "name": "last", + + "type": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + }, + + { + + "name": "before", + + "type": { + + "kind": "SCALAR", + + "name": "Cursor", + + "ofType": null + + } + + }, + + { + + "name": "after", + + "type": { + + "kind": "SCALAR", + + "name": "Cursor", + + "ofType": null + + } + + }, + + { + + "name": "offset", + + "type": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + }, + + { + + "name": "filter", + + "type": { + + "kind": "INPUT_OBJECT", + + "name": "AccountFilter", + + "ofType": null + + } + + }, + + { + + "name": "orderBy", + + "type": { + + "kind": "LIST", + + "name": null, + + "ofType": { + + "kind": "NON_NULL", + + "name": null + + } + + } + + } + + ], + + "name": "returnsSetofAccount", + + "type": { + + "kind": "OBJECT" + + }, + + "description": null + + } + + ] + + } + + } + + } + } (1 row) diff --git a/test/expected/function_calls_unsupported.out b/test/expected/function_calls_unsupported.out index 97c79334..80609dbc 100644 --- a/test/expected/function_calls_unsupported.out +++ b/test/expected/function_calls_unsupported.out @@ -308,90 +308,98 @@ begin; } } } $$)); - jsonb_pretty ---------------------------------------------------------------------------------- - { + - "data": { + - "__schema": { + - "queryType": { + - "fields": [ + - { + - "args": [ + - { + - "name": "first", + - "type": { + - "name": "Int" + - } + - }, + - { + - "name": "last", + - "type": { + - "name": "Int" + - } + - }, + - { + - "name": "before", + - "type": { + - "name": "Cursor" + - } + - }, + - { + - "name": "after", + - "type": { + - "name": "Cursor" + - } + - }, + - { + - "name": "offset", + - "type": { + - "name": "Int" + - } + - }, + - { + - "name": "filter", + - "type": { + - "name": "AccountFilter" + - } + - }, + - { + - "name": "orderBy", + - "type": { + - "name": null + - } + - } + - ], + - "name": "accountCollection", + - "type": { + - "kind": "NON_NULL", + - "name": null, + - "ofType": { + - "kind": "OBJECT", + - "name": "AccountConnection" + - } + - }, + - "description": "A pagable collection of type `Account`"+ - }, + - { + - "args": [ + - { + - "name": "nodeId", + - "type": { + - "name": null + - } + - } + - ], + - "name": "node", + - "type": { + - "kind": "INTERFACE", + - "name": "Node", + - "ofType": null + - }, + - "description": "Retrieve a record by its `ID`" + - } + - ] + - } + - } + - } + + jsonb_pretty +------------------------------------------------------------------------------------------------- + { + + "data": { + + "__schema": { + + "queryType": { + + "fields": [ + + { + + "args": [ + + { + + "name": "id", + + "type": { + + "name": null + + } + + } + + ], + + "name": "accountByPk", + + "type": { + + "kind": "OBJECT" + + }, + + "description": "Retrieve a record of type `Account` by its primary key"+ + }, + + { + + "args": [ + + { + + "name": "first", + + "type": { + + "name": "Int" + + } + + }, + + { + + "name": "last", + + "type": { + + "name": "Int" + + } + + }, + + { + + "name": "before", + + "type": { + + "name": "Cursor" + + } + + }, + + { + + "name": "after", + + "type": { + + "name": "Cursor" + + } + + }, + + { + + "name": "offset", + + "type": { + + "name": "Int" + + } + + }, + + { + + "name": "filter", + + "type": { + + "name": "AccountFilter" + + } + + }, + + { + + "name": "orderBy", + + "type": { + + "name": null + + } + + } + + ], + + "name": "accountCollection", + + "type": { + + "kind": "OBJECT" + + }, + + "description": "A pagable collection of type `Account`" + + }, + + { + + "args": [ + + { + + "name": "nodeId", + + "type": { + + "name": null + + } + + } + + ], + + "name": "node", + + "type": { + + "kind": "INTERFACE" + + }, + + "description": "Retrieve a record by its `ID`" + + } + + ] + + } + + } + + } + } (1 row) diff --git a/test/expected/function_return_row_is_selectable.out b/test/expected/function_return_row_is_selectable.out index b803fe3f..3b35c5c6 100644 --- a/test/expected/function_return_row_is_selectable.out +++ b/test/expected/function_return_row_is_selectable.out @@ -56,6 +56,9 @@ begin; "__schema": { + "queryType": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + diff --git a/test/expected/function_return_view_has_pkey.out b/test/expected/function_return_view_has_pkey.out index 24114f50..438f37ee 100644 --- a/test/expected/function_return_view_has_pkey.out +++ b/test/expected/function_return_view_has_pkey.out @@ -102,6 +102,9 @@ begin; "__schema": { + "queryType": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + diff --git a/test/expected/permissions_table_level.out b/test/expected/permissions_table_level.out index d0c35295..4ca722b2 100644 --- a/test/expected/permissions_table_level.out +++ b/test/expected/permissions_table_level.out @@ -21,6 +21,9 @@ begin; "data": { + "__type": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + @@ -96,6 +99,9 @@ begin; "data": { + "__type": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + @@ -138,6 +144,9 @@ begin; "data": { + "__type": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + @@ -180,6 +189,9 @@ begin; "data": { + "__type": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + diff --git a/test/expected/primary_key_queries.out b/test/expected/primary_key_queries.out new file mode 100644 index 00000000..f2e45957 --- /dev/null +++ b/test/expected/primary_key_queries.out @@ -0,0 +1,315 @@ +begin; + -- Set up test tables with different primary key configurations + + -- Table with single column integer primary key + create table person( + id int primary key, + name text, + email text + ); + insert into public.person(id, name, email) + values + (1, 'Alice', 'alice@example.com'), + (2, 'Bob', 'bob@example.com'), + (3, 'Charlie', null); + -- Table with multi-column primary key + create table item( + item_id int, + product_id int, + quantity int, + price numeric(10,2), + primary key(item_id, product_id) + ); + insert into item(item_id, product_id, quantity, price) + values + (1, 101, 2, 10.99), + (1, 102, 1, 24.99), + (2, 101, 3, 10.99), + (3, 103, 5, 5.99); + -- Table with text primary key (instead of UUID) + create table document( + id text primary key, + title text, + content text + ); + insert into document(id, title, content) + values + ('doc-1', 'Document 1', 'Content 1'), + ('doc-2', 'Document 2', 'Content 2'); + savepoint a; + -- Test 1: Query a person by primary key (single integer column) + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 1) { + id + name + email + } + } + $$) + ); + jsonb_pretty +------------------------------------------ + { + + "data": { + + "personByPk": { + + "id": 1, + + "name": "Alice", + + "email": "alice@example.com"+ + } + + } + + } +(1 row) + + -- Test 2: Query a person by primary key with relationship + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 2) { + id + name + email + nodeId + } + } + $$) + ); + jsonb_pretty +---------------------------------------------------------- + { + + "data": { + + "personByPk": { + + "id": 2, + + "name": "Bob", + + "email": "bob@example.com", + + "nodeId": "WyJwdWJsaWMiLCAicGVyc29uIiwgMl0="+ + } + + } + + } +(1 row) + + -- Test 3: Query a non-existent person by primary key + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 999) { + id + name + } + } + $$) + ); + jsonb_pretty +---------------------------- + { + + "data": { + + "personByPk": null+ + } + + } +(1 row) + + -- Test 4: Query with multi-column primary key + select jsonb_pretty( + graphql.resolve($$ + { + itemByPk(itemId: 1, productId: 102) { + itemId + productId + quantity + price + } + } + $$) + ); + jsonb_pretty +------------------------------- + { + + "data": { + + "itemByPk": { + + "price": "24.99",+ + "itemId": 1, + + "quantity": 1, + + "productId": 102 + + } + + } + + } +(1 row) + + -- Test 5: Query with multi-column primary key, one column value is incorrect + select jsonb_pretty( + graphql.resolve($$ + { + itemByPk(itemId: 1, productId: 999) { + itemId + productId + quantity + price + } + } + $$) + ); + jsonb_pretty +-------------------------- + { + + "data": { + + "itemByPk": null+ + } + + } +(1 row) + + -- Test 6: Query with text primary key + select jsonb_pretty( + graphql.resolve($$ + { + documentByPk(id: "doc-1") { + id + title + content + } + } + $$) + ); + jsonb_pretty +------------------------------------ + { + + "data": { + + "documentByPk": { + + "id": "doc-1", + + "title": "Document 1",+ + "content": "Content 1"+ + } + + } + + } +(1 row) + + -- Test 7: Using variables with primary key queries + select jsonb_pretty( + graphql.resolve($$ + query GetPerson($personId: Int!) { + personByPk(id: $personId) { + id + name + email + } + } + $$, '{"personId": 3}') + ); + jsonb_pretty +-------------------------------- + { + + "data": { + + "personByPk": { + + "id": 3, + + "name": "Charlie",+ + "email": null + + } + + } + + } +(1 row) + + -- Test 8: Using variables with multi-column primary key queries + select jsonb_pretty( + graphql.resolve($$ + query GetItem($itemId: Int!, $productId: Int!) { + itemByPk(itemId: $itemId, productId: $productId) { + itemId + productId + quantity + price + } + } + $$, '{"itemId": 2, "productId": 101}') + ); + jsonb_pretty +------------------------------- + { + + "data": { + + "itemByPk": { + + "price": "10.99",+ + "itemId": 2, + + "quantity": 3, + + "productId": 101 + + } + + } + + } +(1 row) + + -- Test 9: Error case - missing required primary key column + select jsonb_pretty( + graphql.resolve($$ + { + itemByPk(itemId: 1) { + itemId + productId + } + } + $$) + ); + jsonb_pretty +------------------------------------------------------------------- + { + + "data": null, + + "errors": [ + + { + + "message": "All primary key columns must be provided"+ + } + + ] + + } +(1 row) + + -- Test 10: Using fragments with primary key queries + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 1) { + ...PersonFields + } + } + + fragment PersonFields on Person { + id + name + email + } + $$) + ); + jsonb_pretty +------------------------------------------ + { + + "data": { + + "personByPk": { + + "id": 1, + + "name": "Alice", + + "email": "alice@example.com"+ + } + + } + + } +(1 row) + + -- Test 11: Query with null values in results + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 3) { + id + name + email + } + } + $$) + ); + jsonb_pretty +-------------------------------- + { + + "data": { + + "personByPk": { + + "id": 3, + + "name": "Charlie",+ + "email": null + + } + + } + + } +(1 row) + +rollback; diff --git a/test/expected/resolve_graphiql_schema.out b/test/expected/resolve_graphiql_schema.out index cac1414c..ccd5fcaa 100644 --- a/test/expected/resolve_graphiql_schema.out +++ b/test/expected/resolve_graphiql_schema.out @@ -5745,6 +5745,37 @@ begin; "kind": "OBJECT", + "name": "Query", + "fields": [ + + { + + "args": [ + + { + + "name": "id", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + } + + }, + + "description": "The record's `id` value", + + "defaultValue": null + + } + + ], + + "name": "accountByPk", + + "type": { + + "kind": "OBJECT", + + "name": "Account", + + "ofType": null + + }, + + "description": "Retrieve a record of type `Account` by its primary key", + + "isDeprecated": false, + + "deprecationReason": null + + }, + { + "args": [ + { + @@ -5840,6 +5871,37 @@ begin; "isDeprecated": false, + "deprecationReason": null + }, + + { + + "args": [ + + { + + "name": "id", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + } + + }, + + "description": "The record's `id` value", + + "defaultValue": null + + } + + ], + + "name": "blogByPk", + + "type": { + + "kind": "OBJECT", + + "name": "Blog", + + "ofType": null + + }, + + "description": "Retrieve a record of type `Blog` by its primary key", + + "isDeprecated": false, + + "deprecationReason": null + + }, + { + "args": [ + { + @@ -5935,6 +5997,37 @@ begin; "isDeprecated": false, + "deprecationReason": null + }, + + { + + "args": [ + + { + + "name": "id", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "SCALAR", + + "name": "UUID", + + "ofType": null + + } + + } + + }, + + "description": "The record's `id` value", + + "defaultValue": null + + } + + ], + + "name": "blogPostByPk", + + "type": { + + "kind": "OBJECT", + + "name": "BlogPost", + + "ofType": null + + }, + + "description": "Retrieve a record of type `BlogPost` by its primary key", + + "isDeprecated": false, + + "deprecationReason": null + + }, + { + "args": [ + { + @@ -6057,6 +6150,33 @@ begin; "isDeprecated": false, + "deprecationReason": null + }, + + { + + "args": [ + + { + + "name": "id", + + "type": { + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "SCALAR", + + "name": "Int", + + "ofType": null + + } + + }, + + "description": "The record's `id` value", + + "defaultValue": null + + } + + ], + + "name": "personByPk", + + "type": { + + "kind": "OBJECT", + + "name": "Person", + + "ofType": null + + }, + + "description": "Retrieve a record of type `Person` by its primary key", + + "isDeprecated": false, + + "deprecationReason": null + + }, + { + "args": [ + { + diff --git a/test/expected/views_integration.out b/test/expected/views_integration.out index f570e2c3..edb98187 100644 --- a/test/expected/views_integration.out +++ b/test/expected/views_integration.out @@ -31,9 +31,15 @@ begin; "data": { + "__type": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + + { + + "name": "blogByPk" + + }, + { + "name": "blogCollection" + }, + @@ -69,15 +75,24 @@ begin; "data": { + "__type": { + "fields": [ + + { + + "name": "accountByPk" + + }, + { + "name": "accountCollection"+ }, + + { + + "name": "blogByPk" + + }, + { + "name": "blogCollection" + }, + { + "name": "node" + }, + + { + + "name": "personByPk" + + }, + { + "name": "personCollection" + } + diff --git a/test/sql/primary_key_queries.sql b/test/sql/primary_key_queries.sql new file mode 100644 index 00000000..809b4d66 --- /dev/null +++ b/test/sql/primary_key_queries.sql @@ -0,0 +1,196 @@ +begin; + -- Set up test tables with different primary key configurations + + -- Table with single column integer primary key + create table person( + id int primary key, + name text, + email text + ); + + insert into public.person(id, name, email) + values + (1, 'Alice', 'alice@example.com'), + (2, 'Bob', 'bob@example.com'), + (3, 'Charlie', null); + + -- Table with multi-column primary key + create table item( + item_id int, + product_id int, + quantity int, + price numeric(10,2), + primary key(item_id, product_id) + ); + + insert into item(item_id, product_id, quantity, price) + values + (1, 101, 2, 10.99), + (1, 102, 1, 24.99), + (2, 101, 3, 10.99), + (3, 103, 5, 5.99); + + -- Table with text primary key (instead of UUID) + create table document( + id text primary key, + title text, + content text + ); + + insert into document(id, title, content) + values + ('doc-1', 'Document 1', 'Content 1'), + ('doc-2', 'Document 2', 'Content 2'); + + savepoint a; + + -- Test 1: Query a person by primary key (single integer column) + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 1) { + id + name + email + } + } + $$) + ); + + -- Test 2: Query a person by primary key with relationship + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 2) { + id + name + email + nodeId + } + } + $$) + ); + + -- Test 3: Query a non-existent person by primary key + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 999) { + id + name + } + } + $$) + ); + + -- Test 4: Query with multi-column primary key + select jsonb_pretty( + graphql.resolve($$ + { + itemByPk(itemId: 1, productId: 102) { + itemId + productId + quantity + price + } + } + $$) + ); + + -- Test 5: Query with multi-column primary key, one column value is incorrect + select jsonb_pretty( + graphql.resolve($$ + { + itemByPk(itemId: 1, productId: 999) { + itemId + productId + quantity + price + } + } + $$) + ); + + -- Test 6: Query with text primary key + select jsonb_pretty( + graphql.resolve($$ + { + documentByPk(id: "doc-1") { + id + title + content + } + } + $$) + ); + + -- Test 7: Using variables with primary key queries + select jsonb_pretty( + graphql.resolve($$ + query GetPerson($personId: Int!) { + personByPk(id: $personId) { + id + name + email + } + } + $$, '{"personId": 3}') + ); + + -- Test 8: Using variables with multi-column primary key queries + select jsonb_pretty( + graphql.resolve($$ + query GetItem($itemId: Int!, $productId: Int!) { + itemByPk(itemId: $itemId, productId: $productId) { + itemId + productId + quantity + price + } + } + $$, '{"itemId": 2, "productId": 101}') + ); + + -- Test 9: Error case - missing required primary key column + select jsonb_pretty( + graphql.resolve($$ + { + itemByPk(itemId: 1) { + itemId + productId + } + } + $$) + ); + + -- Test 10: Using fragments with primary key queries + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 1) { + ...PersonFields + } + } + + fragment PersonFields on Person { + id + name + email + } + $$) + ); + + -- Test 11: Query with null values in results + select jsonb_pretty( + graphql.resolve($$ + { + personByPk(id: 3) { + id + name + email + } + } + $$) + ); + +rollback; \ No newline at end of file From b10cbfba489743dcf123802bf444fb039a5e6295 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 6 May 2025 17:10:35 +0530 Subject: [PATCH 02/15] fix pre-commit hook errors --- test/expected/primary_key_queries.out | 5 ++--- test/sql/primary_key_queries.sql | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/test/expected/primary_key_queries.out b/test/expected/primary_key_queries.out index f2e45957..b78e27ad 100644 --- a/test/expected/primary_key_queries.out +++ b/test/expected/primary_key_queries.out @@ -1,6 +1,5 @@ begin; -- Set up test tables with different primary key configurations - -- Table with single column integer primary key create table person( id int primary key, @@ -266,7 +265,7 @@ begin; ...PersonFields } } - + fragment PersonFields on Person { id name @@ -312,4 +311,4 @@ begin; } (1 row) -rollback; +rollback; diff --git a/test/sql/primary_key_queries.sql b/test/sql/primary_key_queries.sql index 809b4d66..4e90838e 100644 --- a/test/sql/primary_key_queries.sql +++ b/test/sql/primary_key_queries.sql @@ -1,6 +1,6 @@ begin; -- Set up test tables with different primary key configurations - + -- Table with single column integer primary key create table person( id int primary key, @@ -171,7 +171,7 @@ begin; ...PersonFields } } - + fragment PersonFields on Person { id name @@ -193,4 +193,4 @@ begin; $$) ); -rollback; \ No newline at end of file +rollback; From d68c423cc1e71c8715261d5151640a12356cb408 Mon Sep 17 00:00:00 2001 From: Dale Lakes <6843636+spitfire55@users.noreply.github.com> Date: Tue, 13 May 2025 16:23:03 -0400 Subject: [PATCH 03/15] - Make sure primary keys are supported types - Fix TODO nodeId check, move out of transpile into builder - Create SupportedPrimaryKeyType enum for PK type matching --- src/builder.rs | 10 +++++ src/graphql.rs | 95 +++++++++++++++++++++++++----------------------- src/sql_types.rs | 47 ++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 46 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 9f465b3f..b327f760 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1068,6 +1068,16 @@ pub struct NodeIdInstance { pub values: Vec, } +impl NodeIdInstance { + pub fn validate(&self, table: &Table) -> Result<(), String> { + // Validate that nodeId belongs to the table being queried + if self.schema_name != table.schema || self.table_name != table.name { + return Err("nodeId belongs to a different collection".to_string()); + } + Ok(()) + } +} + #[derive(Clone, Debug)] pub struct NodeIdBuilder { pub alias: String, diff --git a/src/graphql.rs b/src/graphql.rs index b7876839..9363cdd1 100644 --- a/src/graphql.rs +++ b/src/graphql.rs @@ -1249,55 +1249,58 @@ impl ___Type for QueryType { f.push(collection_entrypoint); // Add single record query by primary key if the table has a primary key + // and the primary key types are supported (int, bigint, uuid, string) if let Some(primary_key) = table.primary_key() { - let node_type = NodeType { - table: Arc::clone(table), - fkey: None, - reverse_reference: None, - schema: Arc::clone(&self.schema), - }; - - // Create arguments for each primary key column - let mut pk_args = Vec::new(); - for col_name in &primary_key.column_names { - if let Some(col) = table.columns.iter().find(|c| &c.name == col_name) { - let col_type = sql_column_to_graphql_type(col, &self.schema) - .ok_or_else(|| { - format!( - "Could not determine GraphQL type for column {}", - col_name - ) - }) - .unwrap_or_else(|_| __Type::Scalar(Scalar::String(None))); - - // Use graphql_column_field_name to convert snake_case to camelCase if needed - let arg_name = self.schema.graphql_column_field_name(col); - - pk_args.push(__InputValue { - name_: arg_name, - type_: __Type::NonNull(NonNullType { - type_: Box::new(col_type), - }), - description: Some(format!("The record's `{}` value", col_name)), - default_value: None, - sql_type: Some(NodeSQLType::Column(Arc::clone(col))), - }); + if table.has_supported_pk_types_for_by_pk() { + let node_type = NodeType { + table: Arc::clone(table), + fkey: None, + reverse_reference: None, + schema: Arc::clone(&self.schema), + }; + + // Create arguments for each primary key column + let mut pk_args = Vec::new(); + for col_name in &primary_key.column_names { + if let Some(col) = table.columns.iter().find(|c| &c.name == col_name) { + let col_type = sql_column_to_graphql_type(col, &self.schema) + .ok_or_else(|| { + format!( + "Could not determine GraphQL type for column {}", + col_name + ) + }) + .unwrap_or_else(|_| __Type::Scalar(Scalar::String(None))); + + // Use graphql_column_field_name to convert snake_case to camelCase if needed + let arg_name = self.schema.graphql_column_field_name(col); + + pk_args.push(__InputValue { + name_: arg_name, + type_: __Type::NonNull(NonNullType { + type_: Box::new(col_type), + }), + description: Some(format!("The record's `{}` value", col_name)), + default_value: None, + sql_type: Some(NodeSQLType::Column(Arc::clone(col))), + }); + } } - } - let pk_entrypoint = __Field { - name_: format!("{}ByPk", lowercase_first_letter(table_base_type_name)), - type_: __Type::Node(node_type), - args: pk_args, - description: Some(format!( - "Retrieve a record of type `{}` by its primary key", - table_base_type_name - )), - deprecation_reason: None, - sql_type: None, - }; + let pk_entrypoint = __Field { + name_: format!("{}ByPk", lowercase_first_letter(table_base_type_name)), + type_: __Type::Node(node_type), + args: pk_args, + description: Some(format!( + "Retrieve a record of type `{}` by its primary key", + table_base_type_name + )), + deprecation_reason: None, + sql_type: None, + }; - f.push(pk_entrypoint); + f.push(pk_entrypoint); + } } } } @@ -3485,7 +3488,7 @@ impl FromStr for FilterOp { "contains" => Ok(Self::Contains), "containedBy" => Ok(Self::ContainedBy), "overlaps" => Ok(Self::Overlap), - _ => Err("Invalid filter operation".to_string()), + other => Err(format!("Invalid filter operation: {}", other)), } } } diff --git a/src/sql_types.rs b/src/sql_types.rs index 1520f383..18c81aac 100644 --- a/src/sql_types.rs +++ b/src/sql_types.rs @@ -578,6 +578,18 @@ impl Table { .collect::>>() } + pub fn has_supported_pk_types_for_by_pk(&self) -> bool { + let pk_columns = self.primary_key_columns(); + if pk_columns.is_empty() { + return false; + } + + // Check that all primary key columns have supported types + pk_columns.iter().all(|col| { + SupportedPrimaryKeyType::from_type_name(&col.type_name).is_some() + }) + } + pub fn is_any_column_selectable(&self) -> bool { self.columns.iter().any(|x| x.permissions.is_selectable) } @@ -601,6 +613,41 @@ impl Table { } } +#[derive(Debug, PartialEq)] +pub enum SupportedPrimaryKeyType { + // Integer types + Int, // int, int4, integer + BigInt, // bigint, int8 + SmallInt, // smallint, int2 + // String types + Text, // text + VarChar, // varchar + Char, // char, bpchar + CiText, // citext + // UUID + UUID, // uuid +} + +impl SupportedPrimaryKeyType { + fn from_type_name(type_name: &str) -> Option { + match type_name { + // Integer types + "int" | "int4" | "integer" => Some(Self::Int), + "bigint" | "int8" => Some(Self::BigInt), + "smallint" | "int2" => Some(Self::SmallInt), + // String types + "text" => Some(Self::Text), + "varchar" => Some(Self::VarChar), + "char" | "bpchar" => Some(Self::Char), + "citext" => Some(Self::CiText), + // UUID + "uuid" => Some(Self::UUID), + // Any other type is not supported + _ => None, + } + } +} + #[derive(Deserialize, Clone, Debug, Eq, PartialEq, Hash)] pub struct SchemaDirectives { // @graphql({"inflect_names": true}) From 16161b86ac9517d839d862e6d7ffc23323d1a82f Mon Sep 17 00:00:00 2001 From: spitfire55 <6843636+spitfire55@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:38:18 -0500 Subject: [PATCH 04/15] Fix tests, error handling, and add tests for nodeByPk with nested function and nodeByPk with connection --- src/builder.rs | 33 +- src/resolve.rs | 8 +- src/transpile.rs | 16 +- test/expected/function_calls.out | 27 +- test/expected/function_calls_unsupported.out | 15 +- test/expected/primary_key_queries.out | 474 +++++++++++++++++++ test/sql/primary_key_queries.sql | 251 ++++++++++ 7 files changed, 781 insertions(+), 43 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index b327f760..e9823a9a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1068,16 +1068,6 @@ pub struct NodeIdInstance { pub values: Vec, } -impl NodeIdInstance { - pub fn validate(&self, table: &Table) -> Result<(), String> { - // Validate that nodeId belongs to the table being queried - if self.schema_name != table.schema || self.table_name != table.name { - return Err("nodeId belongs to a different collection".to_string()); - } - Ok(()) - } -} - #[derive(Clone, Debug)] pub struct NodeIdBuilder { pub alias: String, @@ -2185,7 +2175,7 @@ pub fn to_node_by_pk_builder<'a, T>( fragment_definitions: &Vec>, variables: &serde_json::Value, variable_definitions: &Vec>, -) -> Result +) -> GraphQLResult where T: Text<'a> + Eq + AsRef + Clone, T::Value: Hash, @@ -2197,7 +2187,7 @@ where __Type::Node(xtype) => { let type_name = xtype .name() - .ok_or("Encountered type without name in node_by_pk builder")?; + .ok_or_else(|| GraphQLError::internal("Encountered type without name in node_by_pk builder"))?; let field_map = field_map(&__Type::Node(xtype.clone())); @@ -2205,7 +2195,7 @@ where let pkey = xtype .table .primary_key() - .ok_or("Table has no primary key".to_string())?; + .ok_or_else(|| GraphQLError::validation("Table has no primary key"))?; // Create a map of expected field arguments based on the field's arg definitions let mut pk_arg_map = HashMap::new(); @@ -2231,7 +2221,7 @@ where // Need values for all primary key columns if pk_values.len() != pkey.column_names.len() { - return Err("All primary key columns must be provided".to_string()); + return Err(GraphQLError::argument("All primary key columns must be provided")); } let mut builder_fields = vec![]; @@ -2245,8 +2235,7 @@ where for selection_field in selection_fields { match field_map.get(selection_field.name.as_ref()) { None => { - return Err(format!( - "Unknown field '{}' on type '{}'", + return Err(GraphQLError::field_not_found( selection_field.name.as_ref(), &type_name )) @@ -2287,9 +2276,9 @@ where FunctionSelection::Connection(connection_builder) } _ => { - return Err( - "invalid return type from function".to_string() - ) + return Err(GraphQLError::type_error( + "invalid return type from function" + )) } }; NodeSelection::Function(FunctionBuilder { @@ -2337,10 +2326,10 @@ where NodeSelection::Node(node_builder?) } _ => { - return Err(format!( + return Err(GraphQLError::type_error(format!( "unexpected field type on node {}", f.name() - )); + ))); } }, }, @@ -2357,7 +2346,7 @@ where selections: builder_fields, }) } - _ => Err("cannot build query for non-node type".to_string()), + _ => Err(GraphQLError::type_error("cannot build query for non-node type")), } } diff --git a/src/resolve.rs b/src/resolve.rs index 8c5d5c1d..1103328f 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -283,9 +283,9 @@ where Ok(d) => { res_data[alias_or_name(selection)] = d; } - Err(msg) => res_errors.push(ErrorMessage { message: msg }), + Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), }, - Err(msg) => res_errors.push(ErrorMessage { message: msg }), + Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), } } else { // Regular node access @@ -303,9 +303,9 @@ where Ok(d) => { res_data[alias_or_name(selection)] = d; } - Err(msg) => res_errors.push(ErrorMessage { message: msg }), + Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), }, - Err(msg) => res_errors.push(ErrorMessage { message: msg }), + Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), } } } diff --git a/src/transpile.rs b/src/transpile.rs index d8e3fb2c..0a81e7e9 100644 --- a/src/transpile.rs +++ b/src/transpile.rs @@ -1527,7 +1527,7 @@ impl NodeByPkBuilder { &self, block_name: &str, param_context: &mut ParamContext, - ) -> Result { + ) -> GraphQLResult { let mut field_clauses = vec![]; for selection in &self.selections { field_clauses.push(selection.to_sql(block_name, param_context)?); @@ -1545,7 +1545,7 @@ impl NodeByPkBuilder { &self, block_name: &str, param_context: &mut ParamContext, - ) -> Result { + ) -> GraphQLResult { let mut conditions = Vec::new(); for (column_name, value) in &self.pk_values { @@ -1556,7 +1556,7 @@ impl NodeByPkBuilder { .columns .iter() .find(|c| &c.name == column_name) - .ok_or_else(|| format!("Column {} not found", column_name))? + .ok_or_else(|| GraphQLError::internal(format!("Column {} not found", column_name)))? .type_name, )?; @@ -1573,7 +1573,7 @@ impl NodeByPkBuilder { } impl QueryEntrypoint for NodeByPkBuilder { - fn to_sql_entrypoint(&self, param_context: &mut ParamContext) -> Result { + fn to_sql_entrypoint(&self, param_context: &mut ParamContext) -> GraphQLResult { let quoted_block_name = rand_block_name(); let quoted_schema = quote_ident(&self.table.schema); let quoted_table = quote_ident(&self.table.name); @@ -1613,14 +1613,14 @@ impl NodeIdInstance { let pkey = table .primary_key() - .ok_or_else(|| "Found table with no primary key".to_string())?; + .ok_or_else(|| GraphQLError::validation("Found table with no primary key"))?; if pkey.column_names.len() != self.values.len() { - return Err(format!( + return Err(GraphQLError::validation(format!( "Primary key column count mismatch. Expected {}, provided {}", pkey.column_names.len(), self.values.len() - )); + ))); } let mut conditions = vec![]; @@ -1630,7 +1630,7 @@ impl NodeIdInstance { .columns .iter() .find(|c| &c.name == column_name) - .ok_or(format!("Primary key column {} not found", column_name))?; + .ok_or_else(|| GraphQLError::validation(format!("Primary key column {} not found", column_name)))?; let value_clause = param_context.clause_for(value, &column.type_name)?; diff --git a/test/expected/function_calls.out b/test/expected/function_calls.out index aefeb10a..3d6a3ea3 100644 --- a/test/expected/function_calls.out +++ b/test/expected/function_calls.out @@ -2065,7 +2065,9 @@ begin; ], + "name": "accountByPk", + "type": { + - "kind": "OBJECT" + + "kind": "OBJECT", + + "name": "Account", + + "ofType": null + }, + "description": "Retrieve a record of type `Account` by its primary key"+ }, + @@ -2133,7 +2135,12 @@ begin; ], + "name": "accountCollection", + "type": { + - "kind": "OBJECT" + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "OBJECT", + + "name": "AccountConnection" + + } + }, + "description": "A pagable collection of type `Account`" + }, + @@ -2153,7 +2160,9 @@ begin; ], + "name": "node", + "type": { + - "kind": "INTERFACE" + + "kind": "INTERFACE", + + "name": "Node", + + "ofType": null + }, + "description": "Retrieve a record by its `ID`" + }, + @@ -2162,7 +2171,9 @@ begin; ], + "name": "returnsAccount", + "type": { + - "kind": "OBJECT" + + "kind": "OBJECT", + + "name": "Account", + + "ofType": null + }, + "description": null + }, + @@ -2182,7 +2193,9 @@ begin; ], + "name": "returnsAccountWithId", + "type": { + - "kind": "OBJECT" + + "kind": "OBJECT", + + "name": "Account", + + "ofType": null + }, + "description": null + }, + @@ -2261,7 +2274,9 @@ begin; ], + "name": "returnsSetofAccount", + "type": { + - "kind": "OBJECT" + + "kind": "OBJECT", + + "name": "AccountConnection", + + "ofType": null + }, + "description": null + } + diff --git a/test/expected/function_calls_unsupported.out b/test/expected/function_calls_unsupported.out index 80609dbc..3be4d720 100644 --- a/test/expected/function_calls_unsupported.out +++ b/test/expected/function_calls_unsupported.out @@ -326,7 +326,9 @@ begin; ], + "name": "accountByPk", + "type": { + - "kind": "OBJECT" + + "kind": "OBJECT", + + "name": "Account", + + "ofType": null + }, + "description": "Retrieve a record of type `Account` by its primary key"+ }, + @@ -377,7 +379,12 @@ begin; ], + "name": "accountCollection", + "type": { + - "kind": "OBJECT" + + "kind": "NON_NULL", + + "name": null, + + "ofType": { + + "kind": "OBJECT", + + "name": "AccountConnection" + + } + }, + "description": "A pagable collection of type `Account`" + }, + @@ -392,7 +399,9 @@ begin; ], + "name": "node", + "type": { + - "kind": "INTERFACE" + + "kind": "INTERFACE", + + "name": "Node", + + "ofType": null + }, + "description": "Retrieve a record by its `ID`" + } + diff --git a/test/expected/primary_key_queries.out b/test/expected/primary_key_queries.out index b78e27ad..35616a11 100644 --- a/test/expected/primary_key_queries.out +++ b/test/expected/primary_key_queries.out @@ -311,4 +311,478 @@ begin; } (1 row) + rollback to savepoint a; + -- Set up tables with relationships for connection and function tests + create table author( + id int primary key, + name text not null + ); + create table book( + id int primary key, + title text not null, + author_id int references author(id) + ); + insert into author(id, name) + values + (1, 'Jane Austen'), + (2, 'Charles Dickens'), + (3, 'Mark Twain'); + insert into book(id, title, author_id) + values + (1, 'Pride and Prejudice', 1), + (2, 'Sense and Sensibility', 1), + (3, 'Emma', 1), + (4, 'Oliver Twist', 2), + (5, 'Great Expectations', 2), + (6, 'Adventures of Tom Sawyer', 3); + -- Create a function that extends the author type + create function public._book_count(rec public.author) + returns int + stable + language sql + as $$ + select count(*)::int from book where author_id = rec.id + $$; + -- Create a function that returns text + create function public._formatted_name(rec public.author) + returns text + immutable + language sql + as $$ + select 'Author: ' || rec.name + $$; + -- Test 12: nodeByPk with a nested function (scalar return) + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCount + formattedName + } + } + $$) + ); + jsonb_pretty +---------------------------------------------------- + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "bookCount": 3, + + "formattedName": "Author: Jane Austen"+ + } + + } + + } +(1 row) + + -- Test 13: nodeByPk with a connection (one-to-many relationship) + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +-------------------------------------------------------------- + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "bookCollection": { + + "edges": [ + + { + + "node": { + + "id": 1, + + "title": "Pride and Prejudice" + + } + + }, + + { + + "node": { + + "id": 2, + + "title": "Sense and Sensibility"+ + } + + }, + + { + + "node": { + + "id": 3, + + "title": "Emma" + + } + + } + + ] + + } + + } + + } + + } +(1 row) + + -- Test 14: nodeByPk with connection and pagination + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection(first: 2) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +-------------------------------------------------------------- + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "bookCollection": { + + "edges": [ + + { + + "node": { + + "id": 1, + + "title": "Pride and Prejudice" + + } + + }, + + { + + "node": { + + "id": 2, + + "title": "Sense and Sensibility"+ + } + + } + + ], + + "pageInfo": { + + "hasNextPage": true, + + "hasPreviousPage": false + + } + + } + + } + + } + + } +(1 row) + + -- Test 15: nodeByPk with connection filter + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection(filter: {title: {like: "%Pride%"}}) { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +------------------------------------------------------------ + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "bookCollection": { + + "edges": [ + + { + + "node": { + + "id": 1, + + "title": "Pride and Prejudice"+ + } + + } + + ] + + } + + } + + } + + } +(1 row) + + -- Test 16: nodeByPk with connection ordering + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection(orderBy: [{title: DescNullsLast}]) { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +-------------------------------------------------------------- + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "bookCollection": { + + "edges": [ + + { + + "node": { + + "id": 2, + + "title": "Sense and Sensibility"+ + } + + }, + + { + + "node": { + + "id": 1, + + "title": "Pride and Prejudice" + + } + + }, + + { + + "node": { + + "id": 3, + + "title": "Emma" + + } + + } + + ] + + } + + } + + } + + } +(1 row) + + -- Test 17: nodeByPk with both function and connection + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 2) { + id + name + bookCount + formattedName + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +----------------------------------------------------------- + { + + "data": { + + "authorByPk": { + + "id": 2, + + "name": "Charles Dickens", + + "bookCount": 2, + + "formattedName": "Author: Charles Dickens", + + "bookCollection": { + + "edges": [ + + { + + "node": { + + "id": 4, + + "title": "Oliver Twist" + + } + + }, + + { + + "node": { + + "id": 5, + + "title": "Great Expectations"+ + } + + } + + ] + + } + + } + + } + + } +(1 row) + + -- Test 18: nodeByPk with nested relationship (book -> author) + select jsonb_pretty( + graphql.resolve($$ + { + bookByPk(id: 1) { + id + title + author { + id + name + bookCount + } + } + } + $$) + ); + jsonb_pretty +--------------------------------------------- + { + + "data": { + + "bookByPk": { + + "id": 1, + + "title": "Pride and Prejudice",+ + "author": { + + "id": 1, + + "name": "Jane Austen", + + "bookCount": 3 + + } + + } + + } + + } +(1 row) + + -- Test 19: nodeByPk with deeply nested connection + select jsonb_pretty( + graphql.resolve($$ + { + bookByPk(id: 4) { + id + title + author { + id + name + bookCollection { + edges { + node { + id + title + } + } + } + } + } + } + $$) + ); + jsonb_pretty +--------------------------------------------------------------- + { + + "data": { + + "bookByPk": { + + "id": 4, + + "title": "Oliver Twist", + + "author": { + + "id": 2, + + "name": "Charles Dickens", + + "bookCollection": { + + "edges": [ + + { + + "node": { + + "id": 4, + + "title": "Oliver Twist" + + } + + }, + + { + + "node": { + + "id": 5, + + "title": "Great Expectations"+ + } + + } + + ] + + } + + } + + } + + } + + } +(1 row) + + -- Test 20: nodeByPk returning null with connection (non-existent author) + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 999) { + id + name + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +---------------------------- + { + + "data": { + + "authorByPk": null+ + } + + } +(1 row) + + -- Test 21: nodeByPk with empty connection (author with no books) + insert into author(id, name) values (4, 'New Author'); + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 4) { + id + name + bookCount + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +----------------------------------- + { + + "data": { + + "authorByPk": { + + "id": 4, + + "name": "New Author",+ + "bookCount": 0, + + "bookCollection": { + + "edges": [ + + ] + + } + + } + + } + + } +(1 row) + rollback; diff --git a/test/sql/primary_key_queries.sql b/test/sql/primary_key_queries.sql index 4e90838e..0125047a 100644 --- a/test/sql/primary_key_queries.sql +++ b/test/sql/primary_key_queries.sql @@ -193,4 +193,255 @@ begin; $$) ); + rollback to savepoint a; + + -- Set up tables with relationships for connection and function tests + create table author( + id int primary key, + name text not null + ); + + create table book( + id int primary key, + title text not null, + author_id int references author(id) + ); + + insert into author(id, name) + values + (1, 'Jane Austen'), + (2, 'Charles Dickens'), + (3, 'Mark Twain'); + + insert into book(id, title, author_id) + values + (1, 'Pride and Prejudice', 1), + (2, 'Sense and Sensibility', 1), + (3, 'Emma', 1), + (4, 'Oliver Twist', 2), + (5, 'Great Expectations', 2), + (6, 'Adventures of Tom Sawyer', 3); + + -- Create a function that extends the author type + create function public._book_count(rec public.author) + returns int + stable + language sql + as $$ + select count(*)::int from book where author_id = rec.id + $$; + + -- Create a function that returns text + create function public._formatted_name(rec public.author) + returns text + immutable + language sql + as $$ + select 'Author: ' || rec.name + $$; + + -- Test 12: nodeByPk with a nested function (scalar return) + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCount + formattedName + } + } + $$) + ); + + -- Test 13: nodeByPk with a connection (one-to-many relationship) + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 14: nodeByPk with connection and pagination + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection(first: 2) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 15: nodeByPk with connection filter + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection(filter: {title: {like: "%Pride%"}}) { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 16: nodeByPk with connection ordering + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookCollection(orderBy: [{title: DescNullsLast}]) { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 17: nodeByPk with both function and connection + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 2) { + id + name + bookCount + formattedName + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 18: nodeByPk with nested relationship (book -> author) + select jsonb_pretty( + graphql.resolve($$ + { + bookByPk(id: 1) { + id + title + author { + id + name + bookCount + } + } + } + $$) + ); + + -- Test 19: nodeByPk with deeply nested connection + select jsonb_pretty( + graphql.resolve($$ + { + bookByPk(id: 4) { + id + title + author { + id + name + bookCollection { + edges { + node { + id + title + } + } + } + } + } + } + $$) + ); + + -- Test 20: nodeByPk returning null with connection (non-existent author) + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 999) { + id + name + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 21: nodeByPk with empty connection (author with no books) + insert into author(id, name) values (4, 'New Author'); + + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 4) { + id + name + bookCount + bookCollection { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + rollback; From dea909222e8d833cd017bda8b594c845274a6c9e Mon Sep 17 00:00:00 2001 From: spitfire55 <6843636+spitfire55@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:56:52 -0500 Subject: [PATCH 05/15] Add tests for byPk __typename introspection and unknown field in byPk --- test/expected/resolve___typename.out | 56 +++++++++++++++++++ test/expected/resolve_error_node_no_field.out | 14 +++++ test/sql/resolve___typename.sql | 34 +++++++++++ test/sql/resolve_error_node_no_field.sql | 10 ++++ 4 files changed, 114 insertions(+) diff --git a/test/expected/resolve___typename.out b/test/expected/resolve___typename.out index 9e4742d6..f48f423d 100644 --- a/test/expected/resolve___typename.out +++ b/test/expected/resolve___typename.out @@ -154,4 +154,60 @@ begin; } (1 row) + -- Reset data for byPk tests + insert into public.account(id, parent_id) + values + (1, 1), + (2, 1); + -- Test __typename with byPk query + select jsonb_pretty( + graphql.resolve($$ + query { + accountByPk(id: 1) { + __typename + id + parent { + __typename + id + } + } + } + $$) + ); + jsonb_pretty +----------------------------------------- + { + + "data": { + + "accountByPk": { + + "id": 1, + + "parent": { + + "id": 1, + + "__typename": "Account"+ + }, + + "__typename": "Account" + + } + + } + + } +(1 row) + + -- Test __typename with byPk query returning null + select jsonb_pretty( + graphql.resolve($$ + query { + accountByPk(id: 999) { + __typename + id + } + } + $$) + ); + jsonb_pretty +----------------------------- + { + + "data": { + + "accountByPk": null+ + } + + } +(1 row) + rollback; diff --git a/test/expected/resolve_error_node_no_field.out b/test/expected/resolve_error_node_no_field.out index 8c334c9c..c3620a2c 100644 --- a/test/expected/resolve_error_node_no_field.out +++ b/test/expected/resolve_error_node_no_field.out @@ -22,4 +22,18 @@ begin; {"data": null, "errors": [{"message": "Unknown field 'dneField' on type 'Account'"}]} (1 row) + -- Test unknown field on byPk query + select graphql.resolve($$ + { + accountByPk(id: 1) { + id + nonExistentField + } + } + $$); + resolve +----------------------------------------------------------------------------------------------- + {"data": null, "errors": [{"message": "Unknown field \"nonExistentField\" on type Account"}]} +(1 row) + rollback; diff --git a/test/sql/resolve___typename.sql b/test/sql/resolve___typename.sql index 8a5548a1..2a553507 100644 --- a/test/sql/resolve___typename.sql +++ b/test/sql/resolve___typename.sql @@ -79,4 +79,38 @@ begin; $$) ); + -- Reset data for byPk tests + insert into public.account(id, parent_id) + values + (1, 1), + (2, 1); + + -- Test __typename with byPk query + select jsonb_pretty( + graphql.resolve($$ + query { + accountByPk(id: 1) { + __typename + id + parent { + __typename + id + } + } + } + $$) + ); + + -- Test __typename with byPk query returning null + select jsonb_pretty( + graphql.resolve($$ + query { + accountByPk(id: 999) { + __typename + id + } + } + $$) + ); + rollback; diff --git a/test/sql/resolve_error_node_no_field.sql b/test/sql/resolve_error_node_no_field.sql index eaf81884..cdad7730 100644 --- a/test/sql/resolve_error_node_no_field.sql +++ b/test/sql/resolve_error_node_no_field.sql @@ -21,4 +21,14 @@ begin; } $$); + -- Test unknown field on byPk query + select graphql.resolve($$ + { + accountByPk(id: 1) { + id + nonExistentField + } + } + $$); + rollback; From c60242195c30bab7be7d289dfcc64fe30415984c Mon Sep 17 00:00:00 2001 From: spitfire55 <6843636+spitfire55@users.noreply.github.com> Date: Tue, 20 Jan 2026 17:15:06 -0500 Subject: [PATCH 06/15] Add tests for byPk with other function calls --- test/expected/primary_key_queries.out | 257 ++++++++++++++++++++++++++ test/sql/primary_key_queries.sql | 137 ++++++++++++++ 2 files changed, 394 insertions(+) diff --git a/test/expected/primary_key_queries.out b/test/expected/primary_key_queries.out index 35616a11..ce66a614 100644 --- a/test/expected/primary_key_queries.out +++ b/test/expected/primary_key_queries.out @@ -785,4 +785,261 @@ begin; } (1 row) + -- Test 22: nodeByPk with function returning array type + create function public._book_titles(rec public.author) + returns text[] + stable + language sql + as $$ + select array_agg(title) from book where author_id = rec.id + $$; + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookTitles + } + } + $$) + ); + jsonb_pretty +------------------------------------------ + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "bookTitles": [ + + "Pride and Prejudice", + + "Sense and Sensibility",+ + "Emma" + + ] + + } + + } + + } +(1 row) + + -- Test 23: nodeByPk with function returning node type (single related record) + create function public._latest_book(rec public.author) + returns public.book + stable + language sql + as $$ + select * from book where author_id = rec.id order by id desc limit 1 + $$; + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + latestBook { + id + title + } + } + } + $$) + ); + jsonb_pretty +------------------------------------ + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen",+ + "latestBook": { + + "id": 3, + + "title": "Emma" + + } + + } + + } + + } +(1 row) + + -- Test 24: nodeByPk with function returning node type, nested selection + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 2) { + id + name + latestBook { + id + title + author { + id + name + } + } + } + } + $$) + ); + jsonb_pretty +------------------------------------------------ + { + + "data": { + + "authorByPk": { + + "id": 2, + + "name": "Charles Dickens", + + "latestBook": { + + "id": 5, + + "title": "Great Expectations",+ + "author": { + + "id": 2, + + "name": "Charles Dickens" + + } + + } + + } + + } + + } +(1 row) + + -- Test 25: nodeByPk with function returning connection type (setof) + create function public._popular_books(rec public.author) + returns setof public.book + stable + language sql + as $$ + select * from book where author_id = rec.id and id <= 2 + $$; + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + popularBooks { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +-------------------------------------------------------------- + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "popularBooks": { + + "edges": [ + + { + + "node": { + + "id": 1, + + "title": "Pride and Prejudice" + + } + + }, + + { + + "node": { + + "id": 2, + + "title": "Sense and Sensibility"+ + } + + } + + ] + + } + + } + + } + + } +(1 row) + + -- Test 26: nodeByPk with function returning connection type with pagination + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + popularBooks(first: 1) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +------------------------------------------------------------ + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "popularBooks": { + + "edges": [ + + { + + "node": { + + "id": 1, + + "title": "Pride and Prejudice"+ + } + + } + + ], + + "pageInfo": { + + "hasNextPage": true, + + "hasPreviousPage": false + + } + + } + + } + + } + + } +(1 row) + + -- Test 27: nodeByPk with function returning connection type with filter + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + popularBooks(filter: {id: {eq: 1}}) { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + jsonb_pretty +------------------------------------------------------------ + { + + "data": { + + "authorByPk": { + + "id": 1, + + "name": "Jane Austen", + + "popularBooks": { + + "edges": [ + + { + + "node": { + + "id": 1, + + "title": "Pride and Prejudice"+ + } + + } + + ] + + } + + } + + } + + } +(1 row) + rollback; diff --git a/test/sql/primary_key_queries.sql b/test/sql/primary_key_queries.sql index 0125047a..64991423 100644 --- a/test/sql/primary_key_queries.sql +++ b/test/sql/primary_key_queries.sql @@ -444,4 +444,141 @@ begin; $$) ); + -- Test 22: nodeByPk with function returning array type + create function public._book_titles(rec public.author) + returns text[] + stable + language sql + as $$ + select array_agg(title) from book where author_id = rec.id + $$; + + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + bookTitles + } + } + $$) + ); + + -- Test 23: nodeByPk with function returning node type (single related record) + create function public._latest_book(rec public.author) + returns public.book + stable + language sql + as $$ + select * from book where author_id = rec.id order by id desc limit 1 + $$; + + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + latestBook { + id + title + } + } + } + $$) + ); + + -- Test 24: nodeByPk with function returning node type, nested selection + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 2) { + id + name + latestBook { + id + title + author { + id + name + } + } + } + } + $$) + ); + + -- Test 25: nodeByPk with function returning connection type (setof) + create function public._popular_books(rec public.author) + returns setof public.book + stable + language sql + as $$ + select * from book where author_id = rec.id and id <= 2 + $$; + + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + popularBooks { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 26: nodeByPk with function returning connection type with pagination + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + popularBooks(first: 1) { + pageInfo { + hasNextPage + hasPreviousPage + } + edges { + node { + id + title + } + } + } + } + } + $$) + ); + + -- Test 27: nodeByPk with function returning connection type with filter + select jsonb_pretty( + graphql.resolve($$ + { + authorByPk(id: 1) { + id + name + popularBooks(filter: {id: {eq: 1}}) { + edges { + node { + id + title + } + } + } + } + } + $$) + ); + rollback; From 40671a6ddba6fffc4d32ea8478fe621318dc6100 Mon Sep 17 00:00:00 2001 From: spitfire55 <6843636+spitfire55@users.noreply.github.com> Date: Tue, 20 Jan 2026 17:25:18 -0500 Subject: [PATCH 07/15] Simplify resolve_selection_set to remove dead code path for byPk --- src/resolve.rs | 62 ++++++++++++-------------------------------------- 1 file changed, 15 insertions(+), 47 deletions(-) diff --git a/src/resolve.rs b/src/resolve.rs index 1103328f..20f2f299 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -258,55 +258,23 @@ where } } __Type::Node(_) => { - // Determine if this is a primary key query field - let has_pk_args = !field_def.args().is_empty() - && field_def.args().iter().all(|arg| { - // All PK field args have a SQL Column type - arg.sql_type.is_some() - && matches!( - arg.sql_type.as_ref().unwrap(), - NodeSQLType::Column(_) - ) - }); - - if has_pk_args { - let node_by_pk_builder = to_node_by_pk_builder( - field_def, - selection, - &fragment_definitions, - variables, - variable_definitions, - ); - - match node_by_pk_builder { - Ok(builder) => match builder.execute() { - Ok(d) => { - res_data[alias_or_name(selection)] = d; - } - Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), - }, - Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), - } - } else { - // Regular node access - let node_builder = to_node_builder( - field_def, - selection, - &fragment_definitions, - variables, - &[], - variable_definitions, - ); + // Node types at Query level are *ByPk fields with primary key column args + let node_by_pk_builder = to_node_by_pk_builder( + field_def, + selection, + &fragment_definitions, + variables, + variable_definitions, + ); - match node_builder { - Ok(builder) => match builder.execute() { - Ok(d) => { - res_data[alias_or_name(selection)] = d; - } - Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), - }, + match node_by_pk_builder { + Ok(builder) => match builder.execute() { + Ok(d) => { + res_data[alias_or_name(selection)] = d; + } Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), - } + }, + Err(msg) => res_errors.push(ErrorMessage { message: msg.to_string() }), } } __Type::__Type(_) => { From b9b381aee61bd21ead4ea99dacd44704834eba10 Mon Sep 17 00:00:00 2001 From: spitfire55 <6843636+spitfire55@users.noreply.github.com> Date: Tue, 20 Jan 2026 17:30:47 -0500 Subject: [PATCH 08/15] More changes to improve coverage --- src/builder.rs | 309 +++++++++++++++++++++++++------------------------ 1 file changed, 155 insertions(+), 154 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index e9823a9a..09bbc203 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -2183,171 +2183,172 @@ where let type_ = field.type_().unmodified_type(); let alias = alias_or_name(query_field); - match type_ { - __Type::Node(xtype) => { - let type_name = xtype - .name() - .ok_or_else(|| GraphQLError::internal("Encountered type without name in node_by_pk builder"))?; - - let field_map = field_map(&__Type::Node(xtype.clone())); - - // Get primary key columns from the table - let pkey = xtype - .table - .primary_key() - .ok_or_else(|| GraphQLError::validation("Table has no primary key"))?; - - // Create a map of expected field arguments based on the field's arg definitions - let mut pk_arg_map = HashMap::new(); - for arg in field.args() { - if let Some(NodeSQLType::Column(col)) = &arg.sql_type { - pk_arg_map.insert(arg.name().to_string(), col.name.clone()); - } - } + // This function is only called for Node types from resolve_selection_set + let xtype = match type_ { + __Type::Node(node_type) => node_type, + _ => return Err(GraphQLError::internal("to_node_by_pk_builder called with non-Node type")), + }; - let mut pk_values = HashMap::new(); + let type_name = xtype + .name() + .ok_or_else(|| GraphQLError::internal("Encountered type without name in node_by_pk builder"))?; - // Process each argument in the query - for arg in &query_field.arguments { - let arg_name = arg.0.as_ref(); + let field_map = field_map(&__Type::Node(xtype.clone())); - // Find the corresponding column name from our argument map - if let Some(col_name) = pk_arg_map.get(arg_name) { - let value = to_gson(&arg.1, variables, variable_definitions)?; - let json_value = gson::gson_to_json(&value)?; - pk_values.insert(col_name.clone(), json_value); - } - } + // Get primary key columns from the table + let pkey = xtype + .table + .primary_key() + .ok_or_else(|| GraphQLError::validation("Table has no primary key"))?; - // Need values for all primary key columns - if pk_values.len() != pkey.column_names.len() { - return Err(GraphQLError::argument("All primary key columns must be provided")); - } + // Create a map of expected field arguments based on the field's arg definitions + let mut pk_arg_map = HashMap::new(); + for arg in field.args() { + if let Some(NodeSQLType::Column(col)) = &arg.sql_type { + pk_arg_map.insert(arg.name().to_string(), col.name.clone()); + } + } - let mut builder_fields = vec![]; - let selection_fields = normalize_selection_set( - &query_field.selection_set, - fragment_definitions, - &type_name, - variables, - )?; + let mut pk_values = HashMap::new(); - for selection_field in selection_fields { - match field_map.get(selection_field.name.as_ref()) { - None => { - return Err(GraphQLError::field_not_found( - selection_field.name.as_ref(), - &type_name - )) - } - Some(f) => { - let alias = alias_or_name(&selection_field); - - let node_selection = match &f.sql_type { - Some(node_sql_type) => match node_sql_type { - NodeSQLType::Column(col) => NodeSelection::Column(ColumnBuilder { - alias, - column: Arc::clone(col), - }), - NodeSQLType::Function(func) => { - let function_selection = match &f.type_() { - __Type::Scalar(_) => FunctionSelection::ScalarSelf, - __Type::List(_) => FunctionSelection::Array, - __Type::Node(_) => { - let node_builder = to_node_builder( - f, - &selection_field, - fragment_definitions, - variables, - &[], - variable_definitions, - )?; - FunctionSelection::Node(node_builder) - } - __Type::Connection(_) => { - let connection_builder = to_connection_builder( - f, - &selection_field, - fragment_definitions, - variables, - &[], - variable_definitions, - )?; - FunctionSelection::Connection(connection_builder) - } - _ => { - return Err(GraphQLError::type_error( - "invalid return type from function" - )) - } - }; - NodeSelection::Function(FunctionBuilder { - alias, - function: Arc::clone(func), - table: Arc::clone(&xtype.table), - selection: function_selection, - }) + // Process each argument in the query + for arg in &query_field.arguments { + let arg_name = arg.0.as_ref(); + + // Find the corresponding column name from our argument map + if let Some(col_name) = pk_arg_map.get(arg_name) { + let value = to_gson(&arg.1, variables, variable_definitions)?; + let json_value = gson::gson_to_json(&value)?; + pk_values.insert(col_name.clone(), json_value); + } + } + + // Need values for all primary key columns + if pk_values.len() != pkey.column_names.len() { + return Err(GraphQLError::argument("All primary key columns must be provided")); + } + + let mut builder_fields = vec![]; + let selection_fields = normalize_selection_set( + &query_field.selection_set, + fragment_definitions, + &type_name, + variables, + )?; + + for selection_field in selection_fields { + match field_map.get(selection_field.name.as_ref()) { + None => { + return Err(GraphQLError::field_not_found( + selection_field.name.as_ref(), + &type_name + )) + } + Some(f) => { + let alias = alias_or_name(&selection_field); + + let node_selection = match &f.sql_type { + Some(node_sql_type) => match node_sql_type { + NodeSQLType::Column(col) => NodeSelection::Column(ColumnBuilder { + alias, + column: Arc::clone(col), + }), + NodeSQLType::Function(func) => { + let function_selection = match &f.type_() { + __Type::Scalar(_) => FunctionSelection::ScalarSelf, + __Type::List(_) => FunctionSelection::Array, + __Type::Node(_) => { + let node_builder = to_node_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + )?; + FunctionSelection::Node(node_builder) } - NodeSQLType::NodeId(pkey_columns) => { - NodeSelection::NodeId(NodeIdBuilder { - alias, - columns: pkey_columns.clone(), - table_name: xtype.table.name.clone(), - schema_name: xtype.table.schema.clone(), - }) + __Type::Connection(_) => { + let connection_builder = to_connection_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + )?; + FunctionSelection::Connection(connection_builder) } - }, - _ => match f.name().as_ref() { - "__typename" => NodeSelection::Typename { - alias: alias_or_name(&selection_field), - typename: xtype.name().expect("node type should have a name"), - }, - _ => match f.type_().unmodified_type() { - __Type::Connection(_) => { - let con_builder = to_connection_builder( - f, - &selection_field, - fragment_definitions, - variables, - &[], - variable_definitions, - ); - NodeSelection::Connection(con_builder?) - } - __Type::Node(_) => { - let node_builder = to_node_builder( - f, - &selection_field, - fragment_definitions, - variables, - &[], - variable_definitions, - ); - NodeSelection::Node(node_builder?) - } - _ => { - return Err(GraphQLError::type_error(format!( - "unexpected field type on node {}", - f.name() - ))); - } - }, - }, - }; - builder_fields.push(node_selection); - } - } + _ => { + return Err(GraphQLError::type_error( + "invalid return type from function" + )) + } + }; + NodeSelection::Function(FunctionBuilder { + alias, + function: Arc::clone(func), + table: Arc::clone(&xtype.table), + selection: function_selection, + }) + } + NodeSQLType::NodeId(pkey_columns) => { + NodeSelection::NodeId(NodeIdBuilder { + alias, + columns: pkey_columns.clone(), + table_name: xtype.table.name.clone(), + schema_name: xtype.table.schema.clone(), + }) + } + }, + _ => match f.name().as_ref() { + "__typename" => NodeSelection::Typename { + alias: alias_or_name(&selection_field), + typename: xtype.name().expect("node type should have a name"), + }, + _ => match f.type_().unmodified_type() { + __Type::Connection(_) => { + let con_builder = to_connection_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + ); + NodeSelection::Connection(con_builder?) + } + __Type::Node(_) => { + let node_builder = to_node_builder( + f, + &selection_field, + fragment_definitions, + variables, + &[], + variable_definitions, + ); + NodeSelection::Node(node_builder?) + } + _ => { + return Err(GraphQLError::type_error(format!( + "unexpected field type on node {}", + f.name() + ))); + } + }, + }, + }; + builder_fields.push(node_selection); } - - Ok(NodeByPkBuilder { - pk_values, - _alias: alias, - table: Arc::clone(&xtype.table), - selections: builder_fields, - }) } - _ => Err(GraphQLError::type_error("cannot build query for non-node type")), } + + Ok(NodeByPkBuilder { + pk_values, + _alias: alias, + table: Arc::clone(&xtype.table), + selections: builder_fields, + }) } // Introspection From d17246abb335df7facdd96ec0a23af5409a8ab94 Mon Sep 17 00:00:00 2001 From: spitfire55 <6843636+spitfire55@users.noreply.github.com> Date: Tue, 20 Jan 2026 17:33:01 -0500 Subject: [PATCH 09/15] Remove dead code --- src/transpile.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/transpile.rs b/src/transpile.rs index 0a81e7e9..60093bd4 100644 --- a/src/transpile.rs +++ b/src/transpile.rs @@ -1533,10 +1533,6 @@ impl NodeByPkBuilder { field_clauses.push(selection.to_sql(block_name, param_context)?); } - if field_clauses.is_empty() { - return Ok("'{}'::jsonb".to_string()); - } - let fields_clause = field_clauses.join(", "); Ok(format!("jsonb_build_object({fields_clause})")) } From 4e0d14a0f52e78bb50c7cf3e19d2e6f75692fd92 Mon Sep 17 00:00:00 2001 From: spitfire55 <6843636+spitfire55@users.noreply.github.com> Date: Mon, 26 Jan 2026 10:35:17 -0500 Subject: [PATCH 10/15] Switch from UUID to Uuid everywhere. Add more tests for byPk. Better error for missing Pk columns --- docs/usage_with_apollo.md | 2 +- docs/usage_with_relay.md | 2 +- src/builder.rs | 18 +- src/graphql.rs | 20 +-- src/parser_util.rs | 2 +- src/sql_types.rs | 8 +- test/expected/array_args_and_return_types.out | 12 +- test/expected/function_calls.out | 4 +- test/expected/function_calls_default_args.out | 2 +- test/expected/issue_444.out | 2 +- test/expected/issue_533.out | 2 +- .../expected/issue_557_1_to_1_nullability.out | 6 +- .../issue_581_missing_desc_on_schema.out | 2 +- test/expected/omit_weird_names.out | 6 +- test/expected/primary_key_queries.out | 168 ++++++++++++++++-- test/expected/resolve___schema.out | 6 +- test/expected/resolve_graphiql_schema.out | 34 ++-- test/expected/roundtrip_types.out | 4 +- test/sql/primary_key_queries.sql | 70 +++++++- 19 files changed, 289 insertions(+), 81 deletions(-) diff --git a/docs/usage_with_apollo.md b/docs/usage_with_apollo.md index 35da0164..4d0529de 100644 --- a/docs/usage_with_apollo.md +++ b/docs/usage_with_apollo.md @@ -27,7 +27,7 @@ const config: CodegenConfig = { plugins: [], config: { scalars: { - UUID: 'string', + Uuid: 'string', Date: 'string', Time: 'string', Datetime: 'string', diff --git a/docs/usage_with_relay.md b/docs/usage_with_relay.md index 94a5e0f3..4903e4bb 100644 --- a/docs/usage_with_relay.md +++ b/docs/usage_with_relay.md @@ -21,7 +21,7 @@ Modify your `relay.config.js` file to reflect the following: nodeInterfaceIdVariableName: 'nodeId', }, customScalarTypes: { - UUID: 'string', + Uuid: 'string', Datetime: 'string', JSON: 'string', BigInt: 'string', diff --git a/src/builder.rs b/src/builder.rs index 09bbc203..1275b3fb 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1039,14 +1039,8 @@ pub struct NodeBuilder { #[derive(Clone, Debug)] pub struct NodeByPkBuilder { - // args - map of column name to value pub pk_values: HashMap, - - pub _alias: String, - - // metadata pub table: Arc
, - pub selections: Vec, } @@ -2181,7 +2175,6 @@ where T::Value: Hash, { let type_ = field.type_().unmodified_type(); - let alias = alias_or_name(query_field); // This function is only called for Node types from resolve_selection_set let xtype = match type_ { @@ -2225,7 +2218,15 @@ where // Need values for all primary key columns if pk_values.len() != pkey.column_names.len() { - return Err(GraphQLError::argument("All primary key columns must be provided")); + let missing_cols: Vec<_> = pkey + .column_names + .iter() + .filter(|col| !pk_values.contains_key(*col)) + .collect(); + return Err(GraphQLError::argument(format!( + "Missing primary key column(s): {}", + missing_cols.iter().map(|s| s.as_str()).collect::>().join(", ") + ))); } let mut builder_fields = vec![]; @@ -2345,7 +2346,6 @@ where Ok(NodeByPkBuilder { pk_values, - _alias: alias, table: Arc::clone(&xtype.table), selections: builder_fields, }) diff --git a/src/graphql.rs b/src/graphql.rs index 9363cdd1..d349dfad 100644 --- a/src/graphql.rs +++ b/src/graphql.rs @@ -903,7 +903,7 @@ pub enum Scalar { Time, Datetime, BigInt, - UUID, + Uuid, JSON, Cursor, BigFloat, @@ -1638,7 +1638,7 @@ impl ___Type for Scalar { Self::Date => "Date", Self::Time => "Time", Self::BigInt => "BigInt", - Self::UUID => "UUID", + Self::Uuid => "Uuid", Self::JSON => "JSON", Self::Cursor => "Cursor", Self::BigFloat => "BigFloat", @@ -1660,7 +1660,7 @@ impl ___Type for Scalar { Self::Date => "A date without time information", Self::Time => "A time without date information", Self::Datetime => "A date and time", - Self::UUID => "A universally unique identifier", + Self::Uuid => "A universally unique identifier", Self::JSON => "A Javascript Object Notation value serialized as a string", Self::Cursor => { "An opaque string using for tracking a position in results during pagination" @@ -1944,7 +1944,7 @@ impl Type { 3802 => __Type::Scalar(Scalar::JSON), // jsonb 114 => __Type::Scalar(Scalar::JSON), // json 1083 => __Type::Scalar(Scalar::Time), // time without time zone - 2950 => __Type::Scalar(Scalar::UUID), // uuid + 2950 => __Type::Scalar(Scalar::Uuid), // uuid 1700 => __Type::Scalar(Scalar::BigFloat), // numeric 25 => __Type::Scalar(Scalar::String(None)), // text // char, bpchar, varchar @@ -3520,7 +3520,7 @@ impl ___Type for FilterTypeType { // IDFilter only supports equality Scalar::ID => vec![FilterOp::Equal], // UUIDs are not ordered - Scalar::UUID => { + Scalar::Uuid => { vec![ FilterOp::Equal, FilterOp::NotEqual, @@ -3823,7 +3823,7 @@ impl ___Type for FilterEntityType { | Scalar::Float | Scalar::String(_) | Scalar::Boolean - | Scalar::UUID + | Scalar::Uuid | Scalar::BigInt | Scalar::BigFloat | Scalar::Time @@ -4087,7 +4087,7 @@ impl __Schema { __Type::Scalar(Scalar::Time), __Type::Scalar(Scalar::Datetime), __Type::Scalar(Scalar::BigInt), - __Type::Scalar(Scalar::UUID), + __Type::Scalar(Scalar::Uuid), __Type::Scalar(Scalar::JSON), __Type::Scalar(Scalar::Cursor), __Type::Scalar(Scalar::BigFloat), @@ -4134,7 +4134,7 @@ impl __Schema { schema: Arc::clone(&schema_rc), }), __Type::FilterType(FilterTypeType { - entity: FilterableType::Scalar(Scalar::UUID), + entity: FilterableType::Scalar(Scalar::Uuid), schema: Arc::clone(&schema_rc), }), __Type::FilterType(FilterTypeType { @@ -4195,7 +4195,7 @@ impl __Schema { }), __Type::FilterType(FilterTypeType { entity: FilterableType::List(ListType { - type_: Box::new(__Type::Scalar(Scalar::UUID)), + type_: Box::new(__Type::Scalar(Scalar::Uuid)), }), schema: Arc::clone(&schema_rc), }), @@ -4736,7 +4736,7 @@ fn sql_type_to_scalar(sql_type_name: &str, typmod: Option) -> Option Some(Scalar::Date), "time" | "timetz" => Some(Scalar::Time), "timestamp" | "timestamptz" => Some(Scalar::Datetime), - "uuid" => Some(Scalar::UUID), + "uuid" => Some(Scalar::Uuid), "json" | "jsonb" => Some(Scalar::JSON), _ => Some(Scalar::Opaque), // Fallback for unknown types } diff --git a/src/parser_util.rs b/src/parser_util.rs index 0d763a2c..811c01c7 100644 --- a/src/parser_util.rs +++ b/src/parser_util.rs @@ -409,7 +409,7 @@ pub fn validate_arg_from_type(type_: &__Type, value: &gson::Value) -> GraphQLRes ))) } }, - Scalar::UUID => { + Scalar::Uuid => { match value { // XXX: future - validate uuid here GsonValue::Absent | GsonValue::Null | GsonValue::String(_) => value.clone(), diff --git a/src/sql_types.rs b/src/sql_types.rs index 18c81aac..cd11d202 100644 --- a/src/sql_types.rs +++ b/src/sql_types.rs @@ -624,8 +624,8 @@ pub enum SupportedPrimaryKeyType { VarChar, // varchar Char, // char, bpchar CiText, // citext - // UUID - UUID, // uuid + // Uuid + Uuid, // uuid } impl SupportedPrimaryKeyType { @@ -640,8 +640,8 @@ impl SupportedPrimaryKeyType { "varchar" => Some(Self::VarChar), "char" | "bpchar" => Some(Self::Char), "citext" => Some(Self::CiText), - // UUID - "uuid" => Some(Self::UUID), + // Uuid + "uuid" => Some(Self::Uuid), // Any other type is not supported _ => None, } diff --git a/test/expected/array_args_and_return_types.out b/test/expected/array_args_and_return_types.out index 656dcc17..f3cecb0e 100644 --- a/test/expected/array_args_and_return_types.out +++ b/test/expected/array_args_and_return_types.out @@ -1081,7 +1081,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID" + + "name": "Uuid" + } + } + } + @@ -1102,7 +1102,7 @@ begin; "name": "getUuidArrayItem", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "description": null + @@ -1334,7 +1334,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + }, + @@ -2462,7 +2462,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID" + + "name": "Uuid" + } + } + } + @@ -2483,7 +2483,7 @@ begin; "name": "getUuidArrayItem", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "description": null + @@ -2692,7 +2692,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + }, + diff --git a/test/expected/function_calls.out b/test/expected/function_calls.out index 3d6a3ea3..a16f4aa0 100644 --- a/test/expected/function_calls.out +++ b/test/expected/function_calls.out @@ -825,7 +825,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID" + + "name": "Uuid" + } + } + } + @@ -1687,7 +1687,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID" + + "name": "Uuid" + } + } + } + diff --git a/test/expected/function_calls_default_args.out b/test/expected/function_calls_default_args.out index a31e03ae..4e651c7b 100644 --- a/test/expected/function_calls_default_args.out +++ b/test/expected/function_calls_default_args.out @@ -362,7 +362,7 @@ begin; "name": "h", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "defaultValue": null + diff --git a/test/expected/issue_444.out b/test/expected/issue_444.out index 20e81847..b617851e 100644 --- a/test/expected/issue_444.out +++ b/test/expected/issue_444.out @@ -58,7 +58,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR",+ - "name": "UUID" + + "name": "Uuid" + } + } + } + diff --git a/test/expected/issue_533.out b/test/expected/issue_533.out index aa9ee2d3..db4b97b1 100644 --- a/test/expected/issue_533.out +++ b/test/expected/issue_533.out @@ -49,7 +49,7 @@ begin; "name": "pUserId", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "defaultValue": null + diff --git a/test/expected/issue_557_1_to_1_nullability.out b/test/expected/issue_557_1_to_1_nullability.out index 1667aeb3..1329503e 100644 --- a/test/expected/issue_557_1_to_1_nullability.out +++ b/test/expected/issue_557_1_to_1_nullability.out @@ -68,7 +68,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "description": "A universally unique identifier" + }, + "description": null + @@ -163,7 +163,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "description": "A universally unique identifier" + }, + "description": null + @@ -255,7 +255,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "description": "A universally unique identifier" + }, + "description": null + diff --git a/test/expected/issue_581_missing_desc_on_schema.out b/test/expected/issue_581_missing_desc_on_schema.out index a7ce6cdc..0412cd5a 100644 --- a/test/expected/issue_581_missing_desc_on_schema.out +++ b/test/expected/issue_581_missing_desc_on_schema.out @@ -99,7 +99,7 @@ fragment TypeRef on __Type { $$, NULL, 'IntrospectionQuery'); resolve ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"data": {"__schema": {"types": [{"kind": "SCALAR", "name": "BigFloat", "fields": null, "enumValues": [], "interfaces": [], "description": "A high precision floating point value represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloat\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "BigInt", "fields": null, "enumValues": [], "interfaces": [], "description": "An arbitrary size integer represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigInt\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigIntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Boolean", "fields": null, "enumValues": [], "interfaces": [], "description": "A value that is true or false", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Boolean\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BooleanList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Cursor", "fields": null, "enumValues": [], "interfaces": [], "description": "An opaque string using for tracking a position in results during pagination", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Date", "fields": null, "enumValues": [], "interfaces": [], "description": "A date without time information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Date\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DateList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Datetime", "fields": null, "enumValues": [], "interfaces": [], "description": "A date and time", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Datetime\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DatetimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "FilterIs", "fields": null, "enumValues": [{"name": "NULL", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NOT_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Float", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar floating point value up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Float\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"FloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "ID", "fields": null, "enumValues": [], "interfaces": [], "description": "A globally unique identifier for a given record", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IDFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"ID\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "ID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Int", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar integer up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Int\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"IntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "JSON", "fields": null, "enumValues": [], "interfaces": [], "description": "A Javascript Object Notation value serialized as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INTERFACE", "name": "Node", "fields": [{"args": [], "name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "Retrieves a record by `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": []}, {"kind": "SCALAR", "name": "Opaque", "fields": null, "enumValues": [], "interfaces": [], "description": "Any type not handled by the type system", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "OpaqueFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Opaque\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Opaque", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "OrderByDirection", "fields": null, "enumValues": [{"name": "AscNullsFirst", "description": "Ascending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "AscNullsLast", "description": "Ascending order, nulls last", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsFirst", "description": "Descending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsLast", "description": "Descending order, nulls last", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "Defines a per-field sorting order", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "PageInfo", "fields": [{"args": [], "name": "endCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasNextPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasPreviousPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "startCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "Query", "fields": [{"args": [{"name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "The record's `ID`", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "node", "type": {"kind": "INTERFACE", "name": "Node", "ofType": null}, "description": "Retrieve a record by its `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The root type for querying data", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "String", "fields": null, "enumValues": [], "interfaces": [], "description": "A string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"String\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ilike", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "iregex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "like", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "regex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "startsWith", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"StringList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Time", "fields": null, "enumValues": [], "interfaces": [], "description": "A time without date information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Time\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"TimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "UUID", "fields": null, "enumValues": [], "interfaces": [], "description": "A universally unique identifier", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UUIDFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"UUID\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "UUID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "UUID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UUIDListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"UUIDList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "OBJECT", "name": "__Directive", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isRepeatable", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "locations", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__DirectiveLocation", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\\n\\nIn some cases, you need to provide options to alter GraphQL execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__DirectiveLocation", "fields": null, "enumValues": [{"name": "QUERY", "description": "Location adjacent to a query operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "MUTATION", "description": "Location adjacent to a mutation operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "SUBSCRIPTION", "description": "Location adjacent to a subscription operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD", "description": "Location adjacent to a field.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_DEFINITION", "description": "Location adjacent to a fragment definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_SPREAD", "description": "Location adjacent to a fragment spread.", "isDeprecated": false, "deprecationReason": null}, {"name": "INLINE_FRAGMENT", "description": "Location adjacent to an inline fragment.", "isDeprecated": false, "deprecationReason": null}, {"name": "VARIABLE_DEFINITION", "description": "Location adjacent to a variable definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCHEMA", "description": "Location adjacent to a schema definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCALAR", "description": "Location adjacent to a scalar definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": "Location adjacent to an object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD_DEFINITION", "description": "Location adjacent to a field definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ARGUMENT_DEFINITION", "description": "Location adjacent to an argument definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": "Location adjacent to an interface definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": "Location adjacent to a union definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": "Location adjacent to an enum definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM_VALUE", "description": "Location adjacent to an enum value definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": "Location adjacent to an input object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_FIELD_DEFINITION", "description": "Location adjacent to an input object field definition.", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__EnumValue", "fields": [{"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Field", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__InputValue", "fields": [{"args": [], "name": "defaultValue", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": "A GraphQL-formatted string representing the default value for this input value.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Schema", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "directives", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Directive", "ofType": null}}}}, "description": "A list of all directives supported by this server.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "mutationType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server supports mutation, the type that mutation operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "queryType", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": "The type that query operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "subscriptionType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server support subscription, the type that subscription operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "types", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}}, "description": "A list of all types supported by this server.", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Type", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "enumValues", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__EnumValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "fields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Field", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "inputFields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "interfaces", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "kind", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__TypeKind", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "ofType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "possibleTypes", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "specifiedByURL", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\\n\\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name, description and optional `specifiedByURL`, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types ", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__TypeKind", "fields": null, "enumValues": [{"name": "SCALAR", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "LIST", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NON_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "An enum describing what kind of type a given `__Type` is.", "inputFields": null, "possibleTypes": null}], "queryType": {"name": "Query"}, "directives": [{"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Included when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "include", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be included only when the `if` argument is true."}, {"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Skipped when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "skip", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be skipped when the `if` argument is true."}], "description": "Represents the GraphQL schema of the database", "mutationType": null, "subscriptionType": null}}} + {"data": {"__schema": {"types": [{"kind": "SCALAR", "name": "BigFloat", "fields": null, "enumValues": [], "interfaces": [], "description": "A high precision floating point value represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloat\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "BigInt", "fields": null, "enumValues": [], "interfaces": [], "description": "An arbitrary size integer represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigInt\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigIntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Boolean", "fields": null, "enumValues": [], "interfaces": [], "description": "A value that is true or false", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Boolean\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BooleanList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Cursor", "fields": null, "enumValues": [], "interfaces": [], "description": "An opaque string using for tracking a position in results during pagination", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Date", "fields": null, "enumValues": [], "interfaces": [], "description": "A date without time information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Date\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DateList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Datetime", "fields": null, "enumValues": [], "interfaces": [], "description": "A date and time", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Datetime\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DatetimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "FilterIs", "fields": null, "enumValues": [{"name": "NULL", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NOT_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Float", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar floating point value up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Float\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"FloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "ID", "fields": null, "enumValues": [], "interfaces": [], "description": "A globally unique identifier for a given record", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IDFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"ID\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "ID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Int", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar integer up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Int\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"IntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "JSON", "fields": null, "enumValues": [], "interfaces": [], "description": "A Javascript Object Notation value serialized as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INTERFACE", "name": "Node", "fields": [{"args": [], "name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "Retrieves a record by `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": []}, {"kind": "SCALAR", "name": "Opaque", "fields": null, "enumValues": [], "interfaces": [], "description": "Any type not handled by the type system", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "OpaqueFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Opaque\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Opaque", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "OrderByDirection", "fields": null, "enumValues": [{"name": "AscNullsFirst", "description": "Ascending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "AscNullsLast", "description": "Ascending order, nulls last", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsFirst", "description": "Descending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsLast", "description": "Descending order, nulls last", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "Defines a per-field sorting order", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "PageInfo", "fields": [{"args": [], "name": "endCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasNextPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasPreviousPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "startCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "Query", "fields": [{"args": [{"name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "The record's `ID`", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "node", "type": {"kind": "INTERFACE", "name": "Node", "ofType": null}, "description": "Retrieve a record by its `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The root type for querying data", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "String", "fields": null, "enumValues": [], "interfaces": [], "description": "A string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"String\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ilike", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "iregex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "like", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "regex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "startsWith", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"StringList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Time", "fields": null, "enumValues": [], "interfaces": [], "description": "A time without date information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Time\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"TimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Uuid", "fields": null, "enumValues": [], "interfaces": [], "description": "A universally unique identifier", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UuidFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Uuid\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Uuid", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Uuid", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UuidListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"UuidList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "OBJECT", "name": "__Directive", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isRepeatable", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "locations", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__DirectiveLocation", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\\n\\nIn some cases, you need to provide options to alter GraphQL execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__DirectiveLocation", "fields": null, "enumValues": [{"name": "QUERY", "description": "Location adjacent to a query operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "MUTATION", "description": "Location adjacent to a mutation operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "SUBSCRIPTION", "description": "Location adjacent to a subscription operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD", "description": "Location adjacent to a field.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_DEFINITION", "description": "Location adjacent to a fragment definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_SPREAD", "description": "Location adjacent to a fragment spread.", "isDeprecated": false, "deprecationReason": null}, {"name": "INLINE_FRAGMENT", "description": "Location adjacent to an inline fragment.", "isDeprecated": false, "deprecationReason": null}, {"name": "VARIABLE_DEFINITION", "description": "Location adjacent to a variable definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCHEMA", "description": "Location adjacent to a schema definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCALAR", "description": "Location adjacent to a scalar definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": "Location adjacent to an object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD_DEFINITION", "description": "Location adjacent to a field definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ARGUMENT_DEFINITION", "description": "Location adjacent to an argument definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": "Location adjacent to an interface definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": "Location adjacent to a union definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": "Location adjacent to an enum definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM_VALUE", "description": "Location adjacent to an enum value definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": "Location adjacent to an input object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_FIELD_DEFINITION", "description": "Location adjacent to an input object field definition.", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__EnumValue", "fields": [{"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Field", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__InputValue", "fields": [{"args": [], "name": "defaultValue", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": "A GraphQL-formatted string representing the default value for this input value.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Schema", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "directives", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Directive", "ofType": null}}}}, "description": "A list of all directives supported by this server.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "mutationType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server supports mutation, the type that mutation operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "queryType", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": "The type that query operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "subscriptionType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server support subscription, the type that subscription operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "types", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}}, "description": "A list of all types supported by this server.", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Type", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "enumValues", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__EnumValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "fields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Field", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "inputFields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "interfaces", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "kind", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__TypeKind", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "ofType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "possibleTypes", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "specifiedByURL", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\\n\\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name, description and optional `specifiedByURL`, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types ", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__TypeKind", "fields": null, "enumValues": [{"name": "SCALAR", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "LIST", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NON_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "An enum describing what kind of type a given `__Type` is.", "inputFields": null, "possibleTypes": null}], "queryType": {"name": "Query"}, "directives": [{"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Included when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "include", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be included only when the `if` argument is true."}, {"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Skipped when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "skip", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be skipped when the `if` argument is true."}], "description": "Represents the GraphQL schema of the database", "mutationType": null, "subscriptionType": null}}} (1 row) rollback; diff --git a/test/expected/omit_weird_names.out b/test/expected/omit_weird_names.out index 61ef8fff..66e0034b 100644 --- a/test/expected/omit_weird_names.out +++ b/test/expected/omit_weird_names.out @@ -133,13 +133,13 @@ begin; "name": "TimeListFilter" + }, + { + - "name": "UUID" + + "name": "Uuid" + }, + { + - "name": "UUIDFilter" + + "name": "UuidFilter" + }, + { + - "name": "UUIDListFilter" + + "name": "UuidListFilter" + }, + { + "name": "__Directive" + diff --git a/test/expected/primary_key_queries.out b/test/expected/primary_key_queries.out index ce66a614..a1553a2b 100644 --- a/test/expected/primary_key_queries.out +++ b/test/expected/primary_key_queries.out @@ -1,4 +1,5 @@ begin; + savepoint a; -- Set up test tables with different primary key configurations -- Table with single column integer primary key create table person( @@ -35,7 +36,7 @@ begin; values ('doc-1', 'Document 1', 'Content 1'), ('doc-2', 'Document 2', 'Content 2'); - savepoint a; + savepoint b; -- Test 1: Query a person by primary key (single integer column) select jsonb_pretty( graphql.resolve($$ @@ -245,15 +246,15 @@ begin; } $$) ); - jsonb_pretty -------------------------------------------------------------------- - { + - "data": null, + - "errors": [ + - { + - "message": "All primary key columns must be provided"+ - } + - ] + + jsonb_pretty +-------------------------------------------------------------------- + { + + "data": null, + + "errors": [ + + { + + "message": "Missing primary key column(s): product_id"+ + } + + ] + } (1 row) @@ -311,7 +312,7 @@ begin; } (1 row) - rollback to savepoint a; + rollback to savepoint b; -- Set up tables with relationships for connection and function tests create table author( id int primary key, @@ -335,7 +336,7 @@ begin; (4, 'Oliver Twist', 2), (5, 'Great Expectations', 2), (6, 'Adventures of Tom Sawyer', 3); - -- Create a function that extends the author type + -- Create a function that takes the author type as its first argument create function public._book_count(rec public.author) returns int stable @@ -1042,4 +1043,147 @@ begin; } (1 row) + -- Test 28: Aliases work correctly with ByPk fields + select jsonb_pretty( + graphql.resolve($$ + { + firstAuthor: authorByPk(id: 1) { + id + name + } + secondAuthor: authorByPk(id: 2) { + id + name + } + } + $$) + ); + jsonb_pretty +--------------------------------------- + { + + "data": { + + "firstAuthor": { + + "id": 1, + + "name": "Jane Austen" + + }, + + "secondAuthor": { + + "id": 2, + + "name": "Charles Dickens"+ + } + + } + + } +(1 row) + + -- Test 29: Nested aliases within ByPk queries + select jsonb_pretty( + graphql.resolve($$ + { + myAuthor: authorByPk(id: 1) { + authorId: id + authorName: name + books: bookCollection { + edges { + node { + bookId: id + bookTitle: title + } + } + } + } + } + $$) + ); + jsonb_pretty +------------------------------------------------------------------ + { + + "data": { + + "myAuthor": { + + "books": { + + "edges": [ + + { + + "node": { + + "bookId": 1, + + "bookTitle": "Pride and Prejudice" + + } + + }, + + { + + "node": { + + "bookId": 2, + + "bookTitle": "Sense and Sensibility"+ + } + + }, + + { + + "node": { + + "bookId": 3, + + "bookTitle": "Emma" + + } + + } + + ] + + }, + + "authorId": 1, + + "authorName": "Jane Austen" + + } + + } + + } +(1 row) + + -- Test 30: ByPk fields are only exposed for tables with supported primary key types + rollback to savepoint a; + -- Create tables with various primary key configurations + create table no_pk_table(value int); -- No primary key + create table float_pk_table(id float primary key); -- Unsupported: float + create table bool_pk_table(id boolean primary key); -- Unsupported: boolean + create table bytea_pk_table(id bytea primary key); -- Unsupported: bytea + create table smallint_pk_table(id smallint primary key); -- Supported: smallint + create table bigint_pk_table(id bigint primary key); -- Supported: bigint + -- Query the schema to verify which tables have ByPk fields + -- Expected ByPk fields: smallintPkTableByPk, bigintPkTableByPk + -- Should NOT have: noPkTableByPk, floatPkTableByPk, boolPkTableByPk, byteaPkTableByPk + select jsonb_pretty( + graphql.resolve($$ + { + __type(name: "Query") { + fields { + name + } + } + } + $$) + ); + jsonb_pretty +--------------------------------------------------------- + { + + "data": { + + "__type": { + + "fields": [ + + { + + "name": "bigintPkTableByPk" + + }, + + { + + "name": "bigintPkTableCollection" + + }, + + { + + "name": "boolPkTableCollection" + + }, + + { + + "name": "byteaPkTableCollection" + + }, + + { + + "name": "floatPkTableCollection" + + }, + + { + + "name": "node" + + }, + + { + + "name": "smallintPkTableByPk" + + }, + + { + + "name": "smallintPkTableCollection"+ + } + + ] + + } + + } + + } +(1 row) + rollback; diff --git a/test/expected/resolve___schema.out b/test/expected/resolve___schema.out index 5a8e4a19..9f32ab96 100644 --- a/test/expected/resolve___schema.out +++ b/test/expected/resolve___schema.out @@ -339,15 +339,15 @@ begin; }, + { + "kind": "SCALAR", + - "name": "UUID" + + "name": "Uuid" + }, + { + "kind": "INPUT_OBJECT", + - "name": "UUIDFilter" + + "name": "UuidFilter" + }, + { + "kind": "INPUT_OBJECT", + - "name": "UUIDListFilter" + + "name": "UuidListFilter" + }, + { + "kind": "OBJECT", + diff --git a/test/expected/resolve_graphiql_schema.out b/test/expected/resolve_graphiql_schema.out index ccd5fcaa..da9a2a32 100644 --- a/test/expected/resolve_graphiql_schema.out +++ b/test/expected/resolve_graphiql_schema.out @@ -2169,7 +2169,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + }, + @@ -2477,7 +2477,7 @@ begin; "name": "id", + "type": { + "kind": "INPUT_OBJECT", + - "name": "UUIDFilter", + + "name": "UuidFilter", + "ofType": null + }, + "description": null, + @@ -2616,7 +2616,7 @@ begin; "name": "id", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "description": null, + @@ -2922,7 +2922,7 @@ begin; "name": "id", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "description": null, + @@ -6009,7 +6009,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + } + @@ -6749,7 +6749,7 @@ begin; }, + { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "fields": null, + "enumValues": [ + ], + @@ -6761,19 +6761,19 @@ begin; }, + { + "kind": "INPUT_OBJECT", + - "name": "UUIDFilter", + + "name": "UuidFilter", + "fields": null, + "enumValues": [ + ], + "interfaces": [ + ], + - "description": "Boolean expression comparing fields on type \"UUID\"", + + "description": "Boolean expression comparing fields on type \"Uuid\"", + "inputFields": [ + { + "name": "eq", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "description": null, + @@ -6789,7 +6789,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + } + @@ -6811,7 +6811,7 @@ begin; "name": "neq", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + }, + "description": null, + @@ -6822,13 +6822,13 @@ begin; }, + { + "kind": "INPUT_OBJECT", + - "name": "UUIDListFilter", + + "name": "UuidListFilter", + "fields": null, + "enumValues": [ + ], + "interfaces": [ + ], + - "description": "Boolean expression comparing fields on type \"UUIDList\"", + + "description": "Boolean expression comparing fields on type \"UuidList\"", + "inputFields": [ + { + "name": "containedBy", + @@ -6840,7 +6840,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + } + @@ -6858,7 +6858,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + } + @@ -6876,7 +6876,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + } + @@ -6904,7 +6904,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + } + diff --git a/test/expected/roundtrip_types.out b/test/expected/roundtrip_types.out index be5194dd..835c8c6f 100644 --- a/test/expected/roundtrip_types.out +++ b/test/expected/roundtrip_types.out @@ -435,7 +435,7 @@ begin; "name": "typeUuid", + "type": { + "kind": "SCALAR", + - "name": "UUID", + + "name": "Uuid", + "ofType": null + } + }, + @@ -625,7 +625,7 @@ begin; "name": "typeUuid", + "type": { + "kind": "INPUT_OBJECT", + - "name": "UUIDFilter", + + "name": "UuidFilter", + "ofType": null + } + }, + diff --git a/test/sql/primary_key_queries.sql b/test/sql/primary_key_queries.sql index 64991423..2e1fccca 100644 --- a/test/sql/primary_key_queries.sql +++ b/test/sql/primary_key_queries.sql @@ -1,4 +1,6 @@ begin; + savepoint a; + -- Set up test tables with different primary key configurations -- Table with single column integer primary key @@ -42,7 +44,7 @@ begin; ('doc-1', 'Document 1', 'Content 1'), ('doc-2', 'Document 2', 'Content 2'); - savepoint a; + savepoint b; -- Test 1: Query a person by primary key (single integer column) select jsonb_pretty( @@ -193,7 +195,7 @@ begin; $$) ); - rollback to savepoint a; + rollback to savepoint b; -- Set up tables with relationships for connection and function tests create table author( @@ -222,7 +224,7 @@ begin; (5, 'Great Expectations', 2), (6, 'Adventures of Tom Sawyer', 3); - -- Create a function that extends the author type + -- Create a function that takes the author type as its first argument create function public._book_count(rec public.author) returns int stable @@ -581,4 +583,66 @@ begin; $$) ); + -- Test 28: Aliases work correctly with ByPk fields + select jsonb_pretty( + graphql.resolve($$ + { + firstAuthor: authorByPk(id: 1) { + id + name + } + secondAuthor: authorByPk(id: 2) { + id + name + } + } + $$) + ); + + -- Test 29: Nested aliases within ByPk queries + select jsonb_pretty( + graphql.resolve($$ + { + myAuthor: authorByPk(id: 1) { + authorId: id + authorName: name + books: bookCollection { + edges { + node { + bookId: id + bookTitle: title + } + } + } + } + } + $$) + ); + + -- Test 30: ByPk fields are only exposed for tables with supported primary key types + rollback to savepoint a; + + -- Create tables with various primary key configurations + create table no_pk_table(value int); -- No primary key + create table float_pk_table(id float primary key); -- Unsupported: float + create table bool_pk_table(id boolean primary key); -- Unsupported: boolean + create table bytea_pk_table(id bytea primary key); -- Unsupported: bytea + create table smallint_pk_table(id smallint primary key); -- Supported: smallint + create table bigint_pk_table(id bigint primary key); -- Supported: bigint + + -- Query the schema to verify which tables have ByPk fields + -- Expected ByPk fields: smallintPkTableByPk, bigintPkTableByPk + -- Should NOT have: noPkTableByPk, floatPkTableByPk, boolPkTableByPk, byteaPkTableByPk + select jsonb_pretty( + graphql.resolve($$ + { + __type(name: "Query") { + fields { + name + } + } + } + $$) + ); + rollback; From 522c0e585d7307c22145a2b2ab154f3e3516ca6b Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 3 Feb 2026 16:14:34 +0530 Subject: [PATCH 11/15] revert UUID rename --- docs/usage_with_apollo.md | 2 +- docs/usage_with_relay.md | 2 +- src/graphql.rs | 20 +++++------ src/parser_util.rs | 2 +- src/sql_types.rs | 22 ++++++------ test/expected/array_args_and_return_types.out | 12 +++---- test/expected/function_calls.out | 4 +-- test/expected/function_calls_default_args.out | 2 +- test/expected/issue_444.out | 2 +- test/expected/issue_533.out | 2 +- .../expected/issue_557_1_to_1_nullability.out | 6 ++-- .../issue_581_missing_desc_on_schema.out | 2 +- test/expected/omit_weird_names.out | 6 ++-- test/expected/resolve___schema.out | 6 ++-- test/expected/resolve_graphiql_schema.out | 34 +++++++++---------- test/expected/roundtrip_types.out | 4 +-- 16 files changed, 64 insertions(+), 64 deletions(-) diff --git a/docs/usage_with_apollo.md b/docs/usage_with_apollo.md index 4d0529de..35da0164 100644 --- a/docs/usage_with_apollo.md +++ b/docs/usage_with_apollo.md @@ -27,7 +27,7 @@ const config: CodegenConfig = { plugins: [], config: { scalars: { - Uuid: 'string', + UUID: 'string', Date: 'string', Time: 'string', Datetime: 'string', diff --git a/docs/usage_with_relay.md b/docs/usage_with_relay.md index 4903e4bb..94a5e0f3 100644 --- a/docs/usage_with_relay.md +++ b/docs/usage_with_relay.md @@ -21,7 +21,7 @@ Modify your `relay.config.js` file to reflect the following: nodeInterfaceIdVariableName: 'nodeId', }, customScalarTypes: { - Uuid: 'string', + UUID: 'string', Datetime: 'string', JSON: 'string', BigInt: 'string', diff --git a/src/graphql.rs b/src/graphql.rs index d349dfad..9363cdd1 100644 --- a/src/graphql.rs +++ b/src/graphql.rs @@ -903,7 +903,7 @@ pub enum Scalar { Time, Datetime, BigInt, - Uuid, + UUID, JSON, Cursor, BigFloat, @@ -1638,7 +1638,7 @@ impl ___Type for Scalar { Self::Date => "Date", Self::Time => "Time", Self::BigInt => "BigInt", - Self::Uuid => "Uuid", + Self::UUID => "UUID", Self::JSON => "JSON", Self::Cursor => "Cursor", Self::BigFloat => "BigFloat", @@ -1660,7 +1660,7 @@ impl ___Type for Scalar { Self::Date => "A date without time information", Self::Time => "A time without date information", Self::Datetime => "A date and time", - Self::Uuid => "A universally unique identifier", + Self::UUID => "A universally unique identifier", Self::JSON => "A Javascript Object Notation value serialized as a string", Self::Cursor => { "An opaque string using for tracking a position in results during pagination" @@ -1944,7 +1944,7 @@ impl Type { 3802 => __Type::Scalar(Scalar::JSON), // jsonb 114 => __Type::Scalar(Scalar::JSON), // json 1083 => __Type::Scalar(Scalar::Time), // time without time zone - 2950 => __Type::Scalar(Scalar::Uuid), // uuid + 2950 => __Type::Scalar(Scalar::UUID), // uuid 1700 => __Type::Scalar(Scalar::BigFloat), // numeric 25 => __Type::Scalar(Scalar::String(None)), // text // char, bpchar, varchar @@ -3520,7 +3520,7 @@ impl ___Type for FilterTypeType { // IDFilter only supports equality Scalar::ID => vec![FilterOp::Equal], // UUIDs are not ordered - Scalar::Uuid => { + Scalar::UUID => { vec![ FilterOp::Equal, FilterOp::NotEqual, @@ -3823,7 +3823,7 @@ impl ___Type for FilterEntityType { | Scalar::Float | Scalar::String(_) | Scalar::Boolean - | Scalar::Uuid + | Scalar::UUID | Scalar::BigInt | Scalar::BigFloat | Scalar::Time @@ -4087,7 +4087,7 @@ impl __Schema { __Type::Scalar(Scalar::Time), __Type::Scalar(Scalar::Datetime), __Type::Scalar(Scalar::BigInt), - __Type::Scalar(Scalar::Uuid), + __Type::Scalar(Scalar::UUID), __Type::Scalar(Scalar::JSON), __Type::Scalar(Scalar::Cursor), __Type::Scalar(Scalar::BigFloat), @@ -4134,7 +4134,7 @@ impl __Schema { schema: Arc::clone(&schema_rc), }), __Type::FilterType(FilterTypeType { - entity: FilterableType::Scalar(Scalar::Uuid), + entity: FilterableType::Scalar(Scalar::UUID), schema: Arc::clone(&schema_rc), }), __Type::FilterType(FilterTypeType { @@ -4195,7 +4195,7 @@ impl __Schema { }), __Type::FilterType(FilterTypeType { entity: FilterableType::List(ListType { - type_: Box::new(__Type::Scalar(Scalar::Uuid)), + type_: Box::new(__Type::Scalar(Scalar::UUID)), }), schema: Arc::clone(&schema_rc), }), @@ -4736,7 +4736,7 @@ fn sql_type_to_scalar(sql_type_name: &str, typmod: Option) -> Option Some(Scalar::Date), "time" | "timetz" => Some(Scalar::Time), "timestamp" | "timestamptz" => Some(Scalar::Datetime), - "uuid" => Some(Scalar::Uuid), + "uuid" => Some(Scalar::UUID), "json" | "jsonb" => Some(Scalar::JSON), _ => Some(Scalar::Opaque), // Fallback for unknown types } diff --git a/src/parser_util.rs b/src/parser_util.rs index 811c01c7..0d763a2c 100644 --- a/src/parser_util.rs +++ b/src/parser_util.rs @@ -409,7 +409,7 @@ pub fn validate_arg_from_type(type_: &__Type, value: &gson::Value) -> GraphQLRes ))) } }, - Scalar::Uuid => { + Scalar::UUID => { match value { // XXX: future - validate uuid here GsonValue::Absent | GsonValue::Null | GsonValue::String(_) => value.clone(), diff --git a/src/sql_types.rs b/src/sql_types.rs index cd11d202..c3206753 100644 --- a/src/sql_types.rs +++ b/src/sql_types.rs @@ -585,9 +585,9 @@ impl Table { } // Check that all primary key columns have supported types - pk_columns.iter().all(|col| { - SupportedPrimaryKeyType::from_type_name(&col.type_name).is_some() - }) + pk_columns + .iter() + .all(|col| SupportedPrimaryKeyType::from_type_name(&col.type_name).is_some()) } pub fn is_any_column_selectable(&self) -> bool { @@ -620,12 +620,12 @@ pub enum SupportedPrimaryKeyType { BigInt, // bigint, int8 SmallInt, // smallint, int2 // String types - Text, // text - VarChar, // varchar - Char, // char, bpchar - CiText, // citext - // Uuid - Uuid, // uuid + Text, // text + VarChar, // varchar + Char, // char, bpchar + CiText, // citext + // UUID + UUID, // uuid } impl SupportedPrimaryKeyType { @@ -640,8 +640,8 @@ impl SupportedPrimaryKeyType { "varchar" => Some(Self::VarChar), "char" | "bpchar" => Some(Self::Char), "citext" => Some(Self::CiText), - // Uuid - "uuid" => Some(Self::Uuid), + // UUID + "uuid" => Some(Self::UUID), // Any other type is not supported _ => None, } diff --git a/test/expected/array_args_and_return_types.out b/test/expected/array_args_and_return_types.out index f3cecb0e..656dcc17 100644 --- a/test/expected/array_args_and_return_types.out +++ b/test/expected/array_args_and_return_types.out @@ -1081,7 +1081,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid" + + "name": "UUID" + } + } + } + @@ -1102,7 +1102,7 @@ begin; "name": "getUuidArrayItem", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "description": null + @@ -1334,7 +1334,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + }, + @@ -2462,7 +2462,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid" + + "name": "UUID" + } + } + } + @@ -2483,7 +2483,7 @@ begin; "name": "getUuidArrayItem", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "description": null + @@ -2692,7 +2692,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + }, + diff --git a/test/expected/function_calls.out b/test/expected/function_calls.out index a16f4aa0..3d6a3ea3 100644 --- a/test/expected/function_calls.out +++ b/test/expected/function_calls.out @@ -825,7 +825,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid" + + "name": "UUID" + } + } + } + @@ -1687,7 +1687,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid" + + "name": "UUID" + } + } + } + diff --git a/test/expected/function_calls_default_args.out b/test/expected/function_calls_default_args.out index 4e651c7b..a31e03ae 100644 --- a/test/expected/function_calls_default_args.out +++ b/test/expected/function_calls_default_args.out @@ -362,7 +362,7 @@ begin; "name": "h", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "defaultValue": null + diff --git a/test/expected/issue_444.out b/test/expected/issue_444.out index b617851e..20e81847 100644 --- a/test/expected/issue_444.out +++ b/test/expected/issue_444.out @@ -58,7 +58,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR",+ - "name": "Uuid" + + "name": "UUID" + } + } + } + diff --git a/test/expected/issue_533.out b/test/expected/issue_533.out index db4b97b1..aa9ee2d3 100644 --- a/test/expected/issue_533.out +++ b/test/expected/issue_533.out @@ -49,7 +49,7 @@ begin; "name": "pUserId", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "defaultValue": null + diff --git a/test/expected/issue_557_1_to_1_nullability.out b/test/expected/issue_557_1_to_1_nullability.out index 1329503e..1667aeb3 100644 --- a/test/expected/issue_557_1_to_1_nullability.out +++ b/test/expected/issue_557_1_to_1_nullability.out @@ -68,7 +68,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "description": "A universally unique identifier" + }, + "description": null + @@ -163,7 +163,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "description": "A universally unique identifier" + }, + "description": null + @@ -255,7 +255,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "description": "A universally unique identifier" + }, + "description": null + diff --git a/test/expected/issue_581_missing_desc_on_schema.out b/test/expected/issue_581_missing_desc_on_schema.out index 0412cd5a..a7ce6cdc 100644 --- a/test/expected/issue_581_missing_desc_on_schema.out +++ b/test/expected/issue_581_missing_desc_on_schema.out @@ -99,7 +99,7 @@ fragment TypeRef on __Type { $$, NULL, 'IntrospectionQuery'); resolve ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"data": {"__schema": {"types": [{"kind": "SCALAR", "name": "BigFloat", "fields": null, "enumValues": [], "interfaces": [], "description": "A high precision floating point value represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloat\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "BigInt", "fields": null, "enumValues": [], "interfaces": [], "description": "An arbitrary size integer represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigInt\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigIntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Boolean", "fields": null, "enumValues": [], "interfaces": [], "description": "A value that is true or false", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Boolean\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BooleanList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Cursor", "fields": null, "enumValues": [], "interfaces": [], "description": "An opaque string using for tracking a position in results during pagination", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Date", "fields": null, "enumValues": [], "interfaces": [], "description": "A date without time information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Date\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DateList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Datetime", "fields": null, "enumValues": [], "interfaces": [], "description": "A date and time", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Datetime\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DatetimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "FilterIs", "fields": null, "enumValues": [{"name": "NULL", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NOT_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Float", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar floating point value up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Float\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"FloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "ID", "fields": null, "enumValues": [], "interfaces": [], "description": "A globally unique identifier for a given record", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IDFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"ID\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "ID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Int", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar integer up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Int\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"IntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "JSON", "fields": null, "enumValues": [], "interfaces": [], "description": "A Javascript Object Notation value serialized as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INTERFACE", "name": "Node", "fields": [{"args": [], "name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "Retrieves a record by `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": []}, {"kind": "SCALAR", "name": "Opaque", "fields": null, "enumValues": [], "interfaces": [], "description": "Any type not handled by the type system", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "OpaqueFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Opaque\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Opaque", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "OrderByDirection", "fields": null, "enumValues": [{"name": "AscNullsFirst", "description": "Ascending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "AscNullsLast", "description": "Ascending order, nulls last", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsFirst", "description": "Descending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsLast", "description": "Descending order, nulls last", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "Defines a per-field sorting order", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "PageInfo", "fields": [{"args": [], "name": "endCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasNextPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasPreviousPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "startCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "Query", "fields": [{"args": [{"name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "The record's `ID`", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "node", "type": {"kind": "INTERFACE", "name": "Node", "ofType": null}, "description": "Retrieve a record by its `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The root type for querying data", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "String", "fields": null, "enumValues": [], "interfaces": [], "description": "A string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"String\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ilike", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "iregex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "like", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "regex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "startsWith", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"StringList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Time", "fields": null, "enumValues": [], "interfaces": [], "description": "A time without date information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Time\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"TimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Uuid", "fields": null, "enumValues": [], "interfaces": [], "description": "A universally unique identifier", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UuidFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Uuid\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Uuid", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Uuid", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UuidListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"UuidList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Uuid", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "OBJECT", "name": "__Directive", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isRepeatable", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "locations", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__DirectiveLocation", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\\n\\nIn some cases, you need to provide options to alter GraphQL execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__DirectiveLocation", "fields": null, "enumValues": [{"name": "QUERY", "description": "Location adjacent to a query operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "MUTATION", "description": "Location adjacent to a mutation operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "SUBSCRIPTION", "description": "Location adjacent to a subscription operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD", "description": "Location adjacent to a field.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_DEFINITION", "description": "Location adjacent to a fragment definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_SPREAD", "description": "Location adjacent to a fragment spread.", "isDeprecated": false, "deprecationReason": null}, {"name": "INLINE_FRAGMENT", "description": "Location adjacent to an inline fragment.", "isDeprecated": false, "deprecationReason": null}, {"name": "VARIABLE_DEFINITION", "description": "Location adjacent to a variable definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCHEMA", "description": "Location adjacent to a schema definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCALAR", "description": "Location adjacent to a scalar definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": "Location adjacent to an object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD_DEFINITION", "description": "Location adjacent to a field definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ARGUMENT_DEFINITION", "description": "Location adjacent to an argument definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": "Location adjacent to an interface definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": "Location adjacent to a union definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": "Location adjacent to an enum definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM_VALUE", "description": "Location adjacent to an enum value definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": "Location adjacent to an input object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_FIELD_DEFINITION", "description": "Location adjacent to an input object field definition.", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__EnumValue", "fields": [{"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Field", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__InputValue", "fields": [{"args": [], "name": "defaultValue", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": "A GraphQL-formatted string representing the default value for this input value.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Schema", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "directives", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Directive", "ofType": null}}}}, "description": "A list of all directives supported by this server.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "mutationType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server supports mutation, the type that mutation operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "queryType", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": "The type that query operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "subscriptionType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server support subscription, the type that subscription operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "types", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}}, "description": "A list of all types supported by this server.", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Type", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "enumValues", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__EnumValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "fields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Field", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "inputFields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "interfaces", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "kind", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__TypeKind", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "ofType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "possibleTypes", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "specifiedByURL", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\\n\\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name, description and optional `specifiedByURL`, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types ", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__TypeKind", "fields": null, "enumValues": [{"name": "SCALAR", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "LIST", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NON_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "An enum describing what kind of type a given `__Type` is.", "inputFields": null, "possibleTypes": null}], "queryType": {"name": "Query"}, "directives": [{"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Included when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "include", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be included only when the `if` argument is true."}, {"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Skipped when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "skip", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be skipped when the `if` argument is true."}], "description": "Represents the GraphQL schema of the database", "mutationType": null, "subscriptionType": null}}} + {"data": {"__schema": {"types": [{"kind": "SCALAR", "name": "BigFloat", "fields": null, "enumValues": [], "interfaces": [], "description": "A high precision floating point value represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloat\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigFloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigFloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigFloat", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "BigInt", "fields": null, "enumValues": [], "interfaces": [], "description": "An arbitrary size integer represented as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigInt\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "BigInt", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BigIntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BigIntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "BigInt", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Boolean", "fields": null, "enumValues": [], "interfaces": [], "description": "A value that is true or false", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Boolean\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "BooleanListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"BooleanList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Cursor", "fields": null, "enumValues": [], "interfaces": [], "description": "An opaque string using for tracking a position in results during pagination", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Date", "fields": null, "enumValues": [], "interfaces": [], "description": "A date without time information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Date\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Date", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DateListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DateList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Date", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Datetime", "fields": null, "enumValues": [], "interfaces": [], "description": "A date and time", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Datetime\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Datetime", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "DatetimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"DatetimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Datetime", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "FilterIs", "fields": null, "enumValues": [{"name": "NULL", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NOT_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "Float", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar floating point value up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Float\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Float", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "FloatListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"FloatList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Float", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "ID", "fields": null, "enumValues": [], "interfaces": [], "description": "A globally unique identifier for a given record", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IDFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"ID\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "ID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Int", "fields": null, "enumValues": [], "interfaces": [], "description": "A scalar integer up to 32 bits", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Int\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Int", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "IntListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"IntList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Int", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "JSON", "fields": null, "enumValues": [], "interfaces": [], "description": "A Javascript Object Notation value serialized as a string", "inputFields": null, "possibleTypes": null}, {"kind": "INTERFACE", "name": "Node", "fields": [{"args": [], "name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "Retrieves a record by `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": []}, {"kind": "SCALAR", "name": "Opaque", "fields": null, "enumValues": [], "interfaces": [], "description": "Any type not handled by the type system", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "OpaqueFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Opaque\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Opaque", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "ENUM", "name": "OrderByDirection", "fields": null, "enumValues": [{"name": "AscNullsFirst", "description": "Ascending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "AscNullsLast", "description": "Ascending order, nulls last", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsFirst", "description": "Descending order, nulls first", "isDeprecated": false, "deprecationReason": null}, {"name": "DescNullsLast", "description": "Descending order, nulls last", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "Defines a per-field sorting order", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "PageInfo", "fields": [{"args": [], "name": "endCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasNextPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "hasPreviousPage", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "startCursor", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": null, "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "Query", "fields": [{"args": [{"name": "nodeId", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "ID", "ofType": null}}, "description": "The record's `ID`", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "node", "type": {"kind": "INTERFACE", "name": "Node", "ofType": null}, "description": "Retrieve a record by its `ID`", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The root type for querying data", "inputFields": null, "possibleTypes": null}, {"kind": "SCALAR", "name": "String", "fields": null, "enumValues": [], "interfaces": [], "description": "A string", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"String\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ilike", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "iregex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "like", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "regex", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "startsWith", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "StringListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"StringList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "Time", "fields": null, "enumValues": [], "interfaces": [], "description": "A time without date information", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"Time\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "gte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lt", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "lte", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "Time", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "TimeListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"TimeList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Time", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "SCALAR", "name": "UUID", "fields": null, "enumValues": [], "interfaces": [], "description": "A universally unique identifier", "inputFields": null, "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UUIDFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"UUID\"", "inputFields": [{"name": "eq", "type": {"kind": "SCALAR", "name": "UUID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "in", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "neq", "type": {"kind": "SCALAR", "name": "UUID", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "INPUT_OBJECT", "name": "UUIDListFilter", "fields": null, "enumValues": [], "interfaces": [], "description": "Boolean expression comparing fields on type \"UUIDList\"", "inputFields": [{"name": "containedBy", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "contains", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "eq", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "is", "type": {"kind": "ENUM", "name": "FilterIs", "ofType": null}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}, {"name": "overlaps", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "UUID", "ofType": null}}}, "description": null, "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "possibleTypes": null}, {"kind": "OBJECT", "name": "__Directive", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isRepeatable", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "locations", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__DirectiveLocation", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\\n\\nIn some cases, you need to provide options to alter GraphQL execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__DirectiveLocation", "fields": null, "enumValues": [{"name": "QUERY", "description": "Location adjacent to a query operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "MUTATION", "description": "Location adjacent to a mutation operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "SUBSCRIPTION", "description": "Location adjacent to a subscription operation.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD", "description": "Location adjacent to a field.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_DEFINITION", "description": "Location adjacent to a fragment definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FRAGMENT_SPREAD", "description": "Location adjacent to a fragment spread.", "isDeprecated": false, "deprecationReason": null}, {"name": "INLINE_FRAGMENT", "description": "Location adjacent to an inline fragment.", "isDeprecated": false, "deprecationReason": null}, {"name": "VARIABLE_DEFINITION", "description": "Location adjacent to a variable definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCHEMA", "description": "Location adjacent to a schema definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "SCALAR", "description": "Location adjacent to a scalar definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": "Location adjacent to an object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "FIELD_DEFINITION", "description": "Location adjacent to a field definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ARGUMENT_DEFINITION", "description": "Location adjacent to an argument definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": "Location adjacent to an interface definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": "Location adjacent to a union definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": "Location adjacent to an enum definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM_VALUE", "description": "Location adjacent to an enum value definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": "Location adjacent to an input object type definition.", "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_FIELD_DEFINITION", "description": "Location adjacent to an input object field definition.", "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__EnumValue", "fields": [{"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Field", "fields": [{"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "args", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__InputValue", "fields": [{"args": [], "name": "defaultValue", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": "A GraphQL-formatted string representing the default value for this input value.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "deprecationReason", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "isDeprecated", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "String", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "type", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Schema", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "directives", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Directive", "ofType": null}}}}, "description": "A list of all directives supported by this server.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "mutationType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server supports mutation, the type that mutation operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "queryType", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}, "description": "The type that query operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "subscriptionType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": "If this server support subscription, the type that subscription operations will be rooted at.", "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "types", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}}, "description": "A list of all types supported by this server.", "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", "inputFields": null, "possibleTypes": null}, {"kind": "OBJECT", "name": "__Type", "fields": [{"args": [], "name": "description", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "enumValues", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__EnumValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "fields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Field", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [{"name": "includeDeprecated", "type": {"kind": "SCALAR", "name": "Boolean", "ofType": null}, "description": null, "defaultValue": "false", "isDeprecated": false, "deprecationReason": null}], "name": "inputFields", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__InputValue", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "interfaces", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "kind", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "ENUM", "name": "__TypeKind", "ofType": null}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "name", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "ofType", "type": {"kind": "OBJECT", "name": "__Type", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "possibleTypes", "type": {"kind": "LIST", "name": null, "ofType": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "OBJECT", "name": "__Type", "ofType": null}}}, "description": null, "isDeprecated": false, "deprecationReason": null}, {"args": [], "name": "specifiedByURL", "type": {"kind": "SCALAR", "name": "String", "ofType": null}, "description": null, "isDeprecated": false, "deprecationReason": null}], "enumValues": [], "interfaces": [], "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\\n\\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name, description and optional `specifiedByURL`, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types ", "inputFields": null, "possibleTypes": null}, {"kind": "ENUM", "name": "__TypeKind", "fields": null, "enumValues": [{"name": "SCALAR", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INTERFACE", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "UNION", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "ENUM", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "INPUT_OBJECT", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "LIST", "description": null, "isDeprecated": false, "deprecationReason": null}, {"name": "NON_NULL", "description": null, "isDeprecated": false, "deprecationReason": null}], "interfaces": [], "description": "An enum describing what kind of type a given `__Type` is.", "inputFields": null, "possibleTypes": null}], "queryType": {"name": "Query"}, "directives": [{"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Included when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "include", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be included only when the `if` argument is true."}, {"args": [{"name": "if", "type": {"kind": "NON_NULL", "name": null, "ofType": {"kind": "SCALAR", "name": "Boolean", "ofType": null}}, "description": "Skipped when true", "defaultValue": null, "isDeprecated": false, "deprecationReason": null}], "name": "skip", "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], "description": "This field or fragment will be skipped when the `if` argument is true."}], "description": "Represents the GraphQL schema of the database", "mutationType": null, "subscriptionType": null}}} (1 row) rollback; diff --git a/test/expected/omit_weird_names.out b/test/expected/omit_weird_names.out index 66e0034b..61ef8fff 100644 --- a/test/expected/omit_weird_names.out +++ b/test/expected/omit_weird_names.out @@ -133,13 +133,13 @@ begin; "name": "TimeListFilter" + }, + { + - "name": "Uuid" + + "name": "UUID" + }, + { + - "name": "UuidFilter" + + "name": "UUIDFilter" + }, + { + - "name": "UuidListFilter" + + "name": "UUIDListFilter" + }, + { + "name": "__Directive" + diff --git a/test/expected/resolve___schema.out b/test/expected/resolve___schema.out index 9f32ab96..5a8e4a19 100644 --- a/test/expected/resolve___schema.out +++ b/test/expected/resolve___schema.out @@ -339,15 +339,15 @@ begin; }, + { + "kind": "SCALAR", + - "name": "Uuid" + + "name": "UUID" + }, + { + "kind": "INPUT_OBJECT", + - "name": "UuidFilter" + + "name": "UUIDFilter" + }, + { + "kind": "INPUT_OBJECT", + - "name": "UuidListFilter" + + "name": "UUIDListFilter" + }, + { + "kind": "OBJECT", + diff --git a/test/expected/resolve_graphiql_schema.out b/test/expected/resolve_graphiql_schema.out index da9a2a32..ccd5fcaa 100644 --- a/test/expected/resolve_graphiql_schema.out +++ b/test/expected/resolve_graphiql_schema.out @@ -2169,7 +2169,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + }, + @@ -2477,7 +2477,7 @@ begin; "name": "id", + "type": { + "kind": "INPUT_OBJECT", + - "name": "UuidFilter", + + "name": "UUIDFilter", + "ofType": null + }, + "description": null, + @@ -2616,7 +2616,7 @@ begin; "name": "id", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "description": null, + @@ -2922,7 +2922,7 @@ begin; "name": "id", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "description": null, + @@ -6009,7 +6009,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + } + @@ -6749,7 +6749,7 @@ begin; }, + { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "fields": null, + "enumValues": [ + ], + @@ -6761,19 +6761,19 @@ begin; }, + { + "kind": "INPUT_OBJECT", + - "name": "UuidFilter", + + "name": "UUIDFilter", + "fields": null, + "enumValues": [ + ], + "interfaces": [ + ], + - "description": "Boolean expression comparing fields on type \"Uuid\"", + + "description": "Boolean expression comparing fields on type \"UUID\"", + "inputFields": [ + { + "name": "eq", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "description": null, + @@ -6789,7 +6789,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + } + @@ -6811,7 +6811,7 @@ begin; "name": "neq", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + }, + "description": null, + @@ -6822,13 +6822,13 @@ begin; }, + { + "kind": "INPUT_OBJECT", + - "name": "UuidListFilter", + + "name": "UUIDListFilter", + "fields": null, + "enumValues": [ + ], + "interfaces": [ + ], + - "description": "Boolean expression comparing fields on type \"UuidList\"", + + "description": "Boolean expression comparing fields on type \"UUIDList\"", + "inputFields": [ + { + "name": "containedBy", + @@ -6840,7 +6840,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + } + @@ -6858,7 +6858,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + } + @@ -6876,7 +6876,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + } + @@ -6904,7 +6904,7 @@ begin; "name": null, + "ofType": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + } + diff --git a/test/expected/roundtrip_types.out b/test/expected/roundtrip_types.out index 835c8c6f..be5194dd 100644 --- a/test/expected/roundtrip_types.out +++ b/test/expected/roundtrip_types.out @@ -435,7 +435,7 @@ begin; "name": "typeUuid", + "type": { + "kind": "SCALAR", + - "name": "Uuid", + + "name": "UUID", + "ofType": null + } + }, + @@ -625,7 +625,7 @@ begin; "name": "typeUuid", + "type": { + "kind": "INPUT_OBJECT", + - "name": "UuidFilter", + + "name": "UUIDFilter", + "ofType": null + } + }, + From 1a78eea9173030fa72b330b1713b35b19d022f16 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 3 Feb 2026 16:16:19 +0530 Subject: [PATCH 12/15] fix clippy warnings --- src/graphql.rs | 2 +- src/sql_types.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/graphql.rs b/src/graphql.rs index 9363cdd1..0b27a432 100644 --- a/src/graphql.rs +++ b/src/graphql.rs @@ -1270,7 +1270,7 @@ impl ___Type for QueryType { col_name ) }) - .unwrap_or_else(|_| __Type::Scalar(Scalar::String(None))); + .unwrap_or(__Type::Scalar(Scalar::String(None))); // Use graphql_column_field_name to convert snake_case to camelCase if needed let arg_name = self.schema.graphql_column_field_name(col); diff --git a/src/sql_types.rs b/src/sql_types.rs index c3206753..40e636e0 100644 --- a/src/sql_types.rs +++ b/src/sql_types.rs @@ -625,7 +625,7 @@ pub enum SupportedPrimaryKeyType { Char, // char, bpchar CiText, // citext // UUID - UUID, // uuid + Uuid, // uuid } impl SupportedPrimaryKeyType { @@ -641,7 +641,7 @@ impl SupportedPrimaryKeyType { "char" | "bpchar" => Some(Self::Char), "citext" => Some(Self::CiText), // UUID - "uuid" => Some(Self::UUID), + "uuid" => Some(Self::Uuid), // Any other type is not supported _ => None, } From 91963175a147a17925712fd1cce1e00afb14fe39 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 3 Feb 2026 16:24:54 +0530 Subject: [PATCH 13/15] add more tests --- test/expected/resolve___typename.out | 70 ++++++++++++++++++++++++++++ test/sql/resolve___typename.sql | 49 +++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/test/expected/resolve___typename.out b/test/expected/resolve___typename.out index f48f423d..d411602a 100644 --- a/test/expected/resolve___typename.out +++ b/test/expected/resolve___typename.out @@ -190,6 +190,76 @@ begin; } (1 row) + -- Test __typename with multi-column primary key + create table order_item( + order_id int, + item_id int, + quantity int, + primary key (order_id, item_id) + ); + insert into public.order_item(order_id, item_id, quantity) + values + (100, 1, 5), + (100, 2, 3); + select jsonb_pretty( + graphql.resolve($$ + query { + orderItemByPk(orderId: 100, itemId: 1) { + __typename + orderId + itemId + quantity + } + } + $$) + ); + jsonb_pretty +--------------------------------------- + { + + "data": { + + "orderItemByPk": { + + "itemId": 1, + + "orderId": 100, + + "quantity": 5, + + "__typename": "OrderItem"+ + } + + } + + } +(1 row) + + -- Test __typename with non-int primary key + create table product( + sku text primary key, + name text + ); + insert into public.product(sku, name) + values + ('PROD-001', 'Widget'), + ('PROD-002', 'Gadget'); + select jsonb_pretty( + graphql.resolve($$ + query { + productByPk(sku: "PROD-001") { + __typename + sku + name + } + } + $$) + ); + jsonb_pretty +------------------------------------- + { + + "data": { + + "productByPk": { + + "sku": "PROD-001", + + "name": "Widget", + + "__typename": "Product"+ + } + + } + + } +(1 row) + -- Test __typename with byPk query returning null select jsonb_pretty( graphql.resolve($$ diff --git a/test/sql/resolve___typename.sql b/test/sql/resolve___typename.sql index 2a553507..16730544 100644 --- a/test/sql/resolve___typename.sql +++ b/test/sql/resolve___typename.sql @@ -101,6 +101,55 @@ begin; $$) ); + -- Test __typename with multi-column primary key + create table order_item( + order_id int, + item_id int, + quantity int, + primary key (order_id, item_id) + ); + + insert into public.order_item(order_id, item_id, quantity) + values + (100, 1, 5), + (100, 2, 3); + + select jsonb_pretty( + graphql.resolve($$ + query { + orderItemByPk(orderId: 100, itemId: 1) { + __typename + orderId + itemId + quantity + } + } + $$) + ); + + -- Test __typename with non-int primary key + create table product( + sku text primary key, + name text + ); + + insert into public.product(sku, name) + values + ('PROD-001', 'Widget'), + ('PROD-002', 'Gadget'); + + select jsonb_pretty( + graphql.resolve($$ + query { + productByPk(sku: "PROD-001") { + __typename + sku + name + } + } + $$) + ); + -- Test __typename with byPk query returning null select jsonb_pretty( graphql.resolve($$ From 4cc939feb6b6434ddd6f1bc8bb4c87dbce56886c Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 27 Jan 2026 15:45:01 +0530 Subject: [PATCH 14/15] docs: add docs for primary key quries feature --- docs/api.md | 177 ++++++++++++++++++++++++++++++++++++++++++++++ docs/changelog.md | 2 + 2 files changed, 179 insertions(+) diff --git a/docs/api.md b/docs/api.md index 25b89beb..3c5e287f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1742,6 +1742,183 @@ The default order of results is defined by the underlying table's primary key co Note, only one key value pair may be provided to each element of the input array. For example, `[{name: AscNullsLast}, {id: AscNullFirst}]` is valid. Passing multiple key value pairs in a single element of the input array e.g. `[{name: AscNullsLast, id: AscNullFirst}]`, is invalid. +### Primary Key Queries + +Each table has a top level field in the `Query` type for selecting a single record by primary key from that table. The field is named `
ByPk` + +**SQL Setup** +```sql +create table "Blog"( + id serial primary key, + name varchar(255) not null, + description varchar(255), + "createdAt" timestamp not null, + "updatedAt" timestamp not null +); +``` + +**GraphQL Types** +=== "QueryType" + + ```graphql + """The root type for querying data""" + type Query { + + """Retrieve a blog by its id""" + blogByPk(id: Int!): Blog + + } + ``` + +To query the table by primary key, pass the value of the primary key field to the field: + +**Example** +=== "Query" + + ```graphql + { + blogByPk( + id: 1 + ) { + id + name + description + } + } + ``` + +=== "Response" + + ```json + { + "data": { + "blogByPk": { + "id": 1, + "name": "Some Blog", + "description": "Description of Some Blog" + } + } + } + ``` + +If a record with the give id doesn't exist, the field will return null: + +**Example** +=== "Query" + + ```graphql + { + blogByPk( + id: 999 + ) { + id + name + description + } + } + ``` + +=== "Response" + + ```json + { + "data": { + "blogByPk": null + } + } + ``` + +If the key is a composite primary key, all the columns of the primary key should be sent in the query: + + + +**SQL Setup** +```sql +create table item( + item_id int, + product_id int, + quantity int, + price numeric(10,2), + primary key(item_id, product_id) +); +``` + +**GraphQL Types** +=== "QueryType" + + ```graphql + """The root type for querying data""" + type Query { + + """Retrieve an item by its item and product ids""" + itemByPk(itemId: Int!, productId: Int!): Item + + } + ``` +**Example** +=== "Query" + + ```graphql + { + itemByPk( + itemId: 1, productId: 2 + ) { + itemId + productId + quantity + price + } + } + ``` + +=== "Response" + + ```json + { + "data": { + "itemByPk": { + "itemId": 1, + "productId": 2, + "quantity": 1, + "price": 24.99 + } + } + } + ``` + +Otherwise an error will be returned: + +**Example** +=== "Query" + + ```graphql + { + itemByPk( + itemId: 1 + ) { + itemId + productId + quantity + price + } + } + ``` + +=== "Response" + + ```json + { + "data": null, + "errors": [ + { + "message": "Missing primary key column(s): product_id" + } + ] + } + ``` + + + ## MutationType The `Mutation` type is the entrypoint for mutations/edits. diff --git a/docs/changelog.md b/docs/changelog.md index 29b85a7b..a2b9285b 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -127,3 +127,5 @@ - feature: Add support for Postgres 18 ## master + +- feature: Add support for single record queries by primary key From b5d7786e73ac3029023ae65d4025af627d20a65c Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 3 Feb 2026 16:47:46 +0530 Subject: [PATCH 15/15] fix return type in docs --- docs/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index 3c5e287f..39362281 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1880,7 +1880,7 @@ create table item( "itemId": 1, "productId": 2, "quantity": 1, - "price": 24.99 + "price": "24.99" } } }