gocraft/dbr

InsertStmt.Load drops constraint error

dmlyons opened this issue · 2 comments

I have encountered a bug in dbr when using InsertStmt.Load() on postgres (not sure, but could be in other drivers as well). Possibly it doesn't appear to ever call Rows.Error() so it misses constraints? Here is a repeatable example:

package main

import (
	"log"

	"github.com/gocraft/dbr"
	_ "github.com/jackc/pgx/stdlib"
)

type foo struct {
	ID int
}

func main() {
	conn, err := dbr.Open("pgx", "postgres://postgres:postgres@localhost/test", nil)
	if err != nil {
		log.Fatal(err)
	}
	conn.SetMaxOpenConns(10)

	_, err = conn.Exec(`drop table if exists foo`)
	if err != nil {
		log.Fatal(err)
	}
	_, err = conn.Exec(`create table foo (id int primary key)`)
	if err != nil {
		log.Fatal(err)
	}

	var f foo

	sess := conn.NewSession(nil)

	err = sess.InsertInto(`foo`).
		Columns(`id`).
		Values(1).
		Returning(`id`).
		Load(&f)
	if err != nil {
		log.Fatalf(`Should not error here: %+v`, err)
	}

	err = sess.InsertInto(`foo`).
		Columns(`id`).
		Values(1).
		Returning(`id`).
		Load(&f)
	if err != nil {
		log.Fatalf(`Should error here: %+v`, err)
	}

	_, err = sess.Exec(`insert into foo(id) values ($1)`, 1)
	if err != nil {
		log.Fatalf(`Will error here: %+v`, err)
	}
}

A little digging shows that InsertStmt.Load will eventually call sql.QueryContext, when it probably should be calling sql.Exec.

#183 fixed this.