-- ============================================================================
-- NESTED_STATEMENTS Feature - Comprehensive Test Suite
-- ============================================================================
-- This script tests the NESTED_STATEMENTS feature and demonstrates
-- how nesting levels reflect the actual PostgreSQL executor call stack.
--
-- KEY INSIGHT: Nesting levels depend on HOW a function is called:
--   PERFORM func() / SELECT func() INTO var → creates new executor level
--   result := func()                        → same executor level as caller
-- ============================================================================

\echo '============================================================================'
\echo 'NESTED_STATEMENTS Feature - Comprehensive Test Suite'
\echo '============================================================================'
\echo ''
\echo 'This test suite demonstrates:'
\echo '  1. Validation (NESTED_STATEMENTS requires ANALYZE)'
\echo '  2. Simple PL/pgSQL function (all level 1)'
\echo '  3. PERFORM pattern (creates deeper nesting levels)'
\echo '  4. Expression assignment pattern (stays at same level)'
\echo '  5. Comparison: PERFORM vs expression assignment'
\echo '  6. SQL function nesting (true SQL nesting)'
\echo '  7. Three-level chain with PERFORM'
\echo '  8. Recursive function (increasing levels)'
\echo '  9. Exception handling blocks'
\echo '  10. No nested statements (plain query)'
\echo '  11. Trigger-fired nested statements'
\echo '  12. Combined with VERBOSE and BUFFERS options'
\echo '  13. Statement numbering = completion order (triggers demo)'
\echo '  14. BEGIN/ROLLBACK safety pattern'
\echo ''

-- ============================================================================
-- Setup: Create shared test table
-- ============================================================================
CREATE TABLE products (id INT, name TEXT, price NUMERIC, category TEXT);
INSERT INTO products VALUES
    (1, 'Laptop', 999, 'Electronics'),
    (2, 'Mouse', 29, 'Electronics'),
    (3, 'Book', 19, 'Books');

-- ============================================================================
-- TEST 1: Validation
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 1: Validation - NESTED_STATEMENTS requires ANALYZE'
\echo '============================================================================'
\echo ''
\echo 'Expected: ERROR message'
\echo ''

EXPLAIN (NESTED_STATEMENTS) SELECT 1;

\echo ''

-- ============================================================================
-- TEST 2: Simple PL/pgSQL Function (All Level 1)
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 2: Simple PL/pgSQL Function - All Statements at Level 1'
\echo '============================================================================'
\echo ''
\echo 'Purpose: SQL statements in a single function all execute at level 1'
\echo '         because they run sequentially in the same executor context.'
\echo ''

CREATE OR REPLACE FUNCTION simple_function() RETURNS INTEGER AS $$
DECLARE cnt INTEGER;
BEGIN
    SELECT COUNT(*) INTO cnt FROM products;
    INSERT INTO products VALUES (10, 'Temp', 1, 'Temp');
    UPDATE products SET price = price + 1 WHERE id = 1;
    DELETE FROM products WHERE id = 10;
    RETURN cnt;
END;
$$ LANGUAGE plpgsql;

\echo 'Expected: All 4 statements at level 1'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT simple_function();

\echo ''

-- ============================================================================
-- TEST 3: PERFORM Pattern - Creates Deeper Nesting
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 3: PERFORM Pattern - Creates Deeper Nesting Levels'
\echo '============================================================================'
\echo ''
\echo 'Purpose: PERFORM func() creates a new executor call (SELECT func()),'
\echo '         so statements inside the called function run at a deeper level.'
\echo ''
\echo 'How it works internally:'
\echo '  PERFORM func() → executes "SELECT func()" → ExecutorRun increments level'
\echo '  → func() body runs its SQL at the elevated level'
\echo ''

CREATE OR REPLACE FUNCTION inner_perform() RETURNS void AS $$
BEGIN
    UPDATE products SET price = price + 1 WHERE id = 2;
    INSERT INTO products VALUES (20, 'Inner', 50, 'Test');
    DELETE FROM products WHERE id = 20;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION outer_perform() RETURNS void AS $$
