diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 27e568f..6aa7f87 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -110,7 +110,7 @@ typedef struct
 
 
 static void transformColumnDefinition(CreateStmtContext *cxt,
-						  ColumnDef *column);
+						  ColumnDef *column, bool if_not_exists);
 static void transformTableConstraint(CreateStmtContext *cxt,
 						 Constraint *constraint);
 static void transformTableLikeClause(CreateStmtContext *cxt,
@@ -138,7 +138,8 @@ static void transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd);
 static void validateInfiniteBounds(ParseState *pstate, List *blist);
 static Const *transformPartitionBoundValue(ParseState *pstate, A_Const *con,
 							 const char *colName, Oid colType, int32 colTypmod);
-
+static bool skip_serial_add_column_if_not_exists(Relation rel, const char *colname,
+							bool if_not_exists);
 
 /*
  * transformCreateStmt -
@@ -277,7 +278,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 		switch (nodeTag(element))
 		{
 			case T_ColumnDef:
-				transformColumnDefinition(&cxt, (ColumnDef *) element);
+				transformColumnDefinition(&cxt, (ColumnDef *) element, false);
 				break;
 
 			case T_Constraint:
@@ -500,7 +501,7 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
  *		Also used in ALTER TABLE ADD COLUMN
  */
 static void
-transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
+transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column, bool if_not_exists)
 {
 	bool		is_serial;
 	bool		saw_nullable;
@@ -557,8 +558,8 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 	if (column->typeName)
 		transformColumnType(cxt, column);
 
-	/* Special actions for SERIAL pseudo-types */
-	if (is_serial)
+	/* Special actions for SERIAL pseudo-types, skip when IF NOT EXISTS is used */
+	if (is_serial && !skip_serial_add_column_if_not_exists(cxt->rel, column->colname, if_not_exists))
 	{
 		char	   *snamespace;
 		char	   *sname;
@@ -2714,7 +2715,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
 				{
 					ColumnDef  *def = castNode(ColumnDef, cmd->def);
 
-					transformColumnDefinition(&cxt, def);
+					transformColumnDefinition(&cxt, def, cmd->missing_ok);
 
 					/*
 					 * If the column has a non-null default, we can't skip
@@ -3560,3 +3561,29 @@ transformPartitionBoundValue(ParseState *pstate, A_Const *con,
 
 	return (Const *) value;
 }
+
+/*
+ * Skip SEQUENCE step when if_not_exists and column already exists
+ */
+static bool
+skip_serial_add_column_if_not_exists(Relation rel, const char *colname,
+									 bool if_not_exists)
+{
+	HeapTuple	attTuple;
+
+	if (!RelationIsValid(rel))
+		return false;
+
+	attTuple = SearchSysCache2(ATTNAME,
+							   ObjectIdGetDatum(RelationGetRelid(rel)),
+							   PointerGetDatum(colname));
+	if (!HeapTupleIsValid(attTuple))
+		return false;
+
+	ReleaseSysCache(attTuple);
+
+	if (if_not_exists)
+		return true;
+
+	return false;
+}
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 0478a8a..b759ce0 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -3121,6 +3121,48 @@ NOTICE:  column "c3" of relation "test_add_column" already exists, skipping
  c3     | integer |           |          | 
  c4     | integer |           |          | 
 
+ALTER TABLE test_add_column
+	ADD COLUMN c5 serial;
+\d test_add_column
+                            Table "public.test_add_column"
+ Column |  Type   | Collation | Nullable |                   Default                   
+--------+---------+-----------+----------+---------------------------------------------
+ c1     | integer |           |          | 
+ c2     | integer |           |          | 
+ c3     | integer |           |          | 
+ c4     | integer |           |          | 
+ c5     | integer |           | not null | nextval('test_add_column_c5_seq'::regclass)
+
+\ds test_add_column*
+                   List of relations
+ Schema |          Name          |   Type   |  Owner   
+--------+------------------------+----------+----------
+ public | test_add_column_c5_seq | sequence | fabrizio
+(1 row)
+
+ALTER TABLE test_add_column
+	ADD COLUMN c5 serial; -- fail because c5 already exists
+ERROR:  column "c5" of relation "test_add_column" already exists
+ALTER TABLE test_add_column
+	ADD COLUMN IF NOT EXISTS c5 serial; -- skipping because c5 already exists
+NOTICE:  column "c5" of relation "test_add_column" already exists, skipping
+\d test_add_column
+                            Table "public.test_add_column"
+ Column |  Type   | Collation | Nullable |                   Default                   
+--------+---------+-----------+----------+---------------------------------------------
+ c1     | integer |           |          | 
+ c2     | integer |           |          | 
+ c3     | integer |           |          | 
+ c4     | integer |           |          | 
+ c5     | integer |           | not null | nextval('test_add_column_c5_seq'::regclass)
+
+\ds test_add_column*
+                   List of relations
+ Schema |          Name          |   Type   |  Owner   
+--------+------------------------+----------+----------
+ public | test_add_column_c5_seq | sequence | fabrizio
+(1 row)
+
 DROP TABLE test_add_column;
 -- unsupported constraint types for partitioned tables
 CREATE TABLE partitioned (
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 37cca72..15ce995 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -1965,6 +1965,16 @@ ALTER TABLE test_add_column
 	ADD COLUMN IF NOT EXISTS c3 integer, -- skipping because c3 already exists
 	ADD COLUMN c4 integer;
 \d test_add_column
+ALTER TABLE test_add_column
+	ADD COLUMN c5 serial;
+\d test_add_column
+\ds test_add_column*
+ALTER TABLE test_add_column
+	ADD COLUMN c5 serial; -- fail because c5 already exists
+ALTER TABLE test_add_column
+	ADD COLUMN IF NOT EXISTS c5 serial; -- skipping because c5 already exists
+\d test_add_column
+\ds test_add_column*
 DROP TABLE test_add_column;
 
 -- unsupported constraint types for partitioned tables
