From ceb4ccac6b8f679293862b823f71102a5bf02271 Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Tue, 4 Nov 2025 12:42:30 +0100 Subject: [PATCH 1/4] Some db are stricter with casting --- wallet/db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wallet/db.c b/wallet/db.c index 6057952dd9c1..2e4e3d2adfea 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -244,10 +244,10 @@ static struct migration dbmigrations[] = { {SQL("UPDATE invoices SET pay_index=id WHERE state=1;"), NULL}, /* only paid invoice */ /* Create next_pay_index variable (highest pay_index). */ - {SQL("INSERT INTO vars(name, val)" + {SQL("INSERT INTO vars(name, val)" " VALUES('next_pay_index', " - " COALESCE((SELECT MAX(pay_index) FROM invoices WHERE state=1), 0) " - "+ 1" + " CAST(COALESCE((SELECT MAX(pay_index) FROM invoices WHERE state=1), 0) " + "+ 1 AS TEXT)" " );"), NULL}, /* Create first_block field; initialize from channel id if any. From b619ab2c14eea6e14b90505f80cd1e1b35a32b75 Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Tue, 4 Nov 2025 15:12:38 +0100 Subject: [PATCH 2/4] replace _ROWID_ with standard SQL --- wallet/db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallet/db.c b/wallet/db.c index 2e4e3d2adfea..90ee463310cf 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -943,7 +943,7 @@ static struct migration dbmigrations[] = { " in_channel_scid" ", COALESCE(" " (SELECT channel_htlc_id FROM channel_htlcs WHERE id = forwarded_payments.in_htlc_id)," - " -_ROWID_" + " -row_number() OVER ()" " )" ", out_channel_scid" ", (SELECT channel_htlc_id FROM channel_htlcs WHERE id = forwarded_payments.out_htlc_id)" From b90fcd47da58378948189c95d52322415b3577d8 Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Tue, 4 Nov 2025 15:35:04 +0100 Subject: [PATCH 3/4] support cockroach db 64 bits integer --- db/db_postgres.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/db/db_postgres.c b/db/db_postgres.c index ae9785c6da85..86decacc0440 100644 --- a/db/db_postgres.c +++ b/db/db_postgres.c @@ -183,16 +183,23 @@ static u64 db_postgres_column_u64(struct db_stmt *stmt, int col) static s64 db_postgres_column_int(struct db_stmt *stmt, int col) { PGresult *res = (PGresult*)stmt->inner_stmt; - be32 bin; - size_t expected = sizeof(bin), actual = PQgetlength(res, stmt->row, col); - - if (expected != actual) - db_fatal(stmt->db, - "s32 field doesn't match size: expected %zu, actual %zu\n", - expected, actual); + size_t actual = PQgetlength(res, stmt->row, col); + + /* CockroachDB returns 8 bytes for INTEGER, PostgreSQL returns 4 */ + if (actual == 4) { + be32 bin; + memcpy(&bin, PQgetvalue(res, stmt->row, col), sizeof(bin)); + return be32_to_cpu(bin); + } else if (actual == 8) { + be64 bin; + memcpy(&bin, PQgetvalue(res, stmt->row, col), sizeof(bin)); + return be64_to_cpu(bin); + } - memcpy(&bin, PQgetvalue(res, stmt->row, col), sizeof(bin)); - return be32_to_cpu(bin); + db_fatal(stmt->db, + "integer field size unexpected: expected 4 or 8, actual %zu\n", + actual); + return 0; /* Never reached, but silences compiler warning */ } static size_t db_postgres_column_bytes(struct db_stmt *stmt, int col) From d584cb92dbffb849c26f5e2736535fa71328c5ea Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Fri, 7 Nov 2025 08:29:42 +0100 Subject: [PATCH 4/4] use OID to determine int column type --- db/db_postgres.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/db/db_postgres.c b/db/db_postgres.c index 86decacc0440..3b8a9094ce8d 100644 --- a/db/db_postgres.c +++ b/db/db_postgres.c @@ -182,24 +182,34 @@ static u64 db_postgres_column_u64(struct db_stmt *stmt, int col) static s64 db_postgres_column_int(struct db_stmt *stmt, int col) { - PGresult *res = (PGresult*)stmt->inner_stmt; - size_t actual = PQgetlength(res, stmt->row, col); - - /* CockroachDB returns 8 bytes for INTEGER, PostgreSQL returns 4 */ - if (actual == 4) { - be32 bin; - memcpy(&bin, PQgetvalue(res, stmt->row, col), sizeof(bin)); - return be32_to_cpu(bin); - } else if (actual == 8) { - be64 bin; - memcpy(&bin, PQgetvalue(res, stmt->row, col), sizeof(bin)); - return be64_to_cpu(bin); - } - - db_fatal(stmt->db, - "integer field size unexpected: expected 4 or 8, actual %zu\n", - actual); - return 0; /* Never reached, but silences compiler warning */ + PGresult *res = (PGresult*)stmt->inner_stmt; + Oid col_type = PQftype(res, col); // Get the column's type OID + + if (col_type == INT4OID) { + /* This is a 32-bit integer (PG INT or CRDB INT4) */ + if (PQgetlength(res, stmt->row, col) != 4) { + /* This check is now for safety/correctness */ + db_fatal(stmt->db, "INT4 field size not 4 bytes\n"); + } + be32 bin; + memcpy(&bin, PQgetvalue(res, stmt->row, col), sizeof(bin)); + return (s64)be32_to_cpu(bin); // Cast to s64 for return + } + else if (col_type == INT8OID) { + /* This is a 64-bit integer (PG BIGINT or CRDB INT) */ + if (PQgetlength(res, stmt->row, col) != 8) { + db_fatal(stmt->db, "INT8 field size not 8 bytes\n"); + } + be64 bin; + memcpy(&bin, PQgetvalue(res, stmt->row, col), sizeof(bin)); + return be64_to_cpu(bin); + } + + /* This function was called on an unsupported column type */ + db_fatal(stmt->db, + "integer field type unexpected: expected INT4 (23) or INT8 (20), actual %u\n", + col_type); + return 0; } static size_t db_postgres_column_bytes(struct db_stmt *stmt, int col)