diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 3432bb921d..ac961df791 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -4563,6 +4563,7 @@ _copyPartitionSpec(const PartitionSpec *from)
 
 	COPY_STRING_FIELD(strategy);
 	COPY_NODE_FIELD(partParams);
+	COPY_NODE_FIELD(partdefs);
 	COPY_LOCATION_FIELD(location);
 
 	return newnode;
@@ -4608,6 +4609,23 @@ _copyPartitionCmd(const PartitionCmd *from)
 	return newnode;
 }
 
+static SubPartition *
+_copySubPartition(const SubPartition *from)
+{
+	SubPartition *newnode = makeNode(SubPartition);
+	/*
+	 * TODO (Next Version)
+	 * It supports the necessary options in our current version
+	 * We should add something here for options support.
+	 */
+	COPY_NODE_FIELD(name);
+	COPY_NODE_FIELD(bound);
+	COPY_STRING_FIELD(tablespacename);
+	COPY_NODE_FIELD(partspec);
+
+	return newnode;
+}
+
 static CreatePublicationStmt *
 _copyCreatePublicationStmt(const CreatePublicationStmt *from)
 {
@@ -5634,6 +5652,9 @@ copyObjectImpl(const void *from)
 		case T_PartitionCmd:
 			retval = _copyPartitionCmd(from);
 			break;
+		case T_SubPartition:
+			retval = _copySubPartition(from);
+			break;
 
 			/*
 			 * MISCELLANEOUS NODES
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 18cb014373..cc966d38a4 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -2872,6 +2872,7 @@ _equalPartitionSpec(const PartitionSpec *a, const PartitionSpec *b)
 {
 	COMPARE_STRING_FIELD(strategy);
 	COMPARE_NODE_FIELD(partParams);
+	COMPARE_NODE_FIELD(partdefs);
 	COMPARE_LOCATION_FIELD(location);
 
 	return true;
@@ -2911,6 +2912,21 @@ _equalPartitionCmd(const PartitionCmd *a, const PartitionCmd *b)
 	return true;
 }
 
+static bool
+_equalSubPartition(const SubPartition *a, const SubPartition *b)
+{
+	/*
+	 * TODO
+	 * It just supports the necessary options currently for POC
+	 */
+	COMPARE_NODE_FIELD(name);
+	COMPARE_NODE_FIELD(bound);
+	COMPARE_STRING_FIELD(tablespacename);
+	COMPARE_NODE_FIELD(partspec);
+
+	return true;
+}
+
 /*
  * Stuff from pg_list.h
  */
@@ -3730,6 +3746,9 @@ equal(const void *a, const void *b)
 		case T_PartitionCmd:
 			retval = _equalPartitionCmd(a, b);
 			break;
+		case T_SubPartition:
+			retval = _equalSubPartition(a, b);
+			break;
 
 		default:
 			elog(ERROR, "unrecognized node type: %d",
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 3f67aaf30e..9273bb6ea8 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -588,6 +588,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <list>		part_params
 %type <partboundspec> PartitionBoundSpec
 %type <list>		hash_partbound
+%type <list>		table_partitions_list
+%type <node>		table_partition
 %type <defelt>		hash_partbound_elem
 
 /*
@@ -3870,6 +3872,18 @@ PartitionSpec: PARTITION BY part_strategy '(' part_params ')'
 
 					$$ = n;
 				}
+
+				|  PARTITION BY part_strategy '(' part_params ')' '(' table_partitions_list ')'
+				{
+					PartitionSpec *n = makeNode(PartitionSpec);
+
+					n->strategy = $3;
+					n->partParams = $5;
+					n->partdefs = $8;
+					n->location = @1;
+
+					$$ = n;
+				}
 		;
 
 part_strategy:	IDENT					{ $$ = $1; }
@@ -3915,6 +3929,35 @@ part_elem: ColId opt_collate opt_class
 				}
 		;
 
+/*
+ * table_partitions_list returns the list of PartitionCmd
+ * for now, Latter we may want to use more specific data structure
+ * when we will introduce the shard server specification syntax.
+ */
+table_partitions_list:
+			table_partitions_list ',' table_partition
+			{
+				$$ = lappend($1, $3);
+			}
+
+			| table_partition
+			{
+				$$ = list_make1($1);
+			}
+		;
+
+table_partition: PARTITION qualified_name PartitionBoundSpec OptTableSpace OptPartitionSpec
+				{
+					SubPartition *n = makeNode(SubPartition);
+
+					n->name = $2;
+					n->bound = $3;
+					n->tablespacename = $4;
+					n->partspec = $5;
+					$$ = n;
+				}
+		;
+
 table_access_method_clause:
 			USING access_method					{ $$ = $2; }
 			| /*EMPTY*/							{ $$ = NULL; }
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 6e5768c66c..7fe7d38c7b 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -121,6 +121,10 @@ static void transformTableLikeClause(CreateStmtContext *cxt,
 									 TableLikeClause *table_like_clause);
 static void transformOfType(CreateStmtContext *cxt,
 							TypeName *ofTypename);
+static void transformSubPartitionDefinition(CreateStmtContext *cxt,
+											SubPartition *partition, RangeVar *parentrelation);
+static void transformSubPartitionList(CreateStmtContext *cxt, List *partlist, RangeVar *parentrelation);
+
 static CreateStatsStmt *generateClonedExtStatsStmt(RangeVar *heapRel,
 												   Oid heapRelid, Oid source_statsid);
 static List *get_collation(Oid collation, Oid actual_datatype);
@@ -261,6 +265,14 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
 					 errmsg("cannot create partitioned table as inheritance child")));
+		/*
+		 * For handle the new syntax for create subpartition
+		 * during create parent partition table.
+		 */
+		if(stmt->partspec->partdefs)
+		{
+			transformSubPartitionList(&cxt, stmt->partspec->partdefs, cxt.relation);
+		}
 	}
 
 	/*
@@ -492,6 +504,66 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
 		*sname_p = sname;
 }
 
+/*
+ * transformSubPartitionList -
+ * Handle the subpartition list, and the function body is in transformCreateStmt
+ * function at first, and it comes to a independent function because of to
+ * implement recursion subpartition.
+ */
+static void
+transformSubPartitionList(CreateStmtContext *cxt, List *partlist, RangeVar *parentrelation)
+{
+	ListCell	*partielems = NULL;
+
+	//partlist = stmt->partspec->partdefs;
+	foreach(partielems, partlist)
+	{
+		Node *element = lfirst(partielems);
+		/*
+		* Set the subpartition create, into cxt.alist.
+		*/
+		transformSubPartitionDefinition(cxt, (SubPartition *) element, parentrelation);
+	}
+}
+
+/*
+ * transformSubPartitionDefinition -
+ * 		transform a partition create within CREATE TABLE
+ */
+static void
+transformSubPartitionDefinition(CreateStmtContext *cxt, SubPartition *partition, RangeVar *relation)
+{
+	CreateStmt *stmt = NULL;
+
+	stmt = makeNode(CreateStmt);
+	stmt->relation = partition->name;
+	stmt->relation->relpersistence = RELPERSISTENCE_PERMANENT;
+	stmt->tableElts = NULL;
+	stmt->inhRelations = list_make1(relation);
+	stmt->partbound = partition->bound;
+	stmt->partspec = partition->partspec;
+	stmt->ofTypename = NULL;
+	stmt->constraints = NIL;
+	/*
+	 * TODO
+	 * For table_access_method_clause
+	 */
+	stmt->accessMethod = NULL;
+	/*
+	 * TODO
+	 * For OptWith
+	 */
+	stmt->options = NULL;
+	stmt->oncommit = ONCOMMIT_NOOP;
+	stmt->tablespacename = partition->tablespacename;
+	cxt->alist = lappend(cxt->alist, stmt);
+
+	if(partition->partspec)
+	{
+		transformSubPartitionList(cxt, partition->partspec->partdefs, partition->name);
+	}
+}
+
 /*
  * transformColumnDefinition -
  *		transform a single ColumnDef within CREATE TABLE
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index bce2d59b0d..582b6d0ae0 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -476,6 +476,7 @@ typedef enum NodeTag
 	T_PartitionBoundSpec,
 	T_PartitionRangeDatum,
 	T_PartitionCmd,
+	T_SubPartition,
 	T_VacuumRelation,
 
 	/*
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index d93a79a554..455224a4a9 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -791,6 +791,9 @@ typedef struct PartitionSpec
 	char	   *strategy;		/* partitioning strategy ('hash', 'list' or
 								 * 'range') */
 	List	   *partParams;		/* List of PartitionElems */
+	List       *partdefs;       /* List of partition definations
+								 * provided in the CREATE TABLE
+								 */
 	int			location;		/* token location, or -1 if unknown */
 } PartitionSpec;
 
@@ -859,6 +862,23 @@ typedef struct PartitionCmd
 	PartitionBoundSpec *bound;	/* FOR VALUES, if attaching */
 } PartitionCmd;
 
+/*
+ * Partition - info for subpartition which created during create parent table.
+ */
+typedef struct SubPartition
+{
+	/*
+	 * TODO
+	 * It supports the necessary options in our current version
+	 * We should add something here for options support.
+	 */
+	NodeTag		type;
+	RangeVar   *name;			/* name of partition to attach/detach/create */
+	char       *tablespacename;	/* table space to use, or NULL */
+	PartitionBoundSpec *bound;	/* FOR VALUES of creating subpartition*/
+	PartitionSpec *partspec;	/* PARTITION BY clause */
+}SubPartition;
+
 /****************************************************************************
  *	Nodes for a Query tree
  ****************************************************************************/
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index fb65265175..ceb65528fb 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -1698,6 +1698,7 @@ PartitionBoundInfo
 PartitionBoundInfoData
 PartitionBoundSpec
 PartitionCmd
+SubPartition
 PartitionDesc
 PartitionDescData
 PartitionDirectory
