SELECT
    CASE WHEN 1 = 1 THEN
        2
    ELSE
        3
    END::text AS col1,
    col2,
    col3
FROM
    tb1;

SELECT
    (
        CASE WHEN 1 = 1 THEN
            2
        ELSE
            3
        END)::text AS col1,
    col2,
    col3
FROM
    tb1;

UPDATE
    point_tbl
SET
    f1[0] = NULL
WHERE
    f1::text = '(10,10)'::point::text
RETURNING
    *;

SELECT
    'TrUe'::text::boolean AS true,
    'fAlse'::text::boolean AS false;

SELECT
    TRUE::boolean::text AS true,
    FALSE::boolean::text AS false;

CREATE PROCEDURE testns.bar ()
    AS '
    SELECT
        1;
'
LANGUAGE sql;

ALTER TABLE test9b
    ALTER COLUMN b TYPE priv_testdomain1;

CREATE TYPE test7b AS (
    a int,
    b priv_testdomain1
);

CREATE TYPE test8b AS (
    a int,
    b int
);

ALTER TYPE test8b
    ADD ATTRIBUTE c priv_testdomain1;

CREATE OR REPLACE PROCEDURE foo ()
    AS $BODY$
DECLARE
BEGIN
    INSERT INTO bar (COLUMN)
        VALUES (1);
    COMMIT;
    BEGIN
        INSERT INTO bar (COLUMN)
            VALUES (2);
        COMMIT;
        BEGIN
            INSERT INTO bar (COLUMN)
                VALUES (3);
            COMMIT;
        END;
    END;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TEXT SEARCH PARSER addr_ts_prs (
    START = prsd_start,
    gettoken = prsd_nexttoken,
    END = prsd_end,
    lextypes = prsd_lextype
);

CREATE FUNCTION fonction_reference (refcursor)
    RETURNS refcursor
    AS $$
BEGIN
    OPEN $1 FOR
        SELECT
            col
        FROM
            test;
    RETURN $1;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION foo ()
    RETURNS TRIGGER
    AS $$
BEGIN
    IF NEW.role NOT IN (
        SELECT
            rolname
        FROM
            pg_authid) THEN
        RAISE EXCEPTION 'role % does not exist.', NEW.role;
    END IF;
END;
$$
LANGUAGE 'plpgsql';

DO $$
DECLARE
    xml_declaration text := '<?xml version="1.0" encoding="ISO-8859-1"?>';
    degree_symbol text;
    res xml[];
BEGIN
    -- Per the documentation, except when the server encoding is UTF8, xpath()
    -- may not work on non-ASCII data.  The untranslatable_character and
    -- undefined_function traps below, currently dead code, will become relevant
    -- if we remove this limitation.
    IF current_setting('server_encoding') <> 'UTF8' THEN
        RAISE LOG 'skip: encoding % unsupported for xpath', current_setting('server_encoding');
        RETURN;
    END IF;
    degree_symbol := convert_from('\xc2b0', 'UTF8');
    res := xpath('text()', (xml_declaration || '<x>' || degree_symbol || '</x>')::xml);
    IF degree_symbol <> res[1]::text THEN
        RAISE 'expected % (%), got % (%)', degree_symbol, convert_to(degree_symbol, 'UTF8'), res[1], convert_to(res[1]::text, 'UTF8');
    END IF;
EXCEPTION
    -- character with byte sequence 0xc2 0xb0 in encoding "UTF8" has no equivalent in encoding "LATIN8"
    WHEN untranslatable_character
        -- default conversion function for encoding "UTF8" to "MULE_INTERNAL" does not exist
        OR undefined_function
        -- unsupported XML feature
        OR feature_not_supported THEN
        RAISE LOG 'skip: %', SQLERRM;
END
$$;

CREATE FUNCTION wait_for_stats ()
    RETURNS void
    AS $$
DECLARE
    start_time timestamptz := clock_timestamp();
    updated1 bool;
    updated2 bool;
    updated3 bool;
    updated4 bool;