DECLARE cnt INTEGER;
BEGIN
    SELECT COUNT(*) INTO cnt FROM products;  -- level 1
    PERFORM inner_perform();        -- creates new executor → inner runs at level 2
    UPDATE products SET price = price - 1 WHERE id = 2;  -- level 1
END;
$$ LANGUAGE plpgsql;

\echo 'Expected:'
\echo '  Statement #1 (level 1): SELECT COUNT in outer_perform'
\echo '  Statement #2 (level 2): UPDATE in inner_perform'
\echo '  Statement #3 (level 2): INSERT in inner_perform'
\echo '  Statement #4 (level 2): DELETE in inner_perform'
\echo '  Statement #5 (level 1): SELECT inner_perform() [the PERFORM call]'
\echo '  Statement #6 (level 1): UPDATE in outer_perform'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT outer_perform();

\echo ''

-- ============================================================================
-- TEST 4: Expression Assignment - Same Level
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 4: Expression Assignment (result := func()) - Same Level'
\echo '============================================================================'
\echo ''
\echo 'Purpose: result := func() evaluates the function as an expression via'
\echo '         ExecEvalFunc WITHOUT creating a new executor call. Statements'
\echo '         inside the called function run at the SAME level as the caller.'
\echo ''
\echo 'How it works internally:'
\echo '  result := func() → ExecEvalFunc(func) → NO new ExecutorRun'
\echo '  → func() body runs its SQL at the SAME level as caller'
\echo ''

CREATE OR REPLACE FUNCTION inner_expr() RETURNS NUMERIC AS $$
DECLARE total NUMERIC;
BEGIN
    SELECT SUM(price) INTO total FROM products;
    UPDATE products SET price = price + 1 WHERE id = 3;
    RETURN total;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION outer_expr() RETURNS TEXT AS $$
DECLARE
    result NUMERIC;
    cnt INTEGER;
BEGIN
    SELECT COUNT(*) INTO cnt FROM products;   -- level 1
    result := inner_expr();                   -- expression eval, inner runs at level 1 too!
    DELETE FROM products WHERE price > 9999;  -- level 1
    RETURN 'Total: ' || result;
END;
$$ LANGUAGE plpgsql;

\echo 'Expected: ALL statements at level 1 (no deeper nesting)'
\echo '  Statement #1 (level 1): SELECT COUNT in outer_expr'
\echo '  Statement #2 (level 1): SELECT SUM in inner_expr  ← same level!'
\echo '  Statement #3 (level 1): UPDATE in inner_expr      ← same level!'
\echo '  Statement #4 (level 1): DELETE in outer_expr'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT outer_expr();

\echo ''

-- ============================================================================
-- TEST 5: Side-by-Side Comparison
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 5: PERFORM vs Expression Assignment - Side by Side'
\echo '============================================================================'
\echo ''
\echo 'Purpose: Same inner function called two different ways to show the'
\echo '         nesting level difference.'
\echo ''

CREATE OR REPLACE FUNCTION shared_inner() RETURNS INTEGER AS $$
DECLARE cnt INTEGER;
BEGIN
    SELECT COUNT(*) INTO cnt FROM products WHERE category = 'Electronics';
    RETURN cnt;
END;
$$ LANGUAGE plpgsql;

-- Calls via PERFORM (creates new executor level)
CREATE OR REPLACE FUNCTION caller_perform() RETURNS void AS $$
BEGIN
    PERFORM shared_inner();  -- new executor → inner at level 2
END;
$$ LANGUAGE plpgsql;

-- Calls via expression assignment (same executor level)
CREATE OR REPLACE FUNCTION caller_assign() RETURNS INTEGER AS $$
DECLARE result INTEGER;
BEGIN
    result := shared_inner();  -- expression eval → inner at level 1
    RETURN result;
