From 20654ebd49f5e98b15cd94a130cf1fda21ade2a2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 30 Jan 2023 16:54:18 +1030 Subject: [PATCH] plugins/sql: pay attention to `deprecated` in schema. For now, we ignore every deprecated field, but put in the logic so that future deprecations will work as expected. Signed-off-by: Rusty Russell --- plugins/sql.c | 30 +++++++++++++++++++++++++++++- tests/test_plugin.py | 27 +++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/plugins/sql.c b/plugins/sql.c index 00d5a98fe..7d604dcae 100644 --- a/plugins/sql.c +++ b/plugins/sql.c @@ -1138,6 +1138,27 @@ static void add_table_singleton(struct table_desc *td, tal_arr_expand(&td->columns, col); } +static bool is_deprecated(const jsmntok_t *deprecated_tok) +{ + const char *deprstr; + + if (!deprecated_tok) + return false; + + /* If deprecated APIs are globally disabled, we don't want them! */ + if (!deprecated_apis) + return true; + + /* If it was deprecated before our release, we don't want it; older ones + * were simply 'deprecated: true' */ + deprstr = json_strdup(tmpctx, schemas, deprecated_tok); + assert(strstarts(deprstr, "v")); + if (streq(deprstr, "v0.12.0") || streq(deprstr, "v23.02")) + return true; + + return false; +} + static void add_table_properties(struct table_desc *td, const jsmntok_t *properties) { @@ -1145,7 +1166,7 @@ static void add_table_properties(struct table_desc *td, size_t i; json_for_each_obj(i, t, properties) { - const jsmntok_t *type; + const jsmntok_t *type, *deprecated_tok; struct column col; if (ignore_column(td, t)) @@ -1155,6 +1176,13 @@ static void add_table_properties(struct table_desc *td, * another branch with actual types, so ignore this */ if (!type) continue; + + /* Depends on when it was deprecated, and whether deprecations + * are enabled! */ + deprecated_tok = json_get_member(schemas, t+1, "deprecated"); + if (is_deprecated(deprecated_tok)) + continue; + if (json_tok_streq(schemas, type, "array")) { const jsmntok_t *items; diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 484db96a0..237771fbc 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -3539,10 +3539,6 @@ def test_sql(node_factory, bitcoind): 'type': 'string'}, {'name': 'closer', 'type': 'string'}, - {'name': 'funding_local_msat', - 'type': 'msat'}, - {'name': 'funding_remote_msat', - 'type': 'msat'}, {'name': 'funding_pushed_msat', 'type': 'msat'}, {'name': 'funding_local_funds_msat', @@ -3787,3 +3783,26 @@ def test_sql(node_factory, bitcoind): wait_for(lambda: len(l3.rpc.listchannels()['channels']) == 2) assert len(l3.rpc.sql("SELECT * FROM channels;")['rows']) == 2 l3.daemon.wait_for_log("Deleting channel: {}".format(scid)) + + # No deprecated fields! + with pytest.raises(RpcError, match='query failed with no such column: funding_local_msat'): + l2.rpc.sql("SELECT funding_local_msat FROM peerchannels;") + + with pytest.raises(RpcError, match='query failed with no such column: funding_remote_msat'): + l2.rpc.sql("SELECT funding_remote_msat FROM peerchannels;") + + with pytest.raises(RpcError, match='query failed with no such table: peers_channels'): + l2.rpc.sql("SELECT * FROM peers_channels;") + + +def test_sql_deprecated(node_factory, bitcoind): + # deprecated-apis breaks schemas... + l1 = node_factory.get_node(start=False, options={'allow-deprecated-apis': True}) + l1.rpc.check_request_schemas = False + l1.start() + + # FIXME: we have no fields which have been deprecated since sql plugin was + # introduced. When we do, add them here! (I manually tested a fake one) + + # ret = l1.rpc.sql("SELECT funding_local_msat, funding_remote_msat FROM peerchannels;") + # assert ret == {'rows': []}