require "../../spec_helper" describe PG::Decoders do test_decode "array", "'{}'::integer[]", [] of Int32 test_decode "array", "ARRAY[9]", [9] test_decode "array", "ARRAY[8,9]", [8, 9] test_decode "array", "'{{9,8},{7,6},{5,4}}'::integer[]", [[9, 8], [7, 6], [5, 4]] test_decode "array", "'{ {9,8,7}, {6,5,4} }'::integer[] ", [[9, 8, 7], [6, 5, 4]] test_decode "array", "'{{{1,2},{3,4}},{{9,8},{7,6}}}'::integer[]", [[[1, 2], [3, 4]], [[9, 8], [7, 6]]] test_decode "array", "ARRAY[1, null, 2] ", [1, nil, 2] test_decode "array", "('[3:5]={1,2,3}'::integer[])", [nil, nil, 1, 2, 3] it "allows special-case casting on simple arrays" do value = PG_DB.query_one("select '{}'::integer[]", &.read(Array(Int32))) typeof(value).should eq(Array(Int32)) value.empty?.should be_true value = PG_DB.query_one("select '{1,2,3}'::integer[]", &.read(Array(Int32))) typeof(value).should eq(Array(Int32)) value.should eq([1, 2, 3]) value = PG_DB.query_one("select '{1,2,3,null}'::integer[]", &.read(Array(Int32?))) typeof(value).should eq(Array(Int32?)) value.should eq([1, 2, 3, nil]) value = PG_DB.query_one("select '{{1,2,3},{4,5,6}}'::integer[]", &.read(Array(Array(Int32)))) typeof(value).should eq(Array(Array(Int32))) value.should eq([[1, 2, 3], [4, 5, 6]]) end it "reads array as nilable" do value = PG_DB.query_one("select '{1,2,3}'::integer[]", &.read(Array(Int32)?)) typeof(value).should eq(Array(Int32)?) value.should eq([1, 2, 3]) value = PG_DB.query_one("select null", &.read(Array(Int32)?)) typeof(value).should eq(Array(Int32)?) value.should be_nil end it "reads arrray of numeric" do value = PG_DB.query_one("select '{1,2,3}'::numeric[]", &.read(Array(PG::Numeric))) typeof(value).should eq(Array(PG::Numeric)) value.map(&.to_f).should eq([1, 2, 3]) end it "reads arrray of nilable numeric" do value = PG_DB.query_one("select '{1,null,3}'::numeric[]", &.read(Array(PG::Numeric?))) typeof(value).should eq(Array(PG::Numeric?)) value.map(&.try &.to_f).should eq([1, nil, 3]) end it "raises when reading null in non-null array" do expect_raises(PG::RuntimeError) do PG_DB.query_one("select '{1,2,3,null}'::integer[]", &.read(Array(Int32))) end end it "reads array of time" do values = PG_DB.query_one("select array[to_date('20170103', 'YYYYMMDD')::timestamp]", &.read(Array(Time))) typeof(values).should eq(Array(Time)) values.size.should eq(1) values[0].should eq(Time.utc(2017, 1, 3)) end it "reads array of date" do values = PG_DB.query_one("select array[to_date('20170103', 'YYYYMMDD')]", &.read(Array(Time))) typeof(values).should eq(Array(Time)) values.size.should eq(1) values[0].should eq(Time.utc(2017, 1, 3)) end it "reads array of uuid" do values = PG_DB.query_one("select array['56d3839e-dbb6-4b51-aa67-c0bc2a78c9d4'::uuid]", &.read(Array(UUID))) typeof(values).should eq(Array(UUID)) values.size.should eq(1) values[0].should eq(UUID.new("56d3839e-dbb6-4b51-aa67-c0bc2a78c9d4")) end it "raises when reading incorrect array type" do expect_raises(PG::RuntimeError) do PG_DB.query_one("select '{1,2,3}'::numeric[]", &.read(Array(Float64))) end end it "errors on negative lower bounds" do expect_raises(PG::RuntimeError) do PG_DB.query_one("select '[-2:-0]={1,2,3}'::integer[]", &.read) end end test_decode "bool array", "$${t,f,t}$$::bool[]", [true, false, true] test_decode "char array", "$${a, b}$$::\"char\"[]", ['a', 'b'] test_decode "int2 array", "$${1,2}$$::int2[]", [1, 2] test_decode "text array", "$${hello, world}$$::text[]", ["hello", "world"] test_decode "int8 array", "$${1,2}$$::int8[]", [1, 2] test_decode "float4 array", "$${1.1,2.2}$$::float4[]", [1.1_f32, 2.2_f32] test_decode "float8 array", "$${1.1,2.2}$$::float8[]", [1.1_f64, 2.2_f64] test_decode "date array", "array[to_date('20170103', 'YYYYMMDD')]", [Time.utc(2017, 1, 3)] test_decode "numeric array", "array[1::numeric]", [PG::Numeric.new(ndigits: 1, weight: 0, sign: PG::Numeric::Sign::Pos.value, dscale: 0, digits: [1] of Int16)] test_decode "time array", "array[to_date('20170103', 'YYYYMMDD')::timestamp]", [Time.utc(2017, 1, 3)] test_decode "uuid array", "array['f0c66172-f617-4bb4-95f4-5677a093cedb']::uuid[]", [UUID.new("f0c66172-f617-4bb4-95f4-5677a093cedb")] it "errors when expecting array returns null" do expect_raises(PG::RuntimeError, "unexpected NULL, expecting to read Array(String)") do PG_DB.query_one("SELECT NULL", as: Array(String)) end end end