END;
$$ LANGUAGE plpgsql;

\echo '--- Via PERFORM (expect level 2 for inner SELECT): ---'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT caller_perform();

\echo ''
\echo '--- Via expression assignment (expect level 1 for inner SELECT): ---'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT caller_assign();

\echo ''
\echo 'Notice: Same function, different nesting levels depending on call pattern.'
\echo ''

-- ============================================================================
-- TEST 6: SQL Function Nesting (True SQL Nesting)
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 6: SQL Functions - True SQL Execution Nesting'
\echo '============================================================================'
\echo ''
\echo 'Purpose: SQL functions execute DURING the parent query, creating true'
\echo '         SQL nesting where inner functions complete before outer.'
\echo ''

CREATE TABLE t1 (id INT, data TEXT);
CREATE TABLE t2 (id INT, data TEXT);
CREATE TABLE t3 (id INT, data TEXT);
INSERT INTO t1 VALUES (1, 'A');
INSERT INTO t2 VALUES (1, 'B');
INSERT INTO t3 VALUES (1, 'C');

CREATE OR REPLACE FUNCTION sql_level3() RETURNS TEXT AS $$
    SELECT data FROM t3 WHERE id = 1;
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION sql_level2() RETURNS TEXT AS $$
    SELECT data || '+' || sql_level3() FROM t2 WHERE id = 1;
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION plpgsql_sql_caller() RETURNS TEXT AS $$
DECLARE result TEXT;
BEGIN
    SELECT data || '+' || sql_level2() INTO result FROM t1 WHERE id = 1;
    RETURN result;
END;
$$ LANGUAGE plpgsql;

\echo 'Expected: Deepest-first execution order (3→2→1)'
\echo '  Statement #1 (level 3): SELECT from t3 (sql_level3)'
\echo '  Statement #2 (level 2): SELECT from t2 (sql_level2)'
\echo '  Statement #3 (level 1): SELECT from t1 (plpgsql_sql_caller)'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT plpgsql_sql_caller();

\echo ''

-- ============================================================================
-- TEST 7: Three-Level Chain with PERFORM
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 7: Three-Level PL/pgSQL Chain (via PERFORM)'
\echo '============================================================================'
\echo ''
\echo 'Purpose: Each PERFORM adds one executor level'
\echo ''

CREATE OR REPLACE FUNCTION chain_level3() RETURNS void AS $$
BEGIN
    PERFORM COUNT(*) FROM products WHERE category = 'Books';
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION chain_level2() RETURNS void AS $$
BEGIN
    PERFORM COUNT(*) FROM products WHERE id = 1;
    PERFORM chain_level3();
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION chain_level1() RETURNS void AS $$
BEGIN
    PERFORM COUNT(*) FROM products;
    PERFORM chain_level2();
END;
$$ LANGUAGE plpgsql;

\echo 'Expected:'
\echo '  Statement #1 (level 1): SELECT COUNT(*) FROM products'
\echo '  Statement #2 (level 2): SELECT COUNT(*) WHERE id = 1'
\echo '  Statement #3 (level 3): SELECT COUNT(*) WHERE category = Books'
\echo '  Statement #4 (level 2): SELECT chain_level3()'
\echo '  Statement #5 (level 1): SELECT chain_level2()'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT chain_level1();

\echo ''

-- ============================================================================
-- TEST 8: Recursive Function
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 8: Recursive Function - Increasing Nesting Levels'
\echo '============================================================================'
\echo ''
\echo 'Purpose: Recursive PERFORM calls increase the nesting level each time'
\echo ''

CREATE TABLE counter_log (depth INT, val INT);

CREATE OR REPLACE FUNCTION recursive_func(n INT) RETURNS VOID AS $$
BEGIN
    INSERT INTO counter_log VALUES (n, n * 10);
    IF n > 1 THEN
        PERFORM recursive_func(n - 1);
    END IF;
END;
$$ LANGUAGE plpgsql;

\echo 'Expected:'
\echo '  Statement #1 (level 1): INSERT with n=3'
\echo '  Statement #2 (level 2): INSERT with n=2'
\echo '  Statement #3 (level 3): INSERT with n=1'
\echo '  + PERFORM calls at levels 2 and 1'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT recursive_func(3);

\echo ''

-- ============================================================================
-- TEST 9: Exception Handling
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 9: Exception Handling - Statements in BEGIN/EXCEPTION Blocks'
\echo '============================================================================'
\echo ''
\echo 'Purpose: Verify statements in exception handlers are captured'
\echo ''

CREATE TABLE safe_table (id INT PRIMARY KEY, data TEXT);
INSERT INTO safe_table VALUES (1, 'existing');

CREATE OR REPLACE FUNCTION exception_func() RETURNS TEXT AS $$
BEGIN
    UPDATE safe_table SET data = 'updated' WHERE id = 1;
    BEGIN
        INSERT INTO safe_table VALUES (1, 'duplicate');  -- will fail
    EXCEPTION WHEN unique_violation THEN
        UPDATE safe_table SET data = 'recovered' WHERE id = 1;
    END;
    RETURN 'done';
END;
$$ LANGUAGE plpgsql;

\echo 'Expected:'
\echo '  - UPDATE (level 1): initial update'
\echo '  - UPDATE (level 1): recovery in exception handler'
\echo '  - The failed INSERT is rolled back and may not appear'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT exception_func();

\echo ''

-- ============================================================================
-- TEST 10: No Nested Statements
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 10: No Nested Statements - Plain Query'
\echo '============================================================================'
\echo ''
\echo 'Purpose: When no nested statements execute, no "Nested Plans:" section'
\echo ''

\echo 'Expected: Normal EXPLAIN output, no Nested Plans section'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT * FROM products WHERE id = 1;

\echo ''

-- ============================================================================
-- TEST 11: Trigger-Fired Nested Statements
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 11: Trigger-Fired Nested Statements'
\echo '============================================================================'
\echo ''
\echo 'Purpose: Triggers fire DURING the triggering statement, creating'
\echo '         deeper nesting. Note: trigger statements may appear BEFORE'
\echo '         their parent (completion order, not start order).'
\echo ''

CREATE TABLE orders (id INT PRIMARY KEY, amount NUMERIC, status TEXT);
CREATE TABLE audit_log (order_id INT, action TEXT, logged_at TIMESTAMP DEFAULT now());

CREATE OR REPLACE FUNCTION log_order_change() RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit_log (order_id, action)
    VALUES (NEW.id, TG_OP || ': ' || NEW.status);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER order_audit_trigger
    AFTER INSERT OR UPDATE ON orders
    FOR EACH ROW EXECUTE FUNCTION log_order_change();

CREATE OR REPLACE FUNCTION process_order(p_id INT) RETURNS VOID AS $$
BEGIN
    INSERT INTO orders VALUES (p_id, 99.99, 'new');
    UPDATE orders SET status = 'processed' WHERE id = p_id;
END;
$$ LANGUAGE plpgsql;

\echo 'Expected:'
\echo '  - INSERT INTO audit_log (level 2): trigger from INSERT'
\echo '  - INSERT INTO orders (level 1): the triggering statement'
\echo '  - INSERT INTO audit_log (level 2): trigger from UPDATE'
\echo '  - UPDATE orders (level 1): the triggering statement'
\echo ''
\echo 'Note: Level 2 statements appear before level 1 because triggers'
\echo '      complete (ExecutorEnd) before the parent statement completes.'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT process_order(1);

\echo ''

-- ============================================================================
-- TEST 12: Combined with VERBOSE and BUFFERS
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 12: NESTED_STATEMENTS with VERBOSE and BUFFERS'
\echo '============================================================================'
\echo ''
\echo 'Purpose: VERBOSE and BUFFERS options are inherited by nested plans'
\echo ''

