subtest types

statement error pgcode 42601 pq: at or near "float": syntax error
CREATE PROCEDURE p(OUT param INT) RETURNS FLOAT AS $$ SELECT 1; $$ LANGUAGE SQL;

statement ok
CREATE PROCEDURE p(IN param1 INT, OUT param2 INT) AS $$ SELECT param1; $$ LANGUAGE SQL;

statement error pgcode 42883 procedure p\(\) does not exist
CALL p();

statement error pgcode 42883 procedure p\(int\) does not exist
CALL p(1);

statement error pgcode 42883 procedure p\(int, string\) does not exist
CALL p(1, NULL::TEXT);

statement error pgcode 42883 procedure p\(int, int, int\) does not exist
CALL p(1, 2, 3);

statement ok
CREATE PROCEDURE p(IN param1 FLOAT, OUT param2 FLOAT) AS $$ SELECT param1; $$ LANGUAGE SQL;

query I colnames
CALL p(1, 2);
----
param2
1

query R colnames
CALL p(1.1, 2.2);
----
param2
1.1

statement error pgcode 42723 function "p" already exists with same argument types
CREATE PROCEDURE p(OUT param1 INT, IN param2 INT) AS $$ SELECT param2; $$ LANGUAGE SQL;

statement ok
CREATE OR REPLACE PROCEDURE p(OUT param2 INT, IN param1 INT) AS $$ SELECT param1; $$ LANGUAGE SQL;

query I colnames
CALL p(1, 2);
----
param2
2

statement error pgcode 42723 function "p" already exists with same argument types
CREATE PROCEDURE p(OUT param1 INT, IN param2 INT, OUT param3 INT) AS $$ SELECT (1, param2); $$ LANGUAGE SQL;

statement ok
CREATE PROCEDURE p(OUT param1 INT, IN param2 INT, IN param3 INT) AS $$ SELECT param2 + param3; $$ LANGUAGE SQL;

query I colnames
CALL p(1, 2, 3);
----
param1
5

statement error pgcode 42723 function "p" already exists with same argument types
CREATE PROCEDURE p(INOUT param1 INT, IN param2 INT) AS $$ SELECT param1 + param2; $$ LANGUAGE SQL;

statement ok
CREATE PROCEDURE p(OUT param1 INT, OUT param2 INT, OUT param3 INT) AS $$ SELECT (1, 2, 3); $$ LANGUAGE SQL;

statement error pgcode 42725 procedure p\(int, int, int\) is not unique
CALL p(1, 2, 3);

statement error pgcode 42725 procedure name "p" is not unique
DROP PROCEDURE p;

# For DROP PROCEDURE (and DROP ROUTINE if/when we implement it), if all
# parameters have unspecified ("default") parameter class, then Postgres applies
# two resolution approaches: Postgres-specific (the main) way of matching based
# on input parameters and SQL-compliant way of matching based on all parameters.
# See https://github.com/postgres/postgres/commit/e56bce5d43789cce95d099554ae9593ada92b3b7
# for more context.

statement error pgcode 42725 procedure name "p" is not unique
DROP PROCEDURE p(INT, INT, INT);

statement error pgcode 42725 procedure name "p" is not unique
DROP PROCEDURE p(INT, INT);

statement ok
DROP PROCEDURE p(OUT INT, INT, INT);

statement ok
CREATE PROCEDURE p(OUT param1 INT, IN param2 INT, IN param3 INT) AS $$ SELECT param2 + param3; $$ LANGUAGE SQL;

statement ok
DROP PROCEDURE p(OUT INT, INT, INT);

query III colnames
CALL p(-1, -2, -3);
----
param1  param2  param3
1       2       3

statement error pgcode 42725 procedure name "p" is not unique
DROP PROCEDURE p;

# Postgres here drops the overload with 3 OUT parameters.
statement ok
DROP PROCEDURE p(INT, INT, INT);

statement error pgcode 42883 procedure p\(\) does not exist
DROP PROCEDURE p(OUT INT, OUT INT, OUT INT);

statement ok
DROP PROCEDURE p(OUT INT, INT);

statement error pgcode 42883 procedure p\(\) does not exist
DROP PROCEDURE p();

statement ok
DROP PROCEDURE p;

statement ok
CREATE PROCEDURE p(OUT param INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

statement error pgcode 42883 procedure p\(\) does not exist
CALL p();

statement error pgcode 42723 function "p" already exists with same argument types
CREATE PROCEDURE p(OUT param1 INT, OUT param2 INT) AS $$ SELECT (1, 2); $$ LANGUAGE SQL;

# Argument expressions for OUT parameters shouldn't be evaluated.
query I colnames
CALL p(1 // 0);
----
param
1

statement ok
DROP PROCEDURE p;

statement ok
CREATE PROCEDURE p(IN INT, INOUT a INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

# Argument expressions for IN and INOUT parameters are evaluated.
statement error pgcode 22012 division by zero
CALL p(1 // 0, 1);

statement error pgcode 22012 division by zero
CALL p(1, 1 // 0);

statement ok
DROP PROCEDURE p;

statement ok
CREATE PROCEDURE p(IN param1 INT, INOUT param2 INT, OUT param3 INT) AS $$ SELECT 1, 2; $$ LANGUAGE SQL;

statement error pgcode 42883 procedure p\(int, int\) does not exist
CALL p(1, 2)

query II colnames
CALL p(3, 4, NULL);
----
param2  param3
1       2

statement ok
DROP PROCEDURE p;

statement ok
CREATE PROCEDURE p(IN param1 INT, IN param2 INT) AS $$ SELECT 1, 2; $$ LANGUAGE SQL;

# This procedure returns VOID type, so this result should be empty.
query empty
CALL p(3, 4);
----

statement ok
DROP PROCEDURE p;

statement error pgcode 42P13 pq: return type mismatch in function declared to return record
CREATE PROCEDURE p(INOUT param1 INT, OUT param2 INT) AS $$ SELECT 1, 2, 3; $$ LANGUAGE SQL;

statement error pgcode 42P13 pq: return type mismatch in function declared to return record
CREATE PROCEDURE p(INOUT param INT) AS $$ SELECT 'hello'; $$ LANGUAGE SQL;

# Verify that function resolution works correctly when dropping procedures (OUT
# arguments are ignored).
statement ok
CREATE PROCEDURE p(OUT param INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

statement ok
DROP PROCEDURE p;

statement ok
CREATE PROCEDURE p(OUT param INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

statement ok
DROP PROCEDURE p(OUT INT);

statement ok
CREATE PROCEDURE p(OUT param1 INT, OUT param2 INT) AS $$ SELECT 1, 2; $$ LANGUAGE SQL;

statement ok
DROP PROCEDURE p(OUT INT);

statement ok
CREATE PROCEDURE p(OUT param1 INT, OUT param2 INT) AS $$ SELECT 1, 2; $$ LANGUAGE SQL;

statement error pgcode 42883 pq: procedure p\(int\) does not exist
DROP PROCEDURE p(INT);

statement ok
DROP PROCEDURE p;

subtest end

subtest show_create

statement ok
CREATE PROCEDURE p(IN p1 INT, INOUT p2 INT, IN OUT p3 INT, OUT p4 INT) AS $$
SELECT p2, p3, p1;
$$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p];
----
CREATE PROCEDURE public.p(IN p1 INT8, INOUT p2 INT8, INOUT p3 INT8, OUT p4 INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT p2, p3, p1;
$$

statement ok
DROP PROCEDURE p;

statement ok
CREATE PROCEDURE p(OUT param INT) AS $$
SELECT 1;
$$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p];
----
CREATE PROCEDURE public.p(OUT param INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT 1;
$$

statement ok
DROP PROCEDURE p;

subtest end

subtest parameter_names

# Sharing of parameter names is only allowed across two different "parameter
# namespaces" (IN vs OUT).

statement error pgcode 42P13 pq: parameter name "a" used more than once
CREATE PROCEDURE p_same_name(IN a INT, IN a INT) LANGUAGE SQL AS $$ SELECT 1 $$;

statement error pgcode 42P13 pq: parameter name "a" used more than once
CREATE PROCEDURE p_same_name(IN a INT, INOUT a INT) LANGUAGE SQL AS $$ SELECT 1 $$;

statement error pgcode 42P13 pq: parameter name "a" used more than once
CREATE PROCEDURE p_same_name(OUT a INT, INOUT a INT) LANGUAGE SQL AS $$ SELECT 1, 1 $$;

statement ok
CREATE PROCEDURE p_same_name(IN a INT, OUT a INT) LANGUAGE SQL AS $$ SELECT 1 $$;

query I colnames
CALL p_same_name(2, NULL);
----
a
1

statement ok
CREATE OR REPLACE PROCEDURE p_same_name(IN a INT, OUT a INT) LANGUAGE SQL AS $$ SELECT a $$;

query I colnames
CALL p_same_name(2, NULL);
----
a
2

statement error pgcode 42703 pq: column "param_out" does not exist
CREATE PROCEDURE p_names(IN param_in INT, OUT param_out INT) LANGUAGE SQL AS $$ SELECT param_out $$;

statement ok
CREATE PROCEDURE p_names(IN param_in INT, OUT param_out INT) LANGUAGE SQL AS $$ SELECT param_in $$;

query I colnames
CALL p_names(2, NULL);
----
param_out
2

statement ok
CREATE PROCEDURE p_out_int(OUT param INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

query I colnames
CALL p_out_int(NULL);
----
param
1

statement ok
CREATE PROCEDURE p_in_int(IN param INT) AS $$ SELECT param; $$ LANGUAGE SQL;

# This procedure returns VOID type, so this result should be empty.
query empty
CALL p_in_int(2);
----

statement ok
CREATE PROCEDURE p_inout_int(INOUT param INT) AS $$ SELECT param; $$ LANGUAGE SQL;

query I colnames
CALL p_inout_int(2);
----
param
2

# Unlike for functions, changing single OUT parameter name is not ok.
statement error pgcode 42P13 pq: cannot change return type of existing function
CREATE OR REPLACE PROCEDURE p_out_int(OUT param_new INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

# Changing IN or INOUT parameter name is not allowed.
statement error pgcode 42P13 pq: cannot change name of input parameter "param"
CREATE OR REPLACE PROCEDURE p_in_int(IN param_new INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

statement error pgcode 42P13 pq: cannot change return type of existing function
CREATE OR REPLACE PROCEDURE p_inout_int(INOUT param_new INT) AS $$ SELECT 1; $$ LANGUAGE SQL;

subtest end

subtest changing_parameters

statement ok
CREATE PROCEDURE p_int(IN param INT) AS $$ SELECT param; $$ LANGUAGE SQL;

statement error pgcode 42P13 pq: cannot change whether a procedure has output parameters
CREATE OR REPLACE PROCEDURE p_int(IN param INT, OUT INT) AS $$ SELECT param; $$ LANGUAGE SQL;

statement ok
DROP PROCEDURE p_int;

statement ok
CREATE PROCEDURE p_int(IN param INT, OUT INT) AS $$ SELECT param; $$ LANGUAGE SQL;

statement error pgcode 42P13 pq: cannot change whether a procedure has output parameters
CREATE OR REPLACE PROCEDURE p_int(IN param INT) AS $$ SELECT param; $$ LANGUAGE SQL;

# We can change the order of parameters across IN and OUT "namespaces" as long
# as we preserve the right ordering within each "namespace".
statement ok
CREATE PROCEDURE p_3_in_2_out(IN param1 INT, IN param2 INT, IN param3 INT, OUT param1 INT, OUT param2 INT) AS $$ SELECT (param1, param2 + param3); $$ LANGUAGE SQL;

query II colnames
CALL p_3_in_2_out(2, 2, 2, NULL, NULL);
----
param1  param2
2       4

statement ok
CREATE OR REPLACE PROCEDURE p_3_in_2_out(IN param1 INT, OUT param1 INT, IN param2 INT, IN param3 INT, OUT param2 INT) AS $$ SELECT (param1, param2 + param3); $$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p_3_in_2_out];
----
CREATE PROCEDURE public.p_3_in_2_out(IN param1 INT8, OUT param1 INT8, IN param2 INT8, IN param3 INT8, OUT param2 INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT (param1, param2 + param3);
$$

query II colnames
CALL p_3_in_2_out(2, NULL, 2, 2, NULL);
----
param1  param2
2       4

# We can also merge some parameters as long as they have the same names.
statement error pgcode 42P13 pq: cannot change return type of existing function
CREATE OR REPLACE PROCEDURE p_3_in_2_out(INOUT param1 INT, IN param2 INT, INOUT param3 INT) AS $$ SELECT (1, 1); $$ LANGUAGE SQL;

statement ok
CREATE OR REPLACE PROCEDURE p_3_in_2_out(INOUT param1 INT, INOUT param2 INT, IN param3 INT) AS $$ SELECT (param1, param2 + param3); $$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p_3_in_2_out];
----
CREATE PROCEDURE public.p_3_in_2_out(INOUT param1 INT8, INOUT param2 INT8, IN param3 INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT (param1, param2 + param3);
$$

query II colnames
CALL p_3_in_2_out(2, 2, 2);
----
param1  param2
2       4

subtest end

subtest default_parameter_names

# Parameter names are optional. Each unnamed output parameter with ordinal 'i'
# (among all output parameters) gets the default name that is "column" || i.

statement ok
CREATE PROCEDURE p_default_names(OUT INT, OUT param2 INT, IN INT, OUT INT) AS $$ SELECT (1, 2, 3); $$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names];
----
CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT (1:::INT8, 2:::INT8, 3:::INT8);
$$

query III colnames
CALL p_default_names(NULL, NULL, 3, NULL);
----
column1  param2  column3
1        2       3

# Introducing the OUT parameter name is disallowed because it'd change the
# return type.
statement error pgcode 42P13 cannot change return type of existing function
CREATE OR REPLACE PROCEDURE p_default_names(OUT INT, OUT param2 INT, IN INT, OUT param3 INT) AS $$ SELECT (1, 2, 3); $$ LANGUAGE SQL;

# Introducing the name that matches the default OUT parameter name is allowed.
statement ok
CREATE OR REPLACE PROCEDURE p_default_names(OUT INT, OUT param2 INT, IN INT, OUT column3 INT) AS $$ SELECT (1, 2, 3); $$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names];
----
CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT column3 INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT (1:::INT8, 2:::INT8, 3:::INT8);
$$

query III colnames
CALL p_default_names(NULL, NULL, 3, NULL);
----
column1  param2  column3
1        2       3

# Then we can omit the default OUT parameter name again.
statement ok
CREATE OR REPLACE PROCEDURE p_default_names(OUT INT, OUT param2 INT, IN INT, OUT INT) AS $$ SELECT (1, 2, 3); $$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names];
----
CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN INT8, OUT INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT (1:::INT8, 2:::INT8, 3:::INT8);
$$

query III colnames
CALL p_default_names(NULL, NULL, 3, NULL);
----
column1  param2  column3
1        2       3

# Introducing the IN parameter name is ok.
statement ok
CREATE OR REPLACE PROCEDURE p_default_names(OUT INT, OUT param2 INT, IN in_param INT, OUT INT) AS $$ SELECT (in_param, 2, 3); $$ LANGUAGE SQL;

query T
SELECT create_statement FROM [SHOW CREATE PROCEDURE p_default_names];
----
CREATE PROCEDURE public.p_default_names(OUT INT8, OUT param2 INT8, IN in_param INT8, OUT INT8)
  LANGUAGE SQL
  SECURITY INVOKER
  AS $$
  SELECT (in_param, 2, 3);
$$

query III colnames
CALL p_default_names(NULL, NULL, 3, NULL);
----
column1  param2  column3
3        2       3

# But then the IN parameter name cannot be changed anymore.
statement error pgcode 42P13 cannot change name of input parameter "in_param"
CREATE OR REPLACE PROCEDURE p_default_names(OUT INT, OUT param2 INT, IN in_param_new INT, OUT INT) AS $$ SELECT (1, 2, 3); $$ LANGUAGE SQL;

subtest end

statement ok
CREATE TYPE typ AS (a INT, b INT);

statement ok
CREATE PROCEDURE p_udt(OUT typ) AS $$ SELECT (1, 2); $$ LANGUAGE SQL;

query T colnames
CALL p_udt(NULL);
----
column1
(1,2)

statement error pgcode 2BP01 cannot drop type "typ" because other objects \(\[test.public.p_udt\]\) still depend on it
DROP TYPE typ;

statement ok
DROP PROCEDURE p_udt;

statement ok
CREATE TYPE greeting AS ENUM('hello', 'hi', 'yo');
CREATE PROCEDURE p_enum(OUT greeting greeting) LANGUAGE SQL AS $$ SELECT 'hi'::greeting; $$;

query T
CALL p_enum(NULL);
----
hi

statement error pgcode 2BP01 cannot drop type "greeting" because other objects \(\[test.public.p_enum\]\) still depend on it
DROP TYPE greeting;

statement ok
DROP PROCEDURE p_enum;

subtest default_exprs

statement error pgcode 22P02 could not parse "a" as type int
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT 2, c INT DEFAULT 'a') LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 42P13 input parameters after one with a default value must also have defaults
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT 2, c INT) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 42P13 input parameters after one with a default value must also have defaults
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT 2, INOUT c INT) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 42P13 only input parameters can have default values
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT 2, OUT c INT = 3) LANGUAGE SQL AS $$ SELECT a + b; $$;

statement error pgcode 42P13 procedure OUT parameters cannot appear after one with a default value
CREATE PROCEDURE my_sum(a INT, b INT DEFAULT 2, OUT INT) LANGUAGE SQL AS $$ SELECT a + b; $$;

statement error pgcode 42703 column "b" does not exist
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT, c INT = b + 1) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 42703 column "b" does not exist
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT 2, c INT = b + 1) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 42703 column "d" does not exist
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT 2, c INT = d + 1) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 42804 argument of DEFAULT must be type int, not type bool
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT true) LANGUAGE SQL AS $$ SELECT a + b; $$;

statement ok
CREATE PROCEDURE my_sum(OUT INT, a INT, b INT, c INT) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 42P13 input parameters after one with a default value must also have defaults
CREATE OR REPLACE PROCEDURE my_sum(OUT INT, a INT = 1, b INT, c INT = 3) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

# Adding a default expression to a parameter is ok.
statement ok
CREATE OR REPLACE PROCEDURE my_sum(OUT INT, a INT, b INT DEFAULT 2, c INT = 3) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

# But removing an existing default expression is not ok.
statement error pgcode 42P13 cannot remove parameter defaults from existing function
CREATE OR REPLACE PROCEDURE my_sum(OUT INT, a INT, b INT, c INT = 3) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 22P02 could not parse "a" as type int
CREATE OR REPLACE PROCEDURE my_sum(OUT INT, a INT = 'a', b INT DEFAULT 2, c INT = 3) LANGUAGE SQL AS $$ SELECT a + b + c; $$;

statement error pgcode 0A000 subqueries are not allowed in DEFAULT expressions
CREATE OR REPLACE PROCEDURE my_sum(a INT, b INT DEFAULT (SELECT 1)) LANGUAGE SQL AS $$ SELECT a + b; $$;

statement error pgcode 0A000 subqueries are not allowed in DEFAULT expressions
CREATE OR REPLACE PROCEDURE my_sum(a INT, b INT DEFAULT 1 + (SELECT 2 FROM (VALUES (NULL)))) LANGUAGE SQL AS $$ SELECT a + b; $$;

query I
CALL my_sum(NULL, 1);
----
6

query I
CALL my_sum(NULL, 1, 1);
----
5

# Add another overload that creates ambiguity for some number of input
# arguments.
statement ok
CREATE PROCEDURE my_sum(OUT INT, a INT) LANGUAGE SQL AS $$ SELECT a; $$;

statement error pgcode 42725 procedure my_sum\(unknown, int\) is not unique
CALL my_sum(NULL, 1);

statement ok
DROP PROCEDURE my_sum(INT);

statement ok
DROP PROCEDURE my_sum;

statement ok
CREATE PROCEDURE my_sum(OUT sum INT, INOUT a INT, INOUT b INT = 3) AS $$ SELECT (a + b, a, b); $$ LANGUAGE SQL;

query III
CALL my_sum(NULL, 1);
----
4  1  3

query III
CALL my_sum(NULL, 1, 1);
----
2  1  1

statement ok
DROP PROCEDURE my_sum;

# Test for a narrowing type coercion.
statement ok
CREATE PROCEDURE f(OUT CHAR, x CHAR DEFAULT 'foo') AS $$ SELECT x; $$ LANGUAGE SQL;

# Note that postgres doesn't actually truncate the value and returns 'foo' here
# (this difference is tracked by #115385).
query T
CALL f(NULL);
----
f

statement ok
DROP PROCEDURE f;

# Test case when DEFAULT expression uses a UDF.

statement ok
CREATE FUNCTION f1(a INT, b INT = 2) RETURNS INT LANGUAGE SQL AS $$ SELECT a + b; $$;

statement ok
CREATE PROCEDURE p2(OUT INT, a INT, b INT = f1(1)) LANGUAGE SQL AS $$ SELECT a + b; $$;

query I
CALL p2(NULL, 1);
----
4

query I
CALL p2(NULL, 1, 1);
----
2

statement ok
CREATE OR REPLACE FUNCTION f1(a INT, b INT = 2) RETURNS INT LANGUAGE SQL AS $$ SELECT a * b; $$;

query I
CALL p2(NULL, 1);
----
3

query I
CALL p2(NULL, 1, 1);
----
2

statement error pgcode 2BP01 cannot drop function "f1" because other objects \(\[test.public.p2\]\) still depend on it
DROP FUNCTION f1;

statement ok
DROP PROCEDURE p2;

statement ok
DROP FUNCTION f1;

# Test that dropping UDTs or enum members used in the DEFAULT expression is not
# allowed.

statement ok
CREATE PROCEDURE p(p1 typ DEFAULT (1, 2), p2 greeting = 'yo') LANGUAGE SQL AS $$ SELECT 1; $$;

statement error pgcode 2BP01 cannot drop type "typ" because other objects \(\[test.public.p\]\) still depend on it
DROP TYPE typ;

statement error pgcode 2BP01 could not remove enum value "yo" as it is being used in a routine "p"
ALTER TYPE greeting DROP VALUE 'yo';

# Dropping enum value not used in the DEFAULT expression should be ok.
statement ok
ALTER TYPE greeting DROP VALUE 'hello';

# Using a different enum value in the DEFAULT expression should allow us to drop
# the original enum value.
statement ok
CREATE OR REPLACE PROCEDURE p(p1 typ DEFAULT (1, 2), p2 greeting = 'hi') LANGUAGE SQL AS $$ SELECT 1; $$;

statement ok
ALTER TYPE greeting DROP VALUE 'yo';

statement error pgcode 2BP01 could not remove enum value "hi" as it is being used in a routine "p"
ALTER TYPE greeting DROP VALUE 'hi';

statement ok
DROP PROCEDURE p;

# Test having sequences in the DEFAULT expression.

statement ok
CREATE SEQUENCE seq;

statement ok
CREATE PROCEDURE p(OUT INT, a INT = nextval('seq'))AS $$ SELECT a; $$ LANGUAGE SQL;

query I
CALL p(NULL);
----
1

query I
CALL p(NULL, 1);
----
1

query I
CALL p(NULL);
----
2

statement error pgcode 2BP01 cannot drop sequence seq because other objects depend on it
DROP SEQUENCE seq;

statement ok
CREATE OR REPLACE PROCEDURE p(OUT INT, a INT = 3) AS $$ SELECT a; $$ LANGUAGE SQL;

# DEFAULT expression no longer uses the sequence.
statement ok
DROP SEQUENCE seq;

statement ok
DROP PROCEDURE p;

# Try doing the same when the sequence is added in the replacement.

statement ok
CREATE SEQUENCE seq;

statement ok
CREATE OR REPLACE PROCEDURE p(OUT INT, a INT = 3) AS $$ SELECT a; $$ LANGUAGE SQL;

statement ok
CREATE OR REPLACE PROCEDURE p(OUT INT, a INT = nextval('seq'))AS $$ SELECT a; $$ LANGUAGE SQL;

statement error pgcode 2BP01 cannot drop sequence seq because other objects depend on it
DROP SEQUENCE seq;

statement ok
DROP PROCEDURE p;

statement ok
DROP SEQUENCE seq;

subtest end
