statement ok
CREATE SEQUENCE seq;

statement ok
CREATE TYPE weekday AS ENUM ('monday', 'tuesday', 'wednesday', 'thursday', 'friday');

statement ok
CREATE TABLE t_rewrite (
  v INT DEFAULT 0,
  w weekday DEFAULT 'monday'::weekday
);

# Need to turn declarative schema changer off because function `get_body_str`
# created below would resolve a descriptorless public schema "system.public"
# which is not supported in declarative schema changer. Declarative schema
# changer falls back to legacy schema changer, and the descriptor id counter is
# increased twice. It cause the test to fail due to id inconsistency.
skipif config local-legacy-schema-changer
statement ok
SET use_declarative_schema_changer = 'off'

statement ok
CREATE FUNCTION get_body_str(fn_name STRING) RETURNS STRING
LANGUAGE SQL
AS $$
  SELECT crdb_internal.pb_to_json(
    'cockroach.sql.sqlbase.Descriptor', descriptor, false
  )->'function'->'functionBody'
  FROM system.descriptor WHERE id = fn_name::regproc::int - 100000;
$$;

skipif config local-legacy-schema-changer
statement ok
SET use_declarative_schema_changer = 'on'

subtest rewrite_plpgsql

statement ok
CREATE FUNCTION f_rewrite() RETURNS INT AS
$$
  DECLARE
    i INT := nextval('seq');
    j INT := nextval('seq');
    curs REFCURSOR := nextval('seq')::STRING;
    curs2 CURSOR FOR SELECT nextval('seq');
  BEGIN
    RAISE NOTICE USING MESSAGE = format('next val: %d',nextval('seq'));
    RAISE NOTICE 'val1: %, val2: %', nextval('seq'), nextval('seq');
    DECLARE
      k INT := nextval('seq');
    BEGIN
      RAISE NOTICE 'k: %, nextval: %', k, nextval('seq');
      IF k > 0 THEN
        SELECT nextval('seq');
      END IF;
    EXCEPTION
      WHEN division_by_zero THEN
        RAISE NOTICE USING MESSAGE = format('next val: %d',nextval('seq'));
      WHEN not_null_violation THEN
        SELECT nextval('seq');
        SELECT nextval('seq');
        RAISE NOTICE USING MESSAGE = format('next val: %d',nextval('seq'));
    END;
    WHILE nextval('seq') < 10 LOOP
      i = nextval('seq');
      SELECT nextval('seq');
      IF nextval('seq') = 1 THEN
        SELECT nextval('seq');
        SELECT nextval('seq');
        CONTINUE;
      ELSIF nextval('seq') = 2 THEN
        SELECT v INTO i FROM nextval('seq') AS v(INT);
      ELSIF nextval('seq') = 3 THEN
        SELECT nextval('seq');
        SELECT nextval('seq');
      END IF;
    END LOOP;
    OPEN curs FOR SELECT nextval('seq');
    RETURN nextval('seq');
  END
$$ LANGUAGE PLPGSQL;

query T
SELECT get_body_str('f_rewrite');
----
"DECLARE\ni INT8 := nextval(106:::REGCLASS);\nj INT8 := nextval(106:::REGCLASS);\ncurs REFCURSOR := nextval(106:::REGCLASS)::STRING;\ncurs2 CURSOR FOR SELECT nextval(106:::REGCLASS);\nBEGIN\nRAISE NOTICE\nUSING MESSAGE = format('next val: %d':::STRING, nextval(106:::REGCLASS));\nRAISE NOTICE 'val1: %, val2: %', nextval(106:::REGCLASS), nextval(106:::REGCLASS);\nDECLARE\nk INT8 := nextval(106:::REGCLASS);\nBEGIN\nRAISE NOTICE 'k: %, nextval: %', k, nextval(106:::REGCLASS);\nIF k > 0 THEN\n\tSELECT nextval(106:::REGCLASS);\nEND IF;\nEXCEPTION\nWHEN division_by_zero THEN\nRAISE NOTICE\nUSING MESSAGE = format('next val: %d':::STRING, nextval(106:::REGCLASS));\nWHEN not_null_violation THEN\nSELECT nextval(106:::REGCLASS);\nSELECT nextval(106:::REGCLASS);\nRAISE NOTICE\nUSING MESSAGE = format('next val: %d':::STRING, nextval(106:::REGCLASS));\nEND;\nWHILE nextval(106:::REGCLASS) < 10:::INT8 LOOP\ni := nextval(106:::REGCLASS);\nSELECT nextval(106:::REGCLASS);\nIF nextval(106:::REGCLASS) = 1:::INT8 THEN\n\tSELECT nextval(106:::REGCLASS);\n\tSELECT nextval(106:::REGCLASS);\n\tCONTINUE;\nELSIF nextval(106:::REGCLASS) = 2:::INT8 THEN\n\tSELECT v FROM ROWS FROM (nextval(106:::REGCLASS)) AS v (\"int\") INTO i;\nELSIF nextval(106:::REGCLASS) = 3:::INT8 THEN\n\tSELECT nextval(106:::REGCLASS);\n\tSELECT nextval(106:::REGCLASS);\nEND IF;\nEND LOOP;\nOPEN curs FOR SELECT nextval(106:::REGCLASS);\nRETURN nextval(106:::REGCLASS);\nEND;\n"