CREATE OR REPLACE FUNCTION verbose_func() RETURNS INT AS $$
DECLARE cnt INT;
BEGIN
    SELECT COUNT(*) INTO cnt FROM products;
    RETURN cnt;
END;
$$ LANGUAGE plpgsql;

\echo 'Expected: Schema-qualified names (public.products) and Output columns'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, VERBOSE, BUFFERS, TIMING OFF, SUMMARY OFF)
SELECT verbose_func();

\echo ''

-- ============================================================================
-- TEST 13: Statement Numbering = Completion Order
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 13: Statement Numbering Shows Completion Order'
\echo '============================================================================'
\echo ''
\echo 'Purpose: Statement #N reflects when a statement FINISHES (ExecutorEnd),'
\echo '         not when it starts. This is most visible with triggers:'
\echo ''
\echo '  Timeline for INSERT with an AFTER trigger:'
\echo '    1. Parent INSERT starts executing'
\echo '    2. Trigger fires → trigger INSERT starts → trigger INSERT FINISHES → gets #1'
\echo '    3. Parent INSERT FINISHES → gets #2'
\echo ''
\echo '  The trigger statement finishes INSIDE the parent, so it gets a lower number.'
\echo ''

CREATE TABLE demo_orders (id INT, item TEXT);
CREATE TABLE demo_log (msg TEXT);

CREATE OR REPLACE FUNCTION demo_log_trigger() RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO demo_log VALUES ('order placed: ' || NEW.item);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER demo_after_insert
    AFTER INSERT ON demo_orders
    FOR EACH ROW EXECUTE FUNCTION demo_log_trigger();

CREATE OR REPLACE FUNCTION place_order() RETURNS void AS $$
BEGIN
    INSERT INTO demo_orders VALUES (1, 'Widget');   -- has trigger
    INSERT INTO demo_orders VALUES (2, 'Gadget');   -- has trigger
END;
$$ LANGUAGE plpgsql;

\echo 'Expected numbering (completion order):'
\echo '  #1 (level 2): INSERT INTO demo_log  ← trigger finishes first'
\echo '  #2 (level 1): INSERT INTO demo_orders (Widget) ← parent finishes second'
\echo '  #3 (level 2): INSERT INTO demo_log  ← second trigger finishes'
\echo '  #4 (level 1): INSERT INTO demo_orders (Gadget) ← second parent finishes'
\echo ''

EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT place_order();

\echo ''
\echo 'Key takeaway: Lower statement number = finished earlier.'
\echo 'Triggers finish inside their parent, so they always get lower numbers.'
\echo ''

-- ============================================================================
-- TEST 14: BEGIN/ROLLBACK Safety Pattern
-- ============================================================================
\echo '============================================================================'
\echo 'TEST 14: BEGIN/ROLLBACK - Safe Analysis of Data-Modifying Functions'
\echo '============================================================================'
\echo ''
\echo 'Purpose: Demonstrate the recommended pattern for safely analyzing'
\echo '         functions that modify data without persisting changes.'
\echo ''
\echo 'Pattern:'
\echo '  BEGIN;'
\echo '  EXPLAIN (ANALYZE, NESTED_STATEMENTS) SELECT my_function();'
\echo '  ROLLBACK;'
\echo ''
\echo 'The function executes (so we get real plans with actual rows),'
\echo 'but ROLLBACK undoes all changes.'
\echo ''

CREATE TABLE safe_orders (id INT, item TEXT, status TEXT);
INSERT INTO safe_orders VALUES (1, 'Widget', 'pending'), (2, 'Gadget', 'pending');

