Add support for PostgreSQL arrays
Rirush opened this issue · comments
Problem
PostgreSQL has support for arrays. For example, we have this table:
CREATE TABLE example (
bytes BYTEA -- byte array
);
In order to insert data into it, we need this query:
INSERT INTO example (bytes) VALUES ({0, 1, 2, 3, 4});
or
INSERT INTO example (bytes) VALUES (ARRAY[0, 1, 2, 3, 4]);
Using dbq that code should've looked like:
stmt := dbq.INSERT("example", []string{"bytes"}, 1, dbq.PostgreSQL)
_, _ = dbq.E(context.Background(), db, stmt, nil, []byte{0, 1, 2, 3, 4})
Expected behavior of this code
It will create statement
INSERT INTO example (bytes) VALUES ({0, 1, 2, 3, 4});
which will correctly insert array into the table.
Actual behavior
It creates statement
INSERT INTO example (bytes) VALUES (0, 1, 2, 3, 4);
which is invalid and doesn't work because each array element is treated like separate field.
I've tried wrapping byte array into []interface{}
and even [][]interface{}
- it doesn't resolve the issue, dbq still treats arrays as lists of fields.
A new insert function will need to be created in a postgresql sub package to create "exotic" queries.
Can you do a PR?
Thanks for a quick response! I will see what I can do. From what I can see right now, dbq.Insert
forms a perfectly valid statement (as it relies on field names provided manually by the user), the problems arise when the query is actually executed. dbq.E
/dbq.Q
treat all arrays like arrays of fields and unpack them. Seems like there's a need for separate function, that will treat all arrays like actual arrays.
E and Q are nothing more than the Exec and Query func in database/sql
stmt := dbq.INSERT("example", []string{"bytes"}, 1, dbq.PostgreSQL)
_, _ = dbq.E(context.Background(), db, stmt, nil, []byte{0, 1, 2, 3, 4})
Have you tried json encoding instead:
stmt := dbq.INSERT("example", []string{"bytes"}, 1, dbq.PostgreSQL)
_, _ = dbq.E(context.Background(), db, stmt, nil, string(json.Marshal([]byte{0, 1, 2, 3, 4})))
Going to close this since I think you know what needs to be done
Yes, okay. I'll make a PR if I'll figure out a good solution for this issue
What's wrong with the solution I have above with JSON?