query TT
SHOW CREATE FUNCTION f_rewrite;
----
f_rewrite  CREATE FUNCTION public.f_rewrite()
             RETURNS INT8
             VOLATILE
             NOT LEAKPROOF
             CALLED ON NULL INPUT
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             DECLARE
             i INT8 := nextval('public.seq'::REGCLASS);
             j INT8 := nextval('public.seq'::REGCLASS);
             curs REFCURSOR := nextval('public.seq'::REGCLASS)::STRING;
             curs2 CURSOR FOR SELECT nextval('public.seq'::REGCLASS);
             BEGIN
             RAISE NOTICE
             USING MESSAGE = format('next val: %d':::STRING, nextval('public.seq'::REGCLASS));
             RAISE NOTICE 'val1: %, val2: %', nextval('public.seq'::REGCLASS), nextval('public.seq'::REGCLASS);
             DECLARE
             k INT8 := nextval('public.seq'::REGCLASS);
             BEGIN
             RAISE NOTICE 'k: %, nextval: %', k, nextval('public.seq'::REGCLASS);
             IF k > 0 THEN
               SELECT nextval('public.seq'::REGCLASS);
             END IF;
             EXCEPTION
             WHEN division_by_zero THEN
             RAISE NOTICE
             USING MESSAGE = format('next val: %d':::STRING, nextval('public.seq'::REGCLASS));
             WHEN not_null_violation THEN
             SELECT nextval('public.seq'::REGCLASS);
             SELECT nextval('public.seq'::REGCLASS);
             RAISE NOTICE
             USING MESSAGE = format('next val: %d':::STRING, nextval('public.seq'::REGCLASS));
             END;
             WHILE nextval('public.seq'::REGCLASS) < 10:::INT8 LOOP
             i := nextval('public.seq'::REGCLASS);
             SELECT nextval('public.seq'::REGCLASS);
             IF nextval('public.seq'::REGCLASS) = 1:::INT8 THEN
               SELECT nextval('public.seq'::REGCLASS);
               SELECT nextval('public.seq'::REGCLASS);
               CONTINUE;
             ELSIF nextval('public.seq'::REGCLASS) = 2:::INT8 THEN
               SELECT v FROM ROWS FROM (nextval('public.seq'::REGCLASS)) AS v ("int") INTO i;
             ELSIF nextval('public.seq'::REGCLASS) = 3:::INT8 THEN
               SELECT nextval('public.seq'::REGCLASS);
               SELECT nextval('public.seq'::REGCLASS);
             END IF;
             END LOOP;
             OPEN curs FOR SELECT nextval('public.seq'::REGCLASS);
             RETURN nextval('public.seq'::REGCLASS);
             END;
           $$

statement ok
ALTER SEQUENCE seq RENAME TO renamed;

query T
SELECT get_body_str('f_rewrite');
----
"DECLARE\ni INT8 := nextval(106:::REGCLASS);\nj INT8 := nextval(106:::REGCLASS);\ncurs REFCURSOR := nextval(106:::REGCLASS)::STRING;\ncurs2 CURSOR FOR SELECT nextval(106:::REGCLASS);\nBEGIN\nRAISE NOTICE\nUSING MESSAGE = format('next val: %d':::STRING, nextval(106:::REGCLASS));\nRAISE NOTICE 'val1: %, val2: %', nextval(106:::REGCLASS), nextval(106:::REGCLASS);\nDECLARE\nk INT8 := nextval(106:::REGCLASS);\nBEGIN\nRAISE NOTICE 'k: %, nextval: %', k, nextval(106:::REGCLASS);\nIF k > 0 THEN\n\tSELECT nextval(106:::REGCLASS);\nEND IF;\nEXCEPTION\nWHEN division_by_zero THEN\nRAISE NOTICE\nUSING MESSAGE = format('next val: %d':::STRING, nextval(106:::REGCLASS));\nWHEN not_null_violation THEN\nSELECT nextval(106:::REGCLASS);\nSELECT nextval(106:::REGCLASS);\nRAISE NOTICE\nUSING MESSAGE = format('next val: %d':::STRING, nextval(106:::REGCLASS));\nEND;\nWHILE nextval(106:::REGCLASS) < 10:::INT8 LOOP\ni := nextval(106:::REGCLASS);\nSELECT nextval(106:::REGCLASS);\nIF nextval(106:::REGCLASS) = 1:::INT8 THEN\n\tSELECT nextval(106:::REGCLASS);\n\tSELECT nextval(106:::REGCLASS);\n\tCONTINUE;\nELSIF nextval(106:::REGCLASS) = 2:::INT8 THEN\n\tSELECT v FROM ROWS FROM (nextval(106:::REGCLASS)) AS v (\"int\") INTO i;\nELSIF nextval(106:::REGCLASS) = 3:::INT8 THEN\n\tSELECT nextval(106:::REGCLASS);\n\tSELECT nextval(106:::REGCLASS);\nEND IF;\nEND LOOP;\nOPEN curs FOR SELECT nextval(106:::REGCLASS);\nRETURN nextval(106:::REGCLASS);\nEND;\n"

query TT
SHOW CREATE FUNCTION f_rewrite;
----
f_rewrite  CREATE FUNCTION public.f_rewrite()
             RETURNS INT8
             VOLATILE
             NOT LEAKPROOF
             CALLED ON NULL INPUT
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             DECLARE
             i INT8 := nextval('public.renamed'::REGCLASS);
             j INT8 := nextval('public.renamed'::REGCLASS);
             curs REFCURSOR := nextval('public.renamed'::REGCLASS)::STRING;
             curs2 CURSOR FOR SELECT nextval('public.renamed'::REGCLASS);
             BEGIN
             RAISE NOTICE
             USING MESSAGE = format('next val: %d':::STRING, nextval('public.renamed'::REGCLASS));
             RAISE NOTICE 'val1: %, val2: %', nextval('public.renamed'::REGCLASS), nextval('public.renamed'::REGCLASS);
             DECLARE
             k INT8 := nextval('public.renamed'::REGCLASS);
             BEGIN
             RAISE NOTICE 'k: %, nextval: %', k, nextval('public.renamed'::REGCLASS);
             IF k > 0 THEN
               SELECT nextval('public.renamed'::REGCLASS);
             END IF;
             EXCEPTION
             WHEN division_by_zero THEN
             RAISE NOTICE
             USING MESSAGE = format('next val: %d':::STRING, nextval('public.renamed'::REGCLASS));
             WHEN not_null_violation THEN
             SELECT nextval('public.renamed'::REGCLASS);
             SELECT nextval('public.renamed'::REGCLASS);
             RAISE NOTICE
             USING MESSAGE = format('next val: %d':::STRING, nextval('public.renamed'::REGCLASS));
             END;
             WHILE nextval('public.renamed'::REGCLASS) < 10:::INT8 LOOP
             i := nextval('public.renamed'::REGCLASS);
             SELECT nextval('public.renamed'::REGCLASS);
             IF nextval('public.renamed'::REGCLASS) = 1:::INT8 THEN
               SELECT nextval('public.renamed'::REGCLASS);
               SELECT nextval('public.renamed'::REGCLASS);
               CONTINUE;
             ELSIF nextval('public.renamed'::REGCLASS) = 2:::INT8 THEN
               SELECT v FROM ROWS FROM (nextval('public.renamed'::REGCLASS)) AS v ("int") INTO i;
             ELSIF nextval('public.renamed'::REGCLASS) = 3:::INT8 THEN
               SELECT nextval('public.renamed'::REGCLASS);
               SELECT nextval('public.renamed'::REGCLASS);
             END IF;
             END LOOP;
             OPEN curs FOR SELECT nextval('public.renamed'::REGCLASS);
             RETURN nextval('public.renamed'::REGCLASS);
             END;
           $$

