MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Sergey Petrunia Date:June 13 2008 3:32pm
Subject:bk commit into 6.0 tree (sergefp:1.2635)
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of sergefp.  When sergefp does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-06-13 19:31:54+04:00, sergefp@stripped +4 -0
  One-sweep Falcon/MRR implementation, attempt #4
  - Will need merge with ORDER BY ... LIMIT optimization

  mysql-test/suite/falcon/r/falcon_select.result@stripped, 2008-06-13 19:31:35+04:00, sergefp@stripped +10 -10
    One-sweep Falcon/MRR implementation:
    - Update test results

  mysql-test/suite/falcon/r/index_merge_falcon.result@stripped, 2008-06-13 19:31:35+04:00, sergefp@stripped +1 -1
    One-sweep Falcon/MRR implementation:
    - Update test results

  storage/falcon/ha_falcon.cpp@stripped, 2008-06-13 19:31:35+04:00, sergefp@stripped +149 -17
    One-sweep Falcon/MRR implementation:
    - Factor out the index scan part from StorageInterface::read_range_first()
      into a separate function
    - Add one-sweep MRR function implementations.

  storage/falcon/ha_falcon.h@stripped, 2008-06-13 19:31:35+04:00, sergefp@stripped +18 -0
    One-sweep Falcon/MRR implementation:
    - Add MRR methods declaration

diff -Nrup a/mysql-test/suite/falcon/r/falcon_select.result b/mysql-test/suite/falcon/r/falcon_select.result
--- a/mysql-test/suite/falcon/r/falcon_select.result	2008-04-06 11:20:37 +04:00
+++ b/mysql-test/suite/falcon/r/falcon_select.result	2008-06-13 19:31:35 +04:00
@@ -154,7 +154,7 @@ honeysuckle
 honoring
 explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	range	fld3	fld3	30	NULL	119	Using where; Using filesort
+1	SIMPLE	t2	range	fld3	fld3	30	NULL	119	Using where; Using MRR; Using filesort
 select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
 fld1	fld3
 148504	Colombo
@@ -174,7 +174,7 @@ fld1
 250502
 explain select fld1 from t2 where fld1=250501 or fld1="250502";
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	range	fld1	fld1	4	NULL	2	Using where
+1	SIMPLE	t2	range	fld1	fld1	4	NULL	2	Using where; Using MRR
 select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
 fld1
 250501
@@ -183,7 +183,7 @@ fld1
 250601
 explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	range	fld1	fld1	4	NULL	2	Using where
+1	SIMPLE	t2	range	fld1	fld1	4	NULL	2	Using where; Using MRR
 select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%' order by fld1;
 fld1	fld3
 012001	flanking
@@ -1318,7 +1318,7 @@ id	select_type	table	type	possible_keys	
 delete from t2 where fld1=999999;
 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where
+1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where; Using MRR
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where; Using join buffer
 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
@@ -1326,19 +1326,19 @@ id	select_type	table	type	possible_keys	
 1	SIMPLE	t4	eq_ref	PRIMARY	PRIMARY	1	test.t2.companynr	1	
 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where
+1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where; Using MRR
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where; Using join buffer
 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where
+1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where; Using MRR
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where
 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	13	Using where
+1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	13	Using where; Using MRR
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where
 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where
+1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where; Using MRR
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where
 explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
@@ -1354,11 +1354,11 @@ id	select_type	table	type	possible_keys	
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where
 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where
+1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	1	Using where; Using MRR
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where
 explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	13	Using where
+1	SIMPLE	t4	range	PRIMARY	PRIMARY	1	NULL	13	Using where; Using MRR
 1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	1199	Using where
 explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
diff -Nrup a/mysql-test/suite/falcon/r/index_merge_falcon.result b/mysql-test/suite/falcon/r/index_merge_falcon.result
--- a/mysql-test/suite/falcon/r/index_merge_falcon.result	2007-09-20 19:43:21 +04:00
+++ b/mysql-test/suite/falcon/r/index_merge_falcon.result	2008-06-13 19:31:35 +04:00
@@ -746,7 +746,7 @@ primary key (pk1, pk2)
 );
 explain select * from t1 where pk1 = 1 and pk2 < 80  and key1=0;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	range	PRIMARY,key1	PRIMARY	8	NULL	1000	Using where
+1	SIMPLE	t1	range	PRIMARY,key1	PRIMARY	8	NULL	1000	Using where; Using MRR
 select * from t1 where pk1 = 1 and pk2 < 80  and key1=0;
 pk1	pk2	key1	key2	pktail1ok	pktail2ok	pktail3bad	pktail4bad	pktail5bad	pk2copy	badkey	filler1	filler2
 1	19	0	0	0	0	0	0	0	19	0	filler-data-19	filler2
diff -Nrup a/storage/falcon/ha_falcon.cpp b/storage/falcon/ha_falcon.cpp
--- a/storage/falcon/ha_falcon.cpp	2008-03-13 02:56:14 +03:00
+++ b/storage/falcon/ha_falcon.cpp	2008-06-13 19:31:35 +04:00
@@ -1327,6 +1327,7 @@ int StorageInterface::index_read(uchar *
 		if ((ret = storageTable->setIndexBound(key, key_len, which)))
 			DBUG_RETURN(error(ret));
 
+	storageTable->clearBitmap();
 	if ((ret = storageTable->indexScan()))
 		DBUG_RETURN(error(ret));
 
@@ -1497,10 +1498,41 @@ int StorageInterface::read_range_first(c
                                       const key_range *end_key,
                                       bool eq_range_arg, bool sorted)
 {
+        int res;
 	DBUG_ENTER("StorageInterface::read_range_first");
+
 	storageTable->clearIndexBounds();
+	if ((res= scanRange(start_key, end_key, eq_range_arg)))
+		DBUG_RETURN(res);
+
+	for (;;)
+		{
+		int result = index_next(table->record[0]);
+
+		if (result)
+			{
+			if (result == HA_ERR_KEY_NOT_FOUND)
+				result = HA_ERR_END_OF_FILE;
+
+			table->status = result;
+			DBUG_RETURN(result);
+			}
+
+		DBUG_RETURN(0);
+		}
+
+	DBUG_RETURN(0);
+}
+
+
+int StorageInterface::scanRange(const key_range *start_key,
+								const key_range *end_key,
+								bool eqRange)
+{
+	DBUG_ENTER("StorageInterface::read_range_first");
 	haveStartKey = false;
 	haveEndKey = false;
+	storageTable->upperBound = storageTable->lowerBound = NULL;
 
 	if (start_key && !storageTable->isKeyNull((const unsigned char*) start_key->key, start_key->length))
 		{
@@ -1532,7 +1564,7 @@ int StorageInterface::read_range_first(c
 	storageTable->indexScan();
 	nextRecord = 0;
 	lastRecord = -1;
-	eq_range = eq_range_arg;
+	eq_range = eqRange;
 	end_range = 0;
 
 	if (end_key)
@@ -1547,22 +1579,7 @@ int StorageInterface::read_range_first(c
 		}
 
 	range_key_part = table->key_info[active_index].key_part;
-
-	for (;;)
-		{
-		int result = index_next(table->record[0]);
-
-		if (result)
-			{
-			if (result == HA_ERR_KEY_NOT_FOUND)
-				result = HA_ERR_END_OF_FILE;
-
-			table->status = result;
-			DBUG_RETURN(result);
-			}
-
-		DBUG_RETURN(0);
-		}
+	DBUG_RETURN(0);
 }
 
 
@@ -1640,6 +1657,121 @@ int StorageInterface::index_next_same(uc
 			DBUG_RETURN(0);
 		}
 }
+
+
+//*****************************************************************************
+// Falcon MRR implementation: One-sweep DS-MRR
+//
+// Overview
+//  - MRR scan is always done in one pass, which consists of two steps:
+//      1. Scan the index and populate Falcon's internal record number bitmap
+//      2. Scan the bitmap, retrieve and return records
+//    (without MRR falcon does steps 1 and 2 for each range)
+//  - The record number bitmap is allocated using Falcon's internal
+//    allocation routines, so we're not using the SQL layer's join buffer space.
+//  - multi_range_read_next() may return "garbage" records - records that are
+//    outside of any of the scanned ranges. Filtering out these records is
+//    the responsibility of whoever is making MRR calls.
+//
+//*****************************************************************************
+
+int StorageInterface::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+                                            uint n_ranges, uint mode, 
+                                            HANDLER_BUFFER *buf)
+{
+	DBUG_ENTER("StorageInterface::multi_range_read_init");
+	if (mode & HA_MRR_USE_DEFAULT_IMPL)
+		{
+		useDefaultMrrImpl= true;
+		int res = handler::multi_range_read_init(seq, seq_init_param, n_ranges, 
+												 mode, buf);
+		DBUG_RETURN(res);
+		}
+	useDefaultMrrImpl = false;
+	multi_range_buffer = buf;
+	mrr_funcs = *seq;
+
+	mrr_iter = mrr_funcs.init(seq_init_param, n_ranges, mode);
+	fillMrrBitmap();
+
+	// multi_range_read_next() will be calling index_next(). The following is
+	// to make index_next() not to check whether the retrieved record is in 
+	// range
+	haveStartKey = haveEndKey = 0;
+	DBUG_RETURN(0);
+}
+
+
+int StorageInterface::fillMrrBitmap()
+{
+	int res;
+	key_range *startKey;
+	key_range *endKey;
+	DBUG_ENTER("StorageInterface::fillMrrBitmap");
+
+	storageTable->clearBitmap();
+	while (!(res = mrr_funcs.next(mrr_iter, &mrr_cur_range)))
+		{
+		startKey = mrr_cur_range.start_key.keypart_map? &mrr_cur_range.start_key: NULL;
+		endKey   = mrr_cur_range.end_key.keypart_map?   &mrr_cur_range.end_key: NULL;
+		if ((res = scanRange(startKey, endKey, test(mrr_cur_range.range_flag & EQ_RANGE))))
+			return res;
+		}
+	DBUG_RETURN(0);
+}
+
+int StorageInterface::multi_range_read_next(char **rangeInfo)
+{
+	if (useDefaultMrrImpl)
+		return handler::multi_range_read_next(rangeInfo);
+	return index_next(table->record[0]);
+}
+
+
+ha_rows StorageInterface::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+													  void *seq_init_param,
+													  uint n_ranges, uint *bufsz,
+													  uint *flags, COST_VECT *cost)
+{
+	ha_rows res;
+	// TODO: SergeyP: move the optimizer_use_mrr check from here out to the
+	// SQL layer, do same for all other MRR implementations
+	bool native_requested = test(*flags & HA_MRR_USE_DEFAULT_IMPL ||
+								 (current_thd->variables.optimizer_use_mrr == 2));
+	res = handler::multi_range_read_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
+											   flags, cost);
+	if ((res != HA_POS_ERROR) && !native_requested)
+		{
+		*flags &= ~HA_MRR_USE_DEFAULT_IMPL;
+		/* We'll be returning records without telling which range they are contained in */
+		*flags |= HA_MRR_NO_ASSOCIATION;
+		/* We'll use our own internal buffer so we won't need any buffer space from the SQL layer */
+		*bufsz = 0;
+		}
+	return res;
+}
+
+
+int StorageInterface::multi_range_read_info(uint keyno, uint n_ranges, 
+                                            uint keys, uint *bufsz, 
+                                            uint *flags, COST_VECT *cost)
+{
+	ha_rows res;
+	bool native_requested = test(*flags & HA_MRR_USE_DEFAULT_IMPL || 
+								 (current_thd->variables.optimizer_use_mrr == 2));
+	res = handler::multi_range_read_info(keyno, n_ranges, keys, bufsz, flags,
+										 cost);
+	if ((res != HA_POS_ERROR) && !native_requested)
+		{
+		*flags &= ~HA_MRR_USE_DEFAULT_IMPL;
+		/* See _info_const() function for explanation of these: */
+		*flags |= HA_MRR_NO_ASSOCIATION;
+		*bufsz = 0;
+		}
+	return res;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
 
 
 double StorageInterface::scan_time(void)
diff -Nrup a/storage/falcon/ha_falcon.h b/storage/falcon/ha_falcon.h
--- a/storage/falcon/ha_falcon.h	2008-03-13 02:56:14 +03:00
+++ b/storage/falcon/ha_falcon.h	2008-06-13 19:31:35 +04:00
@@ -69,6 +69,19 @@ public:
 	virtual int		index_init(uint idx, bool sorted);
 	virtual int		index_end(void);
 	virtual int		index_next(uchar *buf);
+
+	// Multi Range Read interface
+	virtual int		multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
+										  uint n_ranges, uint mode, HANDLER_BUFFER *buf);
+	virtual int		multi_range_read_next(char **range_info);
+	virtual ha_rows	multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+												void *seq_init_param, 
+												uint n_ranges, uint *bufsz,
+												uint *flags, COST_VECT *cost);
+	virtual int		multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+										  uint *bufsz, uint *flags, COST_VECT *cost);
+	// Multi Range Read interface ends
+
 	virtual int		index_next_same(uchar *buf, const uchar *key, uint key_len);
 
 	virtual ha_rows	records_in_range(uint index,
@@ -117,6 +130,10 @@ public:
 	void			decodeRecord(uchar *buf);
 	void			unlockTable(void);
 	void			checkBinLog(void);
+	int				scanRange(const key_range *startKey,
+							   const key_range *endKey,
+							   bool eqRange);
+	int				fillMrrBitmap();
 
 	static StorageConnection* getStorageConnection(THD* thd);
 	
@@ -178,6 +195,7 @@ public:
 	key_range			endKey;
 	uint64				insertCount;
 	ulonglong			tableFlags;
+	bool				useDefaultMrrImpl;
 };
 
 class NfsPluginHandler
Thread
bk commit into 6.0 tree (sergefp:1.2635)Sergey Petrunia13 Jun