go-jet / jet

Type safe SQL builder with code generation and automatic query result data mapping
Apache License 2.0
2.52k stars 118 forks source link

Error on InnerJoin #226

Closed CmpHDL closed 1 year ago

CmpHDL commented 1 year ago

Jet v2.9.0

I'm doing an inner join just like any other day and I'm getting the following error with no context. Strangely enough the .DebugSQL() query works when done directly into the DB. And I'm not using any aliases.

stderr: http: panic serving 172.21.0.1:35436: reflect: slice index out of range
stderr: goroutine 21 [running]:
stderr: net/http.(*conn).serve.func1()
stderr:     /usr/local/go/src/net/http/server.go:1801 +0xb9
stderr: panic({0x91eb40, 0xb2df50})
stderr:     /usr/local/go/src/runtime/panic.go:1047 +0x266
stderr: reflect.Value.Index({0x90b480, 0xc00066a1e8, 0xc000638780}, 0x45)
stderr:     /usr/local/go/src/reflect/value.go:1297 +0x178
stderr: github.com/go-jet/jet/v2/qrm.getSliceElemPtrAt({0xc0000d2780, 0xc00066a1e8, 0xc000638780}, 0x45)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/utill.go:43 +0x32
stderr: github.com/go-jet/jet/v2/qrm.mapRowToSlice(0xc0003ba300, {0xc000387400, 0x3d}, {0xc0000d2780, 0xc00066a1e8, 0xc00064bb48}, 0xc000678150)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:161 +0x3e9
stderr: github.com/go-jet/jet/v2/qrm.mapRowToDestinationPtr(0x90b480, {0xc000387400, 0x3d}, {0xc0000d2780, 0xc00066a1e8, 0x1}, 0xc000678150)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:334 +0xcb
stderr: github.com/go-jet/jet/v2/qrm.mapRowToDestinationValue(0xa40260, {0xc000387400, 0x3d}, {0x90b480, 0xc00066a1e8, 0x90b480}, 0x8b3020)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:308 +0x152
stderr: github.com/go-jet/jet/v2/qrm.mapRowToStruct(0xc0003ba300, {0xc000387400, 0x3d}, {0xa2f380, 0xc00066a160, 0xc00064be18}, 0x4a973d, {0x0, 0x0, 0x0})
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:241 +0x5d0
stderr: github.com/go-jet/jet/v2/qrm.mapRowToDestinationPtr(0xb4b810, {0xc000387400, 0x3d}, {0xa2f380, 0xc00066a160, 0x3}, 0xc000677c70)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:332 +0x114
stderr: github.com/go-jet/jet/v2/qrm.mapRowToDestinationValue(0xa1f860, {0xc000387400, 0x3d}, {0xa2f380, 0xc0000e4d90, 0xa2f380}, 0x8a774b)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:308 +0x152
stderr: github.com/go-jet/jet/v2/qrm.mapRowToStruct(0xc0003ba300, {0xc000387400, 0x3d}, {0x9f2620, 0xc0000e4d10, 0xc00041c900}, 0x91eb40, {0x0, 0x0, 0x0})
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:241 +0x5d0
stderr: github.com/go-jet/jet/v2/qrm.mapRowToSlice(0xc0003ba300, {0x0, 0x0}, {0x8deac0, 0xc0001fb128, 0xc00041c660}, 0x0)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:168 +0x2de
stderr: github.com/go-jet/jet/v2/qrm.queryToSlice({0xb3c950, 0xc0000a2000}, {0xb32160, 0xc00041e4e0}, {0xc000658a80, 0x44f817}, {0xc00041c660, 0x0, 0x0}, {0x8deac0, ...})
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:124 +0x2ec
stderr: github.com/go-jet/jet/v2/qrm.Query({0xb3c950, 0xc0000a2000}, {0xb32160, 0xc00041e4e0}, {0xc000658a80, 0x9f9}, {0xc00041c660, 0x1, 0x1}, {0x8deac0, ...})
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/qrm/qrm.go:29 +0x1bb
stderr: github.com/go-jet/jet/v2/internal/jet.(*serializerStatementInterfaceImpl).QueryContext.func1()
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/internal/jet/statement.go:102 +0x65
stderr: github.com/go-jet/jet/v2/internal/jet.duration(0xc00064c598)
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/internal/jet/statement.go:181 +0x37
stderr: github.com/go-jet/jet/v2/internal/jet.(*serializerStatementInterfaceImpl).QueryContext(0xc0003ba2b0, {0xb3c950, 0xc0000a2000}, {0xb32160, 0xc00041e4e0}, {0x8deac0, 0xc0001fb128})
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/internal/jet/statement.go:101 +0x1d1
stderr: github.com/go-jet/jet/v2/internal/jet.(*serializerStatementInterfaceImpl).Query(0x18, {0xb32160, 0xc00041e4e0}, {0x8deac0, 0xc0001fb128})
stderr:     /go/pkg/mod/github.com/go-jet/jet/v2@v2.9.0/internal/jet/statement.go:90 +0x4a