CREATE OR REPLACE FUNCTION process_all_orders() RETURNS INT AS $$
DECLARE processed INT := 0;
BEGIN
    UPDATE safe_orders SET status = 'processing' WHERE status = 'pending';
    INSERT INTO safe_orders VALUES (3, 'Bonus', 'new');
    DELETE FROM safe_orders WHERE item = 'Gadget';
    GET DIAGNOSTICS processed = ROW_COUNT;
    RETURN processed;
END;
$$ LANGUAGE plpgsql;

\echo '--- Before: ---'
SELECT * FROM safe_orders;

\echo ''
\echo '--- EXPLAIN inside BEGIN/ROLLBACK: ---'

BEGIN;
EXPLAIN (ANALYZE, NESTED_STATEMENTS, COSTS OFF, TIMING OFF, SUMMARY OFF)
SELECT process_all_orders();
ROLLBACK;

\echo ''
\echo '--- After ROLLBACK (data unchanged): ---'
SELECT * FROM safe_orders;

\echo ''
\echo 'Result: We got full execution plans with actual row counts,'
\echo '        but the data is unchanged after ROLLBACK.'
\echo ''

-- ============================================================================
-- Cleanup
-- ============================================================================
DROP FUNCTION IF EXISTS simple_function();
DROP FUNCTION IF EXISTS inner_perform();
DROP FUNCTION IF EXISTS outer_perform();
DROP FUNCTION IF EXISTS inner_expr();
DROP FUNCTION IF EXISTS outer_expr();
DROP FUNCTION IF EXISTS shared_inner();
DROP FUNCTION IF EXISTS caller_perform();
DROP FUNCTION IF EXISTS caller_assign();
DROP FUNCTION IF EXISTS sql_level3();
DROP FUNCTION IF EXISTS sql_level2();
DROP FUNCTION IF EXISTS plpgsql_sql_caller();
DROP FUNCTION IF EXISTS chain_level1();
DROP FUNCTION IF EXISTS chain_level2();
DROP FUNCTION IF EXISTS chain_level3();
DROP FUNCTION IF EXISTS recursive_func(INT);
DROP FUNCTION IF EXISTS exception_func();
DROP FUNCTION IF EXISTS process_order(INT);
DROP TRIGGER IF EXISTS order_audit_trigger ON orders;
DROP FUNCTION IF EXISTS log_order_change();
DROP FUNCTION IF EXISTS verbose_func();
DROP FUNCTION IF EXISTS place_order();
DROP TRIGGER IF EXISTS demo_after_insert ON demo_orders;
DROP FUNCTION IF EXISTS demo_log_trigger();
DROP FUNCTION IF EXISTS process_all_orders();

\echo '============================================================================'
\echo 'Test Suite Complete'
\echo '============================================================================'
\echo ''
\echo 'KEY FINDING: Nesting levels reflect executor call stack depth.'
\echo ''
\echo '  PERFORM func() / SELECT func() INTO var:'
\echo '    → Creates new ExecutorRun → deeper nesting level'
\echo ''
\echo '  result := func():'
\echo '    → ExecEvalFunc (no new ExecutorRun) → SAME nesting level'
\echo ''
\echo 'Tests Covered:'
\echo '  1.  Validation (requires ANALYZE)'
\echo '  2.  Simple PL/pgSQL (all level 1)'
\echo '  3.  PERFORM pattern (creates deeper levels)'
\echo '  4.  Expression assignment (stays at same level)'
\echo '  5.  Side-by-side comparison of both patterns'
\echo '  6.  SQL function nesting (true SQL nesting)'
\echo '  7.  Three-level chain with PERFORM'
\echo '  8.  Recursive function (increasing levels)'
\echo '  9.  Exception handling blocks'
\echo '  10. No nested statements (plain query)'
\echo '  11. Trigger-fired nested statements'
\echo '  12. Combined with VERBOSE and BUFFERS'
\echo '  13. Statement numbering = completion order (triggers demo)'
\echo '  14. BEGIN/ROLLBACK safety pattern'
\echo '============================================================================'