# Reset sequence name for subtest.
statement ok
ALTER SEQUENCE renamed RENAME TO seq;

statement ok
CREATE FUNCTION f_nested(x INT, y weekday) RETURNS INT AS $$
  BEGIN
    IF x > 0 THEN
      RAISE NOTICE 'x: %, y: %', x, y;
    END IF;
    RETURN x * 2;
  END
$$ LANGUAGE PLpgSQL;

statement ok
CREATE PROCEDURE p_nested(x INT, y weekday, OUT z weekday) AS $$
  BEGIN
    IF x > 0 THEN
      RAISE NOTICE 'x: %, y: %', x, y;
    END IF;
  END
$$ LANGUAGE PLpgSQL;

statement ok
DROP FUNCTION f_rewrite();

statement ok
CREATE FUNCTION f_rewrite() RETURNS weekday AS
$$
  DECLARE
    day weekday := 'wednesday'::weekday;
    today weekday := 'thursday'::weekday;
    curs REFCURSOR := 'monday'::weekday::STRING;
    curs2 CURSOR FOR SELECT 'tuesday'::weekday;
  BEGIN
    RAISE NOTICE USING MESSAGE = format('val: %d','wednesday'::weekday);
    RAISE NOTICE 'val1: %, val2: %', 'wednesday'::weekday, 'thursday'::weekday;
    SELECT f_nested(1, 'wednesday'::weekday);
    CALL p_nested(1, 'wednesday'::weekday, day);
    DECLARE
      yesterday weekday := 'wednesday'::weekday;
    BEGIN
      RAISE NOTICE 'val3: %, val4: %', 'wednesday'::weekday, 'thursday'::weekday;
      IF yesterday IS NOT NULL THEN
        SELECT 'wednesday'::weekday;
      END IF;
    EXCEPTION
      WHEN division_by_zero THEN
        RAISE NOTICE USING MESSAGE = format('val: %d','wednesday'::weekday);
      WHEN not_null_violation THEN
        SELECT 'wednesday'::weekday;
        RAISE NOTICE 'val: %', 'wednesday'::weekday;
    END;
    WHILE day != 'wednesday'::weekday LOOP
      day = 'friday'::weekday;
      SELECT 'wednesday'::weekday;
      IF day = 'wednesday'::weekday THEN
        day = 'thursday'::weekday;
        SELECT 'tuesday'::weekday;
        CONTINUE;
      ELSIF day = 'monday'::weekday THEN
        SELECT 'tuesday'::weekday INTO day;
      ELSIF day = 'tuesday'::weekday THEN
        SELECT 'wednesday'::weekday INTO day;
        SELECT 'wednesday'::weekday;
      END IF;
    END LOOP;
    OPEN curs FOR SELECT 'wednesday'::weekday;
    RETURN 'wednesday'::weekday;
  END
$$ LANGUAGE PLPGSQL;

query T
SELECT get_body_str('f_rewrite');
----
"DECLARE\nday @100107 := b'\\x80':::@100107;\ntoday @100107 := b'\\xa0':::@100107;\ncurs REFCURSOR := b' ':::@100107::STRING;\ncurs2 CURSOR FOR SELECT b'@':::@100107;\nBEGIN\nRAISE NOTICE\nUSING MESSAGE = format('val: %d':::STRING, b'\\x80':::@100107);\nRAISE NOTICE 'val1: %, val2: %', b'\\x80':::@100107, b'\\xa0':::@100107;\nSELECT public.f_nested(1:::INT8, b'\\x80':::@100107);\nCALL public.p_nested(1, b'\\x80':::@100107, day);\nDECLARE\nyesterday @100107 := b'\\x80':::@100107;\nBEGIN\nRAISE NOTICE 'val3: %, val4: %', b'\\x80':::@100107, b'\\xa0':::@100107;\nIF yesterday IS NOT NULL THEN\n\tSELECT b'\\x80':::@100107;\nEND IF;\nEXCEPTION\nWHEN division_by_zero THEN\nRAISE NOTICE\nUSING MESSAGE = format('val: %d':::STRING, b'\\x80':::@100107);\nWHEN not_null_violation THEN\nSELECT b'\\x80':::@100107;\nRAISE NOTICE 'val: %', b'\\x80':::@100107;\nEND;\nWHILE day != b'\\x80':::@100107 LOOP\nday := b'\\xc0':::@100107;\nSELECT b'\\x80':::@100107;\nIF day = b'\\x80':::@100107 THEN\n\tday := b'\\xa0':::@100107;\n\tSELECT b'@':::@100107;\n\tCONTINUE;\nELSIF day = b' ':::@100107 THEN\n\tSELECT b'@':::@100107 INTO day;\nELSIF day = b'@':::@100107 THEN\n\tSELECT b'\\x80':::@100107 INTO day;\n\tSELECT b'\\x80':::@100107;\nEND IF;\nEND LOOP;\nOPEN curs FOR SELECT b'\\x80':::@100107;\nRETURN b'\\x80':::@100107;\nEND;\n"

