will / crystal-pg

a postgres driver for crystal

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Arithmetic overflow (OverflowError)

anykeyh opened this issue · comments

Hello,

I'm migrating clear to crystal v0.31 but I have a bug in one of my spec, which check the Array feature.

PG now crash with this stack trace:

       Arithmetic overflow (OverflowError)
         from lib/pg/src/pg/decoder.cr:0:22 in 'decode'
         from lib/pg/src/pg/decoders/array_decoder.cr:58:11 in 'get_next'
         from lib/pg/src/pg/decoders/array_decoder.cr:37:30 in 'build_simple_array'
         from lib/pg/src/pg/decoders/array_decoder.cr:25:11 in 'decode'
         from lib/pg/src/pg/result_set.cr:77:7 in 'read'
         from src/clear/model/collection.cr:8:18 in 'first'
         from src/clear/model/collection.cr:516:7 in 'first!'
         from src/clear/model/collection.cr:515:5 in 'first!'
         from spec/model/model_spec.cr:611:13 in '->'
         ...

I didn't make a code to isolate because the current code is bound to clear's model, but here is the code + SQL executed (the SQL should work out of clear):

SQL

CREATE TABLE model_categories (id bigserial NOT NULL PRIMARY KEY, name text, created_at timestamp without time zone NOT NULL DEFAULT NOW(), updated_at timestamp without time zone NOT NULL DEFAULT NOW())

CREATE TABLE model_posts (id bigserial NOT NULL PRIMARY KEY, title text, tags text[] DEFAULT ARRAY['post', 'arr 2'], flags_other_column_name bigint[] DEFAULT '{}'::bigint[], user_id bigint NOT NULL, category_id bigint, FOREIGN KEY (user_id) REFERENCES model_users (id) ON DELETE cascade, FOREIGN KEY (category_id) REFERENCES model_categories (id) ON DELETE set null)

INSERT INTO "model_users" ("first_name", "updated_at", "created_at") VALUES ('John', '2019-09-25 05:05:39.964 +00:00', '2019-09-25 05:05:39.964 +00:00') RETURNING *

INSERT INTO "model_posts" ("title", "user_id") VALUES ('A post', 1) RETURNING *
UPDATE model_posts SET "tags" = Array['a', 'b', 'c']::text[], "flags_other_column_name" = Array[11234212343543, 11234212343543, -12928394059603, 12038493029484]::bigint[] WHERE ("id" = 1)
SELECT * FROM "model_posts" ORDER BY "id" ASC LIMIT 1

SPEC

it "can load a column of type Array" do
      temporary do
        reinit

        u = User.create!({first_name: "John"})
        p = Post.create!({title: "A post", user_id: u.id})

        p.tags = ["a", "b", "c"]
        p.flags = [11234212343543_i64, 11234212343543_i64, -12928394059603_i64, 12038493029484_i64]
        p.save!

        p = Post.query.first!  #< CRASH HERE
        p.tags.should eq ["a", "b", "c"]
        p.flags.should eq [11234212343543_i64, 11234212343543_i64, -12928394059603_i64, 12038493029484_i64]

        # Test insertion of empty array
        Post.create!({title: "A post", user_id: u.id, tags: [] of String})
      end
    end

Reduced:

url = "postgres://..."
db = DB.open(url)

db.exec "DROP TABLE foo"
db.exec "CREATE TABLE foo (flags bigint)"
db.exec "INSERT INTO foo VALUES (-12928394059603::bigint)"

db.query_one "select flags from foo", as: Int64

I'll send a fix in a minute.

Thanks for finding this issue :)