Heres the statement but I doubt the reason is here.

stmt := postgres.
    SELECT(
        table.A.AllColumns,
        table.B.AllColumns,
        table.C.AllColumns).
    FROM(table.A.
        INNER_JOIN(table.B,
            table.A.BID.EQ(table.B.ID)).
        INNER_JOIN(table.C,
            table.C.AID.EQ(table.A.ID))).
    WHERE(table.A.BuyerID.EQ(postgres.Int(ID)))

It seems to work fine when I remove table.C's Select (and leave the inner-join), although as you can see I'm not aliasing anything so there shouldn't be any name conflicts or similar.

go-jet commented 1 year ago

Hi @CmpHDL , Callstack looks similar to the issue from this thread. Did you manage to create reproducible sample? Also could you share how your destination looks like.

CmpHDL commented 1 year ago

@go-jet Destination is a slice.

var as []A
return as, stmt.Query(db, &as)
CmpHDL commented 1 year ago
type A struct {
  model.As
  B *B
  Cs []C
}

type B struct {
  model.Bs
}

type C struct {
  model.Cs
}
go-jet commented 1 year ago

I've add a new test on bug226 branch that resembles your case. But, I still can't reproduce it.

Could you share what are the field types of As.ID, Bs.ID, Cs.ID in model types. Also is there sql:"primary_key" tag on those fields? Did you in any way changed something in jet, or you're just using official tag release?

CmpHDL commented 1 year ago

@go-jet It's interacting with a belongs-to on a property not being selected. Trying to figure it out, this is going to be hard to recreate.


type A struct {
  model.As
  B *B
  Cs []C

  D *D
}

// Crash
type D struct {
  model.Ds
  Z []Z
  Y []Y
  X []X
}
jet-go select A innerjoin B innerjoin C

// Crash
type D struct {
  model.Ds
  Z []Z
  Y []Y
}
jet-go select A innerjoin B innerjoin C

// Crash
type D struct {
  model.Ds
  Y []Y
}
jet-go select A innerjoin B innerjoin C

// Crash
type D struct {
  model.Ds
  Z []Z
}
jet-go select A innerjoin B innerjoin C

// Crash
type D struct {
  model.Ds
  X []X
}
jet-go select A innerjoin B innerjoin C

// Works
type D struct {
  model.Ds
}
jet-go select A innerjoin B innerjoin C
`
CmpHDL commented 1 year ago

Z Y and X are all

type Z struct { model.Zs }

If I put any wrapped model like Z as a property or slice on D it crashes even if its not being selected at all.

go-jet commented 1 year ago

Ok, I've managed to reproduce it. Could you check if the bug226 branch now fixes the issue for you.

CmpHDL commented 1 year ago

@go-jet Worked, man how do you do it.