[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mysql-internals
Subject:    bk commit into 4.0 tree (monty:1.1691)
From:       monty () mysql ! com
Date:       2004-01-30 9:46:31
Message-ID: 20040130094631.D73DB36938 () linux ! local
[Download RAW message or body]

Below is the list of changes that have just been committed into a local
4.0 repository of monty. When monty 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://www.mysql.com/doc/I/n/Installing_source_tree.html

ChangeSet
  1.1691 04/01/30 10:46:30 monty@mysql.com +6 -0
  Fixed parsing of column names and foreign key constraints in Innobase to handle \
quoted identifiers and identifiers with space. (Bug #1725)  Fix optimizer tuning bug \
when first used key part was a constant. (Bug #1679)

  sql/sql_select.cc
    1.272 04/01/30 10:46:29 monty@mysql.com +12 -3
    Fix optimizer tuning bug when first used key part was a constant.
    Previously all keys that had this key part first was regarded as equal, even if \
the query used more key parts for some of the keys.  Now we use the range optimizer \
results to just limit the number of estimated rows if not all key parts where \
constants.  (Bug #1679)

  sql/sql_class.h
    1.173 04/01/30 10:46:29 monty@mysql.com +3 -1
    Add path to dumpfile so that we can delete the generated file if something goes \
wrong.

  sql/sql_class.cc
    1.108 04/01/30 10:46:29 monty@mysql.com +14 -8
    Safety fix for select into outfile and select into dumpfile. Before calling \
send_error() could cause end_io_cache() to be called several times.

  mysql-test/t/innodb.test
    1.51 04/01/30 10:46:29 monty@mysql.com +9 -0
    Test of innodb internal parsing

  mysql-test/r/innodb.result
    1.74 04/01/30 10:46:29 monty@mysql.com +3 -0
    Test of innodb internal parsing

  innobase/dict/dict0dict.c
    1.33 04/01/30 10:46:29 monty@mysql.com +46 -29
    Fixed parsing of column names and foreign key constraints to handle quoted \
identifiers and identifiers with space. (Bug #1725)

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	monty
# Host:	narttu.
# Root:	/home/my/mysql-4.0

--- 1.107/sql/sql_class.cc	Fri Oct 31 23:20:16 2003
+++ 1.108/sql/sql_class.cc	Fri Jan 30 10:46:29 2004
@@ -538,7 +538,6 @@
 int
 select_export::prepare(List<Item> &list)
 {
-  char path[FN_REFLEN];
   uint option=4;
   bool blob_flag=0;
 #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
@@ -739,9 +738,13 @@
 void select_export::send_error(uint errcode,const char *err)
 {
   ::send_error(&thd->net,errcode,err);
-  (void) end_io_cache(&cache);
-  (void) my_close(file,MYF(0));
-  file= -1;
+  if (file > 0)
+  {
+    (void) end_io_cache(&cache);
+    (void) my_close(file,MYF(0));
+    (void) my_delete(path,MYF(0));		// Delete file on error
+    file= -1;
+  }
 }
 
 
@@ -849,10 +852,13 @@
 void select_dump::send_error(uint errcode,const char *err)
 {
   ::send_error(&thd->net,errcode,err);
-  (void) end_io_cache(&cache);
-  (void) my_close(file,MYF(0));
-  (void) my_delete(path,MYF(0));		// Delete file on error
-  file= -1;
+  if (file > 0)
+  {
+    (void) end_io_cache(&cache);
+    (void) my_close(file,MYF(0));
+    (void) my_delete(path,MYF(0));		// Delete file on error
+    file= -1;
+  }
 }
 
 

--- 1.172/sql/sql_class.h	Tue Dec 30 12:14:18 2003
+++ 1.173/sql/sql_class.h	Fri Jan 30 10:46:29 2004
@@ -665,11 +665,13 @@
   File file;
   IO_CACHE cache;
   ha_rows row_count;
+  char path[FN_REFLEN];
   uint field_term_length;
   int field_sep_char,escape_char,line_sep_char;
   bool fixed_row_size;
 public:
-  select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {}
+  select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L)
+  { path[0]=0; }
   ~select_export();
   int prepare(List<Item> &list);
   bool send_fields(List<Item> &list,

--- 1.271/sql/sql_select.cc	Mon Jan 19 23:10:00 2004
+++ 1.272/sql/sql_select.cc	Fri Jan 30 10:46:29 2004
@@ -1912,7 +1912,8 @@
 
     read_time+=record_count/(double) TIME_FOR_COMPARE;
     if (join->sort_by_table &&
-	join->sort_by_table != join->positions[join->const_tables].table->table)
+	join->sort_by_table !=
+	join->positions[join->const_tables].table->table)
       read_time+=record_count;			// We have to make a temp table
     if (read_time < join->best_read)
     {
@@ -1946,7 +1947,7 @@
 	uint max_key_part=0;
 
 	/* Test how we can use keys */
-	rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;  /* Assumed records/key */
+	rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE;  // Assumed records/key
 	for (keyuse=s->keyuse ; keyuse->table == table ;)
 	{
 	  key_map found_part=0;
@@ -2085,7 +2086,7 @@
 		will match
 	      */
 	      if (table->quick_keys & ((key_map) 1 << key) &&
-		  table->quick_key_parts[key] <= max_key_part)
+		  table->quick_key_parts[key] == max_key_part)
 		tmp=records= (double) table->quick_rows[key];
 	      else
 	      {
@@ -2127,6 +2128,14 @@
 		  }
 		  records=(ulong) tmp;
 		}
+		/*
+		  If quick_select was used on a part of this key, we know
+		  the maximum number of rows that the key can match.
+		*/
+		if (table->quick_keys & ((key_map) 1 << key) &&
+		    table->quick_key_parts[key] <= max_key_part &&
+		    records > (double) table->quick_rows[key])
+		  tmp= records= (double) table->quick_rows[key];
 	      }
 	      /* Limit the number of matched rows */
 	      set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);

--- 1.32/innobase/dict/dict0dict.c	Thu Aug 28 00:59:26 2003
+++ 1.33/innobase/dict/dict0dict.c	Fri Jan 30 10:46:29 2004
@@ -2138,19 +2138,37 @@
 		return(ptr);
 	}
 
-	if (*ptr == '`') {
-		ptr++;
-	}
-
-	old_ptr = ptr;
+	if (*ptr == '`' || *ptr == '"') {
+	  /*
+	    The identifier is quoted. Search for end quote.
+	    We can't use the general code here as the name may contain
+	    special characters like space.
+	  */
+	  char quote= *ptr++;
+
+	  old_ptr= ptr;
+	  /*
+	    The colum name should always end with 'quote' but we check for
+	    end zero just to be safe if this is called outside of MySQL
+	  */
+	  while (*ptr && *ptr != quote)
+	    ptr++;
+	  *column_name_len = (ulint)(ptr - old_ptr);
+
+	  if (*ptr)				/* Skip end quote */
+	    ptr++;
+	}
+	else
+	{
+	  old_ptr = ptr;
 	
-	while (!isspace(*ptr) && *ptr != ',' && *ptr != ')' && 	*ptr != '`'
-	       && *ptr != '\0') {
-
+	  while (!isspace(*ptr) && *ptr != ',' && *ptr != ')'
+		 && *ptr != '\0') {
 		ptr++;
+	  }
+	  *column_name_len = (ulint)(ptr - old_ptr);
 	}
 
-	*column_name_len = (ulint)(ptr - old_ptr);
 	
 	if (table == NULL) {
 		*success = TRUE;
@@ -2161,9 +2179,9 @@
 
 			col = dict_table_get_nth_col(table, i);
 
-			if (ut_strlen(col->name) == (ulint)(ptr - old_ptr)
+			if (ut_strlen(col->name) == *column_name_len
 			    && 0 == ut_cmp_in_lower_case(col->name, old_ptr,
-						(ulint)(ptr - old_ptr))) {
+						*column_name_len)) {
 		    		/* Found */
 
 		    		*success = TRUE;
@@ -2175,10 +2193,6 @@
 		}
 	}
 	
-	if (*ptr == '`') {
-		ptr++;
-	}
-	
 	return(ptr);
 }
 
@@ -2200,6 +2214,7 @@
 	char*	dot_ptr			= NULL;
 	char*	old_ptr;
 	ulint	i;
+	char	quote			= 0;
 	
 	*success = FALSE;
 	*table = NULL;
@@ -2213,14 +2228,16 @@
 		return(ptr);
 	}
 
-	if (*ptr == '`') {
-		ptr++;
+	if (*ptr == '`' || *ptr == '"') {
+		quote= *ptr++;
 	}
 
 	old_ptr = ptr;
 	
-	while (!isspace(*ptr) && *ptr != '(' && *ptr != '`' && *ptr != '\0') {
-		if (*ptr == '.') {
+	while (*ptr != quote &&
+	       (quote || (!isspace(*ptr) && *ptr != '(')) &&
+	       *ptr != '\0') {
+		if (!quote && *ptr == '.') {
 			dot_ptr = ptr;
 		}
 
@@ -2273,7 +2290,7 @@
 
 	*table = dict_table_get_low(second_table_name);
 
-	if (*ptr == '`') {
+	if (*ptr && *ptr == quote) {
 		ptr++;
 	}
 
@@ -2293,7 +2310,7 @@
 			scannable */
 	ulint*	len)	/* out: length of the id */
 {
-	ibool	scanned_backquote	= FALSE;
+	char quote	= 0;
 
 	*start = NULL;
 
@@ -2306,23 +2323,23 @@
 		return(ptr);
 	}
 
-	if (*ptr == '`') {
-		scanned_backquote = TRUE;
-		ptr++;
+	if (*ptr == '`' || *ptr == '"') {
+		quote = *ptr++;
 	}
 	
 	*start = ptr;
 
-	while (!isspace(*ptr) && *ptr != ',' && *ptr != '(' && *ptr != ')'
-		&& *ptr != '\0' && *ptr != '`') {
-
+	while (*ptr != quote &&
+	       (!quote || (!isspace(*ptr) && *ptr != ',' && *ptr != '(' &&
+			   *ptr != ')'))
+	       && *ptr != '\0') {
 		ptr++;
 	}
 
 	*len = (ulint) (ptr - *start);
 	
-	if (scanned_backquote) {
-		if (*ptr == '`') {
+	if (quote) {
+		if (*ptr == quote) {
 			ptr++;
 		} else {
 			/* Syntax error */

--- 1.73/mysql-test/r/innodb.result	Fri Dec 12 21:26:56 2003
+++ 1.74/mysql-test/r/innodb.result	Fri Jan 30 10:46:29 2004
@@ -1243,3 +1243,6 @@
 3
 4
 drop table t1;
+CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) TYPE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY \
(`t1_id`) REFERENCES `t1`(`id 1`)  ON DELETE CASCADE ) TYPE=INNODB; +drop table \
t1,t2;

--- 1.50/mysql-test/t/innodb.test	Fri Dec 12 21:26:56 2003
+++ 1.51/mysql-test/t/innodb.test	Fri Jan 30 10:46:29 2004
@@ -869,3 +869,12 @@
 insert into t1 (a) values (NULL),(NULL);
 SELECT * from t1;
 drop table t1;
+
+#
+# Test dictionary handling with spaceand quoting
+#
+
+CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) TYPE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY \
(`t1_id`) REFERENCES `t1`(`id 1`)  ON DELETE CASCADE ) TYPE=INNODB; +#show create \
table t2; +drop table t1,t2;

-- 
MySQL Internals Mailing List
For list archives: http://lists.mysql.com/internals
To unsubscribe:    http://lists.mysql.com/internals?unsub=mysql-internals@progressive-comp.com



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic