diff --git a/src/test/regress/expected/create_module.out b/src/test/regress/expected/create_module.out
new file mode 100644
index 0000000000..634df03e4c
--- /dev/null
+++ b/src/test/regress/expected/create_module.out
@@ -0,0 +1,83 @@
+CREATE TABLE cm_test (a int, b text);
+CREATE MODULE mtest1
+  CREATE FUNCTION m1testa() RETURNS text
+     LANGUAGE sql
+     RETURN '1x'
+  CREATE FUNCTION m1testb() RETURNS text
+     LANGUAGE sql
+     RETURN '1y';
+CREATE SCHEMA temp_mod_test;
+GRANT ALL ON SCHEMA temp_mod_test TO public;
+CREATE MODULE temp_mod_test.mtest2
+  CREATE PROCEDURE m2testa(x text)
+  LANGUAGE SQL
+  AS $$
+  INSERT INTO cm_test VALUES (1, x);
+  $$
+  CREATE FUNCTION m2testb() RETURNS text
+     LANGUAGE sql
+     RETURN '2y';
+CREATE MODULE mtest3
+  CREATE FUNCTION mtest3.m3testa() RETURNS text
+     LANGUAGE sql
+     RETURN '3x';
+ERROR:  CREATE FUNCTION (mtest3.m3testa) specifies a namespace inside of CREATE MODULE (mtest3)
+SELECT mtest1.m1testa();
+ m1testa 
+---------
+ 1x
+(1 row)
+
+SELECT mtest1.m1testb();
+ m1testb 
+---------
+ 1y
+(1 row)
+
+SELECT public.mtest1.m1testa();
+ m1testa 
+---------
+ 1x
+(1 row)
+
+SELECT public.mtest1.m1testb();
+ m1testb 
+---------
+ 1y
+(1 row)
+
+SELECT temp_mod_test.mtest2.m2testb();
+ m2testb 
+---------
+ 2y
+(1 row)
+
+SELECT temp_mod_test.mtest2.m2testa('x');  -- error
+ERROR:  temp_mod_test.mtest2.m2testa(unknown) is a procedure
+LINE 1: SELECT temp_mod_test.mtest2.m2testa('x');
+               ^
+HINT:  To call a procedure, use CALL.
+CALL temp_mod_test.mtest2.m2testa('a');  -- ok
+CALL temp_mod_test.mtest2.m2testa('xy' || 'zzy');  -- ok, constant-folded arg
+CREATE PROCEDURE mtest1.m1testc(x text)
+  LANGUAGE SQL
+  AS $$
+  INSERT INTO cm_test VALUES (2, x);
+  $$;
+ERROR:  schema "mtest1" does not exist
+CALL mtest1.m1testc('a');  -- ok
+ERROR:  schema "mtest1" does not exist
+LINE 1: CALL mtest1.m1testc('a');
+             ^
+DROP PROCEDURE mtest1.m1testc(text);
+ERROR:  procedure mtest1.m1testc(text) does not exist
+DROP FUNCTION temp_mod_test.mtest2.m2testb();
+-- cleanup
+DROP MODULE mtest1 CASCADE;
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to function mtest1.m1testa()
+drop cascades to function mtest1.m1testb()
+DROP MODULE temp_mod_test.mtest2 CASCADE;
+NOTICE:  drop cascades to function mtest2.m2testa(text)
+DROP SCHEMA temp_mod_test;
+DROP TABLE cm_test;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 22b0d3584d..e572bf212d 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -51,7 +51,7 @@ test: copy copyselect copydml insert insert_conflict
 # ----------
 # More groups of parallel tests
 # ----------
-test: create_misc create_operator create_procedure
+test: create_misc create_operator create_procedure create_module
 # These depend on create_misc and create_operator
 test: create_index create_index_spgist create_view index_including index_including_gist
 
diff --git a/src/test/regress/sql/create_module.sql b/src/test/regress/sql/create_module.sql
new file mode 100644
index 0000000000..8c1db1e636
--- /dev/null
+++ b/src/test/regress/sql/create_module.sql
@@ -0,0 +1,58 @@
+CREATE TABLE cm_test (a int, b text);
+
+CREATE MODULE mtest1
+  CREATE FUNCTION m1testa() RETURNS text
+     LANGUAGE sql
+     RETURN '1x'
+  CREATE FUNCTION m1testb() RETURNS text
+     LANGUAGE sql
+     RETURN '1y';
+
+CREATE SCHEMA temp_mod_test;
+GRANT ALL ON SCHEMA temp_mod_test TO public;
+
+CREATE MODULE temp_mod_test.mtest2
+  CREATE PROCEDURE m2testa(x text)
+  LANGUAGE SQL
+  AS $$
+  INSERT INTO cm_test VALUES (1, x);
+  $$
+  CREATE FUNCTION m2testb() RETURNS text
+     LANGUAGE sql
+     RETURN '2y';
+
+CREATE MODULE mtest3
+  CREATE FUNCTION mtest3.m3testa() RETURNS text
+     LANGUAGE sql
+     RETURN '3x';
+
+SELECT mtest1.m1testa();
+SELECT mtest1.m1testb();
+
+SELECT public.mtest1.m1testa();
+SELECT public.mtest1.m1testb();
+
+SELECT temp_mod_test.mtest2.m2testb();
+
+SELECT temp_mod_test.mtest2.m2testa('x');  -- error
+CALL temp_mod_test.mtest2.m2testa('a');  -- ok
+CALL temp_mod_test.mtest2.m2testa('xy' || 'zzy');  -- ok, constant-folded arg
+
+CREATE PROCEDURE mtest1.m1testc(x text)
+  LANGUAGE SQL
+  AS $$
+  INSERT INTO cm_test VALUES (2, x);
+  $$;
+
+CALL mtest1.m1testc('a');  -- ok
+
+DROP PROCEDURE mtest1.m1testc(text);
+DROP FUNCTION temp_mod_test.mtest2.m2testb();
+
+-- cleanup
+
+DROP MODULE mtest1 CASCADE;
+DROP MODULE temp_mod_test.mtest2 CASCADE;
+
+DROP SCHEMA temp_mod_test;
+DROP TABLE cm_test;
