manual merge
sql/field.cc: Auto merged sql/item.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/item_func.cc: Auto merged sql/mysqld.cc: Auto merged sql/opt_range.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_view.cc: Auto merged strings/ctype-utf8.c: Auto merged
This commit is contained in:
commit
3c82f72091
@ -64,7 +64,12 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Calculate a hash for a row */
|
/*
|
||||||
|
Calculate a hash for a row
|
||||||
|
|
||||||
|
TODO
|
||||||
|
Add support for bit fields
|
||||||
|
*/
|
||||||
|
|
||||||
ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
|
ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
|
||||||
{
|
{
|
||||||
@ -126,9 +131,17 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Returns 0 if both rows have equal unique value
|
/*
|
||||||
*/
|
compare unique key for two rows
|
||||||
|
|
||||||
|
TODO
|
||||||
|
Add support for bit fields
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 if both rows have equal unique value
|
||||||
|
# Rows are different
|
||||||
|
*/
|
||||||
|
|
||||||
int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
|
int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
|
||||||
my_bool null_are_equal)
|
my_bool null_are_equal)
|
||||||
|
@ -288,7 +288,7 @@ static struct my_option my_long_options[] =
|
|||||||
|
|
||||||
static void print_version(void)
|
static void print_version(void)
|
||||||
{
|
{
|
||||||
VOID(printf("%s Ver 1.22 for %s on %s\n",
|
VOID(printf("%s Ver 1.23 for %s on %s\n",
|
||||||
my_progname, SYSTEM_TYPE, MACHINE_TYPE));
|
my_progname, SYSTEM_TYPE, MACHINE_TYPE));
|
||||||
NETWARE_SET_SCREEN_MODE(1);
|
NETWARE_SET_SCREEN_MODE(1);
|
||||||
}
|
}
|
||||||
|
@ -731,6 +731,27 @@ n
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1052 Column 'n' in group statement is ambiguous
|
Warning 1052 Column 'n' in group statement is ambiguous
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1 (c1 char(3), c2 char(3));
|
||||||
|
create table t2 (c3 char(3), c4 char(3));
|
||||||
|
insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||||
|
insert into t2 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||||
|
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||||
|
group by c2;
|
||||||
|
c2
|
||||||
|
aaa
|
||||||
|
aaa
|
||||||
|
Warnings:
|
||||||
|
Warning 1052 Column 'c2' in group statement is ambiguous
|
||||||
|
show warnings;
|
||||||
|
Level Code Message
|
||||||
|
Warning 1052 Column 'c2' in group statement is ambiguous
|
||||||
|
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||||
|
group by t1.c1;
|
||||||
|
c2
|
||||||
|
aaa
|
||||||
|
show warnings;
|
||||||
|
Level Code Message
|
||||||
|
drop table t1, t2;
|
||||||
CREATE TABLE t1 (a int, b int);
|
CREATE TABLE t1 (a int, b int);
|
||||||
INSERT INTO t1 VALUES (1,2), (1,3);
|
INSERT INTO t1 VALUES (1,2), (1,3);
|
||||||
SELECT a, b FROM t1 GROUP BY 'const';
|
SELECT a, b FROM t1 GROUP BY 'const';
|
||||||
|
@ -227,6 +227,9 @@ latin1_bin latin1
|
|||||||
latin1_general_ci latin1
|
latin1_general_ci latin1
|
||||||
latin1_general_cs latin1
|
latin1_general_cs latin1
|
||||||
latin1_spanish_ci latin1
|
latin1_spanish_ci latin1
|
||||||
|
drop procedure if exists sel2;
|
||||||
|
drop function if exists sub1;
|
||||||
|
drop function if exists sub2;
|
||||||
create function sub1(i int) returns int
|
create function sub1(i int) returns int
|
||||||
return i+1;
|
return i+1;
|
||||||
create procedure sel2()
|
create procedure sel2()
|
||||||
@ -823,6 +826,8 @@ GRANT SELECT ON *.* TO 'user4'@'localhost'
|
|||||||
drop user user1@localhost, user2@localhost, user3@localhost, user4@localhost;
|
drop user user1@localhost, user2@localhost, user3@localhost, user4@localhost;
|
||||||
use test;
|
use test;
|
||||||
drop database mysqltest;
|
drop database mysqltest;
|
||||||
|
drop procedure if exists p1;
|
||||||
|
drop procedure if exists p2;
|
||||||
create procedure p1 () modifies sql data set @a = 5;
|
create procedure p1 () modifies sql data set @a = 5;
|
||||||
create procedure p2 () set @a = 5;
|
create procedure p2 () set @a = 5;
|
||||||
select sql_data_access from information_schema.routines
|
select sql_data_access from information_schema.routines
|
||||||
|
@ -543,6 +543,27 @@ SELECT hostname, COUNT(DISTINCT user_id) as no FROM t1
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# Bug#11211: Ambiguous column reference in GROUP BY.
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (c1 char(3), c2 char(3));
|
||||||
|
create table t2 (c3 char(3), c4 char(3));
|
||||||
|
insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||||
|
insert into t2 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||||
|
|
||||||
|
# query with ambiguous column reference 'c2'
|
||||||
|
--disable_ps_protocol
|
||||||
|
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||||
|
group by c2;
|
||||||
|
show warnings;
|
||||||
|
--enable_ps_protocol
|
||||||
|
|
||||||
|
# this query has no ambiguity
|
||||||
|
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
|
||||||
|
group by t1.c1;
|
||||||
|
|
||||||
|
show warnings;
|
||||||
|
drop table t1, t2;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test for bug #11414: crash on Windows for a simple GROUP BY query
|
# Test for bug #11414: crash on Windows for a simple GROUP BY query
|
||||||
|
@ -101,6 +101,12 @@ where COLLATION_NAME like 'latin1%';
|
|||||||
# Test for information_schema.ROUTINES &
|
# Test for information_schema.ROUTINES &
|
||||||
#
|
#
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists sel2;
|
||||||
|
drop function if exists sub1;
|
||||||
|
drop function if exists sub2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
create function sub1(i int) returns int
|
create function sub1(i int) returns int
|
||||||
return i+1;
|
return i+1;
|
||||||
delimiter |;
|
delimiter |;
|
||||||
@ -546,6 +552,11 @@ drop database mysqltest;
|
|||||||
#
|
#
|
||||||
# Bug #11055 information_schema: routines.sql_data_access has wrong value
|
# Bug #11055 information_schema: routines.sql_data_access has wrong value
|
||||||
#
|
#
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists p1;
|
||||||
|
drop procedure if exists p2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
create procedure p1 () modifies sql data set @a = 5;
|
create procedure p1 () modifies sql data set @a = 5;
|
||||||
create procedure p2 () set @a = 5;
|
create procedure p2 () set @a = 5;
|
||||||
select sql_data_access from information_schema.routines
|
select sql_data_access from information_schema.routines
|
||||||
|
@ -277,9 +277,8 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
|
|||||||
record being compared against.
|
record being compared against.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
< 0 key of record < key
|
|
||||||
= 0 key of record == key
|
= 0 key of record == key
|
||||||
> 0 key of record > key
|
!= 0 key of record != key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length)
|
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length)
|
||||||
|
@ -2486,7 +2486,7 @@ int Field_new_decimal::store(longlong nr)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
|
if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
|
||||||
nr, false, &decimal_value)))
|
nr, FALSE, &decimal_value)))
|
||||||
{
|
{
|
||||||
if (check_overflow(err))
|
if (check_overflow(err))
|
||||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||||
@ -6829,7 +6829,12 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
¬_used)))
|
¬_used)))
|
||||||
{
|
{
|
||||||
uint conv_errors;
|
uint conv_errors;
|
||||||
tmpstr.copy(from, length, cs, field_charset, &conv_errors);
|
if (tmpstr.copy(from, length, cs, field_charset, &conv_errors))
|
||||||
|
{
|
||||||
|
/* Fatal OOM error */
|
||||||
|
bzero(ptr,Field_blob::pack_length());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
from= tmpstr.ptr();
|
from= tmpstr.ptr();
|
||||||
length= tmpstr.length();
|
length= tmpstr.length();
|
||||||
if (conv_errors)
|
if (conv_errors)
|
||||||
|
@ -1399,27 +1399,25 @@ int ha_federated::update_row(const byte *old_data, byte *new_data)
|
|||||||
|
|
||||||
int ha_federated::delete_row(const byte *buf)
|
int ha_federated::delete_row(const byte *buf)
|
||||||
{
|
{
|
||||||
uint x= 0;
|
|
||||||
char delete_buffer[IO_SIZE];
|
char delete_buffer[IO_SIZE];
|
||||||
char data_buffer[IO_SIZE];
|
char data_buffer[IO_SIZE];
|
||||||
|
|
||||||
String delete_string(delete_buffer, sizeof(delete_buffer), &my_charset_bin);
|
String delete_string(delete_buffer, sizeof(delete_buffer), &my_charset_bin);
|
||||||
delete_string.length(0);
|
|
||||||
String data_string(data_buffer, sizeof(data_buffer), &my_charset_bin);
|
String data_string(data_buffer, sizeof(data_buffer), &my_charset_bin);
|
||||||
data_string.length(0);
|
|
||||||
|
|
||||||
DBUG_ENTER("ha_federated::delete_row");
|
DBUG_ENTER("ha_federated::delete_row");
|
||||||
|
|
||||||
|
delete_string.length(0);
|
||||||
delete_string.append("DELETE FROM `");
|
delete_string.append("DELETE FROM `");
|
||||||
delete_string.append(share->table_base_name);
|
delete_string.append(share->table_base_name);
|
||||||
delete_string.append("`");
|
delete_string.append("`");
|
||||||
delete_string.append(" WHERE ");
|
delete_string.append(" WHERE ");
|
||||||
|
|
||||||
for (Field **field= table->field; *field; field++, x++)
|
for (Field **field= table->field; *field; field++)
|
||||||
{
|
{
|
||||||
delete_string.append((*field)->field_name);
|
Field *cur_field= *field;
|
||||||
|
data_string.length(0);
|
||||||
|
delete_string.append(cur_field->field_name);
|
||||||
|
|
||||||
if ((*field)->is_null())
|
if (cur_field->is_null_in_record((const uchar*) buf))
|
||||||
{
|
{
|
||||||
delete_string.append(" IS ");
|
delete_string.append(" IS ");
|
||||||
data_string.append("NULL");
|
data_string.append("NULL");
|
||||||
@ -1427,17 +1425,15 @@ int ha_federated::delete_row(const byte *buf)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete_string.append("=");
|
delete_string.append("=");
|
||||||
(*field)->val_str(&data_string);
|
cur_field->val_str(&data_string, (char*) buf+ cur_field->offset());
|
||||||
(*field)->quote_data(&data_string);
|
cur_field->quote_data(&data_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_string.append(data_string);
|
delete_string.append(data_string);
|
||||||
data_string.length(0);
|
delete_string.append(" AND ");
|
||||||
|
|
||||||
if (x + 1 < table->s->fields)
|
|
||||||
delete_string.append(" AND ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete_string.length(delete_string.length()-5); // Remove AND
|
||||||
delete_string.append(" LIMIT 1");
|
delete_string.append(" LIMIT 1");
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("Delete sql: %s", delete_string.c_ptr_quick()));
|
("Delete sql: %s", delete_string.c_ptr_quick()));
|
||||||
|
@ -341,7 +341,7 @@ void ha_ndbcluster::records_update()
|
|||||||
{
|
{
|
||||||
Ndb *ndb= get_ndb();
|
Ndb *ndb= get_ndb();
|
||||||
struct Ndb_statistics stat;
|
struct Ndb_statistics stat;
|
||||||
if(ndb_get_table_statistics(ndb, m_tabname, &stat) == 0){
|
if (ndb_get_table_statistics(ndb, m_tabname, &stat) == 0){
|
||||||
mean_rec_length= stat.row_size;
|
mean_rec_length= stat.row_size;
|
||||||
data_file_length= stat.fragment_memory;
|
data_file_length= stat.fragment_memory;
|
||||||
info->records= stat.row_count;
|
info->records= stat.row_count;
|
||||||
@ -448,27 +448,27 @@ void ha_ndbcluster::invalidate_dictionary_cache(bool global)
|
|||||||
NDBINDEX *unique_index = (NDBINDEX *) m_index[i].unique_index;
|
NDBINDEX *unique_index = (NDBINDEX *) m_index[i].unique_index;
|
||||||
NDB_INDEX_TYPE idx_type= m_index[i].type;
|
NDB_INDEX_TYPE idx_type= m_index[i].type;
|
||||||
|
|
||||||
switch(idx_type) {
|
switch (idx_type) {
|
||||||
case(PRIMARY_KEY_ORDERED_INDEX):
|
case PRIMARY_KEY_ORDERED_INDEX:
|
||||||
case(ORDERED_INDEX):
|
case ORDERED_INDEX:
|
||||||
if (global)
|
if (global)
|
||||||
dict->invalidateIndex(index->getName(), m_tabname);
|
dict->invalidateIndex(index->getName(), m_tabname);
|
||||||
else
|
else
|
||||||
dict->removeCachedIndex(index->getName(), m_tabname);
|
dict->removeCachedIndex(index->getName(), m_tabname);
|
||||||
break;
|
break;
|
||||||
case(UNIQUE_ORDERED_INDEX):
|
case UNIQUE_ORDERED_INDEX:
|
||||||
if (global)
|
if (global)
|
||||||
dict->invalidateIndex(index->getName(), m_tabname);
|
dict->invalidateIndex(index->getName(), m_tabname);
|
||||||
else
|
else
|
||||||
dict->removeCachedIndex(index->getName(), m_tabname);
|
dict->removeCachedIndex(index->getName(), m_tabname);
|
||||||
case(UNIQUE_INDEX):
|
case UNIQUE_INDEX:
|
||||||
if (global)
|
if (global)
|
||||||
dict->invalidateIndex(unique_index->getName(), m_tabname);
|
dict->invalidateIndex(unique_index->getName(), m_tabname);
|
||||||
else
|
else
|
||||||
dict->removeCachedIndex(unique_index->getName(), m_tabname);
|
dict->removeCachedIndex(unique_index->getName(), m_tabname);
|
||||||
break;
|
break;
|
||||||
case(PRIMARY_KEY_INDEX):
|
case PRIMARY_KEY_INDEX:
|
||||||
case(UNDEFINED_INDEX):
|
case UNDEFINED_INDEX:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1387,7 +1387,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((res= define_read_attrs(buf, op)))
|
if ((res= define_read_attrs(buf, op)))
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
|
|
||||||
if (execute_no_commit_ie(this,trans) != 0)
|
if (execute_no_commit_ie(this,trans) != 0)
|
||||||
@ -1517,10 +1517,10 @@ int ha_ndbcluster::unique_index_read(const byte *key,
|
|||||||
ERR_RETURN(trans->getNdbError());
|
ERR_RETURN(trans->getNdbError());
|
||||||
|
|
||||||
// Set secondary index key(s)
|
// Set secondary index key(s)
|
||||||
if((res= set_index_key(op, table->key_info + active_index, key)))
|
if ((res= set_index_key(op, table->key_info + active_index, key)))
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
|
|
||||||
if((res= define_read_attrs(buf, op)))
|
if ((res= define_read_attrs(buf, op)))
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
|
|
||||||
if (execute_no_commit_ie(this,trans) != 0)
|
if (execute_no_commit_ie(this,trans) != 0)
|
||||||
@ -1580,7 +1580,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor)
|
|||||||
{
|
{
|
||||||
if (execute_commit(this,trans) != 0)
|
if (execute_commit(this,trans) != 0)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if(trans->restart() != 0)
|
if (trans->restart() != 0)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -1618,7 +1618,7 @@ inline int ha_ndbcluster::next_result(byte *buf)
|
|||||||
if (!m_active_cursor)
|
if (!m_active_cursor)
|
||||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||||
|
|
||||||
if((res= fetch_next(m_active_cursor)) == 0)
|
if ((res= fetch_next(m_active_cursor)) == 0)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("One more record found"));
|
DBUG_PRINT("info", ("One more record found"));
|
||||||
|
|
||||||
@ -1626,7 +1626,7 @@ inline int ha_ndbcluster::next_result(byte *buf)
|
|||||||
table->status= 0;
|
table->status= 0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
else if(res == 1)
|
else if (res == 1)
|
||||||
{
|
{
|
||||||
// No more records
|
// No more records
|
||||||
table->status= STATUS_NOT_FOUND;
|
table->status= STATUS_NOT_FOUND;
|
||||||
@ -1857,7 +1857,7 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
|
|||||||
DBUG_ASSERT(op->getSorted() == sorted);
|
DBUG_ASSERT(op->getSorted() == sorted);
|
||||||
DBUG_ASSERT(op->getLockMode() ==
|
DBUG_ASSERT(op->getLockMode() ==
|
||||||
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type));
|
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type));
|
||||||
if(op->reset_bounds(m_force_send))
|
if (op->reset_bounds(m_force_send))
|
||||||
DBUG_RETURN(ndb_err(m_active_trans));
|
DBUG_RETURN(ndb_err(m_active_trans));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1903,7 +1903,7 @@ int ha_ndbcluster::full_table_scan(byte *buf)
|
|||||||
m_active_cursor= op;
|
m_active_cursor= op;
|
||||||
if (generate_scan_filter(m_cond_stack, op))
|
if (generate_scan_filter(m_cond_stack, op))
|
||||||
DBUG_RETURN(ndb_err(trans));
|
DBUG_RETURN(ndb_err(trans));
|
||||||
if((res= define_read_attrs(buf, op)))
|
if ((res= define_read_attrs(buf, op)))
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
|
|
||||||
if (execute_no_commit(this,trans) != 0)
|
if (execute_no_commit(this,trans) != 0)
|
||||||
@ -2041,7 +2041,7 @@ int ha_ndbcluster::write_row(byte *record)
|
|||||||
no_uncommitted_rows_execute_failure();
|
no_uncommitted_rows_execute_failure();
|
||||||
DBUG_RETURN(ndb_err(trans));
|
DBUG_RETURN(ndb_err(trans));
|
||||||
}
|
}
|
||||||
if(trans->restart() != 0)
|
if (trans->restart() != 0)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -2420,7 +2420,7 @@ void ha_ndbcluster::print_results()
|
|||||||
field= table->field[f];
|
field= table->field[f];
|
||||||
if (!(value= m_value[f]).ptr)
|
if (!(value= m_value[f]).ptr)
|
||||||
{
|
{
|
||||||
my_snprintf(buf, sizeof(buf), "not read");
|
strmov(buf, "not read");
|
||||||
goto print_value;
|
goto print_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2430,7 +2430,7 @@ void ha_ndbcluster::print_results()
|
|||||||
{
|
{
|
||||||
if (value.rec->isNULL())
|
if (value.rec->isNULL())
|
||||||
{
|
{
|
||||||
my_snprintf(buf, sizeof(buf), "NULL");
|
strmov(buf, "NULL");
|
||||||
goto print_value;
|
goto print_value;
|
||||||
}
|
}
|
||||||
type.length(0);
|
type.length(0);
|
||||||
@ -2444,10 +2444,8 @@ void ha_ndbcluster::print_results()
|
|||||||
NdbBlob *ndb_blob= value.blob;
|
NdbBlob *ndb_blob= value.blob;
|
||||||
bool isNull= TRUE;
|
bool isNull= TRUE;
|
||||||
ndb_blob->getNull(isNull);
|
ndb_blob->getNull(isNull);
|
||||||
if (isNull) {
|
if (isNull)
|
||||||
my_snprintf(buf, sizeof(buf), "NULL");
|
strmov(buf, "NULL");
|
||||||
goto print_value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print_value:
|
print_value:
|
||||||
@ -2487,7 +2485,7 @@ check_null_in_key(const KEY* key_info, const byte *key, uint key_len)
|
|||||||
|
|
||||||
for (; curr_part != end_part && key < end_ptr; curr_part++)
|
for (; curr_part != end_part && key < end_ptr; curr_part++)
|
||||||
{
|
{
|
||||||
if(curr_part->null_bit && *key)
|
if (curr_part->null_bit && *key)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
key += curr_part->store_length;
|
key += curr_part->store_length;
|
||||||
@ -2511,7 +2509,7 @@ int ha_ndbcluster::index_read(byte *buf,
|
|||||||
case PRIMARY_KEY_INDEX:
|
case PRIMARY_KEY_INDEX:
|
||||||
if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len)
|
if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len)
|
||||||
{
|
{
|
||||||
if(m_active_cursor && (error= close_scan()))
|
if (m_active_cursor && (error= close_scan()))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
DBUG_RETURN(pk_read(key, key_len, buf));
|
DBUG_RETURN(pk_read(key, key_len, buf));
|
||||||
}
|
}
|
||||||
@ -2525,7 +2523,7 @@ int ha_ndbcluster::index_read(byte *buf,
|
|||||||
if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len &&
|
if (find_flag == HA_READ_KEY_EXACT && key_info->key_length == key_len &&
|
||||||
!check_null_in_key(key_info, key, key_len))
|
!check_null_in_key(key_info, key, key_len))
|
||||||
{
|
{
|
||||||
if(m_active_cursor && (error= close_scan()))
|
if (m_active_cursor && (error= close_scan()))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
DBUG_RETURN(unique_index_read(key, key_len, buf));
|
DBUG_RETURN(unique_index_read(key, key_len, buf));
|
||||||
}
|
}
|
||||||
@ -2637,7 +2635,7 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
|
|||||||
start_key->length == key_info->key_length &&
|
start_key->length == key_info->key_length &&
|
||||||
start_key->flag == HA_READ_KEY_EXACT)
|
start_key->flag == HA_READ_KEY_EXACT)
|
||||||
{
|
{
|
||||||
if(m_active_cursor && (error= close_scan()))
|
if (m_active_cursor && (error= close_scan()))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
error= pk_read(start_key->key, start_key->length, buf);
|
error= pk_read(start_key->key, start_key->length, buf);
|
||||||
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
|
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
|
||||||
@ -2650,7 +2648,7 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
|
|||||||
start_key->flag == HA_READ_KEY_EXACT &&
|
start_key->flag == HA_READ_KEY_EXACT &&
|
||||||
!check_null_in_key(key_info, start_key->key, start_key->length))
|
!check_null_in_key(key_info, start_key->key, start_key->length))
|
||||||
{
|
{
|
||||||
if(m_active_cursor && (error= close_scan()))
|
if (m_active_cursor && (error= close_scan()))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
error= unique_index_read(start_key->key, start_key->length, buf);
|
error= unique_index_read(start_key->key, start_key->length, buf);
|
||||||
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
|
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
|
||||||
@ -2697,7 +2695,7 @@ int ha_ndbcluster::rnd_init(bool scan)
|
|||||||
{
|
{
|
||||||
if (!scan)
|
if (!scan)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if(cursor->restart(m_force_send) != 0)
|
if (cursor->restart(m_force_send) != 0)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -3467,7 +3465,7 @@ int ndbcluster_commit(THD *thd, bool all)
|
|||||||
}
|
}
|
||||||
ndb->closeTransaction(trans);
|
ndb->closeTransaction(trans);
|
||||||
|
|
||||||
if(all)
|
if (all)
|
||||||
thd_ndb->all= NULL;
|
thd_ndb->all= NULL;
|
||||||
else
|
else
|
||||||
thd_ndb->stmt= NULL;
|
thd_ndb->stmt= NULL;
|
||||||
@ -3517,7 +3515,7 @@ int ndbcluster_rollback(THD *thd, bool all)
|
|||||||
}
|
}
|
||||||
ndb->closeTransaction(trans);
|
ndb->closeTransaction(trans);
|
||||||
|
|
||||||
if(all)
|
if (all)
|
||||||
thd_ndb->all= NULL;
|
thd_ndb->all= NULL;
|
||||||
else
|
else
|
||||||
thd_ndb->stmt= NULL;
|
thd_ndb->stmt= NULL;
|
||||||
@ -3773,7 +3771,8 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
col.setType(NDBCOL::Char);
|
col.setType(NDBCOL::Char);
|
||||||
col.setLength(field->pack_length());
|
col.setLength(field->pack_length());
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_BIT: {
|
case MYSQL_TYPE_BIT:
|
||||||
|
{
|
||||||
int no_of_bits= field->field_length*8 + ((Field_bit *) field)->bit_len;
|
int no_of_bits= field->field_length*8 + ((Field_bit *) field)->bit_len;
|
||||||
col.setType(NDBCOL::Bit);
|
col.setType(NDBCOL::Bit);
|
||||||
if (!no_of_bits)
|
if (!no_of_bits)
|
||||||
@ -3908,7 +3907,7 @@ int ha_ndbcluster::create(const char *name,
|
|||||||
if ((my_errno= create_ndb_column(col, field, info)))
|
if ((my_errno= create_ndb_column(col, field, info)))
|
||||||
DBUG_RETURN(my_errno);
|
DBUG_RETURN(my_errno);
|
||||||
tab.addColumn(col);
|
tab.addColumn(col);
|
||||||
if(col.getPrimaryKey())
|
if (col.getPrimaryKey())
|
||||||
pk_length += (field->pack_length() + 3) / 4;
|
pk_length += (field->pack_length() + 3) / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3941,7 +3940,7 @@ int ha_ndbcluster::create(const char *name,
|
|||||||
{
|
{
|
||||||
NdbDictionary::Column * col= tab.getColumn(i);
|
NdbDictionary::Column * col= tab.getColumn(i);
|
||||||
int size= pk_length + (col->getPartSize()+3)/4 + 7;
|
int size= pk_length + (col->getPartSize()+3)/4 + 7;
|
||||||
if(size > NDB_MAX_TUPLE_SIZE_IN_WORDS &&
|
if (size > NDB_MAX_TUPLE_SIZE_IN_WORDS &&
|
||||||
(pk_length+7) < NDB_MAX_TUPLE_SIZE_IN_WORDS)
|
(pk_length+7) < NDB_MAX_TUPLE_SIZE_IN_WORDS)
|
||||||
{
|
{
|
||||||
size= NDB_MAX_TUPLE_SIZE_IN_WORDS - pk_length - 7;
|
size= NDB_MAX_TUPLE_SIZE_IN_WORDS - pk_length - 7;
|
||||||
@ -4169,12 +4168,10 @@ ulonglong ha_ndbcluster::get_auto_increment()
|
|||||||
m_rows_to_insert+= m_autoincrement_prefetch;
|
m_rows_to_insert+= m_autoincrement_prefetch;
|
||||||
}
|
}
|
||||||
cache_size=
|
cache_size=
|
||||||
(int)
|
(int) ((m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ?
|
||||||
(m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ?
|
m_rows_to_insert - m_rows_inserted :
|
||||||
m_rows_to_insert - m_rows_inserted
|
((m_rows_to_insert > m_autoincrement_prefetch) ?
|
||||||
: (m_rows_to_insert > m_autoincrement_prefetch) ?
|
m_rows_to_insert : m_autoincrement_prefetch));
|
||||||
m_rows_to_insert
|
|
||||||
: m_autoincrement_prefetch;
|
|
||||||
auto_value= NDB_FAILED_AUTO_INCREMENT;
|
auto_value= NDB_FAILED_AUTO_INCREMENT;
|
||||||
uint retries= NDB_AUTO_INCREMENT_RETRIES;
|
uint retries= NDB_AUTO_INCREMENT_RETRIES;
|
||||||
do {
|
do {
|
||||||
@ -4778,7 +4775,7 @@ ndbcluster_init()
|
|||||||
g_ndb_cluster_connection->get_connected_port()));
|
g_ndb_cluster_connection->get_connected_port()));
|
||||||
g_ndb_cluster_connection->wait_until_ready(10,3);
|
g_ndb_cluster_connection->wait_until_ready(10,3);
|
||||||
}
|
}
|
||||||
else if(res == 1)
|
else if (res == 1)
|
||||||
{
|
{
|
||||||
if (g_ndb_cluster_connection->start_connect_thread(connect_callback))
|
if (g_ndb_cluster_connection->start_connect_thread(connect_callback))
|
||||||
{
|
{
|
||||||
@ -4826,7 +4823,7 @@ ndbcluster_init()
|
|||||||
DBUG_RETURN(&ndbcluster_hton);
|
DBUG_RETURN(&ndbcluster_hton);
|
||||||
|
|
||||||
ndbcluster_init_error:
|
ndbcluster_init_error:
|
||||||
if(g_ndb)
|
if (g_ndb)
|
||||||
delete g_ndb;
|
delete g_ndb;
|
||||||
g_ndb= NULL;
|
g_ndb= NULL;
|
||||||
if (g_ndb_cluster_connection)
|
if (g_ndb_cluster_connection)
|
||||||
@ -4855,7 +4852,7 @@ bool ndbcluster_end()
|
|||||||
(void) pthread_cond_signal(&COND_ndb_util_thread);
|
(void) pthread_cond_signal(&COND_ndb_util_thread);
|
||||||
(void) pthread_mutex_unlock(&LOCK_ndb_util_thread);
|
(void) pthread_mutex_unlock(&LOCK_ndb_util_thread);
|
||||||
|
|
||||||
if(g_ndb)
|
if (g_ndb)
|
||||||
delete g_ndb;
|
delete g_ndb;
|
||||||
g_ndb= NULL;
|
g_ndb= NULL;
|
||||||
if (g_ndb_cluster_connection)
|
if (g_ndb_cluster_connection)
|
||||||
@ -5105,7 +5102,7 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&share->mutex);
|
pthread_mutex_lock(&share->mutex);
|
||||||
if(share->commit_count_lock == lock)
|
if (share->commit_count_lock == lock)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("Setting commit_count to %llu", stat.commit_count));
|
DBUG_PRINT("info", ("Setting commit_count to %llu", stat.commit_count));
|
||||||
share->commit_count= stat.commit_count;
|
share->commit_count= stat.commit_count;
|
||||||
@ -5596,9 +5593,13 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||||||
for (; multi_range_curr<multi_range_end && curr+reclength <= end_of_buffer;
|
for (; multi_range_curr<multi_range_end && curr+reclength <= end_of_buffer;
|
||||||
multi_range_curr++)
|
multi_range_curr++)
|
||||||
{
|
{
|
||||||
switch(index_type){
|
switch (index_type){
|
||||||
|
case PRIMARY_KEY_ORDERED_INDEX:
|
||||||
|
if (!(multi_range_curr->start_key.length == key_info->key_length &&
|
||||||
|
multi_range_curr->start_key.flag == HA_READ_KEY_EXACT))
|
||||||
|
goto range;
|
||||||
|
/* fall through */
|
||||||
case PRIMARY_KEY_INDEX:
|
case PRIMARY_KEY_INDEX:
|
||||||
pk:
|
|
||||||
{
|
{
|
||||||
multi_range_curr->range_flag |= UNIQUE_RANGE;
|
multi_range_curr->range_flag |= UNIQUE_RANGE;
|
||||||
if ((op= m_active_trans->getNdbOperation(tab)) &&
|
if ((op= m_active_trans->getNdbOperation(tab)) &&
|
||||||
@ -5612,8 +5613,14 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case UNIQUE_ORDERED_INDEX:
|
||||||
|
if (!(multi_range_curr->start_key.length == key_info->key_length &&
|
||||||
|
multi_range_curr->start_key.flag == HA_READ_KEY_EXACT &&
|
||||||
|
!check_null_in_key(key_info, multi_range_curr->start_key.key,
|
||||||
|
multi_range_curr->start_key.length)))
|
||||||
|
goto range;
|
||||||
|
/* fall through */
|
||||||
case UNIQUE_INDEX:
|
case UNIQUE_INDEX:
|
||||||
sk:
|
|
||||||
{
|
{
|
||||||
multi_range_curr->range_flag |= UNIQUE_RANGE;
|
multi_range_curr->range_flag |= UNIQUE_RANGE;
|
||||||
if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) &&
|
if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) &&
|
||||||
@ -5626,19 +5633,8 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||||||
ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
|
ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PRIMARY_KEY_ORDERED_INDEX:
|
case ORDERED_INDEX:
|
||||||
if (multi_range_curr->start_key.length == key_info->key_length &&
|
{
|
||||||
multi_range_curr->start_key.flag == HA_READ_KEY_EXACT)
|
|
||||||
goto pk;
|
|
||||||
goto range;
|
|
||||||
case UNIQUE_ORDERED_INDEX:
|
|
||||||
if (multi_range_curr->start_key.length == key_info->key_length &&
|
|
||||||
multi_range_curr->start_key.flag == HA_READ_KEY_EXACT &&
|
|
||||||
!check_null_in_key(key_info, multi_range_curr->start_key.key,
|
|
||||||
multi_range_curr->start_key.length))
|
|
||||||
goto sk;
|
|
||||||
goto range;
|
|
||||||
case ORDERED_INDEX: {
|
|
||||||
range:
|
range:
|
||||||
multi_range_curr->range_flag &= ~(uint)UNIQUE_RANGE;
|
multi_range_curr->range_flag &= ~(uint)UNIQUE_RANGE;
|
||||||
if (scanOp == 0)
|
if (scanOp == 0)
|
||||||
@ -5649,7 +5645,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||||||
DBUG_ASSERT(scanOp->getSorted() == sorted);
|
DBUG_ASSERT(scanOp->getSorted() == sorted);
|
||||||
DBUG_ASSERT(scanOp->getLockMode() ==
|
DBUG_ASSERT(scanOp->getLockMode() ==
|
||||||
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type));
|
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type));
|
||||||
if(scanOp->reset_bounds(m_force_send))
|
if (scanOp->reset_bounds(m_force_send))
|
||||||
DBUG_RETURN(ndb_err(m_active_trans));
|
DBUG_RETURN(ndb_err(m_active_trans));
|
||||||
|
|
||||||
end_of_buffer -= reclength;
|
end_of_buffer -= reclength;
|
||||||
@ -5675,7 +5671,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(UNDEFINED_INDEX):
|
case UNDEFINED_INDEX:
|
||||||
DBUG_ASSERT(FALSE);
|
DBUG_ASSERT(FALSE);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
break;
|
break;
|
||||||
@ -5784,7 +5780,7 @@ ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p)
|
|||||||
DBUG_MULTI_RANGE(6);
|
DBUG_MULTI_RANGE(6);
|
||||||
// First fetch from cursor
|
// First fetch from cursor
|
||||||
DBUG_ASSERT(range_no == -1);
|
DBUG_ASSERT(range_no == -1);
|
||||||
if((res= m_multi_cursor->nextResult(true)))
|
if ((res= m_multi_cursor->nextResult(true)))
|
||||||
{
|
{
|
||||||
goto close_scan;
|
goto close_scan;
|
||||||
}
|
}
|
||||||
@ -5887,7 +5883,7 @@ ha_ndbcluster::update_table_comment(
|
|||||||
const char* comment)/* in: table comment defined by user */
|
const char* comment)/* in: table comment defined by user */
|
||||||
{
|
{
|
||||||
uint length= strlen(comment);
|
uint length= strlen(comment);
|
||||||
if(length > 64000 - 3)
|
if (length > 64000 - 3)
|
||||||
{
|
{
|
||||||
return((char*)comment); /* string too long */
|
return((char*)comment); /* string too long */
|
||||||
}
|
}
|
||||||
@ -5914,9 +5910,9 @@ ha_ndbcluster::update_table_comment(
|
|||||||
return (char*)comment;
|
return (char*)comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(str,fmt_len_plus_extra,fmt,comment,
|
my_snprintf(str,fmt_len_plus_extra,fmt,comment,
|
||||||
length > 0 ? " ":"",
|
length > 0 ? " ":"",
|
||||||
tab->getReplicaCount());
|
tab->getReplicaCount());
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6015,7 +6011,7 @@ extern "C" pthread_handler_decl(ndb_util_thread_func,
|
|||||||
lock= share->commit_count_lock;
|
lock= share->commit_count_lock;
|
||||||
pthread_mutex_unlock(&share->mutex);
|
pthread_mutex_unlock(&share->mutex);
|
||||||
|
|
||||||
if(ndb_get_table_statistics(ndb, tabname, &stat) == 0)
|
if (ndb_get_table_statistics(ndb, tabname, &stat) == 0)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("ndb_util_thread",
|
DBUG_PRINT("ndb_util_thread",
|
||||||
("Table: %s, commit_count: %llu, rows: %llu",
|
("Table: %s, commit_count: %llu, rows: %llu",
|
||||||
@ -6050,7 +6046,7 @@ extern "C" pthread_handler_decl(ndb_util_thread_func,
|
|||||||
abstime.tv_sec= tick_time.tv_sec;
|
abstime.tv_sec= tick_time.tv_sec;
|
||||||
abstime.tv_nsec= tick_time.tv_usec * 1000;
|
abstime.tv_nsec= tick_time.tv_usec * 1000;
|
||||||
|
|
||||||
if(msecs >= 1000){
|
if (msecs >= 1000){
|
||||||
secs= msecs / 1000;
|
secs= msecs / 1000;
|
||||||
msecs= msecs % 1000;
|
msecs= msecs % 1000;
|
||||||
}
|
}
|
||||||
@ -6159,17 +6155,18 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("Skiping argument %d", context->skip));
|
DBUG_PRINT("info", ("Skiping argument %d", context->skip));
|
||||||
context->skip--;
|
context->skip--;
|
||||||
switch(item->type()) {
|
switch (item->type()) {
|
||||||
case (Item::FUNC_ITEM): {
|
case Item::FUNC_ITEM:
|
||||||
|
{
|
||||||
Item_func *func_item= (Item_func *) item;
|
Item_func *func_item= (Item_func *) item;
|
||||||
context->skip+= func_item->argument_count();
|
context->skip+= func_item->argument_count();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item::INT_ITEM):
|
case Item::INT_ITEM:
|
||||||
case(Item::REAL_ITEM):
|
case Item::REAL_ITEM:
|
||||||
case(Item::STRING_ITEM):
|
case Item::STRING_ITEM:
|
||||||
case(Item::VARBIN_ITEM):
|
case Item::VARBIN_ITEM:
|
||||||
case(Item::DECIMAL_ITEM):
|
case Item::DECIMAL_ITEM:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
@ -6188,8 +6185,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
(func_item= rewrite_context->func_item) &&
|
(func_item= rewrite_context->func_item) &&
|
||||||
rewrite_context->count++ == 0)
|
rewrite_context->count++ == 0)
|
||||||
{
|
{
|
||||||
switch(func_item->functype()) {
|
switch (func_item->functype()) {
|
||||||
case(Item_func::BETWEEN):
|
case Item_func::BETWEEN:
|
||||||
/*
|
/*
|
||||||
Rewrite
|
Rewrite
|
||||||
<field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
|
<field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
|
||||||
@ -6199,7 +6196,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
|
BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
|
||||||
LT(<field>|<const>, <const2>|<field2>), END()
|
LT(<field>|<const>, <const2>|<field2>), END()
|
||||||
*/
|
*/
|
||||||
case(Item_func::IN_FUNC): {
|
case Item_func::IN_FUNC:
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
|
Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
|
||||||
to <field>|<const> = <const1>|<field1> OR
|
to <field>|<const> = <const1>|<field1> OR
|
||||||
@ -6264,17 +6262,18 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
{
|
{
|
||||||
Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
|
Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
|
||||||
const Item_func *func_item= rewrite_context->func_item;
|
const Item_func *func_item= rewrite_context->func_item;
|
||||||
switch(func_item->functype()) {
|
switch (func_item->functype()) {
|
||||||
case(Item_func::BETWEEN): {
|
case Item_func::BETWEEN:
|
||||||
/*
|
{
|
||||||
Rewrite
|
/*
|
||||||
<field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
|
Rewrite
|
||||||
to <field>|<const> > <const1>|<field1> AND
|
<field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
|
||||||
<field>|<const> < <const2>|<field2>
|
to <field>|<const> > <const1>|<field1> AND
|
||||||
or actually in prefix format
|
<field>|<const> < <const2>|<field2>
|
||||||
BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
|
or actually in prefix format
|
||||||
LT(<field>|<const>, <const2>|<field2>), END()
|
BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
|
||||||
*/
|
LT(<field>|<const>, <const2>|<field2>), END()
|
||||||
|
*/
|
||||||
if (rewrite_context->count == 2)
|
if (rewrite_context->count == 2)
|
||||||
{
|
{
|
||||||
// Lower limit of BETWEEN
|
// Lower limit of BETWEEN
|
||||||
@ -6296,7 +6295,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::IN_FUNC): {
|
case Item_func::IN_FUNC:
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
|
Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
|
||||||
to <field>|<const> = <const1>|<field1> OR
|
to <field>|<const> = <const1>|<field1> OR
|
||||||
@ -6345,8 +6345,10 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
|
curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
switch(item->type()) {
|
{
|
||||||
case(Item::FIELD_ITEM): {
|
switch (item->type()) {
|
||||||
|
case Item::FIELD_ITEM:
|
||||||
|
{
|
||||||
Item_field *field_item= (Item_field *) item;
|
Item_field *field_item= (Item_field *) item;
|
||||||
Field *field= field_item->field;
|
Field *field= field_item->field;
|
||||||
enum_field_types type= field->type();
|
enum_field_types type= field->type();
|
||||||
@ -6392,23 +6394,23 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
switch(field->result_type()) {
|
switch (field->result_type()) {
|
||||||
case(STRING_RESULT):
|
case STRING_RESULT:
|
||||||
// Expect char string or binary string
|
// Expect char string or binary string
|
||||||
context->expect_only(Item::STRING_ITEM);
|
context->expect_only(Item::STRING_ITEM);
|
||||||
context->expect(Item::VARBIN_ITEM);
|
context->expect(Item::VARBIN_ITEM);
|
||||||
context->expect_collation(field_item->collation.collation);
|
context->expect_collation(field_item->collation.collation);
|
||||||
break;
|
break;
|
||||||
case(REAL_RESULT):
|
case REAL_RESULT:
|
||||||
context->expect_only(Item::REAL_ITEM);
|
context->expect_only(Item::REAL_ITEM);
|
||||||
context->expect(Item::DECIMAL_ITEM);
|
context->expect(Item::DECIMAL_ITEM);
|
||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
break;
|
break;
|
||||||
case(INT_RESULT):
|
case INT_RESULT:
|
||||||
context->expect_only(Item::INT_ITEM);
|
context->expect_only(Item::INT_ITEM);
|
||||||
context->expect(Item::VARBIN_ITEM);
|
context->expect(Item::VARBIN_ITEM);
|
||||||
break;
|
break;
|
||||||
case(DECIMAL_RESULT):
|
case DECIMAL_RESULT:
|
||||||
context->expect_only(Item::DECIMAL_ITEM);
|
context->expect_only(Item::DECIMAL_ITEM);
|
||||||
context->expect(Item::REAL_ITEM);
|
context->expect(Item::REAL_ITEM);
|
||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
@ -6453,7 +6455,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item::FUNC_ITEM): {
|
case Item::FUNC_ITEM:
|
||||||
|
{
|
||||||
Item_func *func_item= (Item_func *) item;
|
Item_func *func_item= (Item_func *) item;
|
||||||
// Check that we expect a function or functional expression here
|
// Check that we expect a function or functional expression here
|
||||||
if (context->expecting(Item::FUNC_ITEM) ||
|
if (context->expecting(Item::FUNC_ITEM) ||
|
||||||
@ -6466,8 +6469,9 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(func_item->functype()) {
|
switch (func_item->functype()) {
|
||||||
case(Item_func::EQ_FUNC): {
|
case Item_func::EQ_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("EQ_FUNC"));
|
DBUG_PRINT("info", ("EQ_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6483,7 +6487,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::NE_FUNC): {
|
case Item_func::NE_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("NE_FUNC"));
|
DBUG_PRINT("info", ("NE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6499,7 +6504,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::LT_FUNC): {
|
case Item_func::LT_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("LT_FUNC"));
|
DBUG_PRINT("info", ("LT_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6515,7 +6521,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::LE_FUNC): {
|
case Item_func::LE_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("LE_FUNC"));
|
DBUG_PRINT("info", ("LE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6531,7 +6538,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::GE_FUNC): {
|
case Item_func::GE_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("GE_FUNC"));
|
DBUG_PRINT("info", ("GE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6547,7 +6555,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::GT_FUNC): {
|
case Item_func::GT_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("GT_FUNC"));
|
DBUG_PRINT("info", ("GT_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6563,7 +6572,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::LIKE_FUNC): {
|
case Item_func::LIKE_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("LIKE_FUNC"));
|
DBUG_PRINT("info", ("LIKE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6573,7 +6583,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect(Item::FUNC_ITEM);
|
context->expect(Item::FUNC_ITEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::NOTLIKE_FUNC): {
|
case Item_func::NOTLIKE_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("NOTLIKE_FUNC"));
|
DBUG_PRINT("info", ("NOTLIKE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6583,7 +6594,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect(Item::FUNC_ITEM);
|
context->expect(Item::FUNC_ITEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::ISNULL_FUNC): {
|
case Item_func::ISNULL_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("ISNULL_FUNC"));
|
DBUG_PRINT("info", ("ISNULL_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6594,7 +6606,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::ISNOTNULL_FUNC): {
|
case Item_func::ISNOTNULL_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
|
DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6605,7 +6618,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::NOT_FUNC): {
|
case Item_func::NOT_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("NOT_FUNC"));
|
DBUG_PRINT("info", ("NOT_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
func_item);
|
func_item);
|
||||||
@ -6613,7 +6627,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect(Item::COND_ITEM);
|
context->expect(Item::COND_ITEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::BETWEEN) : {
|
case Item_func::BETWEEN:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("BETWEEN, rewriting using AND"));
|
DBUG_PRINT("info", ("BETWEEN, rewriting using AND"));
|
||||||
Ndb_rewrite_context *rewrite_context=
|
Ndb_rewrite_context *rewrite_context=
|
||||||
new Ndb_rewrite_context(func_item);
|
new Ndb_rewrite_context(func_item);
|
||||||
@ -6629,7 +6644,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect(Item::FUNC_ITEM);
|
context->expect(Item::FUNC_ITEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::IN_FUNC) : {
|
case Item_func::IN_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("IN_FUNC, rewriting using OR"));
|
DBUG_PRINT("info", ("IN_FUNC, rewriting using OR"));
|
||||||
Ndb_rewrite_context *rewrite_context=
|
Ndb_rewrite_context *rewrite_context=
|
||||||
new Ndb_rewrite_context(func_item);
|
new Ndb_rewrite_context(func_item);
|
||||||
@ -6645,13 +6661,16 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect(Item::FUNC_ITEM);
|
context->expect(Item::FUNC_ITEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::UNKNOWN_FUNC): {
|
case Item_func::UNKNOWN_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
|
DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
|
||||||
func_item->const_item()?"const":""));
|
func_item->const_item()?"const":""));
|
||||||
DBUG_PRINT("info", ("result type %d", func_item->result_type()));
|
DBUG_PRINT("info", ("result type %d", func_item->result_type()));
|
||||||
if (func_item->const_item())
|
if (func_item->const_item())
|
||||||
switch(func_item->result_type()) {
|
{
|
||||||
case(STRING_RESULT): {
|
switch (func_item->result_type()) {
|
||||||
|
case STRING_RESULT:
|
||||||
|
{
|
||||||
NDB_ITEM_QUALIFICATION q;
|
NDB_ITEM_QUALIFICATION q;
|
||||||
q.value_type= Item::STRING_ITEM;
|
q.value_type= Item::STRING_ITEM;
|
||||||
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
||||||
@ -6680,7 +6699,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->skip= func_item->argument_count();
|
context->skip= func_item->argument_count();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(REAL_RESULT): {
|
case REAL_RESULT:
|
||||||
|
{
|
||||||
NDB_ITEM_QUALIFICATION q;
|
NDB_ITEM_QUALIFICATION q;
|
||||||
q.value_type= Item::REAL_ITEM;
|
q.value_type= Item::REAL_ITEM;
|
||||||
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
||||||
@ -6702,7 +6722,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->skip= func_item->argument_count();
|
context->skip= func_item->argument_count();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(INT_RESULT): {
|
case INT_RESULT:
|
||||||
|
{
|
||||||
NDB_ITEM_QUALIFICATION q;
|
NDB_ITEM_QUALIFICATION q;
|
||||||
q.value_type= Item::INT_ITEM;
|
q.value_type= Item::INT_ITEM;
|
||||||
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
||||||
@ -6724,7 +6745,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->skip= func_item->argument_count();
|
context->skip= func_item->argument_count();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(DECIMAL_RESULT): {
|
case DECIMAL_RESULT:
|
||||||
|
{
|
||||||
NDB_ITEM_QUALIFICATION q;
|
NDB_ITEM_QUALIFICATION q;
|
||||||
q.value_type= Item::DECIMAL_ITEM;
|
q.value_type= Item::DECIMAL_ITEM;
|
||||||
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
||||||
@ -6748,12 +6770,14 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
// Function does not return constant expression
|
// Function does not return constant expression
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("Found func_item of type %d",
|
DBUG_PRINT("info", ("Found func_item of type %d",
|
||||||
func_item->functype()));
|
func_item->functype()));
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
@ -6761,7 +6785,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item::STRING_ITEM):
|
case Item::STRING_ITEM:
|
||||||
DBUG_PRINT("info", ("STRING_ITEM"));
|
DBUG_PRINT("info", ("STRING_ITEM"));
|
||||||
if (context->expecting(Item::STRING_ITEM))
|
if (context->expecting(Item::STRING_ITEM))
|
||||||
{
|
{
|
||||||
@ -6800,7 +6824,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
case(Item::INT_ITEM):
|
case Item::INT_ITEM:
|
||||||
DBUG_PRINT("info", ("INT_ITEM"));
|
DBUG_PRINT("info", ("INT_ITEM"));
|
||||||
if (context->expecting(Item::INT_ITEM))
|
if (context->expecting(Item::INT_ITEM))
|
||||||
{
|
{
|
||||||
@ -6827,7 +6851,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
case(Item::REAL_ITEM):
|
case Item::REAL_ITEM:
|
||||||
DBUG_PRINT("info", ("REAL_ITEM %s"));
|
DBUG_PRINT("info", ("REAL_ITEM %s"));
|
||||||
if (context->expecting(Item::REAL_ITEM))
|
if (context->expecting(Item::REAL_ITEM))
|
||||||
{
|
{
|
||||||
@ -6852,7 +6876,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
case(Item::VARBIN_ITEM):
|
case Item::VARBIN_ITEM:
|
||||||
DBUG_PRINT("info", ("VARBIN_ITEM"));
|
DBUG_PRINT("info", ("VARBIN_ITEM"));
|
||||||
if (context->expecting(Item::VARBIN_ITEM))
|
if (context->expecting(Item::VARBIN_ITEM))
|
||||||
{
|
{
|
||||||
@ -6875,7 +6899,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
case(Item::DECIMAL_ITEM):
|
case Item::DECIMAL_ITEM:
|
||||||
DBUG_PRINT("info", ("DECIMAL_ITEM %s"));
|
DBUG_PRINT("info", ("DECIMAL_ITEM %s"));
|
||||||
if (context->expecting(Item::DECIMAL_ITEM))
|
if (context->expecting(Item::DECIMAL_ITEM))
|
||||||
{
|
{
|
||||||
@ -6901,17 +6925,19 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
case(Item::COND_ITEM): {
|
case Item::COND_ITEM:
|
||||||
|
{
|
||||||
Item_cond *cond_item= (Item_cond *) item;
|
Item_cond *cond_item= (Item_cond *) item;
|
||||||
|
|
||||||
if (context->expecting(Item::COND_ITEM))
|
if (context->expecting(Item::COND_ITEM))
|
||||||
switch(cond_item->functype()) {
|
{
|
||||||
case(Item_func::COND_AND_FUNC):
|
switch (cond_item->functype()) {
|
||||||
|
case Item_func::COND_AND_FUNC:
|
||||||
DBUG_PRINT("info", ("COND_AND_FUNC"));
|
DBUG_PRINT("info", ("COND_AND_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
|
||||||
cond_item);
|
cond_item);
|
||||||
break;
|
break;
|
||||||
case(Item_func::COND_OR_FUNC):
|
case Item_func::COND_OR_FUNC:
|
||||||
DBUG_PRINT("info", ("COND_OR_FUNC"));
|
DBUG_PRINT("info", ("COND_OR_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
|
curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
|
||||||
cond_item);
|
cond_item);
|
||||||
@ -6921,17 +6947,21 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
// Did not expect condition
|
{
|
||||||
|
/* Did not expect condition */
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("Found item of type %d", item->type()));
|
DBUG_PRINT("info", ("Found item of type %d", item->type()));
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (context->supported && context->rewrite_stack)
|
if (context->supported && context->rewrite_stack)
|
||||||
{
|
{
|
||||||
Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
|
Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
|
||||||
@ -6975,18 +7005,19 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
bool negated)
|
bool negated)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("build_scan_filter_predicate");
|
DBUG_ENTER("build_scan_filter_predicate");
|
||||||
switch(cond->ndb_item->type) {
|
switch (cond->ndb_item->type) {
|
||||||
case(NDB_FUNCTION): {
|
case NDB_FUNCTION:
|
||||||
|
{
|
||||||
if (!cond->next)
|
if (!cond->next)
|
||||||
break;
|
break;
|
||||||
Ndb_item *a= cond->next->ndb_item;
|
Ndb_item *a= cond->next->ndb_item;
|
||||||
Ndb_item *b, *field, *value= NULL;
|
Ndb_item *b, *field, *value= NULL;
|
||||||
switch(cond->ndb_item->argument_count()) {
|
switch (cond->ndb_item->argument_count()) {
|
||||||
case(1):
|
case 1:
|
||||||
field=
|
field=
|
||||||
(a->type == NDB_FIELD)? a : NULL;
|
(a->type == NDB_FIELD)? a : NULL;
|
||||||
break;
|
break;
|
||||||
case(2):
|
case 2:
|
||||||
if (!cond->next->next)
|
if (!cond->next->next)
|
||||||
break;
|
break;
|
||||||
b= cond->next->next->ndb_item;
|
b= cond->next->next->ndb_item;
|
||||||
@ -7002,11 +7033,11 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch((negated) ?
|
switch ((negated) ?
|
||||||
Ndb_item::negate(cond->ndb_item->qualification.function_type)
|
Ndb_item::negate(cond->ndb_item->qualification.function_type)
|
||||||
: cond->ndb_item->qualification.function_type)
|
: cond->ndb_item->qualification.function_type) {
|
||||||
|
case Item_func::EQ_FUNC:
|
||||||
{
|
{
|
||||||
case(Item_func::EQ_FUNC): {
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -7019,7 +7050,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::NE_FUNC): {
|
case Item_func::NE_FUNC:
|
||||||
|
{
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -7032,7 +7064,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::LT_FUNC): {
|
case Item_func::LT_FUNC:
|
||||||
|
{
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -7057,7 +7090,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::LE_FUNC): {
|
case Item_func::LE_FUNC:
|
||||||
|
{
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -7082,7 +7116,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::GE_FUNC): {
|
case Item_func::GE_FUNC:
|
||||||
|
{
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -7107,7 +7142,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::GT_FUNC): {
|
case Item_func::GT_FUNC:
|
||||||
|
{
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -7132,7 +7168,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::LIKE_FUNC): {
|
case Item_func::LIKE_FUNC:
|
||||||
|
{
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
if ((value->qualification.value_type != Item::STRING_ITEM) &&
|
if ((value->qualification.value_type != Item::STRING_ITEM) &&
|
||||||
(value->qualification.value_type != Item::VARBIN_ITEM))
|
(value->qualification.value_type != Item::VARBIN_ITEM))
|
||||||
@ -7150,7 +7187,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::NOTLIKE_FUNC): {
|
case Item_func::NOTLIKE_FUNC:
|
||||||
|
{
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
if ((value->qualification.value_type != Item::STRING_ITEM) &&
|
if ((value->qualification.value_type != Item::STRING_ITEM) &&
|
||||||
(value->qualification.value_type != Item::VARBIN_ITEM))
|
(value->qualification.value_type != Item::VARBIN_ITEM))
|
||||||
@ -7168,7 +7206,7 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::ISNULL_FUNC):
|
case Item_func::ISNULL_FUNC:
|
||||||
if (!field)
|
if (!field)
|
||||||
break;
|
break;
|
||||||
DBUG_PRINT("info", ("Generating ISNULL filter"));
|
DBUG_PRINT("info", ("Generating ISNULL filter"));
|
||||||
@ -7176,7 +7214,8 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
cond= cond->next->next;
|
cond= cond->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
case(Item_func::ISNOTNULL_FUNC): {
|
case Item_func::ISNOTNULL_FUNC:
|
||||||
|
{
|
||||||
if (!field)
|
if (!field)
|
||||||
break;
|
break;
|
||||||
DBUG_PRINT("info", ("Generating ISNOTNULL filter"));
|
DBUG_PRINT("info", ("Generating ISNOTNULL filter"));
|
||||||
@ -7202,15 +7241,18 @@ ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
|
|||||||
{
|
{
|
||||||
uint level=0;
|
uint level=0;
|
||||||
bool negated= FALSE;
|
bool negated= FALSE;
|
||||||
|
|
||||||
DBUG_ENTER("build_scan_filter_group");
|
DBUG_ENTER("build_scan_filter_group");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!cond) DBUG_RETURN(1);
|
if (!cond)
|
||||||
switch(cond->ndb_item->type) {
|
DBUG_RETURN(1);
|
||||||
case(NDB_FUNCTION):
|
switch (cond->ndb_item->type) {
|
||||||
switch(cond->ndb_item->qualification.function_type) {
|
case NDB_FUNCTION:
|
||||||
case(Item_func::COND_AND_FUNC): {
|
{
|
||||||
|
switch (cond->ndb_item->qualification.function_type) {
|
||||||
|
case Item_func::COND_AND_FUNC:
|
||||||
|
{
|
||||||
level++;
|
level++;
|
||||||
DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NAND":"AND",
|
DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NAND":"AND",
|
||||||
level));
|
level));
|
||||||
@ -7221,7 +7263,8 @@ ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
|
|||||||
cond= cond->next;
|
cond= cond->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::COND_OR_FUNC): {
|
case Item_func::COND_OR_FUNC:
|
||||||
|
{
|
||||||
level++;
|
level++;
|
||||||
DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NOR":"OR",
|
DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NOR":"OR",
|
||||||
level));
|
level));
|
||||||
@ -7232,11 +7275,11 @@ ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
|
|||||||
cond= cond->next;
|
cond= cond->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(Item_func::NOT_FUNC): {
|
case Item_func::NOT_FUNC:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("Generating negated query"));
|
DBUG_PRINT("info", ("Generating negated query"));
|
||||||
cond= cond->next;
|
cond= cond->next;
|
||||||
negated= TRUE;
|
negated= TRUE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -7246,7 +7289,8 @@ ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case(NDB_END_COND):
|
}
|
||||||
|
case NDB_END_COND:
|
||||||
DBUG_PRINT("info", ("End of group %u", level));
|
DBUG_PRINT("info", ("End of group %u", level));
|
||||||
level--;
|
level--;
|
||||||
if (cond) cond= cond->next;
|
if (cond) cond= cond->next;
|
||||||
@ -7255,7 +7299,8 @@ ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
|
|||||||
if (!negated)
|
if (!negated)
|
||||||
break;
|
break;
|
||||||
// else fall through (NOT END is an illegal condition)
|
// else fall through (NOT END is an illegal condition)
|
||||||
default: {
|
default:
|
||||||
|
{
|
||||||
DBUG_PRINT("info", ("Illegal scan filter"));
|
DBUG_PRINT("info", ("Illegal scan filter"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7270,11 +7315,11 @@ ha_ndbcluster::build_scan_filter(Ndb_cond * &cond, NdbScanFilter *filter)
|
|||||||
bool simple_cond= TRUE;
|
bool simple_cond= TRUE;
|
||||||
DBUG_ENTER("build_scan_filter");
|
DBUG_ENTER("build_scan_filter");
|
||||||
|
|
||||||
switch(cond->ndb_item->type) {
|
switch (cond->ndb_item->type) {
|
||||||
case(NDB_FUNCTION):
|
case NDB_FUNCTION:
|
||||||
switch(cond->ndb_item->qualification.function_type) {
|
switch (cond->ndb_item->qualification.function_type) {
|
||||||
case(Item_func::COND_AND_FUNC):
|
case Item_func::COND_AND_FUNC:
|
||||||
case(Item_func::COND_OR_FUNC):
|
case Item_func::COND_OR_FUNC:
|
||||||
simple_cond= FALSE;
|
simple_cond= FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
15
sql/item.cc
15
sql/item.cc
@ -4381,18 +4381,16 @@ my_decimal *Item_ref::val_decimal(my_decimal *decimal_value)
|
|||||||
int Item_ref::save_in_field(Field *to, bool no_conversions)
|
int Item_ref::save_in_field(Field *to, bool no_conversions)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if(result_field){
|
if (result_field)
|
||||||
|
{
|
||||||
if (result_field->is_null())
|
if (result_field->is_null())
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return set_field_to_null_with_conversions(to, no_conversions);
|
return set_field_to_null_with_conversions(to, no_conversions);
|
||||||
}
|
}
|
||||||
else
|
to->set_notnull();
|
||||||
{
|
field_conv(to, result_field);
|
||||||
to->set_notnull();
|
null_value= 0;
|
||||||
field_conv(to, result_field);
|
|
||||||
null_value= 0;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
res= (*ref)->save_in_field(to, no_conversions);
|
res= (*ref)->save_in_field(to, no_conversions);
|
||||||
@ -5221,8 +5219,7 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
|
|||||||
acceptable information for client in send_field, so we make field
|
acceptable information for client in send_field, so we make field
|
||||||
type from expression type.
|
type from expression type.
|
||||||
*/
|
*/
|
||||||
switch (item->result_type())
|
switch (item->result_type()) {
|
||||||
{
|
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
return MYSQL_TYPE_VAR_STRING;
|
return MYSQL_TYPE_VAR_STRING;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
|
@ -275,7 +275,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
|
|||||||
owner= item;
|
owner= item;
|
||||||
func= comparator_matrix[type]
|
func= comparator_matrix[type]
|
||||||
[test(owner->functype() == Item_func::EQUAL_FUNC)];
|
[test(owner->functype() == Item_func::EQUAL_FUNC)];
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
{
|
{
|
||||||
uint n= (*a)->cols();
|
uint n= (*a)->cols();
|
||||||
@ -1578,6 +1578,21 @@ my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_func_case::fix_fields(THD *thd, struct st_table_list *tables,
|
||||||
|
Item **ref)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
buff should match stack usage from
|
||||||
|
Item_func_case::val_int() -> Item_func_case::find_item()
|
||||||
|
*/
|
||||||
|
char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(longlong)*2];
|
||||||
|
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
|
||||||
|
return TRUE; // Fatal error flag is set!
|
||||||
|
return Item_func::fix_fields(thd, tables, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Item_func_case::fix_length_and_dec()
|
void Item_func_case::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
Item **agg;
|
Item **agg;
|
||||||
|
@ -566,6 +566,7 @@ public:
|
|||||||
longlong val_int();
|
longlong val_int();
|
||||||
String *val_str(String *);
|
String *val_str(String *);
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
|
bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
uint decimal_precision() const;
|
uint decimal_precision() const;
|
||||||
table_map not_null_tables() const { return 0; }
|
table_map not_null_tables() const { return 0; }
|
||||||
|
@ -1880,8 +1880,7 @@ void Item_func_round::fix_length_and_dec()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (args[0]->result_type())
|
switch (args[0]->result_type()) {
|
||||||
{
|
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
hybrid_type= REAL_RESULT;
|
hybrid_type= REAL_RESULT;
|
||||||
@ -1889,16 +1888,17 @@ void Item_func_round::fix_length_and_dec()
|
|||||||
max_length= float_length(decimals);
|
max_length= float_length(decimals);
|
||||||
break;
|
break;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
if ((decimals_to_set==0) &&
|
if (!decimals_to_set &&
|
||||||
(truncate || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)))
|
(truncate || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)))
|
||||||
{
|
{
|
||||||
|
int length_can_increase= test(!truncate && (args[1]->val_int() < 0));
|
||||||
|
max_length= args[0]->max_length + length_can_increase;
|
||||||
/* Here we can keep INT_RESULT */
|
/* Here we can keep INT_RESULT */
|
||||||
hybrid_type= INT_RESULT;
|
hybrid_type= INT_RESULT;
|
||||||
int length_can_increase= !truncate && (args[1]->val_int() < 0);
|
|
||||||
max_length= args[0]->max_length + length_can_increase;
|
|
||||||
decimals= 0;
|
decimals= 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* fall through */
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
{
|
{
|
||||||
hybrid_type= DECIMAL_RESULT;
|
hybrid_type= DECIMAL_RESULT;
|
||||||
@ -4446,7 +4446,8 @@ err:
|
|||||||
|
|
||||||
bool Item_func_match::eq(const Item *item, bool binary_cmp) const
|
bool Item_func_match::eq(const Item *item, bool binary_cmp) const
|
||||||
{
|
{
|
||||||
if (item->type() != FUNC_ITEM || ((Item_func*)item)->functype() != FT_FUNC ||
|
if (item->type() != FUNC_ITEM ||
|
||||||
|
((Item_func*)item)->functype() != FT_FUNC ||
|
||||||
flags != ((Item_func_match*)item)->flags)
|
flags != ((Item_func_match*)item)->flags)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -4807,7 +4808,7 @@ Item_func_sp::execute(Item **itp)
|
|||||||
ulong old_client_capabilites;
|
ulong old_client_capabilites;
|
||||||
int res= -1;
|
int res= -1;
|
||||||
bool save_in_sub_stmt= thd->transaction.in_sub_stmt;
|
bool save_in_sub_stmt= thd->transaction.in_sub_stmt;
|
||||||
my_bool nsok;
|
my_bool save_no_send_ok;
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
st_sp_security_context save_ctx;
|
st_sp_security_context save_ctx;
|
||||||
#endif
|
#endif
|
||||||
@ -4822,7 +4823,7 @@ Item_func_sp::execute(Item **itp)
|
|||||||
thd->client_capabilities &= ~CLIENT_MULTI_RESULTS;
|
thd->client_capabilities &= ~CLIENT_MULTI_RESULTS;
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
nsok= thd->net.no_send_ok;
|
save_no_send_ok= thd->net.no_send_ok;
|
||||||
thd->net.no_send_ok= TRUE;
|
thd->net.no_send_ok= TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4834,7 +4835,7 @@ Item_func_sp::execute(Item **itp)
|
|||||||
if (save_ctx.changed &&
|
if (save_ctx.changed &&
|
||||||
check_routine_access(thd, EXECUTE_ACL,
|
check_routine_access(thd, EXECUTE_ACL,
|
||||||
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
|
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
|
||||||
goto error_check;
|
goto error_check_ctx;
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
Like for SPs, we don't binlog the substatements. If the statement which
|
Like for SPs, we don't binlog the substatements. If the statement which
|
||||||
@ -4857,8 +4858,8 @@ Item_func_sp::execute(Item **itp)
|
|||||||
ER_FAILED_ROUTINE_BREAK_BINLOG,
|
ER_FAILED_ROUTINE_BREAK_BINLOG,
|
||||||
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
||||||
|
|
||||||
error_check_ctx:
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
error_check_ctx:
|
||||||
sp_restore_security_context(thd, m_sp, &save_ctx);
|
sp_restore_security_context(thd, m_sp, &save_ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4866,7 +4867,7 @@ error_check_ctx:
|
|||||||
|
|
||||||
error_check:
|
error_check:
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
thd->net.no_send_ok= nsok;
|
thd->net.no_send_ok= save_no_send_ok;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
|
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
|
||||||
|
@ -2992,9 +2992,7 @@ int win_main(int argc, char **argv)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
DEBUGGER_OFF;
|
DEBUGGER_OFF;
|
||||||
|
|
||||||
MY_INIT(argv[0]); // init my_sys library & pthreads
|
MY_INIT(argv[0]); // init my_sys library & pthreads
|
||||||
|
|
||||||
#ifdef _CUSTOMSTARTUPCONFIG_
|
#ifdef _CUSTOMSTARTUPCONFIG_
|
||||||
@ -3006,14 +3004,15 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
/* Before performing any socket operation (like retrieving hostname */
|
/*
|
||||||
/* in init_common_variables we have to call WSAStartup */
|
Before performing any socket operation (like retrieving hostname
|
||||||
if (!opt_disable_networking)
|
in init_common_variables we have to call WSAStartup
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
WSADATA WsaData;
|
WSADATA WsaData;
|
||||||
if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
|
if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
|
||||||
{
|
{
|
||||||
/* errors are not read yet, so we use test here */
|
/* errors are not read yet, so we use english text here */
|
||||||
my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
|
my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
|
||||||
unireg_abort(1);
|
unireg_abort(1);
|
||||||
}
|
}
|
||||||
|
@ -3528,15 +3528,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
|
|||||||
{
|
{
|
||||||
/* Optimize NOT BETWEEN and NOT IN */
|
/* Optimize NOT BETWEEN and NOT IN */
|
||||||
Item *arg= cond_func->arguments()[0];
|
Item *arg= cond_func->arguments()[0];
|
||||||
if (arg->type() == Item::FUNC_ITEM)
|
if (arg->type() != Item::FUNC_ITEM)
|
||||||
{
|
|
||||||
cond_func= (Item_func*) arg;
|
|
||||||
if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
inv= TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
cond_func= (Item_func*) arg;
|
||||||
|
if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
inv= TRUE;
|
||||||
}
|
}
|
||||||
else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
|
else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -8178,7 +8175,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next()
|
|||||||
(have_max && have_min && (max_res == 0)));
|
(have_max && have_min && (max_res == 0)));
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
If this is a just a GROUP BY or DISTINCT without MIN or MAX and there
|
If this is just a GROUP BY or DISTINCT without MIN or MAX and there
|
||||||
are equality predicates for the key parts after the group, find the
|
are equality predicates for the key parts after the group, find the
|
||||||
first sub-group with the extended prefix.
|
first sub-group with the extended prefix.
|
||||||
*/
|
*/
|
||||||
@ -8581,23 +8578,21 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
|
|||||||
|
|
||||||
if ((result == HA_ERR_KEY_NOT_FOUND) && (cur_range->flag & EQ_RANGE))
|
if ((result == HA_ERR_KEY_NOT_FOUND) && (cur_range->flag & EQ_RANGE))
|
||||||
continue; /* Check the next range. */
|
continue; /* Check the next range. */
|
||||||
else if (result)
|
if (result)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
In no key was found with this upper bound, there certainly are no keys
|
In no key was found with this upper bound, there certainly are no keys
|
||||||
in the ranges to the left.
|
in the ranges to the left.
|
||||||
*/
|
*/
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
/* A key was found. */
|
/* A key was found. */
|
||||||
if (cur_range->flag & EQ_RANGE)
|
if (cur_range->flag & EQ_RANGE)
|
||||||
return result; /* No need to perform the checks below for equal keys. */
|
return 0; /* No need to perform the checks below for equal keys. */
|
||||||
|
|
||||||
/* Check if record belongs to the current group. */
|
/* Check if record belongs to the current group. */
|
||||||
if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
|
if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
|
||||||
{
|
continue; // Row not found
|
||||||
result = HA_ERR_KEY_NOT_FOUND;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there is a lower limit, check if the found key is in the range. */
|
/* If there is a lower limit, check if the found key is in the range. */
|
||||||
if ( !(cur_range->flag & NO_MIN_RANGE) )
|
if ( !(cur_range->flag & NO_MIN_RANGE) )
|
||||||
|
@ -653,6 +653,14 @@ typedef struct system_status_var
|
|||||||
void free_tmp_table(THD *thd, TABLE *entry);
|
void free_tmp_table(THD *thd, TABLE *entry);
|
||||||
|
|
||||||
|
|
||||||
|
/* The following macro is to make init of Query_arena simpler */
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
#define INIT_ARENA_DBUG_INFO is_backup_arena= 0
|
||||||
|
#else
|
||||||
|
#define INIT_ARENA_DBUG_INFO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class Query_arena
|
class Query_arena
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -664,9 +672,6 @@ public:
|
|||||||
MEM_ROOT *mem_root; // Pointer to current memroot
|
MEM_ROOT *mem_root; // Pointer to current memroot
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
bool is_backup_arena; /* True if this arena is used for backup. */
|
bool is_backup_arena; /* True if this arena is used for backup. */
|
||||||
#define INIT_ARENA_DBUG_INFO is_backup_arena= 0
|
|
||||||
#else
|
|
||||||
#define INIT_ARENA_DBUG_INFO
|
|
||||||
#endif
|
#endif
|
||||||
enum enum_state
|
enum enum_state
|
||||||
{
|
{
|
||||||
@ -691,7 +696,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Query_arena() { INIT_ARENA_DBUG_INFO; }
|
Query_arena() { INIT_ARENA_DBUG_INFO; }
|
||||||
|
|
||||||
#undef INIT_ARENA_DBUG_INFO
|
|
||||||
virtual Type type() const;
|
virtual Type type() const;
|
||||||
virtual ~Query_arena() {};
|
virtual ~Query_arena() {};
|
||||||
|
|
||||||
|
@ -2355,10 +2355,6 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
#endif /* !HAVE_REPLICATION */
|
#endif /* !HAVE_REPLICATION */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When option readonly is set deny operations which change tables.
|
When option readonly is set deny operations which change tables.
|
||||||
Except for the replication thread and the 'super' users.
|
Except for the replication thread and the 'super' users.
|
||||||
|
@ -7987,9 +7987,11 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
convert_blob_length);
|
convert_blob_length);
|
||||||
}
|
}
|
||||||
case Item::REF_ITEM:
|
case Item::REF_ITEM:
|
||||||
if ( item->real_item()->type() == Item::FIELD_ITEM)
|
{
|
||||||
|
Item *tmp_item;
|
||||||
|
if ((tmp_item= item->real_item())->type() == Item::FIELD_ITEM)
|
||||||
{
|
{
|
||||||
Item_field *field= (Item_field*) *((Item_ref*)item)->ref;
|
Item_field *field= (Item_field*) tmp_item;
|
||||||
Field *new_field= create_tmp_field_from_field(thd,
|
Field *new_field= create_tmp_field_from_field(thd,
|
||||||
(*from_field= field->field),
|
(*from_field= field->field),
|
||||||
item->name, table,
|
item->name, table,
|
||||||
@ -7999,6 +8001,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
item->set_result_field(new_field);
|
item->set_result_field(new_field);
|
||||||
return new_field;
|
return new_field;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case Item::FUNC_ITEM:
|
case Item::FUNC_ITEM:
|
||||||
case Item::COND_ITEM:
|
case Item::COND_ITEM:
|
||||||
case Item::FIELD_AVG_ITEM:
|
case Item::FIELD_AVG_ITEM:
|
||||||
@ -11807,14 +11810,13 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
find_order_in_list()
|
find_order_in_list()
|
||||||
thd [in] Pointer to current thread structure
|
thd Pointer to current thread structure
|
||||||
ref_pointer_array [in/out] All select, group and order by fields
|
ref_pointer_array All select, group and order by fields
|
||||||
tables [in] List of tables to search in (usually FROM clause)
|
tables List of tables to search in (usually FROM clause)
|
||||||
order [in] Column reference to be resolved
|
order Column reference to be resolved
|
||||||
fields [in] List of fields to search in (usually SELECT list)
|
fields List of fields to search in (usually SELECT list)
|
||||||
all_fields [in/out] All select, group and order by fields
|
all_fields All select, group and order by fields
|
||||||
is_group_field [in] True if order is a GROUP field, false if
|
is_group_field True if order is a GROUP field, false if ORDER by field
|
||||||
ORDER by field
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Given a column reference (represented by 'order') from a GROUP BY or ORDER
|
Given a column reference (represented by 'order') from a GROUP BY or ORDER
|
||||||
@ -11831,6 +11833,8 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
|
|||||||
RETURN
|
RETURN
|
||||||
FALSE if OK
|
FALSE if OK
|
||||||
TRUE if error occurred
|
TRUE if error occurred
|
||||||
|
|
||||||
|
ref_pointer_array and all_fields are updated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -11882,6 +11886,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||||||
|
|
||||||
/* Lookup the current GROUP field in the FROM clause. */
|
/* Lookup the current GROUP field in the FROM clause. */
|
||||||
order_item_type= order_item->type();
|
order_item_type= order_item->type();
|
||||||
|
from_field= (Field*) not_found_field;
|
||||||
if (is_group_field &&
|
if (is_group_field &&
|
||||||
order_item_type == Item::FIELD_ITEM ||
|
order_item_type == Item::FIELD_ITEM ||
|
||||||
order_item_type == Item::REF_ITEM)
|
order_item_type == Item::REF_ITEM)
|
||||||
@ -11889,14 +11894,11 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||||||
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
|
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
|
||||||
&view_ref, IGNORE_ERRORS, TRUE,
|
&view_ref, IGNORE_ERRORS, TRUE,
|
||||||
FALSE);
|
FALSE);
|
||||||
if(!from_field)
|
if (!from_field)
|
||||||
from_field= (Field*) not_found_field;
|
from_field= (Field*) not_found_field;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
from_field= (Field*) not_found_field;
|
|
||||||
|
|
||||||
if (from_field == not_found_field ||
|
if (from_field == not_found_field ||
|
||||||
from_field &&
|
|
||||||
(from_field != view_ref_found ?
|
(from_field != view_ref_found ?
|
||||||
/* it is field of base table => check that fields are same */
|
/* it is field of base table => check that fields are same */
|
||||||
((*select_item)->type() == Item::FIELD_ITEM &&
|
((*select_item)->type() == Item::FIELD_ITEM &&
|
||||||
@ -11909,37 +11911,40 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||||||
view_ref->type() == Item::REF_ITEM &&
|
view_ref->type() == Item::REF_ITEM &&
|
||||||
((Item_ref *) (*select_item))->ref ==
|
((Item_ref *) (*select_item))->ref ==
|
||||||
((Item_ref *) view_ref)->ref)))
|
((Item_ref *) view_ref)->ref)))
|
||||||
/*
|
|
||||||
If there is no such field in the FROM clause, or it is the same field as
|
|
||||||
the one found in the SELECT clause, then use the Item created for the
|
|
||||||
SELECT field. As a result if there was a derived field that 'shadowed'
|
|
||||||
a table field with the same name, the table field will be chosen over
|
|
||||||
the derived field.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
If there is no such field in the FROM clause, or it is the same field
|
||||||
|
as the one found in the SELECT clause, then use the Item created for
|
||||||
|
the SELECT field. As a result if there was a derived field that
|
||||||
|
'shadowed' a table field with the same name, the table field will be
|
||||||
|
chosen over the derived field.
|
||||||
|
*/
|
||||||
order->item= ref_pointer_array + counter;
|
order->item= ref_pointer_array + counter;
|
||||||
order->in_field_list=1;
|
order->in_field_list=1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
There is a field with the same name in the FROM clause. This is the field
|
There is a field with the same name in the FROM clause. This
|
||||||
that will be chosen. In this case we issue a warning so the user knows
|
is the field that will be chosen. In this case we issue a
|
||||||
that the field from the FROM clause overshadows the column reference from
|
warning so the user knows that the field from the FROM clause
|
||||||
the SELECT list.
|
overshadows the column reference from the SELECT list.
|
||||||
*/
|
*/
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
|
||||||
ER(ER_NON_UNIQ_ERROR), from_field->field_name,
|
ER(ER_NON_UNIQ_ERROR), from_field->field_name,
|
||||||
current_thd->where);
|
current_thd->where);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
order->in_field_list=0;
|
order->in_field_list=0;
|
||||||
/*
|
/*
|
||||||
The call to order_item->fix_fields() means that here we resolve 'order_item'
|
The call to order_item->fix_fields() means that here we resolve
|
||||||
to a column from a table in the list 'tables', or to a column in some outer
|
'order_item' to a column from a table in the list 'tables', or to
|
||||||
query. Exactly because of the second case we come to this point even if
|
a column in some outer query. Exactly because of the second case
|
||||||
(select_item == not_found_item), inspite of that fix_fields() calls
|
we come to this point even if (select_item == not_found_item),
|
||||||
find_item_in_list() one more time.
|
inspite of that fix_fields() calls find_item_in_list() one more
|
||||||
|
time.
|
||||||
|
|
||||||
We check order_item->fixed because Item_func_group_concat can put
|
We check order_item->fixed because Item_func_group_concat can put
|
||||||
arguments for which fix_fields already was called.
|
arguments for which fix_fields already was called.
|
||||||
|
@ -656,14 +656,14 @@ bool st_select_lex::cleanup()
|
|||||||
if (join)
|
if (join)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT((st_select_lex*)join->select_lex == this);
|
DBUG_ASSERT((st_select_lex*)join->select_lex == this);
|
||||||
error|= join->destroy();
|
error= join->destroy();
|
||||||
delete join;
|
delete join;
|
||||||
join= 0;
|
join= 0;
|
||||||
}
|
}
|
||||||
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
|
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
|
||||||
lex_unit= lex_unit->next_unit())
|
lex_unit= lex_unit->next_unit())
|
||||||
{
|
{
|
||||||
error|= lex_unit->cleanup();
|
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
|
||||||
}
|
}
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
@ -58,13 +58,13 @@ static void make_unique_view_field_name(Item *target,
|
|||||||
char *name= (target->orig_name ?
|
char *name= (target->orig_name ?
|
||||||
target->orig_name :
|
target->orig_name :
|
||||||
target->name);
|
target->name);
|
||||||
uint name_len;
|
uint name_len, attempt;
|
||||||
uint attempt= 0;
|
|
||||||
char buff[NAME_LEN+1];
|
char buff[NAME_LEN+1];
|
||||||
for (;; attempt++)
|
List_iterator_fast<Item> itc(item_list);
|
||||||
|
|
||||||
|
for (attempt= 0;; attempt++)
|
||||||
{
|
{
|
||||||
Item *check;
|
Item *check;
|
||||||
List_iterator_fast<Item> itc(item_list);
|
|
||||||
bool ok= TRUE;
|
bool ok= TRUE;
|
||||||
|
|
||||||
if (attempt)
|
if (attempt)
|
||||||
@ -84,6 +84,7 @@ static void make_unique_view_field_name(Item *target,
|
|||||||
} while (check != last_element);
|
} while (check != last_element);
|
||||||
if (ok)
|
if (ok)
|
||||||
break;
|
break;
|
||||||
|
itc.rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
target->orig_name= target->name;
|
target->orig_name= target->name;
|
||||||
@ -305,13 +306,14 @@ bool mysql_create_view(THD *thd,
|
|||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
List_iterator_fast<Item> it(select_lex->item_list);
|
List_iterator_fast<Item> it(select_lex->item_list);
|
||||||
|
List_iterator_fast<Item> itc(select_lex->item_list);
|
||||||
while ((item= it++))
|
while ((item= it++))
|
||||||
{
|
{
|
||||||
Item *check;
|
Item *check;
|
||||||
List_iterator_fast<Item> itc(select_lex->item_list);
|
|
||||||
/* treat underlying fields like set by user names */
|
/* treat underlying fields like set by user names */
|
||||||
if (item->real_item()->type() == Item::FIELD_ITEM)
|
if (item->real_item()->type() == Item::FIELD_ITEM)
|
||||||
item->is_autogenerated_name= FALSE;
|
item->is_autogenerated_name= FALSE;
|
||||||
|
itc.rewind();
|
||||||
while ((check= itc++) && check != item)
|
while ((check= itc++) && check != item)
|
||||||
{
|
{
|
||||||
if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
|
if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
|
||||||
@ -822,6 +824,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
|||||||
old_lex->can_use_merged()) &&
|
old_lex->can_use_merged()) &&
|
||||||
!old_lex->can_not_use_merged())
|
!old_lex->can_not_use_merged())
|
||||||
{
|
{
|
||||||
|
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
|
||||||
/* lex should contain at least one table */
|
/* lex should contain at least one table */
|
||||||
DBUG_ASSERT(view_tables != 0);
|
DBUG_ASSERT(view_tables != 0);
|
||||||
|
|
||||||
@ -865,13 +868,11 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
|||||||
nested_join->join_list= view_select->top_join_list;
|
nested_join->join_list= view_select->top_join_list;
|
||||||
|
|
||||||
/* re-nest tables of VIEW */
|
/* re-nest tables of VIEW */
|
||||||
|
ti.rewind();
|
||||||
|
while ((tbl= ti++))
|
||||||
{
|
{
|
||||||
List_iterator_fast<TABLE_LIST> ti(nested_join->join_list);
|
tbl->join_list= &nested_join->join_list;
|
||||||
while ((tbl= ti++))
|
tbl->embedding= table;
|
||||||
{
|
|
||||||
tbl->join_list= &nested_join->join_list;
|
|
||||||
tbl->embedding= table;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2790,7 +2790,7 @@ static void test_mb(CHARSET_INFO *cs, uchar *s)
|
|||||||
{
|
{
|
||||||
while(*s)
|
while(*s)
|
||||||
{
|
{
|
||||||
if(my_ismbhead_utf8(cs,*s))
|
if (my_ismbhead_utf8(cs,*s))
|
||||||
{
|
{
|
||||||
int len=my_mbcharlen_utf8(cs,*s);
|
int len=my_mbcharlen_utf8(cs,*s);
|
||||||
while(len--)
|
while(len--)
|
||||||
|
@ -218,14 +218,6 @@ static int cs_value(MY_XML_PARSER *st,const char *attr, uint len)
|
|||||||
struct my_cs_file_section_st *s;
|
struct my_cs_file_section_st *s;
|
||||||
int state= (int)((s=cs_file_sec(st->attr, (int) strlen(st->attr))) ? s->state : 0);
|
int state= (int)((s=cs_file_sec(st->attr, (int) strlen(st->attr))) ? s->state : 0);
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
if(0){
|
|
||||||
char str[1024];
|
|
||||||
mstr(str,attr,len,sizeof(str)-1);
|
|
||||||
printf("VALUE %d %s='%s'\n",state,st->attr,str);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case _CS_ID:
|
case _CS_ID:
|
||||||
i->cs.number= strtol(attr,(char**)NULL,10);
|
i->cs.number= strtol(attr,(char**)NULL,10);
|
||||||
|
@ -1492,17 +1492,18 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
|
|||||||
{
|
{
|
||||||
int do_inc= FALSE;
|
int do_inc= FALSE;
|
||||||
DBUG_ASSERT(frac0+intg0 >= 0);
|
DBUG_ASSERT(frac0+intg0 >= 0);
|
||||||
switch (round_digit)
|
switch (round_digit) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
dec1 *p0= buf0 + (frac1-frac0);
|
dec1 *p0= buf0 + (frac1-frac0);
|
||||||
for (; p0 > buf0; p0--)
|
for (; p0 > buf0; p0--)
|
||||||
|
{
|
||||||
if (*p0)
|
if (*p0)
|
||||||
{
|
{
|
||||||
do_inc= TRUE;
|
do_inc= TRUE;
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
@ -1511,9 +1512,10 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
|
|||||||
do_inc= (x>5) || ((x == 5) &&
|
do_inc= (x>5) || ((x == 5) &&
|
||||||
(mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
|
(mode == HALF_UP || (frac0+intg0 > 0 && *buf0 & 1)));
|
||||||
break;
|
break;
|
||||||
};
|
}
|
||||||
default:;
|
default:
|
||||||
};
|
break;
|
||||||
|
}
|
||||||
if (do_inc)
|
if (do_inc)
|
||||||
{
|
{
|
||||||
if (frac0+intg0>0)
|
if (frac0+intg0>0)
|
||||||
@ -1567,9 +1569,9 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
|
|||||||
*buf1=1;
|
*buf1=1;
|
||||||
to->intg++;
|
to->intg++;
|
||||||
}
|
}
|
||||||
/* Here we check 999.9 -> 1000 case when we need to increase intg */
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Here we check 999.9 -> 1000 case when we need to increase intg */
|
||||||
int first_dig= to->intg % DIG_PER_DEC1;
|
int first_dig= to->intg % DIG_PER_DEC1;
|
||||||
/* first_dig==0 should be handled above in the 'if' */
|
/* first_dig==0 should be handled above in the 'if' */
|
||||||
if (first_dig && (*buf1 >= powers10[first_dig]))
|
if (first_dig && (*buf1 >= powers10[first_dig]))
|
||||||
|
@ -96,13 +96,13 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a)
|
|||||||
a->end=p->cur;
|
a->end=p->cur;
|
||||||
lex=a->beg[0];
|
lex=a->beg[0];
|
||||||
}
|
}
|
||||||
else if ( (p->cur[0]=='"') || (p->cur[0]=='\'') )
|
else if ( (p->cur[0] == '"') || (p->cur[0] == '\'') )
|
||||||
{
|
{
|
||||||
p->cur++;
|
p->cur++;
|
||||||
for( ; ( p->cur < p->end ) && (p->cur[0] != a->beg[0]); p->cur++)
|
for( ; ( p->cur < p->end ) && (p->cur[0] != a->beg[0]); p->cur++)
|
||||||
{}
|
{}
|
||||||
a->end=p->cur;
|
a->end=p->cur;
|
||||||
if (a->beg[0]==p->cur[0])p->cur++;
|
if (a->beg[0] == p->cur[0])p->cur++;
|
||||||
a->beg++;
|
a->beg++;
|
||||||
my_xml_norm_text(a);
|
my_xml_norm_text(a);
|
||||||
lex=MY_XML_STRING;
|
lex=MY_XML_STRING;
|
||||||
@ -169,8 +169,8 @@ static int my_xml_leave(MY_XML_PARSER *p, const char *str, uint slen)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Find previous '.' or beginning */
|
/* Find previous '.' or beginning */
|
||||||
for( e=p->attrend; (e>p->attr) && (e[0]!='.') ; e--);
|
for( e=p->attrend; (e>p->attr) && (e[0] != '.') ; e--);
|
||||||
glen = (uint) ((e[0]=='.') ? (p->attrend-e-1) : p->attrend-e);
|
glen = (uint) ((e[0] == '.') ? (p->attrend-e-1) : p->attrend-e);
|
||||||
|
|
||||||
if (str && (slen != glen))
|
if (str && (slen != glen))
|
||||||
{
|
{
|
||||||
@ -199,7 +199,7 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
|
|||||||
while ( p->cur < p->end )
|
while ( p->cur < p->end )
|
||||||
{
|
{
|
||||||
MY_XML_ATTR a;
|
MY_XML_ATTR a;
|
||||||
if(p->cur[0]=='<')
|
if (p->cur[0] == '<')
|
||||||
{
|
{
|
||||||
int lex;
|
int lex;
|
||||||
int question=0;
|
int question=0;
|
||||||
@ -207,40 +207,40 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
|
|||||||
|
|
||||||
lex=my_xml_scan(p,&a);
|
lex=my_xml_scan(p,&a);
|
||||||
|
|
||||||
if (MY_XML_COMMENT==lex)
|
if (MY_XML_COMMENT == lex)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
lex=my_xml_scan(p,&a);
|
lex=my_xml_scan(p,&a);
|
||||||
|
|
||||||
if (MY_XML_SLASH==lex)
|
if (MY_XML_SLASH == lex)
|
||||||
{
|
{
|
||||||
if(MY_XML_IDENT!=(lex=my_xml_scan(p,&a)))
|
if (MY_XML_IDENT != (lex=my_xml_scan(p,&a)))
|
||||||
{
|
{
|
||||||
sprintf(p->errstr,"1: %s unexpected (ident wanted)",lex2str(lex));
|
sprintf(p->errstr,"1: %s unexpected (ident wanted)",lex2str(lex));
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
if(MY_XML_OK!=my_xml_leave(p,a.beg,(uint) (a.end-a.beg)))
|
if (MY_XML_OK != my_xml_leave(p,a.beg,(uint) (a.end-a.beg)))
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
lex=my_xml_scan(p,&a);
|
lex=my_xml_scan(p,&a);
|
||||||
goto gt;
|
goto gt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MY_XML_EXCLAM==lex)
|
if (MY_XML_EXCLAM == lex)
|
||||||
{
|
{
|
||||||
lex=my_xml_scan(p,&a);
|
lex=my_xml_scan(p,&a);
|
||||||
exclam=1;
|
exclam=1;
|
||||||
}
|
}
|
||||||
else if (MY_XML_QUESTION==lex)
|
else if (MY_XML_QUESTION == lex)
|
||||||
{
|
{
|
||||||
lex=my_xml_scan(p,&a);
|
lex=my_xml_scan(p,&a);
|
||||||
question=1;
|
question=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MY_XML_IDENT==lex)
|
if (MY_XML_IDENT == lex)
|
||||||
{
|
{
|
||||||
if(MY_XML_OK!=my_xml_enter(p,a.beg,(uint) (a.end-a.beg)))
|
if (MY_XML_OK != my_xml_enter(p,a.beg,(uint) (a.end-a.beg)))
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -250,17 +250,18 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
|
|||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((MY_XML_IDENT==(lex=my_xml_scan(p,&a))) || (MY_XML_STRING==lex))
|
while ((MY_XML_IDENT == (lex=my_xml_scan(p,&a))) ||
|
||||||
|
(MY_XML_STRING == lex))
|
||||||
{
|
{
|
||||||
MY_XML_ATTR b;
|
MY_XML_ATTR b;
|
||||||
if(MY_XML_EQ==(lex=my_xml_scan(p,&b)))
|
if (MY_XML_EQ == (lex=my_xml_scan(p,&b)))
|
||||||
{
|
{
|
||||||
lex=my_xml_scan(p,&b);
|
lex=my_xml_scan(p,&b);
|
||||||
if ( (lex==MY_XML_IDENT) || (lex==MY_XML_STRING) )
|
if ( (lex == MY_XML_IDENT) || (lex == MY_XML_STRING) )
|
||||||
{
|
{
|
||||||
if((MY_XML_OK!=my_xml_enter(p,a.beg,(uint) (a.end-a.beg))) ||
|
if ((MY_XML_OK != my_xml_enter(p,a.beg,(uint) (a.end-a.beg))) ||
|
||||||
(MY_XML_OK!=my_xml_value(p,b.beg,(uint) (b.end-b.beg))) ||
|
(MY_XML_OK != my_xml_value(p,b.beg,(uint) (b.end-b.beg))) ||
|
||||||
(MY_XML_OK!=my_xml_leave(p,a.beg,(uint) (a.end-a.beg))))
|
(MY_XML_OK != my_xml_leave(p,a.beg,(uint) (a.end-a.beg))))
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -270,19 +271,19 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
|
|||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( (MY_XML_STRING==lex) || (MY_XML_IDENT==lex) )
|
else if ((MY_XML_STRING == lex) || (MY_XML_IDENT == lex))
|
||||||
{
|
{
|
||||||
if((MY_XML_OK!=my_xml_enter(p,a.beg,(uint) (a.end-a.beg))) ||
|
if ((MY_XML_OK != my_xml_enter(p,a.beg,(uint) (a.end-a.beg))) ||
|
||||||
(MY_XML_OK!=my_xml_leave(p,a.beg,(uint) (a.end-a.beg))))
|
(MY_XML_OK != my_xml_leave(p,a.beg,(uint) (a.end-a.beg))))
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lex==MY_XML_SLASH)
|
if (lex == MY_XML_SLASH)
|
||||||
{
|
{
|
||||||
if(MY_XML_OK!=my_xml_leave(p,NULL,0))
|
if (MY_XML_OK != my_xml_leave(p,NULL,0))
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
lex=my_xml_scan(p,&a);
|
lex=my_xml_scan(p,&a);
|
||||||
}
|
}
|
||||||
@ -290,23 +291,23 @@ int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len)
|
|||||||
gt:
|
gt:
|
||||||
if (question)
|
if (question)
|
||||||
{
|
{
|
||||||
if (lex!=MY_XML_QUESTION)
|
if (lex != MY_XML_QUESTION)
|
||||||
{
|
{
|
||||||
sprintf(p->errstr,"6: %s unexpected ('?' wanted)",lex2str(lex));
|
sprintf(p->errstr,"6: %s unexpected ('?' wanted)",lex2str(lex));
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
if(MY_XML_OK!=my_xml_leave(p,NULL,0))
|
if (MY_XML_OK != my_xml_leave(p,NULL,0))
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
lex=my_xml_scan(p,&a);
|
lex=my_xml_scan(p,&a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exclam)
|
if (exclam)
|
||||||
{
|
{
|
||||||
if(MY_XML_OK!=my_xml_leave(p,NULL,0))
|
if (MY_XML_OK != my_xml_leave(p,NULL,0))
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lex!=MY_XML_GT)
|
if (lex != MY_XML_GT)
|
||||||
{
|
{
|
||||||
sprintf(p->errstr,"5: %s unexpected ('>' wanted)",lex2str(lex));
|
sprintf(p->errstr,"5: %s unexpected ('>' wanted)",lex2str(lex));
|
||||||
return MY_XML_ERROR;
|
return MY_XML_ERROR;
|
||||||
@ -315,11 +316,11 @@ gt:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
a.beg=p->cur;
|
a.beg=p->cur;
|
||||||
for ( ; (p->cur < p->end) && (p->cur[0]!='<') ; p->cur++);
|
for ( ; (p->cur < p->end) && (p->cur[0] != '<') ; p->cur++);
|
||||||
a.end=p->cur;
|
a.end=p->cur;
|
||||||
|
|
||||||
my_xml_norm_text(&a);
|
my_xml_norm_text(&a);
|
||||||
if (a.beg!=a.end)
|
if (a.beg != a.end)
|
||||||
{
|
{
|
||||||
my_xml_value(p,a.beg,(uint) (a.end-a.beg));
|
my_xml_value(p,a.beg,(uint) (a.end-a.beg));
|
||||||
}
|
}
|
||||||
@ -381,7 +382,7 @@ uint my_xml_error_pos(MY_XML_PARSER *p)
|
|||||||
const char *s;
|
const char *s;
|
||||||
for ( s=p->beg ; s<p->cur; s++)
|
for ( s=p->beg ; s<p->cur; s++)
|
||||||
{
|
{
|
||||||
if (s[0]=='\n')
|
if (s[0] == '\n')
|
||||||
beg=s;
|
beg=s;
|
||||||
}
|
}
|
||||||
return (uint) (p->cur-beg);
|
return (uint) (p->cur-beg);
|
||||||
@ -391,9 +392,9 @@ uint my_xml_error_lineno(MY_XML_PARSER *p)
|
|||||||
{
|
{
|
||||||
uint res=0;
|
uint res=0;
|
||||||
const char *s;
|
const char *s;
|
||||||
for ( s=p->beg ; s<p->cur; s++)
|
for (s=p->beg ; s<p->cur; s++)
|
||||||
{
|
{
|
||||||
if (s[0]=='\n')
|
if (s[0] == '\n')
|
||||||
res++;
|
res++;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user