Nurzhan Nogerbek
Nurzhan Nogerbek

Reputation: 5236

How to correctly Scan pq arrays?

In a PostgreSQL database I have a table:

| ORGANIZATION_ID | FACTOR_IDS   | CALCULATION_VALUES  |
|-----------------|--------------|---------------------|
| 1               | {1,2,3,4,5}  | {0,66.66,50,100,80} |
| 2               | NULL         | NULL                |
| 1               | {6,7,8,9,10} | {0,77.77,60,110,90} |

In Go I make a query to that table and then try to use the Scan method. Unfortunately I get an error:

Trace: runtime error: invalid memory address or nil pointer dereference

My code:

type Entry struct {
    OrganizationID int
    FactorIDS pq.Int64Array
    CalculationValues pq.Float64Array
}

rows, err = database.DBGORM.Raw(`SELECT * FROM ANALYTICS`, ID).Rows()

if err != nil {
    utils.Logger().Println(err)
    return
}

defer rows.Close()

for rows.Next() {
    var entry *Entry

    if err = rows.Scan(&entry.OrganizationID, &entry.FactorIDS, &entry.CalculationValues); err != nil {
        utils.Logger().Println(err) // <- RAISE ERROR
        return
    }

    if entry.FactorIDS != nil {
        for index, value := range factorID {
            // some code here
        }
    }
}

How can I fix this problem?

Also if I change the type from pq.Int64Array to *pq.Int64Array the Go compiler gives the error: Cannot range over data *pq.Int64Array for the code above.

Upvotes: 3

Views: 607

Answers (2)

negi Yogi
negi Yogi

Reputation: 2278

It was panicking because of the these &entry.OrganizationID, &entry.FactorIDS, &entry.CalculationValues. As entry is of pointer type and you haven't initialize the memory to it. If you want the struct of pointer type you can initialize it like this:

for rows.Next() {
    entry:=new(Entry)

    if err = rows.Scan(&entry.OrganizationID, &entry.FactorIDS, &entry.CalculationValues); err != nil {
        utils.Logger().Println(err) // <- RAISE ERROR
        return
    }

    if entry.FactorIDS != nil {
        for index, value := range factorID {
            // some code here
        }
    }
}

Upvotes: -1

Thundercat
Thundercat

Reputation: 120941

The nil pointer dereference is on entry. Fix by changing entry from a pointer to a value:

for rows.Next() {
    var entry Entry  // <--- change on this line
    ... remaining code as in question
}

Upvotes: 6

Related Questions