- 
                Notifications
    
You must be signed in to change notification settings  - Fork 5
 
Bring ndc-postgres in line with ndc-spec RC15 #296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
aac59d3
              c32cd87
              950b877
              51c90f1
              48cc5a0
              8da5bee
              7cf1695
              c1c27d6
              9d7897f
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 
          
            
          
           | 
    @@ -21,7 +21,7 @@ query-engine-metadata = { path = "../../query-engine/metadata" } | |||||||||
| query-engine-sql = { path = "../../query-engine/sql" } | ||||||||||
| query-engine-translation = { path = "../../query-engine/translation" } | ||||||||||
| 
     | 
||||||||||
| ndc-sdk = { git = "https://github.com/hasura/ndc-hub.git", rev = "02d26c1" } | ||||||||||
| ndc-sdk = { git = "https://github.com/hasura/ndc-hub.git", rev = "e0e9629" } | ||||||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
        Suggested change
       
    
  | 
||||||||||
| 
     | 
||||||||||
| async-trait = "0.1.77" | ||||||||||
| percent-encoding = "2.3.1" | ||||||||||
| 
        
          
        
         | 
    @@ -34,8 +34,8 @@ tracing = "0.1.40" | |||||||||
| url = "2.5.0" | ||||||||||
| 
     | 
||||||||||
| [dev-dependencies] | ||||||||||
| ndc-client = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.14" } | ||||||||||
| ndc-test = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.14" } | ||||||||||
| ndc-client = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.15" } | ||||||||||
| ndc-test = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.15" } | ||||||||||
| 
         
      Comment on lines
    
      +37
     to 
      +38
    
   
  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
        Suggested change
       
    
  | 
||||||||||
| tests-common = { path = "../../tests/tests-common" } | ||||||||||
| 
     | 
