diff options
Diffstat (limited to 'sql/ha_federated.cc')
-rw-r--r-- | sql/ha_federated.cc | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index ac1e0962ffb..d414dc34f02 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -643,13 +643,20 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, if ((strchr(share->table_name, '/'))) goto error; + /* + If hostname is omitted, we set it to NULL. According to + mysql_real_connect() manual: + The value of host may be either a hostname or an IP address. + If host is NULL or the string "localhost", a connection to the + local host is assumed. + */ if (share->hostname[0] == '\0') share->hostname= NULL; if (!share->port) { - if (strcmp(share->hostname, my_localhost) == 0) - share->socket= my_strdup(MYSQL_UNIX_ADDR, MYF(0)); + if (!share->hostname || strcmp(share->hostname, my_localhost) == 0) + share->socket= (char*) MYSQL_UNIX_ADDR; else share->port= MYSQL_PORT; } @@ -1094,10 +1101,20 @@ bool ha_federated::create_where_from_key(String *to, { if (*ptr++) { + /* + We got "IS [NOT] NULL" condition against nullable column. We + distinguish between "IS NOT NULL" and "IS NULL" by flag. For + "IS NULL", flag is set to HA_READ_KEY_EXACT. + */ if (emit_key_part_name(&tmp, key_part) || - tmp.append(FEDERATED_ISNULL)) + tmp.append(ranges[i]->flag == HA_READ_KEY_EXACT ? + FEDERATED_ISNULL : " IS NOT NULL ")) DBUG_RETURN(1); - continue; + /* + We need to adjust pointer and length to be prepared for next + key part. As well as check if this was last key part. + */ + goto prepare_for_next_key_part; } } @@ -1199,12 +1216,18 @@ bool ha_federated::create_where_from_key(String *to, if (tmp.append(FEDERATED_CLOSEPAREN)) DBUG_RETURN(1); +prepare_for_next_key_part: if (store_length >= length) break; DBUG_PRINT("info", ("remainder %d", remainder)); DBUG_ASSERT(remainder > 1); length-= store_length; - ptr+= store_length; + /* + For nullable columns, null-byte is already skipped before, that is + ptr was incremented by 1. Since store_length still counts null-byte, + we need to subtract 1 from store_length. + */ + ptr+= store_length - test(key_part->null_bit); if (tmp.append(FEDERATED_AND)) DBUG_RETURN(1); @@ -1319,7 +1342,6 @@ static int free_share(FEDERATED_SHARE *share) { hash_delete(&federated_open_tables, (byte*) share); my_free((gptr) share->scheme, MYF(MY_ALLOW_ZERO_PTR)); - my_free((gptr) share->socket, MYF(MY_ALLOW_ZERO_PTR)); thr_lock_delete(&share->lock); VOID(pthread_mutex_destroy(&share->mutex)); my_free((gptr) share, MYF(0)); |