sqldb: demonstrate the use of ExecutePagedQuery

Here, a new query (GetChannelsByOutpoints) is added which makes use of
the /*SLICE:outpoints*/ directive & added workaround. This is then used
in a test to demonstrate how the ExecutePagedQuery helper can be used to
wrap a query like this such that calls are done in pages.

The query that has been added will also be used by live code paths in an
upcoming commit.
This commit is contained in:
Elle Mouton committed 2025-07-22 17:16:38 +02:00
1 parent 006905d57f
commit f0d2d1fd0a
6 files changed
+175

No files matched your search

+79
View File
@@ -1,3 +1,5 @@
//go:build test_db_postgres || test_db_sqlite
package sqldb
import (
@@ -6,6 +8,7 @@ import (
"fmt"
"testing"
"github.com/lightningnetwork/lnd/sqldb/sqlc"
"github.com/stretchr/testify/require"
)
@@ -234,3 +237,79 @@ func TestExecutePagedQuery(t *testing.T) {
"starting at 2: second page failed")
})
}
// TestSQLSliceQueries tests ExecutePageQuery helper by first showing that a
// query the /*SLICE:<field_name>*/ directive has a maximum number of
// parameters it can handle, and then showing that the paginated version which
// uses ExecutePagedQuery instead of a raw query can handle more parameters by
// executing the query in pages.
func TestSQLSliceQueries(t *testing.T) {
t.Parallel()
ctx := context.Background()
db := NewTestDB(t)
// Increase the number of query strings by an order of magnitude each
// iteration until we hit the limit of the backing DB.
//
// NOTE: from testing, the following limits have been noted:
// - for Postgres, the limit is 65535 parameters.
// - for SQLite, the limit is 32766 parameters.
x := 10
var queryParams []string
for {
for len(queryParams) < x {
queryParams = append(
queryParams,
fmt.Sprintf("%d", len(queryParams)),
)
}
_, err := db.GetChannelsByOutpoints(ctx, queryParams)
if err != nil {
if isSQLite {
require.ErrorContains(
t, err, "SQL logic error: too many "+
"SQL variables",
)
} else {
require.ErrorContains(
t, err, "extended protocol limited "+
"to 65535 parameters",
)
}
break
}
x *= 10
// Just to make sure that the test doesn't carry on too long,
// we assert that we don't exceed a reasonable limit.
require.LessOrEqual(t, x, 100000)
}
// Now that we have found the limit that the raw query can handle, we
// switch to the wrapped version which will perform the query in pages
// so that the limit is not hit. We use the same number of query params
// that caused the error above.
queryWrapper := func(ctx context.Context,
pageOutpoints []string) ([]sqlc.GetChannelsByOutpointsRow,
error) {
return db.GetChannelsByOutpoints(ctx, pageOutpoints)
}
err := ExecutePagedQuery(
ctx,
DefaultPagedQueryConfig(),
queryParams,
func(s string) string {
return s
},
queryWrapper,
func(context.Context, sqlc.GetChannelsByOutpointsRow) error {
return nil
},
)
require.NoError(t, err)
}