CREATE TABLE landing (n Int64) engine=MergeTree order by n;
CREATE TABLE target  (n Int64) engine=MergeTree order by n;
CREATE MATERIALIZED VIEW landing_to_target TO target AS
    SELECT n + throwIf(n == 3333)
    FROM landing;

INSERT INTO landing SELECT * FROM numbers(10000); -- { serverError 395 }
SELECT 'no_transaction_landing', count() FROM landing;
SELECT 'no_transaction_target', count() FROM target;

TRUNCATE TABLE landing;
TRUNCATE TABLE target;


BEGIN TRANSACTION;
INSERT INTO landing SELECT * FROM numbers(10000); -- { serverError 395 }
ROLLBACK;
SELECT 'after_transaction_landing', count() FROM landing;
SELECT 'after_transaction_target', count() FROM target;

-- Same but using implicit_transaction
INSERT INTO landing SETTINGS implicit_transaction=True SELECT * FROM numbers(10000); -- { serverError 395 }
SELECT 'after_implicit_txn_in_query_settings_landing', count() FROM landing;
SELECT 'after_implicit_txn_in_query_settings_target', count() FROM target;

-- Same but using implicit_transaction in a session
SET implicit_transaction=True;
INSERT INTO landing SELECT * FROM numbers(10000); -- { serverError 395 }
SET implicit_transaction=False;
SELECT 'after_implicit_txn_in_session_landing', count() FROM landing;
SELECT 'after_implicit_txn_in_session_target', count() FROM target;

-- Reading from incompatible sources with implicit_transaction works the same way as with normal transactions:
-- Currently reading from system tables inside a transaction is Not implemented:
SELECT name, value, changed FROM system.settings where name = 'implicit_transaction' SETTINGS implicit_transaction=True; -- { serverError 48 }


-- Verify that you don't have to manually close transactions with implicit_transaction
SET implicit_transaction=True;
SELECT throwIf(number == 0) FROM numbers(100); -- { serverError 395 }
SELECT throwIf(number == 0) FROM numbers(100); -- { serverError 395 }
SELECT throwIf(number == 0) FROM numbers(100); -- { serverError 395 }
SELECT throwIf(number == 0) FROM numbers(100); -- { serverError 395 }
SET implicit_transaction=False;

-- implicit_transaction is ignored when inside a transaction (no recursive transaction error)
BEGIN TRANSACTION;
SELECT 'inside_txn_and_implicit', 1 SETTINGS implicit_transaction=True;
SELECT throwIf(number == 0) FROM numbers(100) SETTINGS implicit_transaction=True; -- { serverError 395 }
ROLLBACK;

SELECT 'inside_txn_and_implicit', 1 SETTINGS implicit_transaction=True;

-- You can work with transactions even if `implicit_transaction=True` is set
SET implicit_transaction=True;
BEGIN TRANSACTION;
INSERT INTO target SELECT * FROM numbers(10000);
SELECT 'in_transaction', count() FROM target;
ROLLBACK;
SELECT 'out_transaction', count() FROM target;
SET implicit_transaction=False;


-- Verify that the transaction_id column is populated correctly
SELECT 'Looking_at_transaction_id_True' FORMAT Null SETTINGS implicit_transaction=1;
-- Verify that the transaction_id column is NOT populated without transaction
SELECT 'Looking_at_transaction_id_False' FORMAT Null SETTINGS implicit_transaction=0;
SYSTEM FLUSH LOGS;

SELECT
    'implicit_True',
    count() as all,
    transaction_id = (0,0,'00000000-0000-0000-0000-000000000000') as is_empty
FROM system.query_log
WHERE
    current_database = currentDatabase() AND
    event_date >= yesterday() AND
    query LIKE '-- Verify that the transaction_id column is populated correctly%'
GROUP BY transaction_id
FORMAT JSONEachRow;

SELECT
    'implicit_False',
    count() as all,
    transaction_id = (0,0,'00000000-0000-0000-0000-000000000000') as is_empty
FROM system.query_log
WHERE
    current_database = currentDatabase() AND
    event_date >= yesterday() AND
    query LIKE '-- Verify that the transaction_id column is NOT populated without transaction%'
GROUP BY transaction_id
FORMAT JSONEachRow;