diff options
author | unknown <patg@pc248.lfp.kcls.org> | 2005-01-20 18:36:40 -0800 |
---|---|---|
committer | unknown <patg@pc248.lfp.kcls.org> | 2005-01-20 18:36:40 -0800 |
commit | 66b62e051930dbcd9dc1d38f0cac574692932834 (patch) | |
tree | deb5a7cc7ebc3ade7e8c5fd0d1105f928f2f133a /sql | |
parent | 9aaa87e909484a9c12b2a5e8913da45f8b7d0e9d (diff) | |
download | mariadb-git-66b62e051930dbcd9dc1d38f0cac574692932834.tar.gz |
-Added quote_data and needs_quotes (moved from federated handler.
-New tests and results
logging_ok:
Logging to logging@openlogging.org accepted
ha_federated.h:
removed quote_data and type_quote (now in the Field class)
ha_federated.cc:
moved quote_data and type_quote to field class
field.h:
new methods quote_data and needs_quotes declared
field.cc:
new field class methods quote_data and needs_quotes (per Monty's request)
federated.test:
more tests, joins, index tests
have_federated_db.require:
new name of federated system var
federated.result:
new test results for federated handler
have_federated_db.inc:
changed name of variable in test due to change in vars
sql_analyse.cc:
over-ridden append_escaped to take (String *, char *, uint) per requirements of 'create_where_from_key' method in federated handler.
mysql_priv.h:
define over-ridden append_escaped to take arguments from 'create_where_from_key' method in federated handler
ha_federated.cc:
implemented "create_where_from_key" to deal properly with two-byte prefix and multi keys. Initial testing shows it works, but I still need to move quoting to field class and also look at changes per Segei's suggestions.
sql/mysql_priv.h:
define over-ridden append_escaped to take arguments from 'create_where_from_key' method in federated handler
sql/sql_analyse.cc:
over-ridden append_escaped to take (String *, char *, uint) per requirements of 'create_where_from_key' method in federated handler.
mysql-test/include/have_federated_db.inc:
changed name of variable in test due to change in vars
mysql-test/r/federated.result:
new test results for federated handler
mysql-test/r/have_federated_db.require:
new name of federated system var
mysql-test/t/federated.test:
more tests, joins, index tests
sql/field.cc:
new field class methods quote_data and needs_quotes (per Monty's request)
sql/field.h:
new methods quote_data and needs_quotes declared
sql/ha_federated.cc:
moved quote_data and type_quote to field class
sql/ha_federated.h:
removed quote_data and type_quote (now in the Field class)
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 109 | ||||
-rw-r--r-- | sql/field.h | 2 | ||||
-rw-r--r-- | sql/ha_federated.cc | 221 | ||||
-rwxr-xr-x | sql/ha_federated.h | 5 | ||||
-rw-r--r-- | sql/mysql_priv.h | 4 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 40 |
6 files changed, 199 insertions, 182 deletions
diff --git a/sql/field.cc b/sql/field.cc index 41b6eba695c..b1212025d30 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -524,6 +524,115 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table, return tmp; } +/* + SYNOPSIS + Field::quote_data() + unquoted_string Pointer pointing to the value of a field + + DESCRIPTION + Simple method that passes the field type to the method "type_quote" + To get a true/false value as to whether the value in string1 needs + to be enclosed with quotes. This ensures that values in the final + sql statement to be passed to the remote server will be quoted properly + + RETURN_VALUE + void Immediately - if string doesn't need quote + void Upon prepending/appending quotes on each side of variable + +*/ +bool Field::quote_data(String *unquoted_string) +{ + char escaped_string[IO_SIZE]; + char *unquoted_string_buffer= (char *)(unquoted_string->ptr()); + uint need_quotes; + + DBUG_ENTER("Field::quote_data"); + // this is the same call that mysql_real_escape_string() calls + escape_string_for_mysql(&my_charset_bin, (char *)escaped_string, + unquoted_string->ptr(), unquoted_string->length()); + + + if (is_null()) + DBUG_RETURN(0); + + need_quotes= needs_quotes(); + + if (need_quotes == 0) + { + DBUG_RETURN(0); + } + else + { + // reset string, then re-append with quotes and escaped values + unquoted_string->length(0); + if (unquoted_string->append("'")) + DBUG_RETURN(1); + if (unquoted_string->append((char *)escaped_string)) + DBUG_RETURN(1); + if (unquoted_string->append("'")) + DBUG_RETURN(1); + } + //DBUG_PRINT("Field::quote_data", + // ("FINAL quote_flag %d unquoted_string %s escaped_string %s", + //needs_quotes, unquoted_string->c_ptr_quick(), escaped_string)); + DBUG_RETURN(0); +} + +/* + Quote a field type if needed + + SYNOPSIS + Field::type_quote + + DESCRIPTION + Simple method to give true/false whether a field should be quoted. + Used when constructing INSERT and UPDATE queries to the remote server + see write_row and update_row + + RETURN VALUE + 0 if value is of type NOT needing quotes + 1 if value is of type needing quotes +*/ +bool Field::needs_quotes(void) +{ + DBUG_ENTER("Field::type_quote"); + + switch(type()) { + //FIX this when kernel is fixed + case MYSQL_TYPE_VARCHAR : + case FIELD_TYPE_STRING : + case FIELD_TYPE_VAR_STRING : + case FIELD_TYPE_YEAR : + case FIELD_TYPE_NEWDATE : + case FIELD_TYPE_TIME : + case FIELD_TYPE_TIMESTAMP : + case FIELD_TYPE_DATE : + case FIELD_TYPE_DATETIME : + case FIELD_TYPE_TINY_BLOB : + case FIELD_TYPE_BLOB : + case FIELD_TYPE_MEDIUM_BLOB : + case FIELD_TYPE_LONG_BLOB : + case FIELD_TYPE_GEOMETRY : + DBUG_RETURN(1); + + case FIELD_TYPE_DECIMAL : + case FIELD_TYPE_TINY : + case FIELD_TYPE_SHORT : + case FIELD_TYPE_INT24 : + case FIELD_TYPE_LONG : + case FIELD_TYPE_FLOAT : + case FIELD_TYPE_DOUBLE : + case FIELD_TYPE_LONGLONG : + case FIELD_TYPE_NULL : + case FIELD_TYPE_SET : + case FIELD_TYPE_ENUM : + DBUG_RETURN(0); + + default: DBUG_RETURN(0); + } + DBUG_RETURN(0); + +} /**************************************************************************** Field_null, a field that always return NULL diff --git a/sql/field.h b/sql/field.h index ab911822c2c..af7019f28bf 100644 --- a/sql/field.h +++ b/sql/field.h @@ -227,6 +227,8 @@ public: ptr= old_ptr; return str; } + bool quote_data(String *unquoted_string); + bool needs_quotes(void); virtual bool send_binary(Protocol *protocol); virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0) { diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 0feccc94334..72dd448b06f 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -123,8 +123,8 @@ ha_federated::write_row <for every field/column> - ha_federated::quote_data - ha_federated::quote_data + Field::quote_data + Field::quote_data </for every field/column> ha_federated::reset @@ -136,18 +136,18 @@ ha_federated::index_init ha_federated::index_read ha_federated::index_read_idx - ha_federated::quote_data + Field::quote_data ha_federated::rnd_next ha_federated::convert_row_to_internal_format ha_federated::update_row <quote 3 cols, new and old data> - <ha_federated::quote_data - <ha_federated::quote_data - <ha_federated::quote_data - <ha_federated::quote_data - <ha_federated::quote_data - <ha_federated::quote_data + Field::quote_data + Field::quote_data + Field::quote_data + Field::quote_data + Field::quote_data + Field::quote_data </quote 3 cols, new and old data> ha_federated::extra @@ -595,11 +595,15 @@ bool ha_federated::create_where_from_key( { uint second_loop= 0; KEY_PART_INFO *key_part; + bool needs_quotes; DBUG_ENTER("ha_federated::create_where_from_key"); for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++) { Field *field= key_part->field; + needs_quotes= field->needs_quotes(); + //bool needs_quotes= type_quote(field->type()); + DBUG_PRINT("ha_federated::create_where_from_key", ("key name %s type %d", field->field_name, field->type())); uint length= key_part->length; if (second_loop++ && to->append(" AND ",5)) @@ -613,6 +617,7 @@ bool ha_federated::create_where_from_key( if (*key++) { if (to->append("IS NULL",7)) + DBUG_PRINT("ha_federated::create_where_from_key", ("NULL type %s", to->c_ptr_quick())); DBUG_RETURN(1); key_length-= key_part->store_length; key+= key_part->store_length-1; @@ -620,14 +625,16 @@ bool ha_federated::create_where_from_key( } key_length--; } - if (to->append('=')) + if (to->append("= ")) + DBUG_RETURN(1); + if (needs_quotes && to->append("'")) DBUG_RETURN(1); if (key_part->type == HA_KEYTYPE_BIT) { /* This is can be threated as a hex string */ Field_bit *field= (Field_bit *) (key_part->field); char buff[64+2], *ptr; - byte *end= key + length; + byte *end= (byte *)(key) + length; buff[0]='0'; buff[1]='x'; @@ -639,6 +646,8 @@ bool ha_federated::create_where_from_key( } if (to->append(buff, (uint) (ptr-buff))) DBUG_RETURN(1); + + DBUG_PRINT("ha_federated::create_where_from_key", ("bit type %s", to->c_ptr_quick())); key_length-= length; continue; } @@ -647,165 +656,46 @@ bool ha_federated::create_where_from_key( uint blob_length= uint2korr(key); key+= HA_KEY_BLOB_LENGTH; key_length-= HA_KEY_BLOB_LENGTH; - if (append_escaped(to, key, blob_length)) + if (append_escaped(to, (char *)(key), blob_length)) DBUG_RETURN(1); + + DBUG_PRINT("ha_federated::create_where_from_key", ("blob type %s", to->c_ptr_quick())); length= key_part->length; } else if (key_part->key_part_flag & HA_VAR_LENGTH_PART) { - key_length-= HA_KEY_BLOB_LENGTH; - length= key_part->length; + length= uint2korr(key); key+= HA_KEY_BLOB_LENGTH; - if (append_escaped(to, key, length)) + if (append_escaped(to, (char *)(key), length)) DBUG_RETURN(1); + + DBUG_PRINT("ha_federated::create_where_from_key", ("varchar type %s", to->c_ptr_quick())); } else { - //bool need_quotes= field->needs_quotes(); - bool needs_quotes= type_quote(field->type()); + DBUG_PRINT("ha_federated::create_where_from_key", ("else block, unknown type so far")); char buff[MAX_FIELD_WIDTH]; String str(buff, sizeof(buff), field->charset()), *res; - if (needs_quotes && to->append('=')) - DBUG_RETURN(1); res= field->val_str(&str, (char *)(key)); if (field->result_type() == STRING_RESULT) { - if (append_escaped(to, res->ptr(), res->length())) + if (append_escaped(to, (char *) res->ptr(), res->length())) DBUG_RETURN(1); + res= field->val_str(&str, (char *)(key)); + + DBUG_PRINT("ha_federated::create_where_from_key", ("else block, string type", to->c_ptr_quick())); } else if (to->append(res->ptr(), res->length())) DBUG_RETURN(1); - if (needs_quotes && to->append('=')) - DBUG_RETURN(1); } + if (needs_quotes && to->append("'")) + DBUG_RETURN(1); + DBUG_PRINT("ha_federated::create_where_from_key", ("final value for 'to' %s", to->c_ptr_quick())); key+= length; key_length-= length; - } -} -/* - SYNOPSIS - quote_data() - unquoted_string Pointer pointing to the value of a field - field MySQL Field pointer to field being checked for type - - DESCRIPTION - Simple method that passes the field type to the method "type_quote" - To get a true/false value as to whether the value in string1 needs - to be enclosed with quotes. This ensures that values in the final - sql statement to be passed to the remote server will be quoted properly - - RETURN_VALUE - void Immediately - if string doesn't need quote - void Upon prepending/appending quotes on each side of variable - -*/ -void ha_federated::quote_data(String *unquoted_string, Field *field ) -{ - char escaped_string[IO_SIZE]; - char *unquoted_string_buffer; - - unquoted_string_buffer= unquoted_string->c_ptr_quick(); - - int quote_flag; - DBUG_ENTER("ha_federated::quote_data"); - DBUG_PRINT("ha_federated::quote_data", - ("unescaped %s", unquoted_string->c_ptr_quick())); - // this is the same call that mysql_real_escape_string() calls - escape_string_for_mysql(&my_charset_bin, (char *)escaped_string, - unquoted_string->c_ptr_quick(), unquoted_string->length()); - - DBUG_PRINT("ha_federated::quote_data",("escaped %s",escaped_string)); - - if (field->is_null()) - { - DBUG_PRINT("ha_federated::quote_data", - ("NULL, no quoted needed for unquoted_string %s, returning.", - unquoted_string->c_ptr_quick())); - DBUG_VOID_RETURN; - } - - quote_flag= type_quote(field->type()); - - DBUG_PRINT("ha_federated::quote_data", - ("quote flag %d type %d", quote_flag, field->type())); - - if (quote_flag == 0) - { - DBUG_PRINT("ha_federated::quote_data", - ("quote flag 0 no quoted needed for unquoted_string %s, returning.", - unquoted_string->c_ptr_quick())); - DBUG_VOID_RETURN; - } - else - { - // reset string, then re-append with quotes and escaped values - unquoted_string->length(0); - unquoted_string->append("'"); - unquoted_string->append((char *)escaped_string); - unquoted_string->append("'"); - } - DBUG_PRINT("ha_federated::quote_data", - ("FINAL quote_flag %d unquoted_string %s escaped_string %s", - quote_flag, unquoted_string->c_ptr_quick(), escaped_string)); - DBUG_VOID_RETURN; -} - -/* - Quote a field type if needed - - SYNOPSIS - ha_federated::type_quote - int field Enumerated field type number - - DESCRIPTION - Simple method to give true/false whether a field should be quoted. - Used when constructing INSERT and UPDATE queries to the remote server - see write_row and update_row - - RETURN VALUE - 0 if value is of type NOT needing quotes - 1 if value is of type needing quotes -*/ -uint ha_federated::type_quote(int type) -{ - DBUG_ENTER("ha_federated::type_quote"); - DBUG_PRINT("ha_federated::type_quote", ("field type %d", type)); - - switch(type) { - //FIX this is a bug, fix when kernel is fixed - case MYSQL_TYPE_VARCHAR : - case FIELD_TYPE_STRING : - case FIELD_TYPE_VAR_STRING : - case FIELD_TYPE_YEAR : - case FIELD_TYPE_NEWDATE : - case FIELD_TYPE_TIME : - case FIELD_TYPE_TIMESTAMP : - case FIELD_TYPE_DATE : - case FIELD_TYPE_DATETIME : - case FIELD_TYPE_TINY_BLOB : - case FIELD_TYPE_BLOB : - case FIELD_TYPE_MEDIUM_BLOB : - case FIELD_TYPE_LONG_BLOB : - case FIELD_TYPE_GEOMETRY : - DBUG_RETURN(1); - - case FIELD_TYPE_DECIMAL : - case FIELD_TYPE_TINY : - case FIELD_TYPE_SHORT : - case FIELD_TYPE_INT24 : - case FIELD_TYPE_LONG : - case FIELD_TYPE_FLOAT : - case FIELD_TYPE_DOUBLE : - case FIELD_TYPE_LONGLONG : - case FIELD_TYPE_NULL : - case FIELD_TYPE_SET : - case FIELD_TYPE_ENUM : DBUG_RETURN(0); - - default: DBUG_RETURN(0); } - DBUG_RETURN(0); } int load_conn_info(FEDERATED_SHARE *share, TABLE *table) @@ -1159,7 +1049,8 @@ int ha_federated::write_row(byte * buf) insert_string.append((*field)->field_name); // quote these fields if they require it - quote_data(&insert_field_value_string, *field); + + (*field)->quote_data(&insert_field_value_string); // append the value values_string.append(insert_field_value_string); insert_field_value_string.length(0); @@ -1305,7 +1196,7 @@ int ha_federated::update_row( { // otherwise = (*field)->val_str(&new_field_value); - quote_data(&new_field_value, *field); + (*field)->quote_data(&new_field_value); if ( has_a_primary_key ) { @@ -1323,7 +1214,7 @@ int ha_federated::update_row( { (*field)->val_str(&old_field_value, (char *)(old_data + (*field)->offset())); - quote_data(&old_field_value, *field); + (*field)->quote_data(&old_field_value); where_string.append(old_field_value); } } @@ -1335,7 +1226,7 @@ int ha_federated::update_row( { (*field)->val_str(&old_field_value, (char *)(old_data + (*field)->offset())); - quote_data(&old_field_value, *field); + (*field)->quote_data(&old_field_value); where_string.append(old_field_value); } } @@ -1412,7 +1303,7 @@ int ha_federated::delete_row(const byte * buf) { delete_string.append("="); (*field)->val_str(&data_string); - quote_data(&data_string, *field); + (*field)->quote_data(&data_string); } delete_string.append(data_string); @@ -1469,13 +1360,10 @@ int ha_federated::index_read_idx(byte * buf, uint index, const byte * key, char key_value[IO_SIZE]; char test_value[IO_SIZE]; String index_string(index_value, sizeof(index_value), &my_charset_bin); - String test_string(test_value, sizeof(test_value), &my_charset_bin); index_string.length(0); - test_string.length(0); uint keylen; char sql_query_buffer[IO_SIZE]; - String tmp_string; String sql_query(sql_query_buffer, sizeof(sql_query_buffer), &my_charset_bin); sql_query.length(0); @@ -1484,34 +1372,15 @@ int ha_federated::index_read_idx(byte * buf, uint index, const byte * key, sql_query.append(share->select_query); sql_query.append(" WHERE "); - sql_query.append(table->key_info[index].key_part->field->field_name); - sql_query.append(" = "); - if (table->key_info[index].key_part->field->type() == MYSQL_TYPE_VARCHAR) - { - //keylen= uint2korr(key); - keylen= key[0]; - create_where_from_key(&tmp_string, &table->key_info[index], key, keylen); - memcpy(key_value, key + HA_KEY_BLOB_LENGTH, keylen); - key_value[keylen]= 0; - DBUG_PRINT("ha_federated::index_read_idx", - ("key_value %s len %d", key_value, keylen)); - index_string.append(key_value); - } - else - { - //table->key_info[index].key_part->field->val_str(&index_string, (char - //*)(key)); - index_string.append((char *)(key)); - } + keylen= strlen((char *)(key)); + create_where_from_key(&index_string, &table->key_info[index], key, keylen); + sql_query.append(index_string); + DBUG_PRINT("ha_federated::index_read_idx", ("current key %d key value %s index_string value %s length %d", index, (char *)(key),index_string.c_ptr_quick(), index_string.length())); - //table->key_info[index].key_part->field->val_str(&index_string); - quote_data(&index_string, table->key_info[index].key_part->field); - sql_query.append(index_string); - DBUG_PRINT("ha_federated::index_read_idx", ("current position %d sql_query %s", current_position, sql_query.c_ptr_quick())); diff --git a/sql/ha_federated.h b/sql/ha_federated.h index ce35ce96828..b44ad937650 100755 --- a/sql/ha_federated.h +++ b/sql/ha_federated.h @@ -71,10 +71,7 @@ private: return 0 on success return errorcode otherwise */ - //FIX uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row); - uint type_quote(int type); - void quote_data(String *string1, Field *field); bool ha_federated::create_where_from_key(String *to, KEY *key_info, const byte *key, uint key_length); public: @@ -105,7 +102,7 @@ public: { return (HA_TABLE_SCAN_ON_INDEX | HA_NOT_EXACT_COUNT | HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | HA_AUTO_PART_KEY | - HA_TABLE_SCAN_ON_INDEX); + HA_TABLE_SCAN_ON_INDEX | HA_CAN_INDEX_BLOBS); } /* This is a bitmap of flags that says how the storage engine diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6f569ea3ef4..b8dfc0d3876 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -712,6 +712,10 @@ void free_des_key_file(); /* sql_do.cc */ bool mysql_do(THD *thd, List<Item> &values); +/* sql_analyse.h */ +bool append_escaped(String *to_str, String *from_str); +bool append_escaped(String *to_str, char *from, uint from_len); + /* sql_show.cc */ bool mysqld_show_open_tables(THD *thd,const char *wild); bool mysqld_show_logs(THD *thd); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 6a9a9e51231..8a74d9709dd 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -59,7 +59,8 @@ int compare_ulonglong2(void* cmp_arg __attribute__((unused)), return compare_ulonglong(s,t); } -static bool append_escaped(String *to_str, String *from_str); +bool append_escaped(String *to_str, String *from_str); +bool append_escaped(String *to_str, char *from, uint from_len); Procedure * proc_analyse_init(THD *thd, ORDER *param, select_result *result, @@ -1047,7 +1048,7 @@ uint check_ulonglong(const char *str, uint length) 1 Out of memory */ -static bool append_escaped(String *to_str, String *from_str) +bool append_escaped(String *to_str, String *from_str) { char *from, *end, c; @@ -1081,3 +1082,38 @@ static bool append_escaped(String *to_str, String *from_str) } return 0; } + +bool append_escaped(String *to_str, char *from, uint from_len) +{ + char *end, c; + + if (to_str->realloc(to_str->length() + from_len)) + return 1; + + end= from + from_len; + + for (; from < end; from++) + { + c= *from; + switch (c) { + case '\0': + c= '0'; + break; + case '\032': + c= 'Z'; + break; + case '\\': + case '\'': + break; + default: + goto normal_character; + } + if (to_str->append('\\')) + return 1; + + normal_character: + if (to_str->append(c)) + return 1; + } + return 0; +} |