From c9e1879dc43085b35056f84bdc84196897bc11ee Mon Sep 17 00:00:00 2001
From: Bartek Wrona <wrona@syncad.com>
Date: Tue, 25 Mar 2025 21:27:24 +0100
Subject: [PATCH] String queries wrapped by text due to requirements of new
 SQLAlchemy

---
 .../haf_local_tools/__init__.py               | 13 +++++----
 .../haf_local_tools/db_adapter/db_adapter.py  | 12 ++++----
 .../haf_local_tools/system/haf/__init__.py    | 10 ++++---
 .../applications/test_application_broken.py   | 29 ++++++++++---------
 .../test_application_index_many.py            |  6 ++--
 .../test_application_index_one.py             |  6 ++--
 .../test_application_index_replay.py          |  3 +-
 .../test_application_invalid_index.py         |  3 +-
 .../test_two_applications_one_index.py        |  3 +-
 9 files changed, 49 insertions(+), 36 deletions(-)

diff --git a/tests/integration/haf-local-tools/haf_local_tools/__init__.py b/tests/integration/haf-local-tools/haf_local_tools/__init__.py
index 47e90f9c6..9276943f7 100644
--- a/tests/integration/haf-local-tools/haf_local_tools/__init__.py
+++ b/tests/integration/haf-local-tools/haf_local_tools/__init__.py
@@ -17,6 +17,7 @@ if TYPE_CHECKING:
     from sqlalchemy.engine.row import Row
     from sqlalchemy.orm.session import Session
 
+from sqlalchemy.sql import text
 
 BLOCKS_IN_FORK = 5
 BLOCKS_AFTER_FORK = 5
