huandu / go-sqlbuilder

A flexible and powerful SQL string builder library plus a zero-config ORM.
https://pkg.go.dev/github.com/huandu/go-sqlbuilder
MIT License
1.45k stars 122 forks source link

Using `*Cond` in `SelectBuilder.Where()` causing stack overflow. #178

Open weeee9 opened 3 days ago

weeee9 commented 3 days ago

As title, trying to use *Cond in SelectBuilder.Where() causing stack overflow.

Code to reproduce:

package sql

import (
    "testing"

    "github.com/huandu/go-sqlbuilder"
    "github.com/stretchr/testify/assert"
)

func TestStaskOverflow(t *testing.T) {
    pg := sqlbuilder.PostgreSQL

    selectBuilder := pg.NewSelectBuilder()
    cond := sqlbuilder.NewCond()

    selectBuilder.
        Select("*").
        From("t1").
        Where(cond.Equal("a", 123)) // causing stack overflow

    sql, args := selectBuilder.Build()

    assert.Equal(t, "SELECT * FROM t1 WHERE a = $1", sql)
    assert.Equal(t, []any{123}, args)
}

Output:

=== RUN   TestStaskOverflow
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc020532670 stack=[0xc020532000, 0xc040532000]
fatal error: stack overflow

runtime stack:
runtime.throw({0x1035173ed?, 0x0?})
    /usr/local/go/src/runtime/panic.go:1023 +0x40 fp=0x16f38ad50 sp=0x16f38ad20 pc=0x102ad1190
runtime.newstack()
    /usr/local/go/src/runtime/stack.go:1103 +0x460 fp=0x16f38af00 sp=0x16f38ad50 pc=0x102af0030
runtime.morestack()
    /usr/local/go/src/runtime/asm_arm64.s:341 +0x70 fp=0x16f38af00 sp=0x16f38af00 pc=0x102b0d750

... # skip because it's too long
huandu commented 3 days ago

You should use selectBuilder instead of cond to build WHERE clause. In this package, you never need to call NewCond to create a *Cond. SelectBuilder/UpdateBuilder/DeleteBuilder can be used as a *Cond.

weeee9 commented 2 days ago

@huandu But the pacakge should handle the stack overflow error?