query TT
SHOW CREATE FUNCTION f_rewrite;
----
f_rewrite  CREATE FUNCTION public.f_rewrite()
             RETURNS public.weekday
             VOLATILE
             NOT LEAKPROOF
             CALLED ON NULL INPUT
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             DECLARE
             day public.weekday := 'wednesday':::public.weekday;
             today public.weekday := 'thursday':::public.weekday;
             curs REFCURSOR := 'monday':::public.weekday::STRING;
             curs2 CURSOR FOR SELECT 'tuesday':::public.weekday;
             BEGIN
             RAISE NOTICE
             USING MESSAGE = format('val: %d':::STRING, 'wednesday':::public.weekday);
             RAISE NOTICE 'val1: %, val2: %', 'wednesday':::public.weekday, 'thursday':::public.weekday;
             SELECT public.f_nested(1:::INT8, 'wednesday':::public.weekday);
             CALL public.p_nested(1, 'wednesday':::public.weekday, day);
             DECLARE
             yesterday public.weekday := 'wednesday':::public.weekday;
             BEGIN
             RAISE NOTICE 'val3: %, val4: %', 'wednesday':::public.weekday, 'thursday':::public.weekday;
             IF yesterday IS NOT NULL THEN
               SELECT 'wednesday':::public.weekday;
             END IF;
             EXCEPTION
             WHEN division_by_zero THEN
             RAISE NOTICE
             USING MESSAGE = format('val: %d':::STRING, 'wednesday':::public.weekday);
             WHEN not_null_violation THEN
             SELECT 'wednesday':::public.weekday;
             RAISE NOTICE 'val: %', 'wednesday':::public.weekday;
             END;
             WHILE day != 'wednesday':::public.weekday LOOP
             day := 'friday':::public.weekday;
             SELECT 'wednesday':::public.weekday;
             IF day = 'wednesday':::public.weekday THEN
               day := 'thursday':::public.weekday;
               SELECT 'tuesday':::public.weekday;
               CONTINUE;
             ELSIF day = 'monday':::public.weekday THEN
               SELECT 'tuesday':::public.weekday INTO day;
             ELSIF day = 'tuesday':::public.weekday THEN
               SELECT 'wednesday':::public.weekday INTO day;
               SELECT 'wednesday':::public.weekday;
             END IF;
             END LOOP;
             OPEN curs FOR SELECT 'wednesday':::public.weekday;
             RETURN 'wednesday':::public.weekday;
             END;
           $$

statement ok
ALTER TYPE weekday RENAME VALUE 'wednesday' TO 'humpday';

statement ok
ALTER TYPE weekday RENAME TO workday;