@@ -174,10 +175,10 @@ SQL_CREATE_UPDATE_HISTOGRAM_FUNCTION = """
 
 
 def create_app(session, application_context):
-    session.execute( "CREATE SCHEMA IF NOT EXISTS {}".format( application_context ) )
-    session.execute( "SELECT hive.app_create_context( '{0}', '{0}' )".format( application_context ) )
-    session.execute( SQL_CREATE_AND_REGISTER_HISTOGRAM_TABLE.format( application_context ) )
-    session.execute( SQL_CREATE_UPDATE_HISTOGRAM_FUNCTION.format( application_context ) )
+    session.execute( text("CREATE SCHEMA IF NOT EXISTS {}".format( application_context )) )
+    session.execute( text("SELECT hive.app_create_context( '{0}', '{0}' )".format( application_context )) )
+    session.execute( text(SQL_CREATE_AND_REGISTER_HISTOGRAM_TABLE.format( application_context )) )
+    session.execute( text(SQL_CREATE_UPDATE_HISTOGRAM_FUNCTION.format( application_context )) )
     session.commit()
 
 def wait_until_irreversible_without_new_block(session, irreversible_block, limit, interval):
@@ -222,12 +223,12 @@ def wait_until_irreversible(node_under_test, session):
 
 def query_col(session: Session, sql: str, **kwargs) -> list[Any]:
     """Perform a `SELECT n*1`"""
-    return [row[0] for row in session.execute(sql, params=kwargs).fetchall()]
+    return [row[0] for row in session.execute(text(sql), params=kwargs).fetchall()]
 
 
 def query_all(session: Session, sql: str, **kwargs) -> list[Row]:
     """Perform a `SELECT n*m`"""
-    return session.execute(sql, params=kwargs).fetchall()
+    return session.execute(text(sql), params=kwargs).fetchall()
 
 
 def wait_for_irreversible_in_database(
diff --git a/tests/integration/haf-local-tools/haf_local_tools/db_adapter/db_adapter.py b/tests/integration/haf-local-tools/haf_local_tools/db_adapter/db_adapter.py
index eca48016f..56a0d1015 100644
--- a/tests/integration/haf-local-tools/haf_local_tools/db_adapter/db_adapter.py
+++ b/tests/integration/haf-local-tools/haf_local_tools/db_adapter/db_adapter.py
@@ -2,6 +2,8 @@ from __future__ import annotations
 
 from typing import Any, TYPE_CHECKING, TypeAlias, Union
 
+from sqlalchemy.sql import text
+
 if TYPE_CHECKING:
     from sqlalchemy.engine.row import Row
     from sqlalchemy.orm.session import Session
@@ -14,24 +16,24 @@ class DbAdapter:
     @staticmethod
     def query_all(session: Session, sql: str, **kwargs) -> list[Row]:
         """Perform a `SELECT n*m`"""
-        return session.execute(sql, params=kwargs).all()
+        return session.execute(text(sql), params=kwargs).all()
 
     @staticmethod
     def query_col(session: Session, sql: str, **kwargs) -> ColumnType:
         """Perform a `SELECT n*1`"""
-        return [row[0] for row in session.execute(sql, params=kwargs).all()]
+        return [row[0] for row in session.execute(text(sql), params=kwargs).all()]
 
     @staticmethod
     def query_no_return(session: Session, sql: str, **kwargs) -> None:
         """Perform a query with no return"""
-        session.execute(sql, params=kwargs).close()
+        session.execute(text(sql), params=kwargs).close()
 
     @staticmethod
     def query_row(session: Session, sql: str, **kwargs) -> Row:
         """Perform a `SELECT 1*m`"""
-        return session.execute(sql, params=kwargs).first()
+        return session.execute(text(sql), params=kwargs).first()
 
     @staticmethod
     def query_one(session: Session, sql: str, **kwargs) -> ScalarType:
         """Perform a `SELECT 1*1`"""
-        return session.execute(sql, params=kwargs).scalar()
+        return session.execute(text(sql), params=kwargs).scalar()
diff --git a/tests/integration/haf-local-tools/haf_local_tools/system/haf/__init__.py b/tests/integration/haf-local-tools/haf_local_tools/system/haf/__init__.py
index 337b48156..ec98e618d 100644
--- a/tests/integration/haf-local-tools/haf_local_tools/system/haf/__init__.py
+++ b/tests/integration/haf-local-tools/haf_local_tools/system/haf/__init__.py
@@ -1,4 +1,6 @@
 from sqlalchemy.orm import Session
+from sqlalchemy.sql import text
+
 from typing import TYPE_CHECKING, Union
 
 import test_tools as tt
@@ -36,7 +38,7 @@ def assert_are_indexes_restored(haf_node: HafNode):
 
 
 def does_index_exist(session, namespace, table, indexname):
-    return session.execute("""
+    return session.execute(text("""
     SELECT 1
     FROM pg_index i
     JOIN pg_class idx ON i.indexrelid = idx.oid
@@ -45,7 +47,7 @@ def does_index_exist(session, namespace, table, indexname):
     WHERE n.nspname = :ns
     AND tbl.relname = :table
     AND idx.relname = :index
-    """, {'ns':namespace, 'table': table, 'index': indexname}).fetchone()
+    """), {'ns':namespace, 'table': table, 'index': indexname}).fetchone()
 
 
 def assert_index_exists(session, namespace, table, indexname):
@@ -58,7 +60,7 @@ def assert_index_does_not_exist(session, namespace, table, indexname):
 
 def wait_till_registered_indexes_created(haf_node, context):
     while True:
-        result = haf_node.session.execute("SELECT hive.check_if_registered_indexes_created(:ctx)", {'ctx': context}).scalar()
+        result = haf_node.session.execute(text("SELECT hive.check_if_registered_indexes_created(:ctx)"), {'ctx': context}).scalar()
         if result:
             break
         tt.logger.info("Indexes not yet created. Sleeping for 10 seconds...")
@@ -67,7 +69,7 @@ def wait_till_registered_indexes_created(haf_node, context):
 
 def register_index_dependency(haf_node, context, create_index_command):
     haf_node.session.execute(
-            "SELECT hive.register_index_dependency(:ctx, :cmd)", {'ctx': context, 'cmd': create_index_command})
+            text("SELECT hive.register_index_dependency(:ctx, :cmd)"), {'ctx': context, 'cmd': create_index_command})
 
 
 def assert_is_transaction_in_database(haf_node: HafNode, transaction:  Union[Transaction, TransactionId]):
diff --git a/tests/integration/system/applications/test_application_broken.py b/tests/integration/system/applications/test_application_broken.py
index 00d15d44c..680e253a1 100644
--- a/tests/integration/system/applications/test_application_broken.py
+++ b/tests/integration/system/applications/test_application_broken.py
@@ -1,4 +1,5 @@
 from sqlalchemy.orm.session import sessionmaker
+from sqlalchemy.sql import text
 
 import test_tools as tt
 
@@ -17,15 +18,15 @@ APPLICATION_CONTEXT = "application"
 
 def update_app_continuously(session, application_context, cycles):
     for i in range(cycles):
-        blocks_range = session.execute( "SELECT * FROM hive.app_next_block( '{}' )".format( application_context ) ).fetchone()
+        blocks_range = session.execute( text("SELECT * FROM hive.app_next_block( '{}' )".format( application_context )) ).fetchone()
         (first_block, last_block) = blocks_range
         if last_block is None:
             tt.logger.info( "next blocks_range was NULL\n" )
             continue
         tt.logger.info( "next blocks_range: {}\n".format( blocks_range ) )
-        session.execute( "SELECT public.update_histogram( {}, {} )".format( first_block, last_block ) )
+        session.execute( text("SELECT public.update_histogram( {}, {} )".format( first_block, last_block )) )
         session.commit()
-        ctx_stats = session.execute( "SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( application_context ) ).fetchone()
+        ctx_stats = session.execute( text("SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( application_context )) ).fetchone()
         tt.logger.info(f'ctx_stats-update-app: cbn {ctx_stats[0]} irr {ctx_stats[1]}')
 
 
@@ -59,25 +60,25 @@ def test_application_broken(prepared_networks_and_database_12_8_without_block_lo
     # system under test
     create_app(second_session, APPLICATION_CONTEXT)
 
-    blocks_range = session.execute( "SELECT * FROM hive.app_next_block( '{}' )".format( APPLICATION_CONTEXT ) ).fetchone()
+    blocks_range = session.execute( text("SELECT * FROM hive.app_next_block( '{}' )".format( APPLICATION_CONTEXT )) ).fetchone()
     (first_block, last_block) = blocks_range
     # Last event in `events_queue` == `NEW_IRREVERSIBLE` (before it was `NEW_BLOCK`) therefore first call `hive.app_next_block` returns {None, None}
     if first_block is None:
-        blocks_range = session.execute( "SELECT * FROM hive.app_next_block( '{}' )".format( APPLICATION_CONTEXT ) ).fetchone()
+        blocks_range = session.execute( text("SELECT * FROM hive.app_next_block( '{}' )".format( APPLICATION_CONTEXT )) ).fetchone()
         (first_block, last_block) = blocks_range
 
     tt.logger.info(f'first_block: {first_block}, last_block: {last_block}')
 
-    ctx_stats = session.execute( "SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT ) ).fetchone()
+    ctx_stats = session.execute( text("SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT )) ).fetchone()
     tt.logger.info(f'ctx_stats-before-detach: cbn {ctx_stats[0]} irr {ctx_stats[1]}')
 
-    session.execute( "SELECT hive.app_context_detach( '{}' )".format( APPLICATION_CONTEXT ) )
-    session.execute( "SELECT public.update_histogram( {}, {} )".format( first_block, CONTEXT_ATTACH_BLOCK ) )
-    session.execute( "SELECT hive.app_set_current_block_num( '{}', {} )".format( APPLICATION_CONTEXT, CONTEXT_ATTACH_BLOCK ) )
-    session.execute( "SELECT hive.app_context_attach( '{}' )".format( APPLICATION_CONTEXT ) )
+    session.execute( text("SELECT hive.app_context_detach( '{}' )".format( APPLICATION_CONTEXT )) )
+    session.execute( text("SELECT public.update_histogram( {}, {} )".format( first_block, CONTEXT_ATTACH_BLOCK )) )
+    session.execute( text("SELECT hive.app_set_current_block_num( '{}', {} )".format( APPLICATION_CONTEXT, CONTEXT_ATTACH_BLOCK )) )
+    session.execute( text("SELECT hive.app_context_attach( '{}' )".format( APPLICATION_CONTEXT )) )
     session.commit()
 
-    ctx_stats = session.execute( "SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT ) ).fetchone()
+    ctx_stats = session.execute( text("SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT )) ).fetchone()
     tt.logger.info(f'ctx_stats-after-attach: cbn {ctx_stats[0]} irr {ctx_stats[1]}')
 
     # THEN
@@ -85,7 +86,7 @@ def test_application_broken(prepared_networks_and_database_12_8_without_block_lo
     update_app_continuously(second_session, APPLICATION_CONTEXT, nr_cycles)
     wait_for_irreversible_progress(node_under_test, START_TEST_BLOCK)
 
-    ctx_stats = session.execute( "SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT ) ).fetchone()
+    ctx_stats = session.execute( text("SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT )) ).fetchone()
     tt.logger.info(f'ctx_stats-after-waiting: cbn {ctx_stats[0]} irr {ctx_stats[1]}')
 
     wait_for_irreversible_in_database(session, START_TEST_BLOCK+3)
@@ -107,13 +108,13 @@ def test_application_broken(prepared_networks_and_database_12_8_without_block_lo
     nr_cycles = 1
     update_app_continuously(second_session, APPLICATION_CONTEXT, nr_cycles)
 
-    ctx_stats = session.execute( "SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT ) ).fetchone()
+    ctx_stats = session.execute( text("SELECT current_block_num, irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT )) ).fetchone()
     tt.logger.info(f'ctx_stats-after-waiting-2: cbn {ctx_stats[0]} irr {ctx_stats[1]}')
 
     haf_irreversible = session.query(IrreversibleData).one()
     tt.logger.info(f'consistent_block {haf_irreversible.consistent_block}')
 
-    context_irreversible_block = session.execute( "SELECT irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT ) ).fetchone()[0]
+    context_irreversible_block = session.execute( text("SELECT irreversible_block FROM hafd.contexts WHERE NAME = '{}'".format( APPLICATION_CONTEXT )) ).fetchone()[0]
     tt.logger.info(f'context_irreversible_block {context_irreversible_block}')
 
     assert irreversible_block == haf_irreversible.consistent_block
diff --git a/tests/integration/system/applications/test_application_index_many.py b/tests/integration/system/applications/test_application_index_many.py
index 970d4e129..e194df03b 100644
--- a/tests/integration/system/applications/test_application_index_many.py
+++ b/tests/integration/system/applications/test_application_index_many.py
@@ -5,6 +5,8 @@ from haf_local_tools.haf_node.monolithic_workaround import apply_block_log_type_
 from haf_local_tools.system.haf import (connect_nodes, assert_index_exists, register_index_dependency)
 import time
 
+from sqlalchemy.sql import text
+
 def test_application_index_many(haf_node):
     tt.logger.info(f'Start test_application_index_many')
 
@@ -21,7 +23,7 @@ def test_application_index_many(haf_node):
     session = haf_node.session
     create_app(session, "application")
 
-    session.execute("CREATE EXTENSION IF NOT EXISTS btree_gin")
+    session.execute(text("CREATE EXTENSION IF NOT EXISTS btree_gin"))
 
     register_index_dependency(haf_node, 'application',
             r"CREATE INDEX IF NOT EXISTS hive_operations_vote_author_permlink_1 ON hafd.operations USING gin"
@@ -55,7 +57,7 @@ def test_application_index_many(haf_node):
 
     # THEN
     while True:
-        result = session.execute("SELECT hive.check_if_registered_indexes_created('application')").scalar()
+        result = session.execute(text("SELECT hive.check_if_registered_indexes_created('application')")).scalar()
         if result:
             break
         tt.logger.info("Indexes not yet created. Sleeping for 10 seconds...")
diff --git a/tests/integration/system/applications/test_application_index_one.py b/tests/integration/system/applications/test_application_index_one.py
index 04adae0d6..ebd1d35ed 100644
--- a/tests/integration/system/applications/test_application_index_one.py
+++ b/tests/integration/system/applications/test_application_index_one.py
@@ -5,6 +5,8 @@ from haf_local_tools.haf_node.monolithic_workaround import apply_block_log_type_
 from haf_local_tools.system.haf import (connect_nodes, assert_index_exists, register_index_dependency)
 import time
 
+from sqlalchemy.sql import text
+
 def test_application_index_one(haf_node):
     tt.logger.info(f'Start test_application_index_one')
 
@@ -21,7 +23,7 @@ def test_application_index_one(haf_node):
     session = haf_node.session
     create_app(session, "application")
 
-    session.execute("CREATE EXTENSION IF NOT EXISTS btree_gin")
+    session.execute(text("CREATE EXTENSION IF NOT EXISTS btree_gin"))
 
     register_index_dependency(haf_node, 'application',
             r"CREATE INDEX IF NOT EXISTS hive_operations_vote_author_permlink ON hafd.operations USING gin"
@@ -34,7 +36,7 @@ def test_application_index_one(haf_node):
 
     # THEN
     while True:
-        result = session.execute("SELECT hive.check_if_registered_indexes_created('application')").scalar()
+        result = session.execute(text("SELECT hive.check_if_registered_indexes_created('application')")).scalar()
         if result:
             break
         tt.logger.info("Indexes not yet created. Sleeping for 10 seconds...")
diff --git a/tests/integration/system/applications/test_application_index_replay.py b/tests/integration/system/applications/test_application_index_replay.py
index a75a691fd..997db1cdc 100644
--- a/tests/integration/system/applications/test_application_index_replay.py
+++ b/tests/integration/system/applications/test_application_index_replay.py
@@ -7,6 +7,7 @@ from haf_local_tools.system.haf import (connect_nodes, assert_index_does_not_exi
 
 import time
 
+from sqlalchemy.sql import text
 
 def test_application_index_replay(haf_node):
     tt.logger.info(f'Start test_application_index_replay')
@@ -27,7 +28,7 @@ def test_application_index_replay(haf_node):
     session = haf_node.session
     create_app(session, "application")
 
-    session.execute("CREATE EXTENSION IF NOT EXISTS btree_gin")
+    session.execute(text("CREATE EXTENSION IF NOT EXISTS btree_gin"))
 
     register_index_dependency(haf_node, 'application',
             r"CREATE INDEX IF NOT EXISTS hive_operations_vote_author_permlink ON hafd.operations USING gin"
diff --git a/tests/integration/system/applications/test_application_invalid_index.py b/tests/integration/system/applications/test_application_invalid_index.py
index 7b09579f7..d4b713bfb 100644
--- a/tests/integration/system/applications/test_application_invalid_index.py
+++ b/tests/integration/system/applications/test_application_invalid_index.py
@@ -6,6 +6,7 @@ from haf_local_tools import create_app
 from haf_local_tools.haf_node.monolithic_workaround import apply_block_log_type_to_monolithic_workaround
 from haf_local_tools.system.haf import (connect_nodes, assert_index_exists, wait_till_registered_indexes_created, register_index_dependency)
 
+from sqlalchemy.sql import text
 
 def test_application_invalid_index(haf_node):
     tt.logger.info(f'Start test_application_invalid_index')
@@ -23,7 +24,7 @@ def test_application_invalid_index(haf_node):
     session = haf_node.session
     create_app(session, "app")
 
-    session.execute("CREATE EXTENSION IF NOT EXISTS btree_gin")
+    session.execute(text("CREATE EXTENSION IF NOT EXISTS btree_gin"))
 
     # THEN
     with pytest.raises(sqlalchemy.exc.InternalError):
diff --git a/tests/integration/system/applications/test_two_applications_one_index.py b/tests/integration/system/applications/test_two_applications_one_index.py
index 0b5e5d1dc..0b570d00a 100644
--- a/tests/integration/system/applications/test_two_applications_one_index.py
+++ b/tests/integration/system/applications/test_two_applications_one_index.py
@@ -4,6 +4,7 @@ from haf_local_tools import create_app
 from haf_local_tools.haf_node.monolithic_workaround import apply_block_log_type_to_monolithic_workaround
 from haf_local_tools.system.haf import (connect_nodes, assert_index_exists, wait_till_registered_indexes_created, register_index_dependency)
 
+from sqlalchemy.sql import text
 
 def test_two_applications_one_index(haf_node):
     tt.logger.info(f'Start test_two_applications_one_index')
@@ -22,7 +23,7 @@ def test_two_applications_one_index(haf_node):
     create_app(session, "app_1")
     create_app(session, "app_2")
 
-    session.execute("CREATE EXTENSION IF NOT EXISTS btree_gin")
+    session.execute(text("CREATE EXTENSION IF NOT EXISTS btree_gin"))
 
     register_index_dependency(haf_node, 'app_1',
             r"CREATE INDEX IF NOT EXISTS hive_operations_author_permlink ON hafd.operations USING gin"
-- 
GitLab