From 95fb35644047f524cf63523984da6aef46a56560 Mon Sep 17 00:00:00 2001 From: Leah Ulmschneider Date: Mon, 2 Dec 2024 20:14:30 +0100 Subject: [PATCH 1/3] Fix enum array error --- birdie_snapshots/enum_array_decoding.accepted | 60 +++++++++++++++++++ src/squirrel/internal/database/postgres.gleam | 13 +++- test/squirrel_test.gleam | 6 ++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 birdie_snapshots/enum_array_decoding.accepted diff --git a/birdie_snapshots/enum_array_decoding.accepted b/birdie_snapshots/enum_array_decoding.accepted new file mode 100644 index 0000000..8dec65f --- /dev/null +++ b/birdie_snapshots/enum_array_decoding.accepted @@ -0,0 +1,60 @@ +--- +version: 1.2.3 +title: enum array decoding +file: ./test/squirrel_test.gleam +test_name: enum_array_decoding_test +--- +import decode/zero +import pog + +/// A row you get from running the `query` query +/// defined in `query.sql`. +/// +/// > 🐿️ This type definition was generated automatically using v-test of the +/// > [squirrel package](https://github.com/giacomocavalieri/squirrel). +/// +pub type QueryRow { + QueryRow(res: List(SquirrelColour)) +} + +/// Runs the `query` query +/// defined in `query.sql`. +/// +/// > 🐿️ This function was generated automatically using v-test of +/// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). +/// +pub fn query(db) { + let decoder = { + use res <- zero.field(0, zero.list(squirrel_colour_decoder())) + zero.success(QueryRow(res:)) + } + + let query = "select array['red'::squirrel_colour] as res" + + pog.query(query) + |> pog.returning(zero.run(_, decoder)) + |> pog.execute(db) +} + +// --- Enums ------------------------------------------------------------------- + +/// Corresponds to the Postgres `squirrel_colour` enum. +/// +/// > 🐿️ This type definition was generated automatically using v-test of the +/// > [squirrel package](https://github.com/giacomocavalieri/squirrel). +/// +pub type SquirrelColour { + LightBrown + Grey + Red +} + +fn squirrel_colour_decoder() { + use variant <- zero.then(zero.string) + case variant { + "light brown" -> zero.success(LightBrown) + "grey" -> zero.success(Grey) + "red" -> zero.success(Red) + _ -> zero.failure(LightBrown, "SquirrelColour") + } +} diff --git a/src/squirrel/internal/database/postgres.gleam b/src/squirrel/internal/database/postgres.gleam index 46448b8..1c659bb 100644 --- a/src/squirrel/internal/database/postgres.gleam +++ b/src/squirrel/internal/database/postgres.gleam @@ -60,6 +60,12 @@ select else elem.typname end as type, + -- The oid of the type or the array item type. + case + when elem.typname is null then type.oid + else elem.oid + end as oid, + -- Tells us how to interpret the first column: if this is true then the first -- column is the type of the elements of the array type. -- Otherwise it means we've found a base type. @@ -664,13 +670,14 @@ fn find_gleam_type(query: UntypedQuery, oid: Int) -> Db(gleam.Type) { let params = [pg.Parameter(<>)] use res <- eval.try(run_query(find_postgres_type_query(), params, [23])) - // We know the output must only contain two values: the name and a boolean to - // check wether it is an array or not. + // We know the output must only contain four values: the name, the oid, a boolean to + // check wether it is an array or not and the type of the type / array item. // It's safe to assert because this query is hard coded in our code and the // output shape cannot change without us changing that query. - let assert [[name, is_array, kind]] = res + let assert [[name, oid, is_array, kind]] = res let assert Ok(name) = bit_array.to_string(name) let assert Ok(kind) = bit_array.to_string(kind) + let assert <> = oid use type_ <- eval.try(case kind { "e" -> resolve_enum_type(name, oid) diff --git a/test/squirrel_test.gleam b/test/squirrel_test.gleam index 7e689e7..42226ba 100644 --- a/test/squirrel_test.gleam +++ b/test/squirrel_test.gleam @@ -426,6 +426,12 @@ pub fn enum_encoding_test() { |> birdie.snap(title: "enum encoding") } +pub fn enum_array_decoding_test() { + "select array['red'::squirrel_colour] as res" + |> should_codegen + |> birdie.snap(title: "enum array decoding") +} + // --- CODEGEN STRUCTURE TESTS ------------------------------------------------- // This is a group of tests to ensure the generated code has some specific // structure (e.g. the names and comments are what we expect...) From 2e81a4663cc16633b67b456bd5eb843e33d93fd0 Mon Sep 17 00:00:00 2001 From: Leah Ulmschneider Date: Wed, 4 Dec 2024 13:18:18 +0100 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a22d36c..c87fcb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## Unreleased + +- Fixed a bug where a queries with enum arrays would cause a crash. + ([Leah Ulmschneider](https://github.com/leah-u)) + ## v2.0.4 - 2024-12-04 - Replace deprecated `gleam/regex` module with `gleam/regexp`. From 84d34ca00c83bd129b39dc611261cc3d117b5d75 Mon Sep 17 00:00:00 2001 From: Leah Ulmschneider Date: Wed, 4 Dec 2024 13:20:27 +0100 Subject: [PATCH 3/3] typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c87fcb9..ad2b3ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -- Fixed a bug where a queries with enum arrays would cause a crash. +- Fixed a bug where queries with enum arrays would cause an error. ([Leah Ulmschneider](https://github.com/leah-u)) ## v2.0.4 - 2024-12-04