||||||||||
| axum = "0.6.20" | ||||||||||
| 
          
            
          
           | 
    ||||||||||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -21,7 +21,7 @@ pub async fn get_schema( | |
| ) -> Result<models::SchemaResponse, connector::SchemaError> { | ||
| let configuration::RuntimeConfiguration { metadata, .. } = config; | ||
| 
     | 
||
| let scalar_types: BTreeMap<String, models::ScalarType> = | ||
| let mut scalar_types: BTreeMap<String, models::ScalarType> = | ||
| configuration::occurring_scalar_types(&metadata.tables, &metadata.native_queries) | ||
| .iter() | ||
| .map(|scalar_type| { | ||
| 
          
            
          
           | 
    @@ -260,7 +260,9 @@ pub async fn get_schema( | |
| config.mutations_version, | ||
| ) | ||
| .iter() | ||
| .map(|(name, mutation)| mutation_to_procedure(name, mutation, &mut more_object_types)) | ||
| .map(|(name, mutation)| { | ||
| mutation_to_procedure(name, mutation, &mut more_object_types, &mut scalar_types) | ||
| }) | ||
| .collect(); | ||
| 
     | 
||
| procedures.extend(generated_procedures); | ||
| 
          
            
          
           | 
    @@ -301,17 +303,25 @@ fn mutation_to_procedure( | |
| name: &String, | ||
| mutation: &generate::Mutation, | ||
| object_types: &mut BTreeMap<String, models::ObjectType>, | ||
| scalar_types: &mut BTreeMap<String, models::ScalarType>, | ||
| ) -> models::ProcedureInfo { | ||
| match mutation { | ||
| generate::Mutation::DeleteMutation(delete) => delete_to_procedure(name, delete), | ||
| generate::Mutation::DeleteMutation(delete) => { | ||
| delete_to_procedure(name, delete, object_types, scalar_types) | ||
| } | ||
| generate::Mutation::InsertMutation(insert) => { | ||
| insert_to_procedure(name, insert, object_types) | ||
| insert_to_procedure(name, insert, object_types, scalar_types) | ||
| } | ||
| } | ||
| } | ||
| 
     | 
||
| /// given a `DeleteMutation`, turn it into a `ProcedureInfo` to be output in the schema | ||
| fn delete_to_procedure(name: &String, delete: &delete::DeleteMutation) -> models::ProcedureInfo { | ||
| fn delete_to_procedure( | ||
| name: &String, | ||
| delete: &delete::DeleteMutation, | ||
| object_types: &mut BTreeMap<String, models::ObjectType>, | ||
| scalar_types: &mut BTreeMap<String, models::ScalarType>, | ||
| ) -> models::ProcedureInfo { | ||
| match delete { | ||
| delete::DeleteMutation::DeleteByKey { | ||
| by_column, | ||
| 
        
          
        
         | 
    @@ -329,14 +339,16 @@ fn delete_to_procedure(name: &String, delete: &delete::DeleteMutation) -> models | |
| }, | ||
| ); | ||
| 
     | 
||
| models::ProcedureInfo { | ||
| name: name.to_string(), | ||
| description: Some(description.to_string()), | ||
| make_procedure_type( | ||
| name.to_string(), | ||
| Some(description.to_string()), | ||
| arguments, | ||
| result_type: models::Type::Named { | ||
| models::Type::Named { | ||
| name: collection_name.to_string(), | ||
| }, | ||
| } | ||
| object_types, | ||
| scalar_types, | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| 
          
            
          
           | 
    @@ -379,6 +391,7 @@ fn insert_to_procedure( | |
| name: &String, | ||
| insert: &insert::InsertMutation, | ||
| object_types: &mut BTreeMap<String, models::ObjectType>, | ||
| scalar_types: &mut BTreeMap<String, models::ScalarType>, | ||
| ) -> models::ProcedureInfo { | ||
| let mut arguments = BTreeMap::new(); | ||
| let object_type = make_object_type(&insert.columns); | ||
| 
        
          
        
         | 
    @@ -393,12 +406,83 @@ fn insert_to_procedure( | |
| }, | ||
| ); | ||
| 
     | 
||
| make_procedure_type( | ||
| name.to_string(), | ||
| Some(insert.description.to_string()), | ||
| arguments, | ||
| models::Type::Named { | ||
| name: insert.collection_name.to_string(), | ||
| }, | ||
| object_types, | ||
| scalar_types, | ||
| ) | ||
| } | ||
| 
     | 
||
| /// Build a `ProcedureInfo` type from the given parameters. | ||
| /// | ||
| /// Because procedures return an `affected_rows` count alongside the result type that it's | ||
| /// `returning`, we have to generate a separate object type for its result. As part of that, we may | ||
| /// also have to include the `int4` scalar type (if it isn't included for another reason elsewhere | ||
| /// in the schema). So, this function creates that object type, optionally adds that scalar type, | ||
| /// and then returns a `ProcedureInfo` that points to the correct object type. | ||
| fn make_procedure_type( | ||
| name: String, | ||
| description: Option<String>, | ||
| arguments: BTreeMap<String, models::ArgumentInfo>, | ||
| result_type: models::Type, | ||
| 
     | 
||
| object_types: &mut BTreeMap<String, models::ObjectType>, | ||
| scalar_types: &mut BTreeMap<String, models::ScalarType>, | ||
| ) -> models::ProcedureInfo { | ||
| let mut fields = BTreeMap::new(); | ||
| let object_type_name = format!("{name}_response"); | ||
| 
     | 
||
| // If int4 doesn't exist anywhere else in the schema, we need to add it here. However, a user | ||
| // can't filter or aggregate based on the affected rows of a procedure, so we don't need to add | ||
| // any aggregate functions or comparison operators. However, if int4 exists elsewhere in the | ||
| // schema and has already been added, it will also already contain these functions and | ||
| // operators. | ||
| scalar_types | ||
| .entry("int4".to_string()) | ||
| .or_insert(models::ScalarType { | ||
| aggregate_functions: BTreeMap::new(), | ||
| comparison_operators: BTreeMap::new(), | ||
| }); | ||
| 
         
      Comment on lines
    
      +440
     to 
      +450
    
   
  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this also required when generating the configuration? If it is, then it will need to be moved to  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about it, even if it's not, that still feels like a better place for it. I plan on making that function private and putting the scalar types into the configuration at some point soon, so this function can just read them directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not really part of the configuration. Even if the user omits  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am convinced. Any reason not to add it in up-front rather than mutating later? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only that, if no mutations are generated, it's a type without a purpose, which we seem to be avoiding everywhere else? idk, I'm not sure what the danger is in having all scalar types declared upfront and not having the  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better to keep the cause and effect together. We generate the type because the procedure needs it, and we don't if we don't. It's better to place them together instead of in two separate places.  | 
||
| 
     | 
||
| fields.insert( | ||
| "affected_rows".to_string(), | ||
| models::ObjectField { | ||
| description: Some("The number of rows affected by the mutation".to_string()), | ||
| r#type: models::Type::Named { | ||
| name: "int4".to_string(), | ||
| }, | ||
| }, | ||
| ); | ||
| 
     | 
||
| fields.insert( | ||
| "returning".to_string(), | ||
| models::ObjectField { | ||
| description: Some("Data from rows affected by the mutation".to_string()), | ||
| r#type: models::Type::Array { | ||
| element_type: Box::from(result_type), | ||
| }, | ||
| }, | ||
| ); | ||
| 
     | 
||
| object_types.insert( | ||
| object_type_name.clone(), | ||
| models::ObjectType { | ||
| description: Some(format!("Responses from the '{name}' procedure")), | ||
| fields, | ||
| }, | ||
| ); | ||
| 
     | 
||
| models::ProcedureInfo { | ||
| name: name.to_string(), | ||
| description: Some(insert.description.to_string()), | ||
| name, | ||
| description, | ||
| arguments, | ||
| result_type: models::Type::Named { | ||
| name: insert.collection_name.to_string(), | ||
| name: object_type_name, | ||
| }, | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| 
          
            
          
           | 
    @@ -5,7 +5,7 @@ edition = "2021" | |||||
| license = "Apache-2.0" | ||||||
| 
     | 
||||||
| [dependencies] | ||||||
| ndc-sdk = { git = "https://github.com/hasura/ndc-hub.git", rev = "02d26c1" } | ||||||
| ndc-sdk = { git = "https://github.com/hasura/ndc-hub.git", rev = "e0e9629" } | ||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
        Suggested change
       
    
  | 
||||||
| query-engine-metadata = { path = "../metadata" } | ||||||
| query-engine-sql = { path = "../sql" } | ||||||
| 
     | 
||||||
| 
          
            
          
           | 
    ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can update to RC 16 directly if you like.