query T
SELECT get_body_str('f_rewrite');
----
"DECLARE\nday @100107 := b'\\x80':::@100107;\ntoday @100107 := b'\\xa0':::@100107;\ncurs REFCURSOR := b' ':::@100107::STRING;\ncurs2 CURSOR FOR SELECT b'@':::@100107;\nBEGIN\nRAISE NOTICE\nUSING MESSAGE = format('val: %d':::STRING, b'\\x80':::@100107);\nRAISE NOTICE 'val1: %, val2: %', b'\\x80':::@100107, b'\\xa0':::@100107;\nSELECT public.f_nested(1:::INT8, b'\\x80':::@100107);\nCALL public.p_nested(1, b'\\x80':::@100107, day);\nDECLARE\nyesterday @100107 := b'\\x80':::@100107;\nBEGIN\nRAISE NOTICE 'val3: %, val4: %', b'\\x80':::@100107, b'\\xa0':::@100107;\nIF yesterday IS NOT NULL THEN\n\tSELECT b'\\x80':::@100107;\nEND IF;\nEXCEPTION\nWHEN division_by_zero THEN\nRAISE NOTICE\nUSING MESSAGE = format('val: %d':::STRING, b'\\x80':::@100107);\nWHEN not_null_violation THEN\nSELECT b'\\x80':::@100107;\nRAISE NOTICE 'val: %', b'\\x80':::@100107;\nEND;\nWHILE day != b'\\x80':::@100107 LOOP\nday := b'\\xc0':::@100107;\nSELECT b'\\x80':::@100107;\nIF day = b'\\x80':::@100107 THEN\n\tday := b'\\xa0':::@100107;\n\tSELECT b'@':::@100107;\n\tCONTINUE;\nELSIF day = b' ':::@100107 THEN\n\tSELECT b'@':::@100107 INTO day;\nELSIF day = b'@':::@100107 THEN\n\tSELECT b'\\x80':::@100107 INTO day;\n\tSELECT b'\\x80':::@100107;\nEND IF;\nEND LOOP;\nOPEN curs FOR SELECT b'\\x80':::@100107;\nRETURN b'\\x80':::@100107;\nEND;\n"

query TT
SHOW CREATE FUNCTION f_rewrite;
----
f_rewrite  CREATE FUNCTION public.f_rewrite()
             RETURNS public.workday
             VOLATILE
             NOT LEAKPROOF
             CALLED ON NULL INPUT
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             DECLARE
             day public.workday := 'humpday':::public.workday;
             today public.workday := 'thursday':::public.workday;
             curs REFCURSOR := 'monday':::public.workday::STRING;
             curs2 CURSOR FOR SELECT 'tuesday':::public.workday;
             BEGIN
             RAISE NOTICE
             USING MESSAGE = format('val: %d':::STRING, 'humpday':::public.workday);
             RAISE NOTICE 'val1: %, val2: %', 'humpday':::public.workday, 'thursday':::public.workday;
             SELECT public.f_nested(1:::INT8, 'humpday':::public.workday);
             CALL public.p_nested(1, 'humpday':::public.workday, day);
             DECLARE
             yesterday public.workday := 'humpday':::public.workday;
             BEGIN
             RAISE NOTICE 'val3: %, val4: %', 'humpday':::public.workday, 'thursday':::public.workday;
             IF yesterday IS NOT NULL THEN
               SELECT 'humpday':::public.workday;
             END IF;
             EXCEPTION
             WHEN division_by_zero THEN
             RAISE NOTICE
             USING MESSAGE = format('val: %d':::STRING, 'humpday':::public.workday);
             WHEN not_null_violation THEN
             SELECT 'humpday':::public.workday;
             RAISE NOTICE 'val: %', 'humpday':::public.workday;
             END;
             WHILE day != 'humpday':::public.workday LOOP
             day := 'friday':::public.workday;
             SELECT 'humpday':::public.workday;
             IF day = 'humpday':::public.workday THEN
               day := 'thursday':::public.workday;
               SELECT 'tuesday':::public.workday;
               CONTINUE;
             ELSIF day = 'monday':::public.workday THEN
               SELECT 'tuesday':::public.workday INTO day;
             ELSIF day = 'tuesday':::public.workday THEN
               SELECT 'humpday':::public.workday INTO day;
               SELECT 'humpday':::public.workday;
             END IF;
             END LOOP;
             OPEN curs FOR SELECT 'humpday':::public.workday;
             RETURN 'humpday':::public.workday;
             END;
           $$

# Reset types for subtest.
statement ok
ALTER TYPE workday RENAME TO weekday;

statement ok
ALTER TYPE weekday RENAME VALUE 'humpday' TO 'wednesday';

statement ok
DROP FUNCTION f_rewrite();

statement ok
CREATE FUNCTION f_rewrite(INOUT param1 weekday, OUT param2 weekday) AS
$$
  BEGIN
    param2 = param1;
    param1 = 'friday'::weekday;
  END
$$ LANGUAGE PLPGSQL;

query T
SELECT get_body_str('f_rewrite');
----
"BEGIN\nparam2 := param1;\nparam1 := b'\\xc0':::@100107;\nEND;\n"

