Skip to content

Commit 1378805

Browse files
plcplcSamirTalwar
andauthored
Fields of composite types are always nullable (#565)
### What We used to mark fields of composite type as not-nullable in the NDC schema. This is wrong. Nullability is a property of columns of tables, not of fields of record types. This is also demonstrated by the following transcript: ``` postgres=# create table a_table (nullable_text text, not_nullable_text text not null); CREATE TABLE postgres=# create table derived_table (a_table a_table, other text); CREATE TABLE postgres=# insert into derived_table values (('nullable', 'not nullable'), 'other text'); INSERT 0 1 postgres=# insert into derived_table values ((null, 'not nullable'), 'other text'); INSERT 0 1 postgres=# select (a_table).* from derived_table; nullable_text | not_nullable_text ---------------+------------------- nullable | not nullable | not nullable (2 rows) postgres=# insert into a_table select (a_table).* from derived_table; INSERT 0 2 postgres=# select * from a_table; nullable_text | not_nullable_text ---------------+------------------- nullable | not nullable | not nullable (2 rows) -- We can easily construct a record with (not_nullable_text=null) when on **the composite type** a_table: postgres=# insert into derived_table values (('nullable', null), 'other text'); INSERT 0 1 postgres=# select * from derived_table; a_table | other ---------------------------+------------ (nullable,"not nullable") | other text (,"not nullable") | other text (nullable,) | other text (3 rows) postgres=# select (a_table).* from derived_table; nullable_text | not_nullable_text ---------------+------------------- nullable | not nullable | not nullable nullable | (3 rows) -- ... But we cannot insert this into **the table** a_table. postgres=# insert into a_table select (a_table).* from derived_table; ERROR: null value in column "not_nullable_text" of relation "a_table" violates not-null constraint DETAIL: Failing row contains (nullable, null). ``` ### How We simply make the schema endpoint always return nullable fields of composite types. --------- Co-authored-by: Samir Talwar <[email protected]>
1 parent 346d2db commit 1378805

File tree

4 files changed

+226
-99
lines changed

4 files changed

+226
-99
lines changed

changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
### Fixed
2424

25+
- Make fields of composite types nullable in the schema.
26+
[#565](https://github.com/hasura/ndc-postgres/pull/565)
2527
- Allow Native Operations that end with a semicolon when it's easy to remove them.
2628
[#566](https://github.com/hasura/ndc-postgres/pull/566)
2729
- Fix nested field relationships.

crates/connectors/ndc-postgres/src/schema/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,9 @@ pub fn get_schema(
283283
field_name.clone(),
284284
models::ObjectField {
285285
description: field_info.description.clone(),
286-
r#type: type_to_type(&field_info.r#type),
286+
r#type: models::Type::Nullable {
287+
underlying_type: Box::new(type_to_type(&field_info.r#type)),
288+
},
287289
arguments: BTreeMap::new(),
288290
},
289291
)

crates/tests/databases-tests/src/citus/snapshots/databases_tests__citus__schema_tests__schema_test__get_schema.snap

+81-36
Original file line numberDiff line numberDiff line change
@@ -2965,14 +2965,20 @@ expression: result
29652965
"fields": {
29662966
"name": {
29672967
"type": {
2968-
"type": "named",
2969-
"name": "text"
2968+
"type": "nullable",
2969+
"underlying_type": {
2970+
"type": "named",
2971+
"name": "text"
2972+
}
29702973
}
29712974
},
29722975
"popularity": {
29732976
"type": {
2974-
"type": "named",
2975-
"name": "int8"
2977+
"type": "nullable",
2978+
"underlying_type": {
2979+
"type": "named",
2980+
"name": "int8"
2981+
}
29762982
}
29772983
}
29782984
}
@@ -2981,17 +2987,23 @@ expression: result
29812987
"fields": {
29822988
"members": {
29832989
"type": {
2984-
"type": "array",
2985-
"element_type": {
2986-
"type": "named",
2987-
"name": "chara"
2990+
"type": "nullable",
2991+
"underlying_type": {
2992+
"type": "array",
2993+
"element_type": {
2994+
"type": "named",
2995+
"name": "chara"
2996+
}
29882997
}
29892998
}
29902999
},
29913000
"name": {
29923001
"type": {
2993-
"type": "named",
2994-
"name": "text"
3002+
"type": "nullable",
3003+
"underlying_type": {
3004+
"type": "named",
3005+
"name": "text"
3006+
}
29953007
}
29963008
}
29973009
}
@@ -3000,17 +3012,23 @@ expression: result
30003012
"fields": {
30013013
"members": {
30023014
"type": {
3003-
"type": "array",
3004-
"element_type": {
3005-
"type": "named",
3006-
"name": "person_name"
3015+
"type": "nullable",
3016+
"underlying_type": {
3017+
"type": "array",
3018+
"element_type": {
3019+
"type": "named",
3020+
"name": "person_name"
3021+
}
30073022
}
30083023
}
30093024
},
30103025
"name": {
30113026
"type": {
3012-
"type": "named",
3013-
"name": "text"
3027+
"type": "nullable",
3028+
"underlying_type": {
3029+
"type": "named",
3030+
"name": "text"
3031+
}
30143032
}
30153033
}
30163034
}
@@ -3093,8 +3111,11 @@ expression: result
30933111
"fields": {
30943112
"only_occurring_here1": {
30953113
"type": {
3096-
"type": "named",
3097-
"name": "int8"
3114+
"type": "nullable",
3115+
"underlying_type": {
3116+
"type": "named",
3117+
"name": "int8"
3118+
}
30983119
}
30993120
}
31003121
}
@@ -3268,17 +3289,23 @@ expression: result
32683289
"fields": {
32693290
"committees": {
32703291
"type": {
3271-
"type": "array",
3272-
"element_type": {
3273-
"type": "named",
3274-
"name": "committee"
3292+
"type": "nullable",
3293+
"underlying_type": {
3294+
"type": "array",
3295+
"element_type": {
3296+
"type": "named",
3297+
"name": "committee"
3298+
}
32753299
}
32763300
}
32773301
},
32783302
"name": {
32793303
"type": {
3280-
"type": "named",
3281-
"name": "text"
3304+
"type": "nullable",
3305+
"underlying_type": {
3306+
"type": "named",
3307+
"name": "text"
3308+
}
32823309
}
32833310
}
32843311
}
@@ -3301,14 +3328,20 @@ expression: result
33013328
"fields": {
33023329
"address": {
33033330
"type": {
3304-
"type": "named",
3305-
"name": "person_address"
3331+
"type": "nullable",
3332+
"underlying_type": {
3333+
"type": "named",
3334+
"name": "person_address"
3335+
}
33063336
}
33073337
},
33083338
"name": {
33093339
"type": {
3310-
"type": "named",
3311-
"name": "person_name"
3340+
"type": "nullable",
3341+
"underlying_type": {
3342+
"type": "named",
3343+
"name": "person_name"
3344+
}
33123345
}
33133346
}
33143347
}
@@ -3319,15 +3352,21 @@ expression: result
33193352
"address_line_1": {
33203353
"description": "Address line No 1",
33213354
"type": {
3322-
"type": "named",
3323-
"name": "text"
3355+
"type": "nullable",
3356+
"underlying_type": {
3357+
"type": "named",
3358+
"name": "text"
3359+
}
33243360
}
33253361
},
33263362
"address_line_2": {
33273363
"description": "Address line No 2",
33283364
"type": {
3329-
"type": "named",
3330-
"name": "text"
3365+
"type": "nullable",
3366+
"underlying_type": {
3367+
"type": "named",
3368+
"name": "text"
3369+
}
33313370
}
33323371
}
33333372
}
@@ -3338,15 +3377,21 @@ expression: result
33383377
"first_name": {
33393378
"description": "The first name of a person",
33403379
"type": {
3341-
"type": "named",
3342-
"name": "text"
3380+
"type": "nullable",
3381+
"underlying_type": {
3382+
"type": "named",
3383+
"name": "text"
3384+
}
33433385
}
33443386
},
33453387
"last_name": {
33463388
"description": "The last name of a person",
33473389
"type": {
3348-
"type": "named",
3349-
"name": "text"
3390+
"type": "nullable",
3391+
"underlying_type": {
3392+
"type": "named",
3393+
"name": "text"
3394+
}
33503395
}
33513396
}
33523397
}

0 commit comments

Comments
 (0)