Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query for an integer array from PostreSQL always returns []uint8

Tags:

go

pq

Take a simple PostreSQL db with an integer array:

CREATE TABLE foo (
    id                       serial PRIMARY KEY,
    bar               integer[]
);

INSERT INTO foo VALUES(DEFAULT, '{1234567, 20, 30, 40}');

Using pq, these values are for some reason being retrieved as an array of []uint8.
The documentation says that integer types are returned as int64. Does this not apply to arrays as well?

db, err := sql.Open("postgres", "user=a_user password=your_pwd dbname=blah")
if err != nil {
    fmt.Println(err)
}

var ret []int
err = db.QueryRow("SELECT bar FROM foo WHERE id=$1", 1).Scan(&ret)
if err != nil {
    fmt.Println(err)
}

fmt.Println(ret)

Output:

sql: Scan error on column index 0: unsupported Scan, storing driver.Value type []uint8 into type *[]int64
[]
like image 691
myartsev Avatar asked Dec 24 '17 17:12

myartsev


People also ask

What is [] in PostgreSQL?

Array Type. PostgreSQL gives the opportunity to define a column of a table as a variable length single or multidimensional array. Arrays of any built-in or user-defined base type, enum type, or composite type can be created. We will focus on one data type in particular, the Array of text, text[].

How do I return an array value in PostgreSQL?

CREATE OR REPLACE FUNCTION get_numbers(maxNo INTEGER) RETURNS TEXT[] AS $$ DECLARE counter INTEGER := 0; nums TEXT[] := ARRAY[]::TEXT[]; BEGIN LOOP EXIT WHEN counter = maxNo; counter = counter + 1; nums = array_append(nums, counter::TEXT); END LOOP; RETURN nums; END ; $$ LANGUAGE plpgsql; – nick w.

How do I select an array in PostgreSQL?

PostgreSQL allows us to define a table column as an array type. The array must be of a valid data type such as integer, character, or user-defined types. To insert values into an array column, we use the ARRAY constructor.

How do I declare an array variable in PostgreSQL?

PostgreSQL Array type PL/pgSQL in PostgreSQL allows us to declare a variable as an ARRAY type. This ARRAY can be either a base or a custom type. For example, if we want to store a list of PINCODE values, then, we can declare the variable as v_pincode INT[].


1 Answers

You cannot use a slice of int as a driver.Value. The arguments to Scan must be of one of the supported types, or implement the sql.Scanner interface.

The reason you're seeing []uint8 in the error message is that the raw value returned from the database is a []byte slice, for which []uint8 is a synonym.

To interpret that []byte slice appropriately as a custom PostgreSQL array type, you should use the appropriate array types defined in the pq package, such as the Int64Array.

Try something like this:

var ret pq.Int64Array
err = db.QueryRow("SELECT bar FROM foo WHERE id=$1", 1).Scan(&ret)
if err != nil {
    fmt.Println(err)
}

fmt.Println(ret)
like image 157
Flimzy Avatar answered Sep 22 '22 02:09

Flimzy