hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From iw...@apache.org
Subject [2/3] incubator-hawq git commit: HAWQ-404. Close each partition after inserting when optimizer guarantees input is sorted on partition-id.
Date Tue, 15 Mar 2016 01:54:58 GMT
HAWQ-404. Close each partition after inserting when optimizer guarantees input is sorted on
partition-id.


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/6e6890ae
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/6e6890ae
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/6e6890ae

Branch: refs/heads/master
Commit: 6e6890ae7886b050aeb9c9d7e885fc84eb99937c
Parents: 2c38b42
Author: George Caragea <gcaragea@pivotal.io>
Authored: Mon Feb 29 22:21:13 2016 -0800
Committer: Haisheng Yuan <hyuan@pivotal.io>
Committed: Wed Mar 2 18:27:22 2016 -0800

----------------------------------------------------------------------
 src/backend/executor/execDML.c              |  99 +++++++++++-------
 src/backend/executor/execMain.c             |  13 +--
 src/backend/executor/execUtils.c            |   2 +-
 src/backend/executor/nodeDML.c              |   2 +-
 src/backend/utils/misc/guc.c                |   2 +-
 src/include/executor/execDML.h              |   3 +-
 src/include/nodes/execnodes.h               |   7 +-
 src/test/regress/expected/goh_partition.out | 126 +++++++++++++++++++++++
 src/test/regress/sql/goh_partition.sql      |  68 ++++++++++++
 9 files changed, 271 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/backend/executor/execDML.c
----------------------------------------------------------------------
diff --git a/src/backend/executor/execDML.c b/src/backend/executor/execDML.c
index d36e9ed..d6f05de 100644
--- a/src/backend/executor/execDML.c
+++ b/src/backend/executor/execDML.c
@@ -158,10 +158,11 @@ reconstructMatchingTupleSlot(TupleTableSlot *slot, ResultRelInfo *resultRelInfo)
  */
 void
 ExecInsert(TupleTableSlot *slot,
-		   DestReceiver *dest,
-		   EState *estate,
-		   PlanGenerator planGen,
-		   bool isUpdate)
+		DestReceiver *dest,
+		EState *estate,
+		PlanGenerator planGen,
+		bool isUpdate,
+		bool isInputSorted)
 {
 	void		*tuple = NULL;
 	ResultRelInfo *resultRelInfo = NULL;
@@ -184,7 +185,7 @@ ExecInsert(TupleTableSlot *slot,
 		resultRelInfo = slot_get_partition(slot, estate);
 		estate->es_result_relation_info = resultRelInfo;
 
-		if (NULL != resultRelInfo->ri_parquetSendBack)
+		if (NULL != resultRelInfo->ri_insertSendBack)
 		{
 			/*
 			 * The Parquet part we are about to insert into
@@ -203,59 +204,82 @@ ExecInsert(TupleTableSlot *slot,
 		 * inserted into (GPSQL-2291).
 		 */
 		Oid new_part_oid = resultRelInfo->ri_RelationDesc->rd_id;
-		if (gp_parquet_insert_sort &&
+
+		if (isInputSorted &&
 				PLANGEN_OPTIMIZER == planGen &&
-				InvalidOid != estate->es_last_parq_part &&
-				new_part_oid != estate->es_last_parq_part)
+				InvalidOid != estate->es_last_inserted_part &&
+				new_part_oid != estate->es_last_inserted_part)
 		{
 
 			Assert(NULL != estate->es_partition_state->result_partition_hash);
 
 			ResultPartHashEntry *entry = hash_search(estate->es_partition_state->result_partition_hash,
-									&estate->es_last_parq_part,
-									HASH_FIND,
-									NULL /* found */);
+					&estate->es_last_inserted_part,
+					HASH_FIND,
+					NULL /* found */);
 
 			Assert(NULL != entry);
 			Assert(entry->offset < estate->es_num_result_relations);
 
 			ResultRelInfo *oldResultRelInfo = & estate->es_result_relations[entry->offset];
+			Assert(NULL != oldResultRelInfo);
 
-			elog(DEBUG1, "Switching from old part oid=%d name=[%s] to new part oid=%d name=[%s]",
-					estate->es_last_parq_part,
-					oldResultRelInfo->ri_RelationDesc->rd_rel->relname.data,
-					new_part_oid,
-					resultRelInfo->ri_RelationDesc->rd_rel->relname.data);
-
-			/*
-			 * We are opening a new partition, and the last partition we
-			 * inserted into was a Parquet part. Let's close the old
-			 * parquet insert descriptor to free the memory before
-			 * opening the new one.
-			 */
-			ParquetInsertDescData *oldInsertDesc = oldResultRelInfo->ri_parquetInsertDesc;
 
 			/*
 			 * We need to preserve the "sendback" information that needs to be
 			 * sent back to the QD process from this part.
 			 * Compute it here, and store it for later use.
 			 */
-			QueryContextDispatchingSendBack sendback =
-					CreateQueryContextDispatchingSendBack(1);
+			QueryContextDispatchingSendBack sendback = CreateQueryContextDispatchingSendBack(1);
 			sendback->relid = RelationGetRelid(oldResultRelInfo->ri_RelationDesc);
-			oldInsertDesc->sendback = sendback;
-			parquet_insert_finish(oldInsertDesc);
 
-			/* Store the sendback information in the resultRelInfo for this part */
-			oldResultRelInfo->ri_parquetSendBack = sendback;
+			Relation oldRelation = oldResultRelInfo->ri_RelationDesc;
+			if (RelationIsAoRows(oldRelation))
+			{
+				AppendOnlyInsertDescData *oldInsertDesc = oldResultRelInfo->ri_aoInsertDesc;
+				Assert(NULL != oldInsertDesc);
+
+				elog(DEBUG1, "AO: Switching from old part oid=%d name=[%s] to new part oid=%d name=[%s]",
+						estate->es_last_inserted_part,
+						oldResultRelInfo->ri_RelationDesc->rd_rel->relname.data,
+						new_part_oid,
+						resultRelInfo->ri_RelationDesc->rd_rel->relname.data);
 
-			/* Record in the resultRelInfo that we closed the parquet insert descriptor */
-			oldResultRelInfo->ri_parquetInsertDesc = NULL;
+				oldInsertDesc->sendback = sendback;
 
-			/* Reset the last parquet part Oid, it's now closed */
-			estate->es_last_parq_part = InvalidOid;
+				appendonly_insert_finish(oldInsertDesc);
+				oldResultRelInfo->ri_aoInsertDesc = NULL;
+
+			}
+			else if (RelationIsParquet(oldRelation))
+			{
+				ParquetInsertDescData *oldInsertDesc = oldResultRelInfo->ri_parquetInsertDesc;
+				Assert(NULL != oldInsertDesc);
+
+				elog(DEBUG1, "PARQ: Switching from old part oid=%d name=[%s] to new part oid=%d name=[%s]",
+						estate->es_last_inserted_part,
+						oldResultRelInfo->ri_RelationDesc->rd_rel->relname.data,
+						new_part_oid,
+						resultRelInfo->ri_RelationDesc->rd_rel->relname.data);
+
+				oldInsertDesc->sendback = sendback;
+
+				parquet_insert_finish(oldInsertDesc);
+				oldResultRelInfo->ri_parquetInsertDesc = NULL;
+
+			}
+			else
+			{
+				Assert(false && "Unreachable");
+			}
+
+			/* Store the sendback information in the resultRelInfo for this part */
+			oldResultRelInfo->ri_insertSendBack = sendback;
+
+			estate->es_last_inserted_part = InvalidOid;
 		}
-	}
+
+  }
 	else
 	{
 		resultRelInfo = estate->es_result_relation_info;
@@ -362,7 +386,7 @@ ExecInsert(TupleTableSlot *slot,
 			resultRelInfo->ri_aoInsertDesc =
 				appendonly_insert_init(resultRelationDesc,
 									   segfileinfo);
-
+			estate->es_last_inserted_part = resultRelationDesc->rd_id;
 		}
 
 		appendonly_insert(resultRelInfo->ri_aoInsertDesc, tuple, &newId, &aoTupleId);
@@ -391,8 +415,7 @@ ExecInsert(TupleTableSlot *slot,
 			 * in estate, so that we can close it when switching to a
 			 * new partition (GPSQL-2291)
 			 */
-			elog(DEBUG1, "Saving es_last_parq_part. Old=%d, new=%d", estate->es_last_parq_part,
resultRelationDesc->rd_id);
-			estate->es_last_parq_part = resultRelationDesc->rd_id;
+			estate->es_last_inserted_part = resultRelationDesc->rd_id;
 		}
 
 		newId = parquet_insert(resultRelInfo->ri_parquetInsertDesc, partslot);

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/backend/executor/execMain.c
----------------------------------------------------------------------
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 1c215b0..6fa5cd2 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2927,7 +2927,7 @@ ExecEndPlan(PlanState *planstate, EState *estate)
 	{
 		if (resultRelInfo->ri_aoInsertDesc)
 			++aocount;
-		if (resultRelInfo->ri_parquetInsertDesc || resultRelInfo->ri_parquetSendBack)
+		if (resultRelInfo->ri_parquetInsertDesc || resultRelInfo->ri_insertSendBack)
 			++aocount;
 		resultRelInfo++;
 	}
@@ -2946,6 +2946,7 @@ ExecEndPlan(PlanState *planstate, EState *estate)
 		/* end (flush) the INSERT operation in the access layer */
 		if (resultRelInfo->ri_aoInsertDesc)
 		{
+
 			sendback = CreateQueryContextDispatchingSendBack(1);
 			resultRelInfo->ri_aoInsertDesc->sendback = sendback;
 			sendback->relid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
@@ -2956,9 +2957,9 @@ ExecEndPlan(PlanState *planstate, EState *estate)
 		/*need add processing for parquet insert desc*/
 		if (resultRelInfo->ri_parquetInsertDesc){
 
-			AssertImply(resultRelInfo->ri_parquetSendBack, gp_parquet_insert_sort);
+			AssertImply(resultRelInfo->ri_insertSendBack, gp_parquet_insert_sort);
 
-			if (NULL != resultRelInfo->ri_parquetSendBack)
+			if (NULL != resultRelInfo->ri_insertSendBack)
 			{
 				/*
 				 * The Parquet part we just finished inserting into already
@@ -2984,10 +2985,10 @@ ExecEndPlan(PlanState *planstate, EState *estate)
 		 * in the resultRelInfo, since the ri_parquetInsertDesc is freed
 		 * (GPSQL-2291)
 		 */
-		if (NULL != resultRelInfo->ri_parquetSendBack)
+		if (NULL != resultRelInfo->ri_insertSendBack)
 		{
 			Assert(NULL == sendback);
-			sendback = resultRelInfo->ri_parquetSendBack;
+			sendback = resultRelInfo->ri_insertSendBack;
 		}
 
 		if (resultRelInfo->ri_extInsertDesc)
@@ -3390,7 +3391,7 @@ lmark:	;
 				break;
 
 			case CMD_INSERT:
-				ExecInsert(slot, dest, estate, PLANGEN_PLANNER, false /* isUpdate */);
+				ExecInsert(slot, dest, estate, PLANGEN_PLANNER, false /* isUpdate */, false /* isInputSorted
*/);
 				result = NULL;
 				break;
 

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/backend/executor/execUtils.c
----------------------------------------------------------------------
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index eb1124d..780fa72 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -278,7 +278,7 @@ InternalCreateExecutorState(MemoryContext qcontext, bool is_subquery)
 	estate->es_result_relations = NULL;
 	estate->es_num_result_relations = 0;
 	estate->es_result_relation_info = NULL;
-	estate->es_last_parq_part = InvalidOid;
+	estate->es_last_inserted_part = InvalidOid;
 
 	estate->es_junkFilter = NULL;
 

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/backend/executor/nodeDML.c
----------------------------------------------------------------------
diff --git a/src/backend/executor/nodeDML.c b/src/backend/executor/nodeDML.c
index db103ce..5ba48df 100644
--- a/src/backend/executor/nodeDML.c
+++ b/src/backend/executor/nodeDML.c
@@ -120,7 +120,7 @@ ExecDML(DMLState *node)
 		 */
 		ExecInsert(node->cleanedUpSlot, NULL /* destReceiver */,
 				node->ps.state, PLANGEN_OPTIMIZER /* Plan origin */, 
-				isUpdate);
+				isUpdate, plannode->inputSorted);
 	}
 	else /* DML_DELETE */
 	{

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/backend/utils/misc/guc.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 4e54ae8..b9a5204 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -6150,7 +6150,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"optimizer_parts_to_force_sort_on_insert", PGC_USERSET, DEVELOPER_OPTIONS,
 			gettext_noop("Minimum number of partitions required to force sorting tuples during insertion
in an append only row-oriented partitioned table"),
 			NULL,
-			GUC_NOT_IN_SAMPLE
+			GUC_NOT_IN_SAMPLE | GUC_GPDB_ADDOPT
 		},
 		&optimizer_parts_to_force_sort_on_insert,
 		INT_MAX, 0, INT_MAX, NULL, NULL

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/include/executor/execDML.h
----------------------------------------------------------------------
diff --git a/src/include/executor/execDML.h b/src/include/executor/execDML.h
index f1f45c8..886b585 100644
--- a/src/include/executor/execDML.h
+++ b/src/include/executor/execDML.h
@@ -54,7 +54,8 @@ ExecInsert(TupleTableSlot *slot,
 		   DestReceiver *dest,
 		   EState *estate,
 		   PlanGenerator planGen,
-		   bool isUpdate);
+		   bool isUpdate,
+		   bool isInputSorted);
 
 extern void
 ExecDelete(ItemPointer tupleid,

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/include/nodes/execnodes.h
----------------------------------------------------------------------
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 98c2ee6..7a2e733 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -278,7 +278,7 @@ typedef struct JunkFilter
  *  aoInsertDesc        context for appendonly relation buffered INSERT
  *  extInsertDesc       context for external table INSERT
  *  parquetInsertDesc   context for parquet table INSERT
- *  parquetSendBack     information to be sent back to dispatch after INSERT in a parquet
table
+ *  insertSendBack      information to be sent back to dispatch after INSERT in a parquet
or AO table
  *  aosegno             the AO segfile we inserted into.
  *  aoprocessed         tuples processed for AO
  *  partInsertMap       map input attrno to target attrno
@@ -307,7 +307,8 @@ typedef struct ResultRelInfo
 
 	struct ExternalInsertDescData   *ri_extInsertDesc;
 	struct ParquetInsertDescData    *ri_parquetInsertDesc;
-	struct QueryContextDispatchingSendBackData *ri_parquetSendBack;
+
+	struct QueryContextDispatchingSendBackData *ri_insertSendBack;
 
 	List *ri_aosegnos;
 
@@ -501,7 +502,7 @@ typedef struct EState
 	ResultRelInfo *es_result_relation_info;                /* currently active array elt */
 	JunkFilter *es_junkFilter;        /* currently active junk filter */
 
-	Oid es_last_parq_part; /* The Oid of the last parquet partition we opened for insertion
*/
+	Oid es_last_inserted_part; /* The Oid of the last partition we opened for insertion */
 
 	/* partitioning info for target relation */
 	PartitionNode *es_result_partitions;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/test/regress/expected/goh_partition.out
----------------------------------------------------------------------
diff --git a/src/test/regress/expected/goh_partition.out b/src/test/regress/expected/goh_partition.out
index d636126..b26a76d 100755
--- a/src/test/regress/expected/goh_partition.out
+++ b/src/test/regress/expected/goh_partition.out
@@ -2197,3 +2197,129 @@ NOTICE:  CREATE TABLE will create partition "rank3_1_prt_girls_2_prt_jan04_3_prt
 NOTICE:  CREATE TABLE will create partition "rank3_1_prt_girls_2_prt_jan05_3_prt_mass" for
table "rank3_1_prt_girls_2_prt_jan05"
 NOTICE:  CREATE TABLE will create partition "rank3_1_prt_girls_2_prt_jan05_3_prt_cali" for
table "rank3_1_prt_girls_2_prt_jan05"
 NOTICE:  CREATE TABLE will create partition "rank3_1_prt_girls_2_prt_jan05_3_prt_ohio" for
table "rank3_1_prt_girls_2_prt_jan05"
+-- Tests for sort operator before insert with AO and PARQUET tables (HAWQ-404)
+-- A GUC's value is set to less than the number of partitions in the example table, so that
sort is activated.
+DROP TABLE IF EXISTS ch_sort_src, ch_sort_aodest, ch_sort_pqdest, ch_sort_aopqdest, ch_sort__pq_table;
+SET optimizer_parts_to_force_sort_on_insert = 5;
+CREATE TABLE ch_sort_src (id int, year int, month int, day int, region text)
+DISTRIBUTED BY (month); 
+INSERT INTO ch_sort_src select i, 2000 + i, i % 12, (2*i) % 30, i::text from generate_series(0,
99) i; 
+-- AO partitioned table
+CREATE TABLE ch_sort_aodest (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE)
+DISTRIBUTED BY (id)
+PARTITION BY RANGE (year)
+( 
+    START (2002) END (2010) EVERY (1),
+    DEFAULT PARTITION outlying_years
+);
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_outlying_years" for table
"ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_2" for table "ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_3" for table "ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_4" for table "ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_5" for table "ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_6" for table "ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_7" for table "ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_8" for table "ch_sort_aodest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aodest_1_prt_9" for table "ch_sort_aodest"
+-- PARQUET partitioned table
+CREATE TABLE ch_sort_pqdest (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE, ORIENTATION = PARQUET)
+DISTRIBUTED BY (id)
+PARTITION BY RANGE (year)
+( 
+    START (2002) END (2010) EVERY (1),
+    DEFAULT PARTITION outlying_years
+);
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_outlying_years" for table
"ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_2" for table "ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_3" for table "ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_4" for table "ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_5" for table "ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_6" for table "ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_7" for table "ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_8" for table "ch_sort_pqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_pqdest_1_prt_9" for table "ch_sort_pqdest"
+-- AO/PARQUET mixed table
+CREATE TABLE ch_sort_aopqdest (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE)
+DISTRIBUTED BY (id)
+PARTITION BY RANGE (year)
+( 
+    START (2002) END (2010) EVERY (1),
+    DEFAULT PARTITION outlying_years
+);
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_outlying_years" for table
"ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_2" for table "ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_3" for table "ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_4" for table "ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_5" for table "ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_6" for table "ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_7" for table "ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_8" for table "ch_sort_aopqdest"
+NOTICE:  CREATE TABLE will create partition "ch_sort_aopqdest_1_prt_9" for table "ch_sort_aopqdest"
+CREATE TABLE ch_sort__pq_table (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE, ORIENTATION = PARQUET)
+DISTRIBUTED BY (id);
+ALTER TABLE ch_sort_aopqdest
+EXCHANGE PARTITION FOR(2006)
+WITH TABLE ch_sort__pq_table;
+-- Test that inserts work
+INSERT INTO ch_sort_aodest SELECT * FROM ch_sort_src;
+SELECT COUNT(*) FROM ch_sort_aodest;
+ count 
+-------
+   100
+(1 row)
+
+SELECT COUNT(*) FROM ch_sort_aodest_1_prt_6;
+ count 
+-------
+     1
+(1 row)
+
+SELECT COUNT(*) FROM ch_sort_aodest_1_prt_outlying_years;
+ count 
+-------
+    92
+(1 row)
+
+INSERT INTO ch_sort_pqdest SELECT * FROM ch_sort_src;
+SELECT COUNT(*) FROM ch_sort_pqdest;
+ count 
+-------
+   100
+(1 row)
+
+SELECT COUNT(*) FROM ch_sort_pqdest_1_prt_6;
+ count 
+-------
+     1
+(1 row)
+
+SELECT COUNT(*) FROM ch_sort_pqdest_1_prt_outlying_years;
+ count 
+-------
+    92
+(1 row)
+
+INSERT INTO ch_sort_aopqdest SELECT * FROM ch_sort_src;
+SELECT COUNT(*) FROM ch_sort_aopqdest;
+ count 
+-------
+   100
+(1 row)
+
+SELECT COUNT(*) FROM ch_sort_aopqdest_1_prt_6;
+ count 
+-------
+     1
+(1 row)
+
+SELECT COUNT(*) FROM ch_sort_aopqdest_1_prt_outlying_years;
+ count 
+-------
+    92
+(1 row)
+
+RESET optimizer_parts_to_force_sort_on_insert;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/6e6890ae/src/test/regress/sql/goh_partition.sql
----------------------------------------------------------------------
diff --git a/src/test/regress/sql/goh_partition.sql b/src/test/regress/sql/goh_partition.sql
index 8cea409..4c04bd8 100644
--- a/src/test/regress/sql/goh_partition.sql
+++ b/src/test/regress/sql/goh_partition.sql
@@ -1227,3 +1227,71 @@ subpartition ohio values ('OH')
 )
 )
 );
+
+-- Tests for sort operator before insert with AO and PARQUET tables (HAWQ-404)
+-- A GUC's value is set to less than the number of partitions in the example table, so that
sort is activated.
+
+DROP TABLE IF EXISTS ch_sort_src, ch_sort_aodest, ch_sort_pqdest, ch_sort_aopqdest, ch_sort__pq_table;
+
+SET optimizer_parts_to_force_sort_on_insert = 5;
+
+CREATE TABLE ch_sort_src (id int, year int, month int, day int, region text)
+DISTRIBUTED BY (month); 
+INSERT INTO ch_sort_src select i, 2000 + i, i % 12, (2*i) % 30, i::text from generate_series(0,
99) i; 
+
+-- AO partitioned table
+CREATE TABLE ch_sort_aodest (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE)
+DISTRIBUTED BY (id)
+PARTITION BY RANGE (year)
+( 
+    START (2002) END (2010) EVERY (1),
+    DEFAULT PARTITION outlying_years
+);
+
+-- PARQUET partitioned table
+CREATE TABLE ch_sort_pqdest (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE, ORIENTATION = PARQUET)
+DISTRIBUTED BY (id)
+PARTITION BY RANGE (year)
+( 
+    START (2002) END (2010) EVERY (1),
+    DEFAULT PARTITION outlying_years
+);
+
+-- AO/PARQUET mixed table
+CREATE TABLE ch_sort_aopqdest (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE)
+DISTRIBUTED BY (id)
+PARTITION BY RANGE (year)
+( 
+    START (2002) END (2010) EVERY (1),
+    DEFAULT PARTITION outlying_years
+);
+
+CREATE TABLE ch_sort__pq_table (id int, year int, month int, day int, region text)
+WITH (APPENDONLY=TRUE, ORIENTATION = PARQUET)
+DISTRIBUTED BY (id);
+
+ALTER TABLE ch_sort_aopqdest
+EXCHANGE PARTITION FOR(2006)
+WITH TABLE ch_sort__pq_table;
+
+
+-- Test that inserts work
+INSERT INTO ch_sort_aodest SELECT * FROM ch_sort_src;
+SELECT COUNT(*) FROM ch_sort_aodest;
+SELECT COUNT(*) FROM ch_sort_aodest_1_prt_6;
+SELECT COUNT(*) FROM ch_sort_aodest_1_prt_outlying_years;
+
+INSERT INTO ch_sort_pqdest SELECT * FROM ch_sort_src;
+SELECT COUNT(*) FROM ch_sort_pqdest;
+SELECT COUNT(*) FROM ch_sort_pqdest_1_prt_6;
+SELECT COUNT(*) FROM ch_sort_pqdest_1_prt_outlying_years;
+
+INSERT INTO ch_sort_aopqdest SELECT * FROM ch_sort_src;
+SELECT COUNT(*) FROM ch_sort_aopqdest;
+SELECT COUNT(*) FROM ch_sort_aopqdest_1_prt_6;
+SELECT COUNT(*) FROM ch_sort_aopqdest_1_prt_outlying_years;
+
+RESET optimizer_parts_to_force_sort_on_insert;


Mime
View raw message