query TT
SHOW CREATE FUNCTION f_rewrite;
----
f_rewrite  CREATE FUNCTION public.f_rewrite(INOUT param1 public.weekday, OUT param2 public.weekday)
             RETURNS RECORD
             VOLATILE
             NOT LEAKPROOF
             CALLED ON NULL INPUT
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             BEGIN
             param2 := param1;
             param1 := 'friday':::public.weekday;
             END;
           $$

statement ok
ALTER TYPE weekday RENAME VALUE 'friday' TO 'humpday';

statement ok
ALTER TYPE weekday RENAME TO workday;

query T
SELECT get_body_str('f_rewrite');
----
"BEGIN\nparam2 := param1;\nparam1 := b'\\xc0':::@100107;\nEND;\n"

query TT
SHOW CREATE FUNCTION f_rewrite;
----
f_rewrite  CREATE FUNCTION public.f_rewrite(INOUT param1 public.workday, OUT param2 public.workday)
             RETURNS RECORD
             VOLATILE
             NOT LEAKPROOF
             CALLED ON NULL INPUT
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             BEGIN
             param2 := param1;
             param1 := 'humpday':::public.workday;
             END;
           $$

# Reset types for subtest.
statement ok
ALTER TYPE workday RENAME TO weekday;

statement ok
ALTER TYPE weekday RENAME VALUE 'humpday' TO 'friday';

statement ok
DROP FUNCTION f_rewrite;

subtest end

subtest rewrite_proc

statement ok
CREATE PROCEDURE p_rewrite() AS
$$
  BEGIN
    INSERT INTO t_rewrite(v) VALUES (nextval('seq')) RETURNING v;
  END
$$ LANGUAGE PLPGSQL

query T
SELECT get_body_str('p_rewrite');
----
"BEGIN\nINSERT INTO test.public.t_rewrite(v) VALUES (nextval(106:::REGCLASS)) RETURNING v;\nEND;\n"

statement ok
DROP PROCEDURE p_rewrite();

statement ok
CREATE PROCEDURE p_rewrite() AS
$$
  BEGIN
    UPDATE t_rewrite SET w = 'thursday'::weekday WHERE w = 'wednesday'::weekday RETURNING w;
  END
$$ LANGUAGE PLPGSQL

query T
SELECT get_body_str('p_rewrite');
----
"BEGIN\nUPDATE test.public.t_rewrite SET w = b'\\xa0':::@100107 WHERE w = b'\\x80':::@100107 RETURNING w;\nEND;\n"

statement ok
DROP PROCEDURE p_rewrite();

statement ok
CREATE PROCEDURE p_rewrite(INOUT param1 weekday, OUT param2 weekday) AS
$$
  BEGIN
    param2 = param1;
    param1 = 'friday'::weekday;
  END
$$ LANGUAGE PLPGSQL;

query T
SELECT get_body_str('p_rewrite');
----
"BEGIN\nparam2 := param1;\nparam1 := b'\\xc0':::@100107;\nEND;\n"

query TT
SHOW CREATE PROCEDURE p_rewrite;
----
p_rewrite  CREATE PROCEDURE public.p_rewrite(INOUT param1 public.weekday, OUT param2 public.weekday)
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             BEGIN
             param2 := param1;
             param1 := 'friday':::public.weekday;
             END;
           $$

statement ok
ALTER TYPE weekday RENAME VALUE 'friday' TO 'humpday';

statement ok
ALTER TYPE weekday RENAME TO workday;

query T
SELECT get_body_str('p_rewrite');
----
"BEGIN\nparam2 := param1;\nparam1 := b'\\xc0':::@100107;\nEND;\n"

query TT
SHOW CREATE PROCEDURE p_rewrite;
----
p_rewrite  CREATE PROCEDURE public.p_rewrite(INOUT param1 public.workday, OUT param2 public.workday)
             LANGUAGE plpgsql
             SECURITY INVOKER
             AS $$
             BEGIN
             param2 := param1;
             param1 := 'humpday':::public.workday;
             END;
           $$

# Reset types for subtest.
statement ok
ALTER TYPE workday RENAME TO weekday;

statement ok
ALTER TYPE weekday RENAME VALUE 'humpday' TO 'friday';

statement ok
DROP PROCEDURE p_rewrite;

subtest end
