sqldb/sqlc: add targeted invoice queries
The existing FilterInvoices query uses optional parameters via the
pattern `(col >= param OR param IS NULL)` for every filter. SQLite
cannot use indexes with this pattern because the OR prevents the query
planner from determining at plan time which rows satisfy the condition,
resulting in a full table scan regardless of the available indexes
(invoices_state_idx, invoices_settle_index_idx, and the primary-key
clustered index on id).
Additionally, the conditional ORDER BY:
ORDER BY CASE WHEN reverse = FALSE ... THEN id ELSE NULL END ASC,
CASE WHEN reverse = TRUE ... THEN id ELSE NULL END DESC
prevents the planner from using the index ordering and forces an
explicit sort.
Add five focused replacements, each with a plain sargable predicate and
a direct ORDER BY so the planner can always choose an index scan:
- FetchPendingInvoices: WHERE state IN (0, 3)
- FilterInvoicesBySettleIndex: WHERE settle_index >= $1
- FilterInvoicesByAddIndex: WHERE id >= $1
- FilterInvoicesForward: WHERE id >= $1 ... ORDER BY id ASC
- FilterInvoicesReverse: WHERE id <= $1 ... ORDER BY id DESC
FilterInvoicesForward and FilterInvoicesReverse accept non-nullable
timestamp parameters (created_after, created_before) so the planner
always sees plain range predicates on created_at. Callers supply
Go-side defaults when no date filter is needed, following the same
convention already used by the payments query.
FilterInvoices is kept in this commit so all existing call sites
continue to compile. It will be removed once all callers have been
migrated.
This commit is contained in:
3 files changed
+435
-10
No files matched your search
+337
-5
@@ -64,15 +64,74 @@ func (q *Queries) DeleteInvoice(ctx context.Context, arg DeleteInvoiceParams) (s
|
||||
)
|
||||
}
|
||||
|
||||
const fetchPendingInvoices = `-- name: FetchPendingInvoices :many
|
||||
SELECT
|
||||
invoices.id, invoices.hash, invoices.preimage, invoices.settle_index, invoices.settled_at, invoices.memo, invoices.amount_msat, invoices.cltv_delta, invoices.expiry, invoices.payment_addr, invoices.payment_request, invoices.payment_request_hash, invoices.state, invoices.amount_paid_msat, invoices.is_amp, invoices.is_hodl, invoices.is_keysend, invoices.created_at
|
||||
FROM invoices
|
||||
WHERE state IN (0, 3) -- 0 = ContractOpen, 3 = ContractAccepted
|
||||
ORDER BY id ASC
|
||||
LIMIT $2 OFFSET $1
|
||||
`
|
||||
|
||||
type FetchPendingInvoicesParams struct {
|
||||
NumOffset int32
|
||||
NumLimit int32
|
||||
}
|
||||
|
||||
// FetchPendingInvoices returns all invoices in a pending state (open or
|
||||
// accepted). The invoices_state_idx index on the state column makes this a
|
||||
// fast index scan rather than a full table scan.
|
||||
func (q *Queries) FetchPendingInvoices(ctx context.Context, arg FetchPendingInvoicesParams) ([]Invoice, error) {
|
||||
rows, err := q.db.QueryContext(ctx, fetchPendingInvoices, arg.NumOffset, arg.NumLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Invoice
|
||||
for rows.Next() {
|
||||
var i Invoice
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Hash,
|
||||
&i.Preimage,
|
||||
&i.SettleIndex,
|
||||
&i.SettledAt,
|
||||
&i.Memo,
|
||||
&i.AmountMsat,
|
||||
&i.CltvDelta,
|
||||
&i.Expiry,
|
||||
&i.PaymentAddr,
|
||||
&i.PaymentRequest,
|
||||
&i.PaymentRequestHash,
|
||||
&i.State,
|
||||
&i.AmountPaidMsat,
|
||||
&i.IsAmp,
|
||||
&i.IsHodl,
|
||||
&i.IsKeysend,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const filterInvoices = `-- name: FilterInvoices :many
|
||||
SELECT
|
||||
invoices.id, invoices.hash, invoices.preimage, invoices.settle_index, invoices.settled_at, invoices.memo, invoices.amount_msat, invoices.cltv_delta, invoices.expiry, invoices.payment_addr, invoices.payment_request, invoices.payment_request_hash, invoices.state, invoices.amount_paid_msat, invoices.is_amp, invoices.is_hodl, invoices.is_keysend, invoices.created_at
|
||||
FROM invoices
|
||||
WHERE (
|
||||
id >= $1 OR
|
||||
id >= $1 OR
|
||||
$1 IS NULL
|
||||
) AND (
|
||||
id <= $2 OR
|
||||
id <= $2 OR
|
||||
$2 IS NULL
|
||||
) AND (
|
||||
settle_index >= $3 OR
|
||||
@@ -81,18 +140,18 @@ WHERE (
|
||||
settle_index <= $4 OR
|
||||
$4 IS NULL
|
||||
) AND (
|
||||
state = $5 OR
|
||||
state = $5 OR
|
||||
$5 IS NULL
|
||||
) AND (
|
||||
created_at >= $6 OR
|
||||
$6 IS NULL
|
||||
) AND (
|
||||
created_at < $7 OR
|
||||
created_at < $7 OR
|
||||
$7 IS NULL
|
||||
) AND (
|
||||
CASE
|
||||
WHEN $8 = TRUE THEN (state = 0 OR state = 3)
|
||||
ELSE TRUE
|
||||
ELSE TRUE
|
||||
END
|
||||
)
|
||||
ORDER BY
|
||||
@@ -175,6 +234,279 @@ func (q *Queries) FilterInvoices(ctx context.Context, arg FilterInvoicesParams)
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const filterInvoicesByAddIndex = `-- name: FilterInvoicesByAddIndex :many
|
||||
SELECT
|
||||
invoices.id, invoices.hash, invoices.preimage, invoices.settle_index, invoices.settled_at, invoices.memo, invoices.amount_msat, invoices.cltv_delta, invoices.expiry, invoices.payment_addr, invoices.payment_request, invoices.payment_request_hash, invoices.state, invoices.amount_paid_msat, invoices.is_amp, invoices.is_hodl, invoices.is_keysend, invoices.created_at
|
||||
FROM invoices
|
||||
WHERE id >= $1
|
||||
ORDER BY id ASC
|
||||
LIMIT $3 OFFSET $2
|
||||
`
|
||||
|
||||
type FilterInvoicesByAddIndexParams struct {
|
||||
AddIndexGet int64
|
||||
NumOffset int32
|
||||
NumLimit int32
|
||||
}
|
||||
|
||||
// FilterInvoicesByAddIndex returns invoices whose add_index (primary key id)
|
||||
// is greater than or equal to the given value, ordered by id. Because id is
|
||||
// the primary key, this is always an efficient range scan on the clustered
|
||||
// index.
|
||||
func (q *Queries) FilterInvoicesByAddIndex(ctx context.Context, arg FilterInvoicesByAddIndexParams) ([]Invoice, error) {
|
||||
rows, err := q.db.QueryContext(ctx, filterInvoicesByAddIndex, arg.AddIndexGet, arg.NumOffset, arg.NumLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Invoice
|
||||
for rows.Next() {
|
||||
var i Invoice
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Hash,
|
||||
&i.Preimage,
|
||||
&i.SettleIndex,
|
||||
&i.SettledAt,
|
||||
&i.Memo,
|
||||
&i.AmountMsat,
|
||||
&i.CltvDelta,
|
||||
&i.Expiry,
|
||||
&i.PaymentAddr,
|
||||
&i.PaymentRequest,
|
||||
&i.PaymentRequestHash,
|
||||
&i.State,
|
||||
&i.AmountPaidMsat,
|
||||
&i.IsAmp,
|
||||
&i.IsHodl,
|
||||
&i.IsKeysend,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const filterInvoicesBySettleIndex = `-- name: FilterInvoicesBySettleIndex :many
|
||||
SELECT
|
||||
invoices.id, invoices.hash, invoices.preimage, invoices.settle_index, invoices.settled_at, invoices.memo, invoices.amount_msat, invoices.cltv_delta, invoices.expiry, invoices.payment_addr, invoices.payment_request, invoices.payment_request_hash, invoices.state, invoices.amount_paid_msat, invoices.is_amp, invoices.is_hodl, invoices.is_keysend, invoices.created_at
|
||||
FROM invoices
|
||||
WHERE settle_index >= $1
|
||||
ORDER BY id ASC
|
||||
LIMIT $3 OFFSET $2
|
||||
`
|
||||
|
||||
type FilterInvoicesBySettleIndexParams struct {
|
||||
SettleIndexGet sql.NullInt64
|
||||
NumOffset int32
|
||||
NumLimit int32
|
||||
}
|
||||
|
||||
// FilterInvoicesBySettleIndex returns settled invoices whose settle_index is
|
||||
// greater than or equal to the given value, ordered by id. The caller must
|
||||
// always supply a concrete lower bound so the invoices_settle_index_idx index
|
||||
// can be used.
|
||||
func (q *Queries) FilterInvoicesBySettleIndex(ctx context.Context, arg FilterInvoicesBySettleIndexParams) ([]Invoice, error) {
|
||||
rows, err := q.db.QueryContext(ctx, filterInvoicesBySettleIndex, arg.SettleIndexGet, arg.NumOffset, arg.NumLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Invoice
|
||||
for rows.Next() {
|
||||
var i Invoice
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Hash,
|
||||
&i.Preimage,
|
||||
&i.SettleIndex,
|
||||
&i.SettledAt,
|
||||
&i.Memo,
|
||||
&i.AmountMsat,
|
||||
&i.CltvDelta,
|
||||
&i.Expiry,
|
||||
&i.PaymentAddr,
|
||||
&i.PaymentRequest,
|
||||
&i.PaymentRequestHash,
|
||||
&i.State,
|
||||
&i.AmountPaidMsat,
|
||||
&i.IsAmp,
|
||||
&i.IsHodl,
|
||||
&i.IsKeysend,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const filterInvoicesForward = `-- name: FilterInvoicesForward :many
|
||||
SELECT
|
||||
invoices.id, invoices.hash, invoices.preimage, invoices.settle_index, invoices.settled_at, invoices.memo, invoices.amount_msat, invoices.cltv_delta, invoices.expiry, invoices.payment_addr, invoices.payment_request, invoices.payment_request_hash, invoices.state, invoices.amount_paid_msat, invoices.is_amp, invoices.is_hodl, invoices.is_keysend, invoices.created_at
|
||||
FROM invoices
|
||||
WHERE id >= $1
|
||||
AND (NOT $2 OR state IN (0, 3)) -- 0 = ContractOpen, 3 = ContractAccepted
|
||||
AND created_at >= $3
|
||||
AND created_at < $4
|
||||
ORDER BY id ASC
|
||||
LIMIT $6 OFFSET $5
|
||||
`
|
||||
|
||||
type FilterInvoicesForwardParams struct {
|
||||
AddIndexGet int64
|
||||
PendingOnly interface{}
|
||||
CreatedAfter time.Time
|
||||
CreatedBefore time.Time
|
||||
NumOffset int32
|
||||
NumLimit int32
|
||||
}
|
||||
|
||||
// FilterInvoicesForward returns invoices in ascending id order starting from
|
||||
// add_index_get. All parameters are non-nullable so the planner always sees
|
||||
// plain range predicates and can use the primary-key index. The caller is
|
||||
// responsible for supplying Go-side defaults when a filter is not needed:
|
||||
//
|
||||
// created_after → time.Unix(0, 0).UTC() (epoch – before any invoice)
|
||||
// created_before → time.Date(9999, …) (far future – no upper cap)
|
||||
// pending_only → false (include all states)
|
||||
func (q *Queries) FilterInvoicesForward(ctx context.Context, arg FilterInvoicesForwardParams) ([]Invoice, error) {
|
||||
rows, err := q.db.QueryContext(ctx, filterInvoicesForward,
|
||||
arg.AddIndexGet,
|
||||
arg.PendingOnly,
|
||||
arg.CreatedAfter,
|
||||
arg.CreatedBefore,
|
||||
arg.NumOffset,
|
||||
arg.NumLimit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Invoice
|
||||
for rows.Next() {
|
||||
var i Invoice
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Hash,
|
||||
&i.Preimage,
|
||||
&i.SettleIndex,
|
||||
&i.SettledAt,
|
||||
&i.Memo,
|
||||
&i.AmountMsat,
|
||||
&i.CltvDelta,
|
||||
&i.Expiry,
|
||||
&i.PaymentAddr,
|
||||
&i.PaymentRequest,
|
||||
&i.PaymentRequestHash,
|
||||
&i.State,
|
||||
&i.AmountPaidMsat,
|
||||
&i.IsAmp,
|
||||
&i.IsHodl,
|
||||
&i.IsKeysend,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const filterInvoicesReverse = `-- name: FilterInvoicesReverse :many
|
||||
SELECT
|
||||
invoices.id, invoices.hash, invoices.preimage, invoices.settle_index, invoices.settled_at, invoices.memo, invoices.amount_msat, invoices.cltv_delta, invoices.expiry, invoices.payment_addr, invoices.payment_request, invoices.payment_request_hash, invoices.state, invoices.amount_paid_msat, invoices.is_amp, invoices.is_hodl, invoices.is_keysend, invoices.created_at
|
||||
FROM invoices
|
||||
WHERE id <= $1
|
||||
AND (NOT $2 OR state IN (0, 3)) -- 0 = ContractOpen, 3 = ContractAccepted
|
||||
AND created_at >= $3
|
||||
AND created_at < $4
|
||||
ORDER BY id DESC
|
||||
LIMIT $6 OFFSET $5
|
||||
`
|
||||
|
||||
type FilterInvoicesReverseParams struct {
|
||||
AddIndexLet int64
|
||||
PendingOnly interface{}
|
||||
CreatedAfter time.Time
|
||||
CreatedBefore time.Time
|
||||
NumOffset int32
|
||||
NumLimit int32
|
||||
}
|
||||
|
||||
// FilterInvoicesReverse is the descending counterpart of FilterInvoicesForward.
|
||||
// It returns invoices in descending id order up to and including add_index_let.
|
||||
// See FilterInvoicesForward for the expected Go-side defaults.
|
||||
func (q *Queries) FilterInvoicesReverse(ctx context.Context, arg FilterInvoicesReverseParams) ([]Invoice, error) {
|
||||
rows, err := q.db.QueryContext(ctx, filterInvoicesReverse,
|
||||
arg.AddIndexLet,
|
||||
arg.PendingOnly,
|
||||
arg.CreatedAfter,
|
||||
arg.CreatedBefore,
|
||||
arg.NumOffset,
|
||||
arg.NumLimit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Invoice
|
||||
for rows.Next() {
|
||||
var i Invoice
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Hash,
|
||||
&i.Preimage,
|
||||
&i.SettleIndex,
|
||||
&i.SettledAt,
|
||||
&i.Memo,
|
||||
&i.AmountMsat,
|
||||
&i.CltvDelta,
|
||||
&i.Expiry,
|
||||
&i.PaymentAddr,
|
||||
&i.PaymentRequest,
|
||||
&i.PaymentRequestHash,
|
||||
&i.State,
|
||||
&i.AmountPaidMsat,
|
||||
&i.IsAmp,
|
||||
&i.IsHodl,
|
||||
&i.IsKeysend,
|
||||
&i.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getInvoice = `-- name: GetInvoice :many
|
||||
|
||||
SELECT i.id, i.hash, i.preimage, i.settle_index, i.settled_at, i.memo, i.amount_msat, i.cltv_delta, i.expiry, i.payment_addr, i.payment_request, i.payment_request_hash, i.state, i.amount_paid_msat, i.is_amp, i.is_hodl, i.is_keysend, i.created_at
|
||||
|
||||
@@ -31,8 +31,34 @@ type Querier interface {
|
||||
DeleteZombieChannel(ctx context.Context, arg DeleteZombieChannelParams) (sql.Result, error)
|
||||
FetchAMPSubInvoiceHTLCs(ctx context.Context, arg FetchAMPSubInvoiceHTLCsParams) ([]FetchAMPSubInvoiceHTLCsRow, error)
|
||||
FetchAMPSubInvoices(ctx context.Context, arg FetchAMPSubInvoicesParams) ([]AmpSubInvoice, error)
|
||||
// FetchPendingInvoices returns all invoices in a pending state (open or
|
||||
// accepted). The invoices_state_idx index on the state column makes this a
|
||||
// fast index scan rather than a full table scan.
|
||||
FetchPendingInvoices(ctx context.Context, arg FetchPendingInvoicesParams) ([]Invoice, error)
|
||||
FetchSettledAMPSubInvoices(ctx context.Context, arg FetchSettledAMPSubInvoicesParams) ([]FetchSettledAMPSubInvoicesRow, error)
|
||||
FilterInvoices(ctx context.Context, arg FilterInvoicesParams) ([]Invoice, error)
|
||||
// FilterInvoicesByAddIndex returns invoices whose add_index (primary key id)
|
||||
// is greater than or equal to the given value, ordered by id. Because id is
|
||||
// the primary key, this is always an efficient range scan on the clustered
|
||||
// index.
|
||||
FilterInvoicesByAddIndex(ctx context.Context, arg FilterInvoicesByAddIndexParams) ([]Invoice, error)
|
||||
// FilterInvoicesBySettleIndex returns settled invoices whose settle_index is
|
||||
// greater than or equal to the given value, ordered by id. The caller must
|
||||
// always supply a concrete lower bound so the invoices_settle_index_idx index
|
||||
// can be used.
|
||||
FilterInvoicesBySettleIndex(ctx context.Context, arg FilterInvoicesBySettleIndexParams) ([]Invoice, error)
|
||||
// FilterInvoicesForward returns invoices in ascending id order starting from
|
||||
// add_index_get. All parameters are non-nullable so the planner always sees
|
||||
// plain range predicates and can use the primary-key index. The caller is
|
||||
// responsible for supplying Go-side defaults when a filter is not needed:
|
||||
// created_after → time.Unix(0, 0).UTC() (epoch – before any invoice)
|
||||
// created_before → time.Date(9999, …) (far future – no upper cap)
|
||||
// pending_only → false (include all states)
|
||||
FilterInvoicesForward(ctx context.Context, arg FilterInvoicesForwardParams) ([]Invoice, error)
|
||||
// FilterInvoicesReverse is the descending counterpart of FilterInvoicesForward.
|
||||
// It returns invoices in descending id order up to and including add_index_let.
|
||||
// See FilterInvoicesForward for the expected Go-side defaults.
|
||||
FilterInvoicesReverse(ctx context.Context, arg FilterInvoicesReverseParams) ([]Invoice, error)
|
||||
GetAMPInvoiceID(ctx context.Context, setID []byte) (int64, error)
|
||||
GetChannelAndNodesBySCID(ctx context.Context, arg GetChannelAndNodesBySCIDParams) (GetChannelAndNodesBySCIDRow, error)
|
||||
GetChannelByOutpointWithPolicies(ctx context.Context, arg GetChannelByOutpointWithPoliciesParams) (GetChannelByOutpointWithPoliciesRow, error)
|
||||
|
||||
@@ -65,15 +65,82 @@ FROM invoices i
|
||||
INNER JOIN amp_sub_invoices a
|
||||
ON i.id = a.invoice_id AND a.set_id = $1;
|
||||
|
||||
-- name: FetchPendingInvoices :many
|
||||
-- FetchPendingInvoices returns all invoices in a pending state (open or
|
||||
-- accepted). The invoices_state_idx index on the state column makes this a
|
||||
-- fast index scan rather than a full table scan.
|
||||
SELECT
|
||||
invoices.*
|
||||
FROM invoices
|
||||
WHERE state IN (0, 3) -- 0 = ContractOpen, 3 = ContractAccepted
|
||||
ORDER BY id ASC
|
||||
LIMIT @num_limit OFFSET @num_offset;
|
||||
|
||||
-- name: FilterInvoicesBySettleIndex :many
|
||||
-- FilterInvoicesBySettleIndex returns settled invoices whose settle_index is
|
||||
-- greater than or equal to the given value, ordered by id. The caller must
|
||||
-- always supply a concrete lower bound so the invoices_settle_index_idx index
|
||||
-- can be used.
|
||||
SELECT
|
||||
invoices.*
|
||||
FROM invoices
|
||||
WHERE settle_index >= @settle_index_get
|
||||
ORDER BY id ASC
|
||||
LIMIT @num_limit OFFSET @num_offset;
|
||||
|
||||
-- name: FilterInvoicesByAddIndex :many
|
||||
-- FilterInvoicesByAddIndex returns invoices whose add_index (primary key id)
|
||||
-- is greater than or equal to the given value, ordered by id. Because id is
|
||||
-- the primary key, this is always an efficient range scan on the clustered
|
||||
-- index.
|
||||
SELECT
|
||||
invoices.*
|
||||
FROM invoices
|
||||
WHERE id >= @add_index_get
|
||||
ORDER BY id ASC
|
||||
LIMIT @num_limit OFFSET @num_offset;
|
||||
|
||||
-- name: FilterInvoicesForward :many
|
||||
-- FilterInvoicesForward returns invoices in ascending id order starting from
|
||||
-- add_index_get. All parameters are non-nullable so the planner always sees
|
||||
-- plain range predicates and can use the primary-key index. The caller is
|
||||
-- responsible for supplying Go-side defaults when a filter is not needed:
|
||||
-- created_after → time.Unix(0, 0).UTC() (epoch – before any invoice)
|
||||
-- created_before → time.Date(9999, …) (far future – no upper cap)
|
||||
-- pending_only → false (include all states)
|
||||
SELECT
|
||||
invoices.*
|
||||
FROM invoices
|
||||
WHERE id >= @add_index_get
|
||||
AND (NOT @pending_only OR state IN (0, 3)) -- 0 = ContractOpen, 3 = ContractAccepted
|
||||
AND created_at >= @created_after
|
||||
AND created_at < @created_before
|
||||
ORDER BY id ASC
|
||||
LIMIT @num_limit OFFSET @num_offset;
|
||||
|
||||
-- name: FilterInvoicesReverse :many
|
||||
-- FilterInvoicesReverse is the descending counterpart of FilterInvoicesForward.
|
||||
-- It returns invoices in descending id order up to and including add_index_let.
|
||||
-- See FilterInvoicesForward for the expected Go-side defaults.
|
||||
SELECT
|
||||
invoices.*
|
||||
FROM invoices
|
||||
WHERE id <= @add_index_let
|
||||
AND (NOT @pending_only OR state IN (0, 3)) -- 0 = ContractOpen, 3 = ContractAccepted
|
||||
AND created_at >= @created_after
|
||||
AND created_at < @created_before
|
||||
ORDER BY id DESC
|
||||
LIMIT @num_limit OFFSET @num_offset;
|
||||
|
||||
-- name: FilterInvoices :many
|
||||
SELECT
|
||||
invoices.*
|
||||
FROM invoices
|
||||
WHERE (
|
||||
id >= sqlc.narg('add_index_get') OR
|
||||
id >= sqlc.narg('add_index_get') OR
|
||||
sqlc.narg('add_index_get') IS NULL
|
||||
) AND (
|
||||
id <= sqlc.narg('add_index_let') OR
|
||||
id <= sqlc.narg('add_index_let') OR
|
||||
sqlc.narg('add_index_let') IS NULL
|
||||
) AND (
|
||||
settle_index >= sqlc.narg('settle_index_get') OR
|
||||
@@ -82,18 +149,18 @@ WHERE (
|
||||
settle_index <= sqlc.narg('settle_index_let') OR
|
||||
sqlc.narg('settle_index_let') IS NULL
|
||||
) AND (
|
||||
state = sqlc.narg('state') OR
|
||||
state = sqlc.narg('state') OR
|
||||
sqlc.narg('state') IS NULL
|
||||
) AND (
|
||||
created_at >= sqlc.narg('created_after') OR
|
||||
sqlc.narg('created_after') IS NULL
|
||||
) AND (
|
||||
created_at < sqlc.narg('created_before') OR
|
||||
created_at < sqlc.narg('created_before') OR
|
||||
sqlc.narg('created_before') IS NULL
|
||||
) AND (
|
||||
CASE
|
||||
WHEN sqlc.narg('pending_only') = TRUE THEN (state = 0 OR state = 3)
|
||||
ELSE TRUE
|
||||
ELSE TRUE
|
||||
END
|
||||
)
|
||||
ORDER BY
|
||||
|
||||
Reference in new issue
Block a user