BEGIN
    -- we don't want to wait forever; loop will exit after 30 seconds
    FOR i IN 1..300 LOOP
        -- With parallel query, the seqscan and indexscan on tenk2 might be done
        -- in parallel worker processes, which will send their stats counters
        -- asynchronously to what our own session does.  So we must check for
        -- those counts to be registered separately from the update counts.
        -- check to see if seqscan has been sensed
        SELECT
            (st.seq_scan >= pr.seq_scan + 1) INTO updated1
        FROM
            pg_stat_user_tables AS st,
            pg_class AS cl,
            prevstats AS pr
        WHERE
            st.relname = 'tenk2'
            AND cl.relname = 'tenk2';
        -- check to see if indexscan has been sensed
        SELECT
            (st.idx_scan >= pr.idx_scan + 1) INTO updated2
        FROM
            pg_stat_user_tables AS st,
            pg_class AS cl,
            prevstats AS pr
        WHERE
            st.relname = 'tenk2'
            AND cl.relname = 'tenk2';
        -- check to see if all updates have been sensed
        SELECT
            (n_tup_ins > 0) INTO updated3
        FROM
            pg_stat_user_tables
        WHERE
            relname = 'trunc_stats_test4';
        -- We must also check explicitly that pg_stat_get_snapshot_timestamp has
        -- advanced, because that comes from the global stats file which might
        -- be older than the per-DB stats file we got the other values from.
        SELECT
            (pr.snap_ts < pg_stat_get_snapshot_timestamp ()) INTO updated4
        FROM
            prevstats AS pr;
        exit
        WHEN updated1
            AND updated2
            AND updated3
            AND updated4;
        -- wait a little
        PERFORM
            pg_sleep_for ('100 milliseconds');
        -- reset stats snapshot so we can test again
        PERFORM
            pg_stat_clear_snapshot();
    END LOOP;
    -- report time waited in postmaster log (where it won't change test output)
    RAISE log 'wait_for_stats delayed % seconds', extract(epoch FROM clock_timestamp() - start_time);
END
$$
LANGUAGE plpgsql;

DO $$
DECLARE
    objtype text;
    names text[];
    args text[];
BEGIN
    FOR objtype IN VALUES ('table'), ('publication relation')
    LOOP
        FOR names IN VALUES ('{eins}'), ('{eins, zwei, drei}')
        LOOP
            FOR args IN VALUES ('{}'), ('{integer}')
            LOOP
                BEGIN
                    PERFORM
                        pg_get_object_address(objtype, names, args);
                EXCEPTION
                    WHEN OTHERS THEN
                        RAISE WARNING 'error for %,%,%: %', objtype, names, args, sqlerrm;
                END;
            END LOOP;
        END LOOP;
    END LOOP;
END;

$$;

-- test successful cases
WITH objects (
    TYPE,
    name,
    args
) AS (
    VALUES ('table', '{addr_nsp, gentable}'::text[], '{}'::text[]),
        ('index', '{addr_nsp, parttable_pkey}', '{}'),
        ('sequence', '{addr_nsp, gentable_a_seq}', '{}'),
        -- toast table
        ('view', '{addr_nsp, genview}', '{}'),
        -- large object
        ('operator', '{+}', '{int4, int4}'),
        -- database
        -- tablespace
        ('foreign-data wrapper', '{addr_fdw}', '{}'),
        -- extension
        -- event trigger
        ('policy', '{addr_nsp, gentable, genpol}', '{}'),
        ('statistics object', '{addr_nsp, gentable_stat}', '{}'))
SELECT
    (pg_identify_object (addr1.classid, addr1.objid, addr1.objsubid)).*,
    -- test roundtrip through pg_identify_object_as_address
    ROW (pg_identify_object (addr1.classid, addr1.objid, addr1.objsubid)) = ROW (pg_identify_object (addr2.classid, addr 2.objid, addr2.objsubid))
FROM
    objects,
    pg_get_object_address(TYPE, name, args) addr1,
    pg_identify_object_as_address(classid, objid, objsubid) ioa (typ, nms, args),
    pg_get_object_address(typ, nms, ioa.args) AS addr2
ORDER BY
    addr1.classid,
    addr1.objid,
    addr1.objsubid;

---
--- Cleanup resources
---
DROP FOREIGN DATA WRAPPER addr_fdw CASCADE;

DROP PUBLICATION addr_pub;

DROP SUBSCRIPTION addr_sub;

DROP SCHEMA addr_nsp CASCADE;

DROP OWNED BY regress_addr_user;

DROP USER regress_addr_user;

CREATE PROCEDURE insert_data (a integer, b integer)
LANGUAGE SQL
AS $$
    INSERT INTO tbl
        VALUES (a);
    INSERT INTO tbl
        VALUES (b);
$$;

