Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Since v5 pgx.ScanRow cannot scan null::INTEGER to sql.NullInt64 #1987

Closed
flowHater opened this issue Apr 13, 2024 · 2 comments
Closed

Since v5 pgx.ScanRow cannot scan null::INTEGER to sql.NullInt64 #1987

flowHater opened this issue Apr 13, 2024 · 2 comments
Labels

Comments

@flowHater
Copy link

Describe the bug
It seems since v5, pgx.ScanRow cannot scan a null::INTERGER to a sql.NullInt64.
In v4, I confirm It worked.

To Reproduce
Both function do the same thing. Querying and scanning a null::INTEGER

package main

import (
	"context"
	"database/sql"
	"fmt"

	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgconn"
	"github.com/jackc/pgx/v5/pgtype"

	pgconnV4 "github.com/jackc/pgconn"
	pgtypeV4 "github.com/jackc/pgtype"
	pgxV4 "github.com/jackc/pgx/v4"
)

const SQL = `SELECT null::INTEGER AS test`

func main() {

	if v, err := v4(); err != nil {
		fmt.Printf("Error in v4: %v\n", err)
	} else {
		fmt.Printf("V4 successful v = %v\n", v)
	}

	if v, err := v5(); err != nil {
		fmt.Printf("Error in v5: %v\n", err)
	} else {
		fmt.Printf("V5 successful v = %v\n", v)
	}
}

func v4() (sql.NullInt64, error) {
	pgconn, err := pgconnV4.Connect(context.Background(), "")
	if err != nil {
		return sql.NullInt64{}, fmt.Errorf("pgconnV4.Connect(): %w", err)
	}
	defer pgconn.Close(context.Background())

	result := pgconn.Exec(context.Background(), SQL)

	r, err := result.ReadAll()
	if err != nil {
		return sql.NullInt64{}, fmt.Errorf("result.ReadAll(): %w", err)
	}

	v := sql.NullInt64{}

	fmt.Printf("r[0].Rows[0][0] = %v\n", r[0].Rows[0][0])

	if err := pgxV4.ScanRow(pgtypeV4.NewConnInfo(), r[0].FieldDescriptions, r[0].Rows[0], &v); err != nil {
		return sql.NullInt64{}, fmt.Errorf("pgxV4.ScanRow(): %w", err)
	}

	return v, nil
}

func v5() (sql.NullInt64, error) {
	pgConn, err := pgconn.Connect(context.Background(), "")
	if err != nil {
		return sql.NullInt64{}, fmt.Errorf("pgconn.Connect(): %w", err)
	}
	defer pgConn.Close(context.Background())

	result := pgConn.Exec(context.Background(), SQL)

	r, err := result.ReadAll()
	if err != nil {
		return sql.NullInt64{}, fmt.Errorf("result.ReadAll(): %w", err)
	}

	v := sql.NullInt64{}

	fmt.Printf("r[0].Rows[0][0] = %v\n", r[0].Rows[0][0])

	if err := pgx.ScanRow(pgtype.NewMap(), r[0].FieldDescriptions, r[0].Rows[0], &v); err != nil {
		return sql.NullInt64{}, fmt.Errorf("pgxV4.ScanRow(): %w", err)
	}

	return v, nil
}

Expected behavior
Reading the CHANGELOG, I can't see anything about that behaviour.

Actual behavior
In v5 an error occurs:

pgxV4.ScanRow(): can't scan into dest[0]: strconv.ParseInt: parsing "": invalid syntax

Version

  • Go: go version go1.22.2 linux/amd64
  • PostgreSQL: PostgreSQL 15.4 (Debian 15.4-2.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
  • pgx: github.com/jackc/pgx/v4 v4.18.3
    github.com/jackc/pgx/v5 v5.5.5

Additional context
func (n *NullInt64) Scan(value any) seems to not be called. Want to know if I missed something somewhere between v4 and v5 or I can investigate further more.

I also tried to use a pgtype.Int8 same result.

func (m *Map) PlanScan(oid uint32, formatCode int16, target any) ScanPlan seems to have changed a lot between v4 and v5.

Thanks for your time.

@flowHater flowHater added the bug label Apr 13, 2024
jackc added a commit that referenced this issue May 9, 2024
The ResultReader.Read() method was erroneously converting nil values
to []byte{}.

#1987
@jackc
Copy link
Owner

jackc commented May 9, 2024

Thanks for the good repro case. Fixed in 48ae1f4. The problem was actually with ResultReader.Read(). It was converting []byte(nil) to []byte{}.

@jackc jackc closed this as completed May 9, 2024
@flowHater
Copy link
Author

Thanks for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants