summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <patg@pc248.lfp.kcls.org>2005-01-20 18:36:40 -0800
committerunknown <patg@pc248.lfp.kcls.org>2005-01-20 18:36:40 -0800
commit66b62e051930dbcd9dc1d38f0cac574692932834 (patch)
treedeb5a7cc7ebc3ade7e8c5fd0d1105f928f2f133a /sql
parent9aaa87e909484a9c12b2a5e8913da45f8b7d0e9d (diff)
downloadmariadb-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.cc109
-rw-r--r--sql/field.h2
-rw-r--r--sql/ha_federated.cc221
-rwxr-xr-xsql/ha_federated.h5
-rw-r--r--sql/mysql_priv.h4
-rw-r--r--sql/sql_analyse.cc40
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;
+}