Commit 7c62023b authored by unknown's avatar unknown

Merge mskold@bk-internal.mysql.com:/home/bk/mysql-5.0

into mysql.com:/usr/local/home/marty/MySQL/mysql-5.0


sql/sql_select.cc:
  Auto merged
parents 4360dd16 fec4347f
......@@ -87,6 +87,7 @@ hf@deer.mysql.r18.ru
hf@genie.(none)
holyfoot@mysql.com
igor@hundin.mysql.fi
igor@igor-inspiron.creware.com
igor@linux.local
igor@rurik.mysql.com
ingo@mysql.com
......@@ -236,6 +237,7 @@ rburnett@bk-internal.mysql.com
rburnett@build.mysql.com
reggie@bob.(none)
reggie@mdk10.(none)
reggie@monster.
root@home.(none)
root@mc04.(none)
root@x3.internalnet
......
......@@ -36,7 +36,7 @@
#include "handshake.hpp"
#include "yassl_int.hpp"
#include <stdio.h>
#include "runtime.hpp"
namespace yaSSL {
......
......@@ -74,7 +74,7 @@ extern char *mysql_unix_port;
#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
#define IS_BLOB(n) ((n) & BLOB_FLAG)
#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR)
#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR || (t) == FIELD_TYPE_NEWDECIMAL)
#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG)
#define INTERNAL_NUM_FIELD(f) (((f)->type <= FIELD_TYPE_INT24 && ((f)->type != FIELD_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == FIELD_TYPE_YEAR)
......
......@@ -160,3 +160,20 @@ t1 CREATE TABLE `t1` (
`COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (EMPNUM INT);
INSERT INTO t1 VALUES (0), (2);
CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
INSERT INTO t2 VALUES (0.0), (9.0);
SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
CEMPNUM EMPMUM1 EMPNUM2
0.00 0 0.00
2.00 2 NULL
SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
CEMPNUM EMPMUM1 EMPNUM2
0.00 0 0.00
2.00 2 NULL
DROP TABLE t1,t2;
......@@ -110,3 +110,22 @@ explain extended SELECT
COALESCE('a' COLLATE latin1_bin,'b');
SHOW CREATE TABLE t1;
DROP TABLE t1;
#
# Tests for bug #9939: conversion of the arguments for COALESCE and IFNULL
#
CREATE TABLE t1 (EMPNUM INT);
INSERT INTO t1 VALUES (0), (2);
CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
INSERT INTO t2 VALUES (0.0), (9.0);
SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
DROP TABLE t1,t2;
......@@ -44,7 +44,7 @@ int my_access(const char *path, int amode)
result= GetFileAttributesEx(path, GetFileExInfoStandard, &fileinfo);
if (! result ||
(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) && (amode & W_OK))
(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) && (amode & F_OK))
{
my_errno= errno= EACCES;
return -1;
......
......@@ -5963,11 +5963,14 @@ ha_innobase::external_lock(
TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
an InnoDB table lock if it is released immediately at the end
of LOCK TABLES, and InnoDB's table locks in that case cause
VERY easily deadlocks. */
VERY easily deadlocks. We do not set InnoDB table locks when
MySQL sets them at the start of a stored procedure call
(MySQL does have thd->in_lock_tables TRUE there). */
if (prebuilt->select_lock_type != LOCK_NONE) {
if (thd->in_lock_tables &&
thd->lex->sql_command != SQLCOM_CALL &&
thd->variables.innodb_table_locks &&
(thd->options & OPTION_NOT_AUTOCOMMIT)) {
......@@ -6478,11 +6481,21 @@ ha_innobase::store_lock(
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
/* Starting from 5.0.7, we weaken also the table locks
set at the start of a MySQL stored procedure call, just like
we weaken the locks set at the start of an SQL statement.
MySQL does set thd->in_lock_tables TRUE there, but in reality
we do not need table locks to make the execution of a
single transaction stored procedure call deterministic
(if it does not use a consistent read). */
/* If we are not doing a LOCK TABLE or DISCARD/IMPORT
TABLESPACE or TRUNCATE TABLE, then allow multiple writers */
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
lock_type <= TL_WRITE) && !thd->in_lock_tables
lock_type <= TL_WRITE)
&& (!thd->in_lock_tables
|| thd->lex->sql_command == SQLCOM_CALL)
&& !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE
&& thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
......@@ -6496,7 +6509,10 @@ ha_innobase::store_lock(
to t2. Convert the lock to a normal read lock to allow
concurrent inserts to t2. */
if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) {
if (lock_type == TL_READ_NO_INSERT
&& (!thd->in_lock_tables
|| thd->lex->sql_command == SQLCOM_CALL)) {
lock_type = TL_READ;
}
......
......@@ -1116,8 +1116,8 @@ Item_func_ifnull::fix_length_and_dec()
max_length= (max(args[0]->max_length - args[0]->decimals,
args[1]->max_length - args[1]->decimals) +
decimals);
agg_result_type(&cached_result_type, args, 2);
switch (cached_result_type) {
agg_result_type(&hybrid_type, args, 2);
switch (hybrid_type) {
case STRING_RESULT:
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV);
break;
......@@ -1155,7 +1155,7 @@ Field *Item_func_ifnull::tmp_table_field(TABLE *table)
}
double
Item_func_ifnull::val_real()
Item_func_ifnull::real_op()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val_real();
......@@ -1171,7 +1171,7 @@ Item_func_ifnull::val_real()
}
longlong
Item_func_ifnull::val_int()
Item_func_ifnull::int_op()
{
DBUG_ASSERT(fixed == 1);
longlong value=args[0]->val_int();
......@@ -1187,7 +1187,7 @@ Item_func_ifnull::val_int()
}
my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
my_decimal *value= args[0]->val_decimal(decimal_value);
......@@ -1204,7 +1204,7 @@ my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)
String *
Item_func_ifnull::val_str(String *str)
Item_func_ifnull::str_op(String *str)
{
DBUG_ASSERT(fixed == 1);
String *res =args[0]->val_str(str);
......@@ -1685,7 +1685,7 @@ void Item_func_case::print(String *str)
Coalesce - return first not NULL argument.
*/
String *Item_func_coalesce::val_str(String *str)
String *Item_func_coalesce::str_op(String *str)
{
DBUG_ASSERT(fixed == 1);
null_value=0;
......@@ -1699,7 +1699,7 @@ String *Item_func_coalesce::val_str(String *str)
return 0;
}
longlong Item_func_coalesce::val_int()
longlong Item_func_coalesce::int_op()
{
DBUG_ASSERT(fixed == 1);
null_value=0;
......@@ -1713,7 +1713,7 @@ longlong Item_func_coalesce::val_int()
return 0;
}
double Item_func_coalesce::val_real()
double Item_func_coalesce::real_op()
{
DBUG_ASSERT(fixed == 1);
null_value=0;
......@@ -1728,7 +1728,7 @@ double Item_func_coalesce::val_real()
}
my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
null_value= 0;
......@@ -1745,8 +1745,8 @@ my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)
void Item_func_coalesce::fix_length_and_dec()
{
agg_result_type(&cached_result_type, args, arg_count);
switch (cached_result_type) {
agg_result_type(&hybrid_type, args, arg_count);
switch (hybrid_type) {
case STRING_RESULT:
count_only_length();
decimals= NOT_FIXED_DEC;
......
......@@ -453,23 +453,19 @@ class Item_func_interval :public Item_int_func
};
class Item_func_coalesce :public Item_func
class Item_func_coalesce :public Item_func_numhybrid
{
protected:
enum Item_result cached_result_type;
Item_func_coalesce(Item *a, Item *b)
:Item_func(a, b), cached_result_type(INT_RESULT)
{}
Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
public:
Item_func_coalesce(List<Item> &list)
:Item_func(list),cached_result_type(INT_RESULT)
{}
double val_real();
longlong val_int();
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
double real_op();
longlong int_op();
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
void fix_length_and_dec();
enum Item_result result_type () const { return cached_result_type; }
void find_num_type() {}
enum Item_result result_type () const { return hybrid_type; }
const char *func_name() const { return "coalesce"; }
table_map not_null_tables() const { return 0; }
};
......@@ -482,10 +478,10 @@ class Item_func_ifnull :public Item_func_coalesce
bool field_type_defined;
public:
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
double val_real();
longlong val_int();
String *val_str(String *str);
my_decimal *val_decimal(my_decimal *);
double real_op();
longlong int_op();
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
enum_field_types field_type() const;
void fix_length_and_dec();
const char *func_name() const { return "ifnull"; }
......
......@@ -817,6 +817,8 @@ String *Item_func_numhybrid::val_str(String *str)
str->set(nr,decimals,&my_charset_bin);
break;
}
case STRING_RESULT:
return str_op(&str_value);
default:
DBUG_ASSERT(0);
}
......@@ -841,6 +843,14 @@ double Item_func_numhybrid::val_real()
return (double)int_op();
case REAL_RESULT:
return real_op();
case STRING_RESULT:
{
char *end_not_used;
int err_not_used;
String *res= str_op(&str_value);
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
&end_not_used, &err_not_used) : 0.0);
}
default:
DBUG_ASSERT(0);
}
......@@ -865,6 +875,15 @@ longlong Item_func_numhybrid::val_int()
return int_op();
case REAL_RESULT:
return (longlong)real_op();
case STRING_RESULT:
{
char *end_not_used;
int err_not_used;
String *res= str_op(&str_value);
CHARSET_INFO *cs= str_value.charset();
return (res ? (*(cs->cset->strtoll10))(cs, res->ptr(), &end_not_used,
&err_not_used) : 0);
}
default:
DBUG_ASSERT(0);
}
......@@ -893,6 +912,12 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
break;
}
case STRING_RESULT:
{
String *res= str_op(&str_value);
str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
res->length(), res->charset(), decimal_value);
break;
}
case ROW_RESULT:
default:
DBUG_ASSERT(0);
......@@ -2325,9 +2350,6 @@ longlong Item_func_field::val_int()
{
DBUG_ASSERT(fixed == 1);
if (args[0]->is_null())
return 0;
if (cmp_type == STRING_RESULT)
{
String *field;
......@@ -2343,6 +2365,8 @@ longlong Item_func_field::val_int()
else if (cmp_type == INT_RESULT)
{
longlong val= args[0]->val_int();
if (args[0]->null_value)
return 0;
for (uint i=1; i < arg_count ; i++)
{
if (!args[i]->is_null() && val == args[i]->val_int())
......@@ -2353,6 +2377,8 @@ longlong Item_func_field::val_int()
{
my_decimal dec_arg_buf, *dec_arg,
dec_buf, *dec= args[0]->val_decimal(&dec_buf);
if (args[0]->null_value)
return 0;
for (uint i=1; i < arg_count; i++)
{
dec_arg= args[i]->val_decimal(&dec_arg_buf);
......@@ -2363,6 +2389,8 @@ longlong Item_func_field::val_int()
else
{
double val= args[0]->val_real();
if (args[0]->null_value)
return 0;
for (uint i=1; i < arg_count ; i++)
{
if (!args[i]->is_null() && val == args[i]->val_real())
......
......@@ -189,10 +189,13 @@ class Item_func_numhybrid: public Item_func
protected:
Item_result hybrid_type;
public:
Item_func_numhybrid(Item *a) :Item_func(a),hybrid_type(REAL_RESULT)
Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
{}
Item_func_numhybrid(Item *a,Item *b)
:Item_func(a,b),hybrid_type(REAL_RESULT)
:Item_func(a,b), hybrid_type(REAL_RESULT)
{}
Item_func_numhybrid(List<Item> &list)
:Item_func(list), hybrid_type(REAL_RESULT)
{}
enum Item_result result_type () const { return hybrid_type; }
......@@ -208,6 +211,7 @@ class Item_func_numhybrid: public Item_func
virtual longlong int_op()= 0;
virtual double real_op()= 0;
virtual my_decimal *decimal_op(my_decimal *)= 0;
virtual String *str_op(String *)= 0;
bool is_null() { (void) val_real(); return null_value; }
};
......@@ -220,6 +224,7 @@ class Item_func_num1: public Item_func_numhybrid
void fix_num_length_and_dec();
void find_num_type();
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
};
......@@ -231,6 +236,7 @@ class Item_num_op :public Item_func_numhybrid
virtual void result_precision()= 0;
void print(String *str) { print_op(str); }
void find_num_type();
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
};
......
......@@ -28,7 +28,7 @@ template <uint default_width> class Bitmap
uchar buffer[(default_width+7)/8];
public:
Bitmap() { init(); }
Bitmap(Bitmap& from) { *this=from; }
Bitmap(const Bitmap& from) { *this=from; }
explicit Bitmap(uint prefix_to_set) { init(prefix_to_set); }
void init() { bitmap_init(&map, buffer, default_width, 0); }
void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); }
......@@ -61,18 +61,17 @@ template <uint default_width> class Bitmap
my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
char *print(char *buf) const
{
char *s=buf; int i;
for (i=sizeof(buffer)-1; i>=0 ; i--)
char *s=buf;
const uchar *e=buffer, *b=e+sizeof(buffer)-1;
while (!*b && b>e)
b--;
if ((*s=_dig_vec_upper[*b >> 4]) != '0')
s++;
*s++=_dig_vec_upper[*b & 15];
while (--b>=e)
{
if ((*s=_dig_vec_upper[buffer[i] >> 4]) != '0')
break;
if ((*s=_dig_vec_upper[buffer[i] & 15]) != '0')
break;
}
for (s++, i-- ; i>=0 ; i--)
{
*s++=_dig_vec_upper[buffer[i] >> 4];
*s++=_dig_vec_upper[buffer[i] & 15];
*s++=_dig_vec_upper[*b >> 4];
*s++=_dig_vec_upper[*b & 15];
}
*s=0;
return buf;
......
......@@ -5799,6 +5799,7 @@ make_join_readinfo(JOIN *join, uint options)
if (!table->no_keyread)
{
if (tab->select && tab->select->quick &&
tab->select->quick->index != MAX_KEY && //not index_merge
table->used_keys.is_set(tab->select->quick->index))
{
table->key_read=1;
......
......@@ -7455,12 +7455,16 @@ static void test_explain_bug()
verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
"", "", "", NAME_LEN, 0);
verify_prepare_field(result, 6, "key_len", "",
(mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_LONGLONG : MYSQL_TYPE_VAR_STRING),
"", "", "",
(mysql_get_server_version(mysql) <= 50000 ? 3 : 4096),
0);
if (mysql_get_server_version(mysql) <= 50000)
{
verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
"", "", 3, 0);
}
else
{
verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
"", "", NAME_LEN*MAX_KEY, 0);
}
verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
"", "", "", NAME_LEN*16, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment