diff --git a/doc/src/sgml/ref/create_schema.sgml b/doc/src/sgml/ref/create_schema.sgml
index 930d876..70aeec3 100644
--- a/doc/src/sgml/ref/create_schema.sgml
+++ b/doc/src/sgml/ref/create_schema.sgml
@@ -21,8 +21,8 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE SCHEMA <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">user_name</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
-CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">user_name</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
+CREATE SCHEMA [ IF NOT EXISTS ] <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">user_name</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
+CREATE SCHEMA [ IF NOT EXISTS ] AUTHORIZATION <replaceable class="parameter">user_name</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -62,6 +62,16 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">user_name</replaceabl
 
     <variablelist>
      <varlistentry>
+      <term><literal>IF NOT EXISTS</literal></term>
+      <listitem>
+       <para>
+        Do not throw an error if a schema with the same name already exists.
+        A notice is issued in this case.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><replaceable class="parameter">schema_name</replaceable></term>
       <listitem>
        <para>
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index ec8aa17..8a62341 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1376,6 +1376,7 @@ CreateExtension(CreateExtensionStmt *stmt)
 			csstmt->schemaname = schemaName;
 			csstmt->authid = NULL;		/* will be created by current user */
 			csstmt->schemaElts = NIL;
+			csstmt->if_not_exists = false;
 			CreateSchemaCommand(csstmt, NULL);
 
 			/*
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index cd5ce06..b01c571 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -51,6 +51,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
 	Oid			saved_uid;
 	int			save_sec_context;
 	AclResult	aclresult;
+    bool        if_not_exists = stmt->if_not_exists;
 
 	GetUserIdAndSecContext(&saved_uid, &save_sec_context);
 
@@ -95,12 +96,21 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
 		SetUserIdAndSecContext(owner_uid,
 							save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
 
-	/* Create the schema's namespace */
-	namespaceId = NamespaceCreate(schemaName, owner_uid, false);
-
-	/* Advance cmd counter to make the namespace visible */
-	CommandCounterIncrement();
-
+	/* If schema already exists, skip */
+    namespaceId = get_namespace_oid(schemaName, true);
+	if (OidIsValid(namespaceId) && if_not_exists) {
+        ereport(NOTICE,
+                (errcode(ERRCODE_DUPLICATE_SCHEMA),
+                 errmsg("schema \"%s\" already exists, skipping",
+                        schemaName)));
+	} else {
+
+	    /* Create the schema's namespace */
+	    namespaceId = NamespaceCreate(schemaName, owner_uid, false);
+
+	    /* Advance cmd counter to make the namespace visible */
+	    CommandCounterIncrement();
+    }
 	/*
 	 * Temporarily make the new namespace be the front of the search path, as
 	 * well as the default creation target namespace.  This will be undone at
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index f34f704..9f6458b 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3614,6 +3614,7 @@ _copyCreateSchemaStmt(const CreateSchemaStmt *from)
 	COPY_STRING_FIELD(schemaname);
 	COPY_STRING_FIELD(authid);
 	COPY_NODE_FIELD(schemaElts);
+	COPY_SCALAR_FIELD(if_not_exists);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index b4b1c22..89ae94d 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1910,6 +1910,7 @@ _equalCreateSchemaStmt(const CreateSchemaStmt *a, const CreateSchemaStmt *b)
 	COMPARE_STRING_FIELD(schemaname);
 	COMPARE_STRING_FIELD(authid);
 	COMPARE_NODE_FIELD(schemaElts);
+	COMPARE_SCALAR_FIELD(if_not_exists);
 
 	return true;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 5894cb0..46b17ce 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -1169,8 +1169,23 @@ CreateSchemaStmt:
 						n->schemaname = $5;
 					n->authid = $5;
 					n->schemaElts = $6;
+					n->if_not_exists = false;
 					$$ = (Node *)n;
 				}
+			| CREATE SCHEMA IF_P NOT EXISTS OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
+				{
+					CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
+					/* One can omit the schema name or the authorization id. */
+					if ($6 != NULL)
+						n->schemaname = $6;
+					else
+						n->schemaname = $8;
+					n->authid = $8;
+					n->schemaElts = $9;
+					n->if_not_exists = true;
+					$$ = (Node *)n;
+				}
+
 			| CREATE SCHEMA ColId OptSchemaEltList
 				{
 					CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
@@ -1178,8 +1193,20 @@ CreateSchemaStmt:
 					n->schemaname = $3;
 					n->authid = NULL;
 					n->schemaElts = $4;
+					n->if_not_exists = false;
 					$$ = (Node *)n;
 				}
+			| CREATE SCHEMA IF_P NOT EXISTS ColId OptSchemaEltList
+				{
+					CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
+					/* ...but not both */
+					n->schemaname = $6;
+					n->authid = NULL;
+					n->schemaElts = $7;
+					n->if_not_exists = true;
+					$$ = (Node *)n;
+				}
+
 		;
 
 OptSchemaName:
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 19178b5..dee2004 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1157,6 +1157,7 @@ typedef struct CreateSchemaStmt
 	char	   *schemaname;		/* the name of the schema to create */
 	char	   *authid;			/* the owner of the created schema */
 	List	   *schemaElts;		/* schema components (list of parsenodes) */
+	bool		if_not_exists;	/* just do nothing if schema already exists? */
 } CreateSchemaStmt;
 
 typedef enum DropBehavior
diff --git a/src/test/regress/expected/namespace.out b/src/test/regress/expected/namespace.out
index 7c26da5..611072b 100644
--- a/src/test/regress/expected/namespace.out
+++ b/src/test/regress/expected/namespace.out
@@ -9,6 +9,25 @@ CREATE SCHEMA test_schema_1
               a serial,
               b int UNIQUE
        );
+-- verify if schema already exists
+CREATE SCHEMA test_schema_1;
+ERROR:  schema "test_schema_1" already exists
+CREATE SCHEMA IF NOT EXISTS test_schema_1;
+NOTICE:  schema "test_schema_1" already exists, skipping
+CREATE SCHEMA test_schema_2;
+CREATE SCHEMA IF NOT EXISTS test_schema_2
+       CREATE TABLE abc (
+              a serial,
+              b int UNIQUE
+       );
+NOTICE:  schema "test_schema_2" already exists, skipping
+CREATE SCHEMA IF NOT EXISTS test_schema_2
+       CREATE TABLE IF NOT EXISTS abc (
+              a serial,
+              b int UNIQUE
+       );
+NOTICE:  schema "test_schema_2" already exists, skipping
+NOTICE:  relation "abc" already exists, skipping
 -- verify that the objects were created
 SELECT COUNT(*) FROM pg_class WHERE relnamespace =
     (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
@@ -17,6 +36,13 @@ SELECT COUNT(*) FROM pg_class WHERE relnamespace =
      5
 (1 row)
 
+SELECT count(*) FROM pg_class
+    JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE relkind = 'r' AND nspname = 'test_schema_2';
+ count 
+-------
+     1
+(1 row)
+
 INSERT INTO test_schema_1.abc DEFAULT VALUES;
 INSERT INTO test_schema_1.abc DEFAULT VALUES;
 INSERT INTO test_schema_1.abc DEFAULT VALUES;
@@ -40,6 +66,8 @@ DROP SCHEMA test_schema_1 CASCADE;
 NOTICE:  drop cascades to 2 other objects
 DETAIL:  drop cascades to table test_schema_1.abc
 drop cascades to view test_schema_1.abc_view
+DROP SCHEMA test_schema_2 CASCADE;
+NOTICE:  drop cascades to table test_schema_2.abc
 -- verify that the objects were dropped
 SELECT COUNT(*) FROM pg_class WHERE relnamespace =
     (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
diff --git a/src/test/regress/sql/namespace.sql b/src/test/regress/sql/namespace.sql
index 919f72a..c2ef257 100644
--- a/src/test/regress/sql/namespace.sql
+++ b/src/test/regress/sql/namespace.sql
@@ -13,10 +13,27 @@ CREATE SCHEMA test_schema_1
               b int UNIQUE
        );
 
+-- verify if schema already exists
+CREATE SCHEMA test_schema_1;
+CREATE SCHEMA IF NOT EXISTS test_schema_1;
+CREATE SCHEMA test_schema_2;
+CREATE SCHEMA IF NOT EXISTS test_schema_2
+       CREATE TABLE abc (
+              a serial,
+              b int UNIQUE
+       );
+CREATE SCHEMA IF NOT EXISTS test_schema_2
+       CREATE TABLE IF NOT EXISTS abc (
+              a serial,
+              b int UNIQUE
+       );
 -- verify that the objects were created
 SELECT COUNT(*) FROM pg_class WHERE relnamespace =
     (SELECT oid FROM pg_namespace WHERE nspname = 'test_schema_1');
 
+SELECT count(*) FROM pg_class
+    JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE relkind = 'r' AND nspname = 'test_schema_2';
+
 INSERT INTO test_schema_1.abc DEFAULT VALUES;
 INSERT INTO test_schema_1.abc DEFAULT VALUES;
 INSERT INTO test_schema_1.abc DEFAULT VALUES;
@@ -25,6 +42,7 @@ SELECT * FROM test_schema_1.abc;
 SELECT * FROM test_schema_1.abc_view;
 
 DROP SCHEMA test_schema_1 CASCADE;
+DROP SCHEMA test_schema_2 CASCADE;
 
 -- verify that the objects were dropped
 SELECT COUNT(*) FROM pg_class WHERE relnamespace =
