14 Commits
Author SHA1 Message Date
ziggie e751d96c13 sqldb: remove unused GetInvoice query 2026-03-04 13:04:26 +01:00
ziggie e2dfd8f034 invoices: add TODO to change the return type of the query 2026-03-04 13:04:26 +01:00
ziggie 0ca69e6f57 invoices/sql: replace catch-all GetInvoice with indexed lookups
The GetInvoice query used an OR IS NULL pattern for each filter
parameter:

  WHERE (i.hash = $1 OR $1 IS NULL)
    AND (i.payment_addr = $2 OR $2 IS NULL)

SQLite's query planner decides on an execution plan at prepare time,
before seeing any parameter values. Because either condition can be
trivially true when its parameter is NULL, the planner conservatively
falls back to a full table scan rather than using the unique indexes on
hash and payment_addr. This caused every invoice lookup and update on
the hot path (HTLC settlement) to scan the entire invoices table.

Replace the single catch-all query with three dedicated queries, each
using a direct equality on a uniquely constrained column:

- GetInvoiceByHash:  WHERE hash = $1
- GetInvoiceByAddr:  WHERE payment_addr = $1  (new, covers AMP path)
- GetInvoiceBySetID: existing, unchanged

Update getInvoiceByRef to route to the appropriate query based on which
fields are present in the InvoiceRef. When both hash and payment address
are provided, we look up by hash and then verify the returned invoice's
payment address matches.

GetInvoice is now unused and removed from the SQLInvoiceQueries
interface.
2026-03-04 13:04:26 +01:00
ziggie 9becdfa8a3 sqldb/sqlc: remove deprecated FilterInvoices query
All call sites have been migrated to the targeted replacement queries
in the previous commit. Remove FilterInvoices and its associated
params struct from the SQL source and regenerate.
2026-02-21 16:58:31 +01:00
ziggie 866efbd7fb 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.
2026-02-21 16:09:03 +01:00
Andras Banki-Horvath 94e2724a34 sqldb+invoices: Optimize invoice fetching when the reference is only a hash
The current sqlc GetInvoice query experiences incremental slowdowns during
the migration of large invoice databases, primarily due to its complex
predicate set. For this specific use case, a streamlined GetInvoiceByHash
function provides a more efficient solution, maintaining near-constant
lookup times even with extensive table sizes.
2025-01-23 09:11:01 +01:00
Andras Banki-Horvath d65b630568 sqldb: remove unused preimage query parameter 2025-01-23 09:11:00 +01:00
Andras Banki-Horvath b7d743929d sqldb: add a temporary index to store KV invoice hash to ID mapping 2025-01-23 09:11:00 +01:00
Andras Banki-Horvath 3820497d7f sqldb: set settled_at and settle_index on invocie insertion is set
Previously we intentially did not set settled_at and settle_index when
inserting a new invoice as those fields are set when we settle an
invoice through the usual invoice update. As migration requires that we
set these nullable fields, we can safely add them.
2025-01-23 09:11:00 +01:00
Andras Banki-Horvath 06d4267a76 sqldb: fix end date filter when querying invoices
Previously, the SQL implementation of the invoice query simply
converted the start and end timestamps to time and used them
in SQL queries to check for inclusivity. However, this logic
failed when the start and end timestamps were equal.

This commit addresses and corrects this issue.
2024-09-03 19:40:47 +02:00
Andras Banki-Horvath b57910ee3a sqldb+invoices: synchronize SQL invoice updater behavior with KV version
Previously SQL invoice updater ignored the set ID hint when updating an
AMP invoice resulting in update subscriptions returning all of the AMP
state as well as all AMP HTLCs. This commit synchornizes behavior with
the KV implementation such that we now only return relevant AMP state
and HTLCs when updating an AMP invoice.
2024-09-03 19:40:46 +02:00
Andras Banki-Horvath 043e4aff01 sqldb+invoices: fix ordering bug in FilterInvoices
Previously if the `reverse` named arg was unset (value of NULL), then
SQL would order by NULL instead of ID causing undifined ordering of the
returned rows. To fix that we check for NULL and also make sure to set
the `reverse` arg in the code explicitly as it in the generated code it
is an `interface{}` instead of `bool`.
2024-04-11 15:04:04 +02:00
Andras Banki-Horvath 6a360fb2e2 sqldb: simplify and fixup the existing invoice store schema and queries
This commit attempts to fix some issues with the invoice store's schema that we
couldn't foresee before the implementation was finished. This is safe as the
schema has not been instantiated yet outside of unit tests. Furthermore the
commit updates invoice store SQL queries according to fixes in the schema as
well as to prepare the higher level implementation in the upcoming commits.
2024-03-01 10:08:07 +01:00
positiveblue 7aa2f390fe sqldb: add invoice queries
Set of queries to deal with invoices. A couple of things to take into
account:

    - Because the queries are not rewritten at runtime, we cannot have a
      generic `INSERT` with different tuples.
    - Because the queries are not rewritten at runtime, we cannot build
      one query with only the filters that matter for that queries. The
      two options are a combinatorial approach (a new query for every
      permutation) or a generic query using the pattern

          ```
            SELECT *
            FROM table
            WHERE (
                -- Can be read as:
                -- Match the filter 1 value if filter_1 != nil
                column_1 >= sqlc.narg('filter_1') OR
                sqlc.narg('filter_1') IS NULL
            ) AND (
                column_2 >= sqlc.narg('filter_2') OR
                sqlc.narg('filter_2') IS NULL
            ) ...
          ```
2023-07-10 17:53:29 -07:00