Commit d2e8bf2c authored by unknown's avatar unknown

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

into mysql.com:/space/my/mysql-5.0


tests/mysql_client_test.c:
  Auto merged
parents c14e7af7 9b1b56df
......@@ -48,10 +48,9 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch
c_warnings="$global_warnings -Wunused"
cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor"
base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-raid --with-openssl --with-raid --with-big-tables"
max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-raid --with-openssl --with-raid --with-embedded-server --with-big-tables"
max_no_es_configs="$max_leave_isam_configs --without-isam"
max_configs="$max_no_es_configs --with-embedded-server"
base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine"
max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-openssl --with-embedded-server --with-big-tables"
max_configs="$base_max_configs --with-embedded-server"
path=`dirname $0`
. "$path/check-cpu"
......
......@@ -6,6 +6,6 @@ path=`dirname $0`
extra_flags="$pentium_cflags $debug_cflags $max_cflags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs $max_no_es_configs"
extra_configs="$pentium_configs $debug_configs $base_max_configs"
. "$path/FINISH.sh"
......@@ -396,7 +396,7 @@ unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
const char * STDCALL mysql_info(MYSQL *mysql);
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
int STDCALL mysql_set_character_set(MYSQL *mysql, char *csname);
int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname);
MYSQL * STDCALL mysql_init(MYSQL *mysql);
my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
......
......@@ -1511,39 +1511,6 @@ void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *csinfo)
csinfo->dir = charsets_dir;
}
int STDCALL mysql_set_character_set(MYSQL *mysql, char *cs_name)
{
struct charset_info_st *cs;
const char *save_csdir= charsets_dir;
if (mysql->options.charset_dir)
charsets_dir= mysql->options.charset_dir;
if ((cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
{
char buff[MY_CS_NAME_SIZE + 10];
charsets_dir= save_csdir;
sprintf(buff, "SET NAMES %s", cs_name);
if (!mysql_query(mysql, buff))
{
mysql->charset= cs;
}
}
else
{
char cs_dir_name[FN_REFLEN];
get_charsets_dir(cs_dir_name);
mysql->net.last_errno= CR_CANT_READ_CHARSET;
strmov(mysql->net.sqlstate, unknown_sqlstate);
my_snprintf(mysql->net.last_error, sizeof(mysql->net.last_error) - 1,
ER(mysql->net.last_errno), cs_name, cs_dir_name);
}
charsets_dir= save_csdir;
return mysql->net.last_errno;
}
uint STDCALL mysql_thread_safe(void)
{
#ifdef THREAD
......
--source ./include/have_federated_db.inc
source ./include/master-slave.inc;
# remote table creation
connection slave;
--replicate-ignore-db=federated
stop slave;
--disable_warnings
# at this point, we are connected to master
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
connection master;
--disable_warnings
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
connection master;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
connection slave;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
......@@ -657,3 +657,22 @@ a b
1.1 1.100
2.1 2.100
DROP TABLE t1;
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
utext
lily
river
execute stmt using @param1;
utext
lily
river
select utext from t1 where utext like '%%';
utext
lily
river
drop table t1;
deallocate prepare stmt;
This diff is collapsed.
......@@ -119,7 +119,7 @@ c char(1) character set latin1 collate latin1_danish_ci
insert into t1 values ('A','B','C');
insert into t1 values ('a','c','c');
select * from t1 where a in (b);
ERROR HY000: Illegal mix of collations (latin1_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation ' IN '
ERROR HY000: Illegal mix of collations (latin1_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='
select * from t1 where a in (b,c);
ERROR HY000: Illegal mix of collations (latin1_general_ci,IMPLICIT), (latin1_swedish_ci,IMPLICIT), (latin1_danish_ci,IMPLICIT) for operation ' IN '
select * from t1 where 'a' in (a,b,c);
......@@ -193,3 +193,26 @@ select * from t1 where a in (NULL, 'aa');
a
aa
drop table t1;
CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 VALUES (44), (45), (46);
SELECT * FROM t1 WHERE a IN (45);
a
45
SELECT * FROM t1 WHERE a NOT IN (0, 45);
a
44
46
SELECT * FROM t1 WHERE a NOT IN (45);
a
44
46
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a NOT IN (45);
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <> 45)
SELECT * FROM v1;
a
44
46
DROP VIEW v1;
DROP TABLE t1;
......@@ -759,25 +759,6 @@ execute stmt using @a, @b;
?=?
1
deallocate prepare stmt;
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
utext
lily
river
execute stmt using @param1;
utext
lily
river
select utext from t1 where utext like '%%';
utext
lily
river
drop table t1;
deallocate prepare stmt;
create table t1 (a int);
prepare stmt from "select ??";
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
......@@ -794,3 +775,28 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
select ? from t1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? from t1' at line 1
drop table t1;
prepare stmt from "select @@time_zone";
execute stmt;
@@time_zone
SYSTEM
set @@time_zone:='Japan';
execute stmt;
@@time_zone
Japan
prepare stmt from "select @@tx_isolation";
execute stmt;
@@tx_isolation
REPEATABLE-READ
set transaction isolation level read committed;
execute stmt;
@@tx_isolation
READ-COMMITTED
set transaction isolation level serializable;
execute stmt;
@@tx_isolation
SERIALIZABLE
set @@tx_isolation=default;
execute stmt;
@@tx_isolation
REPEATABLE-READ
deallocate prepare stmt;
......@@ -744,3 +744,27 @@ a b
1 3
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (name varchar(15) NOT NULL, KEY idx(name));
INSERT INTO t1 VALUES ('Betty'), ('Anna');
SELECT * FROM t1;
name
Anna
Betty
DELETE FROM t1 WHERE name NOT LIKE 'A%a';
SELECT * FROM t1;
name
Anna
DROP TABLE t1;
CREATE TABLE t1 (a int, KEY idx(a));
INSERT INTO t1 VALUES (NULL), (1), (2), (3);
SELECT * FROM t1;
a
NULL
1
2
3
DELETE FROM t1 WHERE NOT(a <=> 2);
SELECT * FROM t1;
a
2
DROP TABLE t1;
......@@ -2746,3 +2746,14 @@ WHERE
COUNT(*)
4
drop table t1,t2,t3;
create table t1 (f1 int);
insert into t1 values (1),(NULL);
create table t2 (f2 int, f3 int, f4 int);
create index idx1 on t2 (f4);
insert into t2 values (1,2,3),(2,4,6);
select A.f2 from t1 left join t2 A on A.f2 = f1 where A.f3=(select min(f3)
from t2 C where A.f4 = C.f4) or A.f3 IS NULL;
f2
1
NULL
drop table t1,t2;
......@@ -212,3 +212,27 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop function bug_9503;
use test;
drop database mysqltest;
use test;
select current_user();
current_user()
root@localhost
select user();
user()
root@localhost
create procedure bug7291_0 () sql security invoker select current_user(), user();
create procedure bug7291_1 () sql security definer call bug7291_0();
create procedure bug7291_2 () sql security invoker call bug7291_0();
grant execute on procedure bug7291_0 to user1@localhost;
grant execute on procedure bug7291_1 to user1@localhost;
grant execute on procedure bug7291_2 to user1@localhost;
call bug7291_2();
current_user() user()
user1@localhost user1@localhost
call bug7291_1();
current_user() user()
root@localhost user1@localhost
drop procedure bug7291_1;
drop procedure bug7291_2;
drop procedure bug7291_0;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop user user1@localhost;
......@@ -2657,16 +2657,22 @@ end|
call avg ()|
drop procedure avg|
drop procedure if exists bug6129|
set @@sql_mode = 'traditional'|
create procedure bug6129(mode text)
select @@sql_mode = mode|
call bug6129(@@sql_mode)|
@@sql_mode = mode
1
set @@sql_mode = ''|
call bug6129(@@sql_mode)|
@@sql_mode = mode
0
set @old_mode= @@sql_mode;
set @@sql_mode= "";
create procedure bug6129()
select @@sql_mode|
call bug6129()|
@@sql_mode
set @@sql_mode= "NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO"|
call bug6129()|
@@sql_mode
NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO
set @@sql_mode= "NO_ZERO_IN_DATE"|
call bug6129()|
@@sql_mode
NO_ZERO_IN_DATE
set @@sql_mode=@old_mode;
drop procedure bug6129|
drop procedure if exists bug9856|
create procedure bug9856()
......@@ -3079,4 +3085,18 @@ one 1
delete from t1|
drop procedure bug9565_sub|
drop procedure bug9565|
drop procedure if exists bug9538|
create procedure bug9538()
set @@sort_buffer_size = 1000000|
set @x = @@sort_buffer_size|
set @@sort_buffer_size = 2000000|
select @@sort_buffer_size|
@@sort_buffer_size
2000000
call bug9538()|
select @@sort_buffer_size|
@@sort_buffer_size
1000000
set @@sort_buffer_size = @x|
drop procedure bug9538|
drop table t1,t2;
......@@ -1831,6 +1831,31 @@ select * from v1;
t
01:00
drop view v1;
create table t1 (a timestamp default now());
create table t2 (b timestamp default now());
create view v1 as select a,b,t1.a < now() from t1,t2 where t1.a < now();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b`,(`test`.`t1`.`a` < now()) AS `t1.a < now()` from (`test`.`t1` join `test`.`t2`) where (`test`.`t1`.`a` < now())
drop view v1;
drop table t1, t2;
CREATE TABLE t1 ( a varchar(50) );
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = CURRENT_USER();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = current_user())
DROP VIEW v1;
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = VERSION();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = version())
DROP VIEW v1;
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = DATABASE();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = database())
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (col1 time);
CREATE TABLE t2 (col1 time);
CREATE VIEW v1 AS SELECT CONVERT_TZ(col1,'GMT','MET') FROM t1;
......
......@@ -427,3 +427,17 @@ INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
update t1 set b=a;
SELECT * FROM t1;
DROP TABLE t1;
#
# Bug#9442 Set parameter make query fail if column character set is UCS2
#
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
execute stmt using @param1;
select utext from t1 where utext like '%%';
drop table t1;
deallocate prepare stmt;
This diff is collapsed.
......@@ -101,3 +101,21 @@ create table t1 (a char(20) character set binary);
insert into t1 values ('aa'), ('bb');
select * from t1 where a in (NULL, 'aa');
drop table t1;
#
# Bug #11885: WHERE condition with NOT IN (one element)
#
CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 VALUES (44), (45), (46);
SELECT * FROM t1 WHERE a IN (45);
SELECT * FROM t1 WHERE a NOT IN (0, 45);
SELECT * FROM t1 WHERE a NOT IN (45);
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a NOT IN (45);
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
......@@ -789,19 +789,6 @@ set @b='CHRISTINE';
execute stmt using @a, @b;
deallocate prepare stmt;
#
# Bug#9442 Set parameter make query fail if column character set is UCS2
#
create table t1 (utext varchar(20) character set ucs2);
insert into t1 values ("lily");
insert into t1 values ("river");
prepare stmt from 'select utext from t1 where utext like ?';
set @param1='%%';
execute stmt using @param1;
execute stmt using @param1;
select utext from t1 where utext like '%%';
drop table t1;
deallocate prepare stmt;
#
# Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops
# replication": check that errouneous queries with placeholders are not
# allowed
......@@ -824,3 +811,20 @@ select ??;
select ? from t1;
--enable_ps_protocol
drop table t1;
#
# Bug#9359 "Prepared statements take snapshot of system vars at PREPARE
# time"
#
prepare stmt from "select @@time_zone";
execute stmt;
set @@time_zone:='Japan';
execute stmt;
prepare stmt from "select @@tx_isolation";
execute stmt;
set transaction isolation level read committed;
execute stmt;
set transaction isolation level serializable;
execute stmt;
set @@tx_isolation=default;
execute stmt;
deallocate prepare stmt;
......@@ -553,3 +553,26 @@ SELECT a,b FROM v1 WHERE a < 2 and b=3;
DROP VIEW v1;
DROP TABLE t1;
#
# Bug #11853: DELETE statement with a NOT (LIKE/<=>) where condition
# for an indexed attribute
#
CREATE TABLE t1 (name varchar(15) NOT NULL, KEY idx(name));
INSERT INTO t1 VALUES ('Betty'), ('Anna');
SELECT * FROM t1;
DELETE FROM t1 WHERE name NOT LIKE 'A%a';
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a int, KEY idx(a));
INSERT INTO t1 VALUES (NULL), (1), (2), (3);
SELECT * FROM t1;
DELETE FROM t1 WHERE NOT(a <=> 2);
SELECT * FROM t1;
DROP TABLE t1;
......@@ -2330,3 +2330,14 @@ WHERE
drop table t1,t2,t3;
#
# Bug #11482 4.1.12 produces different resultset for a complex query
# than in previous 4.1.x
create table t1 (f1 int);
insert into t1 values (1),(NULL);
create table t2 (f2 int, f3 int, f4 int);
create index idx1 on t2 (f4);
insert into t2 values (1,2,3),(2,4,6);
select A.f2 from t1 left join t2 A on A.f2 = f1 where A.f3=(select min(f3)
from t2 C where A.f4 = C.f4) or A.f3 IS NULL;
drop table t1,t2;
......@@ -341,3 +341,33 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop function bug_9503;
use test;
drop database mysqltest;
#
# correct value from current_user() in function run from "security definer"
# (BUG#7291)
#
connection con1root;
use test;
select current_user();
select user();
create procedure bug7291_0 () sql security invoker select current_user(), user();
create procedure bug7291_1 () sql security definer call bug7291_0();
create procedure bug7291_2 () sql security invoker call bug7291_0();
grant execute on procedure bug7291_0 to user1@localhost;
grant execute on procedure bug7291_1 to user1@localhost;
grant execute on procedure bug7291_2 to user1@localhost;
connect (user1,localhost,user1,,);
connection user1;
call bug7291_2();
call bug7291_1();
connection con1root;
drop procedure bug7291_1;
drop procedure bug7291_2;
drop procedure bug7291_0;
disconnect user1;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop user user1@localhost;
......@@ -3377,15 +3377,16 @@ drop procedure avg|
--disable_warnings
drop procedure if exists bug6129|
--enable_warnings
set @@sql_mode = 'traditional'|
create procedure bug6129(mode text)
select @@sql_mode = mode|
# 1
call bug6129(@@sql_mode)|
set @@sql_mode = ''|
# 0
call bug6129(@@sql_mode)|
set @old_mode= @@sql_mode;
set @@sql_mode= "";
create procedure bug6129()
select @@sql_mode|
call bug6129()|
set @@sql_mode= "NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO"|
call bug6129()|
set @@sql_mode= "NO_ZERO_IN_DATE"|
call bug6129()|
set @@sql_mode=@old_mode;
drop procedure bug6129|
......@@ -3855,6 +3856,26 @@ drop procedure bug9565_sub|
drop procedure bug9565|
#
# BUG#9538: SProc: Creation fails if we try to SET system variable
# using @@var_name in proc
#
--disable_warnings
drop procedure if exists bug9538|
--enable_warnings
create procedure bug9538()
set @@sort_buffer_size = 1000000|
set @x = @@sort_buffer_size|
set @@sort_buffer_size = 2000000|
select @@sort_buffer_size|
call bug9538()|
select @@sort_buffer_size|
set @@sort_buffer_size = @x|
drop procedure bug9538|
#
# BUG#NNNN: New bug synopsis
#
......
......@@ -1673,6 +1673,27 @@ create view v1 as SELECT TIME_FORMAT(SEC_TO_TIME(3600),'%H:%i') as t;
select * from v1;
drop view v1;
#
# evaluation constant functions in WHERE (BUG#4663)
#
create table t1 (a timestamp default now());
create table t2 (b timestamp default now());
create view v1 as select a,b,t1.a < now() from t1,t2 where t1.a < now();
SHOW CREATE VIEW v1;
drop view v1;
drop table t1, t2;
CREATE TABLE t1 ( a varchar(50) );
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = CURRENT_USER();
SHOW CREATE VIEW v1;
DROP VIEW v1;
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = VERSION();
SHOW CREATE VIEW v1;
DROP VIEW v1;
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = DATABASE();
SHOW CREATE VIEW v1;
DROP VIEW v1;
DROP TABLE t1;
#
# checking views after some view with error (BUG#11337)
#
......
......@@ -23,9 +23,9 @@
NdbMutex* NdbMutex_Create(void)
{
DBUG_ENTER("NdbMutex_Create");
NdbMutex* pNdbMutex;
int result;
DBUG_ENTER("NdbMutex_Create");
pNdbMutex = (NdbMutex*)NdbMem_Allocate(sizeof(NdbMutex));
DBUG_PRINT("info",("NdbMem_Allocate 0x%lx",pNdbMutex));
......@@ -42,8 +42,8 @@ NdbMutex* NdbMutex_Create(void)
int NdbMutex_Destroy(NdbMutex* p_mutex)
{
DBUG_ENTER("NdbMutex_Destroy");
int result;
DBUG_ENTER("NdbMutex_Destroy");
if (p_mutex == NULL)
DBUG_RETURN(-1);
......
......@@ -71,10 +71,10 @@ struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func,
const char* p_thread_name,
NDB_THREAD_PRIO thread_prio)
{
DBUG_ENTER("NdbThread_Create");
struct NdbThread* tmpThread;
int result;
pthread_attr_t thread_attr;
DBUG_ENTER("NdbThread_Create");
(void)thread_prio; /* remove warning for unused parameter */
......
......@@ -2206,7 +2206,8 @@ my_bool mysql_reconnect(MYSQL *mysql)
tmp_mysql.rpl_pivot = mysql->rpl_pivot;
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
mysql->db, mysql->port, mysql->unix_socket,
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
mysql->client_flag | CLIENT_REMEMBER_OPTIONS) ||
mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
{
mysql->net.last_errno= tmp_mysql.net.last_errno;
strmov(mysql->net.last_error, tmp_mysql.net.last_error);
......@@ -2778,8 +2779,49 @@ uint STDCALL mysql_errno(MYSQL *mysql)
return mysql->net.last_errno;
}
const char * STDCALL mysql_error(MYSQL *mysql)
{
return mysql->net.last_error;
}
/*
mysql_set_character_set function sends SET NAMES cs_name to
the server (which changes character_set_client, character_set_result
and character_set_connection) and updates mysql->charset so other
functions like mysql_real_escape will work correctly.
*/
int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name)
{
struct charset_info_st *cs;
const char *save_csdir= charsets_dir;
if (mysql->options.charset_dir)
charsets_dir= mysql->options.charset_dir;
if (strlen(cs_name) < MY_CS_NAME_SIZE &&
(cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
{
char buff[MY_CS_NAME_SIZE + 10];
charsets_dir= save_csdir;
sprintf(buff, "SET NAMES %s", cs_name);
if (!mysql_real_query(mysql, buff, strlen(buff)))
{
mysql->charset= cs;
}
}
else
{
char cs_dir_name[FN_REFLEN];
get_charsets_dir(cs_dir_name);
mysql->net.last_errno= CR_CANT_READ_CHARSET;
strmov(mysql->net.sqlstate, unknown_sqlstate);
my_snprintf(mysql->net.last_error, sizeof(mysql->net.last_error) - 1,
ER(mysql->net.last_errno), cs_name, cs_dir_name);
}
charsets_dir= save_csdir;
return mysql->net.last_errno;
}
This diff is collapsed.
......@@ -26,16 +26,52 @@
#endif
#include <mysql.h>
//#include <client.h>
#define FEDERATED_QUERY_BUFFER_SIZE STRING_BUFFER_USUAL_SIZE * 5
#define FEDERATED_RECORDS_IN_RANGE 2
#define FEDERATED_INFO " SHOW TABLE STATUS LIKE "
#define FEDERATED_SELECT "SELECT "
#define FEDERATED_WHERE " WHERE "
#define FEDERATED_FROM " FROM "
#define FEDERATED_PERCENT "%"
#define FEDERATED_IS " IS "
#define FEDERATED_NULL " NULL "
#define FEDERATED_ISNULL " IS NULL "
#define FEDERATED_LIKE " LIKE "
#define FEDERATED_TRUNCATE "TRUNCATE "
#define FEDERATED_DELETE "DELETE "
#define FEDERATED_INSERT "INSERT INTO "
#define FEDERATED_LIMIT1 " LIMIT 1"
#define FEDERATED_VALUES "VALUES "
#define FEDERATED_UPDATE "UPDATE "
#define FEDERATED_SET "SET "
#define FEDERATED_AND " AND "
#define FEDERATED_CONJUNCTION ") AND ("
#define FEDERATED_OR " OR "
#define FEDERATED_NOT " NOT "
#define FEDERATED_STAR "* "
#define FEDERATED_SPACE " "
#define FEDERATED_SQUOTE "'"
#define FEDERATED_COMMA ", "
#define FEDERATED_DQOUTE '"'
#define FEDERATED_BTICK "`"
#define FEDERATED_OPENPAREN " ("
#define FEDERATED_CLOSEPAREN ") "
#define FEDERATED_NE " != "
#define FEDERATED_GT " > "
#define FEDERATED_LT " < "
#define FEDERATED_LE " <= "
#define FEDERATED_GE " >= "
#define FEDERATED_EQ " = "
#define FEDERATED_1EQ0 " 1=0"
/*
FEDERATED_SHARE is a structure that will be shared amoung all open handlers
The example implements the minimum of what you will probably need.
*/
typedef struct st_federated_share {
char *table_name;
char *table_base_name;
/*
/*
the primary select query to be used in rnd_init
*/
char *select_query;
......@@ -47,11 +83,12 @@ typedef struct st_federated_share {
char *username;
char *password;
char *database;
char *table_name;
char *table;
char *socket;
char *sport;
int port;
uint table_name_length,table_base_name_length,use_count;
ushort port;
uint table_name_length,use_count;
pthread_mutex_t mutex;
THR_LOCK lock;
} FEDERATED_SHARE;
......@@ -63,8 +100,8 @@ class ha_federated: public handler
{
THR_LOCK_DATA lock; /* MySQL lock */
FEDERATED_SHARE *share; /* Shared lock info */
MYSQL *mysql;
MYSQL_RES *result;
MYSQL *mysql; /* MySQL connection */
MYSQL_RES *stored_result;
bool scan_flag;
uint ref_length;
uint fetch_num; // stores the fetch num
......@@ -77,11 +114,13 @@ class ha_federated: public handler
*/
uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row);
bool create_where_from_key(String *to, KEY *key_info,
const byte *key, uint key_length);
const key_range *start_key,
const key_range *end_key,
bool records_in_range);
public:
ha_federated(TABLE *table): handler(table),
mysql(0), result(0), scan_flag(0),
mysql(0), stored_result(0), scan_flag(0),
ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0)
{
}
......@@ -94,20 +133,20 @@ class ha_federated: public handler
The name of the index type that will be used for display
don't implement this method unless you really have indexes
*/
// perhaps get index type
const char *index_type(uint inx) { return "REMOTE"; }
const char **bas_ext() const;
/*
This is a list of flags that says what the storage engine
implements. The current table flags are documented in
handler.h
Serg: Double check these (Brian)
// FIX add blob support
*/
ulong table_flags() const
{
return (HA_TABLE_SCAN_ON_INDEX | HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED |
HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS);
/* fix server to be able to get remote server table flags */
return (HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | HA_REC_NOT_IN_SEQ |
HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS| HA_NO_PREFIX_CHAR_KEYS);
}
/*
This is a bitmap of flags that says how the storage engine
......@@ -119,29 +158,45 @@ class ha_federated: public handler
If all_parts it's set, MySQL want to know the flags for the combined
index up to and including 'part'.
*/
/* fix server to be able to get remote server index flags */
ulong index_flags(uint inx, uint part, bool all_parts) const
{
return (HA_READ_NEXT);
// return (HA_READ_NEXT | HA_ONLY_WHOLE_INDEX);
return (HA_READ_NEXT | HA_READ_RANGE | HA_READ_AFTER_KEY);
}
uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_supported_keys() const { return MAX_KEY; }
uint max_supported_key_parts() const { return 1024; }
uint max_supported_key_length() const { return 1024; }
uint max_supported_key_parts() const { return MAX_REF_PARTS; }
uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
/*
Called in test_quick_select to determine if indexes should be used.
Normally, we need to know number of blocks . For federated we need to
know number of blocks on remote side, and number of packets and blocks
on the network side (?)
Talk to Kostja about this - how to get the
number of rows * ...
disk scan time on other side (block size, size of the row) + network time ...
The reason for "records * 1000" is that such a large number forces
this to use indexes "
*/
virtual double scan_time()
double scan_time()
{
DBUG_PRINT("ha_federated::scan_time",
("rows %d", records)); return (double)(records*2);
DBUG_PRINT("info",
("records %d", records));
return (double)(records*1000);
}
/*
The next method will never be called if you do not implement indexes.
*/
virtual double read_time(uint index, uint ranges, ha_rows rows)
{ return (double) rows / 20.0+1; }
double read_time(uint index, uint ranges, ha_rows rows)
{
/*
Per Brian, this number is bugus, but this method must be implemented,
and at a later date, he intends to document this issue for handler code
*/
return (double) rows / 20.0+1;
}
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
/*
Everything below are methods that we implment in ha_federated.cc.
......@@ -151,16 +206,20 @@ class ha_federated: public handler
int open(const char *name, int mode, uint test_if_locked); // required
int close(void); // required
int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data);
int delete_row(const byte * buf);
int write_row(byte *buf);
int update_row(const byte *old_data, byte *new_data);
int delete_row(const byte *buf);
int index_init(uint keynr);
int index_read(byte * buf, const byte * key,
int index_read(byte *buf, const byte *key,
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
int index_read_idx(byte *buf, uint idx, const byte *key,
uint key_len, enum ha_rkey_function find_flag);
int index_next(byte * buf);
int index_next(byte *buf);
int index_end();
int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
int read_range_next();
/*
unlike index_init(), rnd_init() can be called two times
without rnd_end() in between (it only makes sense if scan=1).
......@@ -172,13 +231,15 @@ class ha_federated: public handler
int rnd_init(bool scan); //required
int rnd_end();
int rnd_next(byte *buf); //required
int rnd_pos(byte * buf, byte *pos); //required
int rnd_pos(byte *buf, byte *pos); //required
void position(const byte *record); //required
void info(uint); //required
int delete_all_rows(void);
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); //required
ha_rows records_in_range(uint inx, key_range *start_key,
key_range *end_key);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); //required
......
......@@ -638,6 +638,38 @@ Item *Item_num::safe_charset_converter(CHARSET_INFO *tocs)
}
Item *Item_static_int_func::safe_charset_converter(CHARSET_INFO *tocs)
{
Item_string *conv;
char buf[64];
String *s, tmp(buf, sizeof(buf), &my_charset_bin);
s= val_str(&tmp);
if ((conv= new Item_static_string_func(func_name, s->ptr(), s->length(),
s->charset())))
{
conv->str_value.copy();
conv->str_value.mark_as_const();
}
return conv;
}
Item *Item_static_float_func::safe_charset_converter(CHARSET_INFO *tocs)
{
Item_string *conv;
char buf[64];
String *s, tmp(buf, sizeof(buf), &my_charset_bin);
s= val_str(&tmp);
if ((conv= new Item_static_string_func(func_name, s->ptr(), s->length(),
s->charset())))
{
conv->str_value.copy();
conv->str_value.mark_as_const();
}
return conv;
}
Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
{
Item_string *conv;
......@@ -663,6 +695,33 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
}
Item *Item_static_string_func::safe_charset_converter(CHARSET_INFO *tocs)
{
Item_string *conv;
uint conv_errors;
String tmp, cstr, *ostr= val_str(&tmp);
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
if (conv_errors ||
!(conv= new Item_static_string_func(func_name,
cstr.ptr(), cstr.length(),
cstr.charset(),
collation.derivation)))
{
/*
Safe conversion is not possible (or EOM).
We could not convert a string into the requested character set
without data loss. The target charset does not cover all the
characters from the string. Operation cannot be done correctly.
*/
return NULL;
}
conv->str_value.copy();
/* Ensure that no one is going to change the result string */
conv->str_value.mark_as_const();
return conv;
}
bool Item_string::eq(const Item *item, bool binary_cmp) const
{
if (type() == item->type() && item->basic_const_item())
......
......@@ -1132,6 +1132,7 @@ class Item_static_int_func :public Item_int
Item_static_int_func(const char *str_arg, longlong i, uint length)
:Item_int(NullS, i, length), func_name(str_arg)
{}
Item *safe_charset_converter(CHARSET_INFO *tocs);
void print(String *str) { str->append(func_name); }
};
......@@ -1242,6 +1243,7 @@ class Item_static_float_func :public Item_float
:Item_float(NullS, val_arg, decimal_par, length), func_name(str)
{}
void print(String *str) { str->append(func_name); }
Item *safe_charset_converter(CHARSET_INFO *tocs);
};
......@@ -1314,6 +1316,7 @@ class Item_static_string_func :public Item_string
Derivation dv= DERIVATION_COERCIBLE)
:Item_string(NullS, str, length, cs, dv), func_name(name_par)
{}
Item *safe_charset_converter(CHARSET_INFO *tocs);
void print(String *str) { str->append(func_name); }
};
......
......@@ -237,32 +237,35 @@ void Item_bool_func2::fix_length_and_dec()
set_cmp_func();
return;
}
Item *real_item= args[0]->real_item();
if (real_item->type() == FIELD_ITEM)
if (!thd->is_context_analysis_only())
{
Field *field= ((Item_field*) real_item)->field;
if (field->can_be_compared_as_longlong())
Item *real_item= args[0]->real_item();
if (real_item->type() == FIELD_ITEM)
{
if (convert_constant_item(thd, field,&args[1]))
Field *field=((Item_field*) real_item)->field;
if (field->can_be_compared_as_longlong())
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
return;
if (convert_constant_item(thd, field,&args[1]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
return;
}
}
}
}
real_item= args[1]->real_item();
if (real_item->type() == FIELD_ITEM)
{
Field *field= ((Item_field*) real_item)->field;
if (field->can_be_compared_as_longlong())
real_item= args[1]->real_item();
if (real_item->type() == FIELD_ITEM /* && !real_item->const_item() */)
{
if (convert_constant_item(thd, field,&args[0]))
Field *field=((Item_field*) real_item)->field;
if (field->can_be_compared_as_longlong())
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
return;
if (convert_constant_item(thd, field,&args[0]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
return;
}
}
}
}
......@@ -990,7 +993,8 @@ void Item_func_between::fix_length_and_dec()
if (args[0]->type() == FIELD_ITEM)
{
Field *field=((Item_field*) args[0])->field;
if (field->can_be_compared_as_longlong())
if (!thd->is_context_analysis_only() &&
field->can_be_compared_as_longlong())
{
/*
The following can't be recoded with || as convert_constant_item
......
......@@ -299,16 +299,8 @@ Item *create_func_pow(Item* a, Item *b)
Item *create_func_current_user()
{
THD *thd=current_thd;
char buff[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
uint length;
thd->lex->safe_to_cache_query= 0;
length= (uint) (strxmov(buff, thd->priv_user, "@", thd->priv_host, NullS) -
buff);
return new Item_static_string_func("current_user()",
thd->memdup(buff, length), length,
system_charset_info);
current_thd->lex->safe_to_cache_query= 0;
return new Item_func_user(TRUE);
}
Item *create_func_radians(Item *a)
......
......@@ -4217,6 +4217,36 @@ void Item_user_var_as_out_param::print(String *str)
}
Item_func_get_system_var::
Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
LEX_STRING *component_arg, const char *name_arg,
size_t name_len_arg)
:var(var_arg), var_type(var_type_arg), component(*component_arg)
{
/* set_name() will allocate the name */
set_name(name_arg, name_len_arg, system_charset_info);
}
bool
Item_func_get_system_var::fix_fields(THD *thd, Item **ref)
{
Item *item= var->item(thd, var_type, &component);
DBUG_ENTER("Item_func_get_system_var::fix_fields");
/*
Evaluate the system variable and substitute the result (a basic constant)
instead of this item. If the variable can not be evaluated,
the error is reported in sys_var::item().
*/
if (item == 0)
DBUG_RETURN(1); // Impossible
item->set_name(name, 0, system_charset_info); // don't allocate a new name
thd->change_item_tree(ref, item);
DBUG_RETURN(0);
}
longlong Item_func_inet_aton::val_int()
{
DBUG_ASSERT(fixed == 1);
......@@ -4563,22 +4593,21 @@ longlong Item_func_bit_xor::val_int()
0 error
# constant item
*/
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
LEX_STRING component)
{
sys_var *var;
char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos;
LEX_STRING *base_name, *component_name;
if (component.str == 0 &&
!my_strcasecmp(system_charset_info, name.str, "VERSION"))
return new Item_string("@@VERSION", server_version,
(uint) strlen(server_version),
system_charset_info, DERIVATION_SYSCONST);
Item *item;
sys_var *var;
char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos;
LEX_STRING *base_name, *component_name;
if (component.str)
{
base_name= &component;
......@@ -4600,9 +4629,8 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
return 0;
}
}
if (!(item=var->item(thd, var_type, component_name)))
return 0; // Impossible
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
buff[0]='@';
buff[1]='@';
pos=buff+2;
......@@ -4623,28 +4651,8 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
memcpy(pos, base_name->str, base_name->length);
pos+= base_name->length;
// set_name() will allocate the name
item->set_name(buff,(uint) (pos-buff), system_charset_info);
return item;
}
Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
uint length, const char *item_name)
{
Item *item;
sys_var *var;
LEX_STRING null_lex_string;
null_lex_string.str= 0;
var= find_sys_var(var_name, length);
DBUG_ASSERT(var != 0);
if (!(item=var->item(thd, var_type, &null_lex_string)))
return 0; // Impossible
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
item->set_name(item_name, 0, system_charset_info); // Will use original name
return item;
return new Item_func_get_system_var(var, var_type, component_name,
buff, pos - buff);
}
......
......@@ -1199,6 +1199,31 @@ class Item_user_var_as_out_param :public Item
};
/* A system variable */
class Item_func_get_system_var :public Item_func
{
sys_var *var;
enum_var_type var_type;
LEX_STRING component;
public:
Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
LEX_STRING *component_arg, const char *name_arg,
size_t name_len_arg);
bool fix_fields(THD *thd, Item **ref);
/*
Stubs for pure virtual methods. Should never be called: this
item is always substituted with a constant in fix_fields().
*/
double val_real() { DBUG_ASSERT(0); return 0.0; }
longlong val_int() { DBUG_ASSERT(0); return 0; }
String* val_str(String*) { DBUG_ASSERT(0); return 0; }
void fix_length_and_dec() { DBUG_ASSERT(0); }
/* TODO: fix to support views */
const char *func_name() const { return "get_system_var"; }
};
class Item_func_inet_aton : public Item_int_func
{
public:
......
......@@ -1552,9 +1552,11 @@ Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs)
uint conv_errors;
String tmp, cstr, *ostr= val_str(&tmp);
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
cstr.charset(),
collation.derivation)))
if (conv_errors ||
!(conv= new Item_static_string_func(fully_qualified_func_name(),
cstr.ptr(), cstr.length(),
cstr.charset(),
collation.derivation)))
{
return NULL;
}
......@@ -1584,13 +1586,24 @@ String *Item_func_user::val_str(String *str)
DBUG_ASSERT(fixed == 1);
THD *thd=current_thd;
CHARSET_INFO *cs= system_charset_info;
const char *host= thd->host_or_ip;
const char *host, *user;
uint res_length;
if (is_current)
{
user= thd->priv_user;
host= thd->priv_host;
}
else
{
user= thd->user;
host= thd->host_or_ip;
}
// For system threads (e.g. replication SQL thread) user may be empty
if (!thd->user)
if (!user)
return &my_empty_string;
res_length= (strlen(thd->user)+strlen(host)+2) * cs->mbmaxlen;
res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
if (str->alloc(res_length))
{
......@@ -1598,12 +1611,13 @@ String *Item_func_user::val_str(String *str)
return 0;
}
res_length=cs->cset->snprintf(cs, (char*)str->ptr(), res_length, "%s@%s",
thd->user, host);
user, host);
str->length(res_length);
str->set_charset(cs);
return str;
}
void Item_func_soundex::fix_length_and_dec()
{
collation.set(args[0]->collation);
......
......@@ -357,8 +357,15 @@ class Item_func_sysconst :public Item_str_func
Item_func_sysconst()
{ collation.set(system_charset_info,DERIVATION_SYSCONST); }
Item *safe_charset_converter(CHARSET_INFO *tocs);
/*
Used to create correct Item name in new converted item in
safe_charset_converter, return string representation of this function
call
*/
virtual const char *fully_qualified_func_name() const = 0;
};
class Item_func_database :public Item_func_sysconst
{
public:
......@@ -370,18 +377,27 @@ class Item_func_database :public Item_func_sysconst
maybe_null=1;
}
const char *func_name() const { return "database"; }
const char *fully_qualified_func_name() const { return "database()"; }
};
class Item_func_user :public Item_func_sysconst
{
bool is_current;
public:
Item_func_user() :Item_func_sysconst() {}
Item_func_user(bool is_current_arg)
:Item_func_sysconst(), is_current(is_current_arg) {}
String *val_str(String *);
void fix_length_and_dec()
{
max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*system_charset_info->mbmaxlen;
void fix_length_and_dec()
{
max_length= ((USERNAME_LENGTH + HOSTNAME_LENGTH + 1) *
system_charset_info->mbmaxlen);
}
const char *func_name() const { return "user"; }
const char *func_name() const
{ return is_current ? "current_user" : "user"; }
const char *fully_qualified_func_name() const
{ return is_current ? "current_user()" : "user()"; }
};
......
......@@ -475,6 +475,11 @@ typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
#include "protocol.h"
#include "sql_udf.h"
class user_var_entry;
enum enum_var_type
{
OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL
};
class sys_var;
#include "item.h"
extern my_decimal decimal_zero;
typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
......@@ -1329,12 +1334,9 @@ extern bool sql_cache_init();
extern void sql_cache_free();
extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
/* item.cc */
/* item_func.cc */
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
LEX_STRING component);
Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name,
uint length, const char *item_name);
/* item_func.cc */
int get_var_with_binlog(THD *thd, LEX_STRING &name,
user_var_entry **out_entry);
/* log.cc */
......
......@@ -3531,7 +3531,8 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
if (arg->type() != Item::FUNC_ITEM)
DBUG_RETURN(0);
cond_func= (Item_func*) arg;
if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
if (cond_func->functype() != Item_func::BETWEEN &&
cond_func->functype() != Item_func::IN_FUNC)
DBUG_RETURN(0);
inv= TRUE;
}
......
......@@ -1652,15 +1652,7 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
/*
Return an Item for a variable. Used with @@[global.]variable_name
If type is not given, return local value if exists, else global
We have to use netprintf() instead of my_error() here as this is
called on the parsing stage.
TODO:
With prepared statements/stored procedures this has to be fixed
to create an item that gets the current value at fix_fields() stage.
*/
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
......
......@@ -30,11 +30,6 @@ class set_var;
typedef struct system_variables SV;
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
enum enum_var_type
{
OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL
};
typedef int (*sys_check_func)(THD *, set_var *);
typedef bool (*sys_update_func)(THD *, set_var *);
typedef void (*sys_after_update_func)(THD *,enum_var_type);
......
......@@ -5370,3 +5370,15 @@ ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009
eng "Scale may not be larger than the precision (column '%-.64s')."
ER_WRONG_LOCK_OF_SYSTEM_TABLE
eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables"
ER_CONNECT_TO_FOREIGN_DATA_SOURCE
eng "Unable to connect to foreign data source - database '%s'!"
ER_QUERY_ON_FOREIGN_DATA_SOURCE
eng "There was a problem processing the query on the foreign data source. Data source error: '%-.64s'"
ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST
eng "The foreign data source you are trying to reference does not exist. Data source error : '%-.64s'"
ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE
eng "Can't create federated table. The data source connection string '%-.64s' is not in the correct format"
ER_FOREIGN_DATA_STRING_INVALID
eng "The data source connection string '%-.64s' is not in the correct format"
ER_CANT_CREATE_FEDERATED_TABLE
eng "Can't create federated table. Foreign data src error : '%-.64s'"
This diff is collapsed.
......@@ -1467,6 +1467,8 @@ class THD :public ilink,
(variables.sql_mode & MODE_STRICT_ALL_TABLES)));
}
void set_status_var_init();
bool is_context_analysis_only()
{ return current_arena->is_stmt_prepare() || lex->view_prepare_mode; }
bool push_open_tables_state();
void pop_open_tables_state();
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment