Merge bk-internal.mysql.com:/data0/bk/mysql-4.1

into bk-internal.mysql.com:/data0/bk/mysql-4.1-cluster-extra


sql/ha_innodb.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
This commit is contained in:
unknown 2004-12-23 10:46:37 +01:00
commit 7f7cdd0b7e
79 changed files with 1065 additions and 19302 deletions

View file

@ -1599,11 +1599,6 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [
;; ;;
esac esac
AC_ARG_WITH([ndb-shm],
[
--with-ndb-shm Include the NDB Cluster shared memory transporter],
[ndb_shm="$withval"],
[ndb_shm=no])
AC_ARG_WITH([ndb-test], AC_ARG_WITH([ndb-test],
[ [
--with-ndb-test Include the NDB Cluster ndbapi test programs], --with-ndb-test Include the NDB Cluster ndbapi test programs],
@ -1633,19 +1628,6 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [
AC_MSG_CHECKING([for NDB Cluster options]) AC_MSG_CHECKING([for NDB Cluster options])
AC_MSG_RESULT([]) AC_MSG_RESULT([])
have_ndb_shm=no
case "$ndb_shm" in
yes )
AC_MSG_RESULT([-- including shared memory transporter])
AC_DEFINE([NDB_SHM_TRANSPORTER], [1],
[Including Ndb Cluster DB shared memory transporter])
have_ndb_shm="yes"
;;
* )
AC_MSG_RESULT([-- not including shared memory transporter])
;;
esac
have_ndb_test=no have_ndb_test=no
case "$ndb_test" in case "$ndb_test" in
yes ) yes )

View file

@ -613,6 +613,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
} }
if (end!=compatible_mode_normal_str) if (end!=compatible_mode_normal_str)
end[-1]= 0; end[-1]= 0;
/*
Set charset to the default compiled value if it hasn't
been reset yet by --default-character-set=xxx.
*/
if (default_charset == (char*) MYSQL_UNIVERSAL_CLIENT_CHARSET)
default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
break; break;
} }
case (int) OPT_MYSQL_PROTOCOL: case (int) OPT_MYSQL_PROTOCOL:

View file

@ -1923,7 +1923,9 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \ pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
pthread_key_delete pthread_rwlock_rdlock pthread_setprio \ pthread_key_delete pthread_rwlock_rdlock pthread_setprio \
pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \ pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \
realpath rename rint rwlock_init setupterm sighold sigset sigthreadmask \ realpath rename rint rwlock_init setupterm \
shmget shmat shmdt shmctl \
sighold sigset sigthreadmask \
snprintf socket stpcpy strcasecmp strerror strnlen strpbrk strstr strtol \ snprintf socket stpcpy strcasecmp strerror strnlen strpbrk strstr strtol \
strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr) strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr)
@ -3078,10 +3080,19 @@ fi
AC_SUBST([ndb_port_base]) AC_SUBST([ndb_port_base])
ndb_transporter_opt_objs="" ndb_transporter_opt_objs=""
if test X"$have_ndb_shm" = Xyes if test "$ac_cv_func_shmget" = "yes" &&
test "$ac_cv_func_shmat" = "yes" &&
test "$ac_cv_func_shmdt" = "yes" &&
test "$ac_cv_func_shmctl" = "yes"
then then
ndb_transporter_opt_objs="$ndb_transporter_opt_objs SHM_Transporter.lo SHM_Transporter.unix.lo" AC_DEFINE([NDB_SHM_TRANSPORTER], [1],
[Including Ndb Cluster DB shared memory transporter])
AC_MSG_RESULT([Including ndb shared memory transporter])
ndb_transporter_opt_objs="$ndb_transporter_opt_objs SHM_Transporter.lo SHM_Transporter.unix.lo"
else
AC_MSG_RESULT([Not including ndb shared memory transporter])
fi fi
if test X"$have_ndb_sci" = Xyes if test X"$have_ndb_sci" = Xyes
then then
ndb_transporter_opt_objs="$ndb_transporter_opt_objs SCI_Transporter.lo" ndb_transporter_opt_objs="$ndb_transporter_opt_objs SCI_Transporter.lo"

View file

@ -1850,6 +1850,7 @@ os_file_pread(
return(n_bytes); return(n_bytes);
#else #else
{ {
off_t ret_offset;
ssize_t ret; ssize_t ret;
ulint i; ulint i;
@ -1858,12 +1859,12 @@ os_file_pread(
os_mutex_enter(os_file_seek_mutexes[i]); os_mutex_enter(os_file_seek_mutexes[i]);
ret = lseek(file, offs, 0); ret_offset = lseek(file, offs, SEEK_SET);
if (ret < 0) { if (ret_offset < 0) {
os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_exit(os_file_seek_mutexes[i]);
return(ret); return(-1);
} }
ret = read(file, buf, (ssize_t)n); ret = read(file, buf, (ssize_t)n);
@ -1936,6 +1937,7 @@ os_file_pwrite(
return(ret); return(ret);
#else #else
{ {
off_t ret_offset;
ulint i; ulint i;
/* Protect the seek / write operation with a mutex */ /* Protect the seek / write operation with a mutex */
@ -1943,12 +1945,12 @@ os_file_pwrite(
os_mutex_enter(os_file_seek_mutexes[i]); os_mutex_enter(os_file_seek_mutexes[i]);
ret = lseek(file, offs, 0); ret_offset = lseek(file, offs, SEEK_SET);
if (ret < 0) { if (ret_offset < 0) {
os_mutex_exit(os_file_seek_mutexes[i]); os_mutex_exit(os_file_seek_mutexes[i]);
return(ret); return(-1);
} }
ret = write(file, buf, (ssize_t)n); ret = write(file, buf, (ssize_t)n);

View file

@ -591,6 +591,32 @@ err:
C_MODE_END C_MODE_END
static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
uint32 dummy32;
uint dummy_err;
char *result;
/* 'tocs' is set 0 when client issues SET character_set_results=NULL */
if (tocs && String::needs_conversion(0, fromcs, tocs, &dummy32))
{
uint new_len= (tocs->mbmaxlen * length) / fromcs->mbminlen + 1;
result= (char *)alloc_root(root, new_len);
length= copy_and_convert(result, new_len,
tocs, from, length, fromcs, &dummy_err);
}
else
{
result= (char *)alloc_root(root, length + 1);
memcpy(result, from, length);
}
result[length]= 0;
return result;
}
bool Protocol::send_fields(List<Item> *list, uint flag) bool Protocol::send_fields(List<Item> *list, uint flag)
{ {
List_iterator_fast<Item> it(*list); List_iterator_fast<Item> it(*list);
@ -598,6 +624,8 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
MYSQL_FIELD *client_field; MYSQL_FIELD *client_field;
MYSQL *mysql= thd->mysql; MYSQL *mysql= thd->mysql;
MEM_ROOT *field_alloc; MEM_ROOT *field_alloc;
CHARSET_INFO *thd_cs= thd->variables.character_set_results;
CHARSET_INFO *cs= system_charset_info;
DBUG_ENTER("send_fields"); DBUG_ENTER("send_fields");
@ -616,12 +644,29 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
Send_field server_field; Send_field server_field;
item->make_field(&server_field); item->make_field(&server_field);
client_field->db= strdup_root(field_alloc, server_field.db_name); client_field->db= dup_str_aux(field_alloc, server_field.db_name,
client_field->table= strdup_root(field_alloc, server_field.table_name); strlen(server_field.db_name), cs, thd_cs);
client_field->name= strdup_root(field_alloc, server_field.col_name); client_field->table= dup_str_aux(field_alloc, server_field.table_name,
client_field->org_table= strdup_root(field_alloc, server_field.org_table_name); strlen(server_field.table_name), cs, thd_cs);
client_field->org_name= strdup_root(field_alloc, server_field.org_col_name); client_field->name= dup_str_aux(field_alloc, server_field.col_name,
client_field->length= server_field.length; strlen(server_field.col_name), cs, thd_cs);
client_field->org_table= dup_str_aux(field_alloc, server_field.org_table_name,
strlen(server_field.org_table_name), cs, thd_cs);
client_field->org_name= dup_str_aux(field_alloc, server_field.org_col_name,
strlen(server_field.org_col_name), cs, thd_cs);
if (item->collation.collation == &my_charset_bin || thd_cs == NULL)
{
/* No conversion */
client_field->charsetnr= server_field.charsetnr;
client_field->length= server_field.length;
}
else
{
/* With conversion */
client_field->charsetnr= thd_cs->number;
uint char_len= server_field.length / item->collation.collation->mbmaxlen;
client_field->length= char_len * thd_cs->mbmaxlen;
}
client_field->type= server_field.type; client_field->type= server_field.type;
client_field->flags= server_field.flags; client_field->flags= server_field.flags;
client_field->decimals= server_field.decimals; client_field->decimals= server_field.decimals;
@ -630,9 +675,8 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
client_field->name_length= strlen(client_field->name); client_field->name_length= strlen(client_field->name);
client_field->org_name_length= strlen(client_field->org_name); client_field->org_name_length= strlen(client_field->org_name);
client_field->org_table_length= strlen(client_field->org_table); client_field->org_table_length= strlen(client_field->org_table);
client_field->charsetnr= server_field.charsetnr;
client_field->catalog= strdup_root(field_alloc, "def"); client_field->catalog= dup_str_aux(field_alloc, "def", 3, cs, thd_cs);
client_field->catalog_length= 3; client_field->catalog_length= 3;
if (INTERNAL_NUM_FIELD(client_field)) if (INTERNAL_NUM_FIELD(client_field))
@ -805,21 +849,3 @@ bool Protocol::net_store_data(const char *from, uint length)
return false; return false;
} }
#if 0
/* The same as Protocol::net_store_data but does the converstion
*/
bool Protocol::convert_str(const char *from, uint length)
{
if (!(*next_field=alloc_root(alloc, length + 1)))
return true;
convert->store_dest(*next_field, from, length);
(*next_field)[length]= 0;
if (next_mysql_field->max_length < length)
next_mysql_field->max_length=length;
++next_field;
++next_mysql_field;
return false;
}
#endif

View file

@ -88,6 +88,10 @@ int mi_rnext_same(MI_INFO *info, byte *buf)
if (my_errno == HA_ERR_KEY_NOT_FOUND) if (my_errno == HA_ERR_KEY_NOT_FOUND)
my_errno=HA_ERR_END_OF_FILE; my_errno=HA_ERR_END_OF_FILE;
} }
else if (!buf)
{
DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
}
else if (!(*info->read_record)(info,info->lastpos,buf)) else if (!(*info->read_record)(info,info->lastpos,buf))
{ {
info->update|= HA_STATE_AKTIV; /* Record is read */ info->update|= HA_STATE_AKTIV; /* Record is read */

View file

@ -16,25 +16,36 @@
#include "myrg_def.h" #include "myrg_def.h"
int myrg_rnext_same(MYRG_INFO *info, byte *buf) int myrg_rnext_same(MYRG_INFO *info, byte *buf)
{ {
uint err; int err;
MI_INFO *mi; MI_INFO *mi;
if (!info->current_table) if (!info->current_table)
return (HA_ERR_KEY_NOT_FOUND); return (HA_ERR_KEY_NOT_FOUND);
err=mi_rnext_same(info->current_table->table,buf); /* at first, do rnext for the table found before */
if (err == HA_ERR_END_OF_FILE) if ((err=mi_rnext_same(info->current_table->table,NULL)))
{ {
queue_remove(&(info->by_key),0); if (err == HA_ERR_END_OF_FILE)
if (!info->by_key.elements) {
return HA_ERR_END_OF_FILE; queue_remove(&(info->by_key),0);
if (!info->by_key.elements)
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table; return HA_ERR_END_OF_FILE;
mi->once_flags|= RRND_PRESERVE_LASTINX; }
return mi_rrnd(mi,buf,mi->lastpos); else
return err;
} }
return err; else
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(byte *)(info->current_table);
queue_replaced(&(info->by_key));
}
/* now, mymerge's read_next is as simple as one queue_top */
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
return _myrg_mi_read_record(mi,buf);
} }

View file

@ -31,12 +31,12 @@ QUIT Quit management client
<id> = ALL | Any database node id <id> = ALL | Any database node id
Connected to Management Server at: localhost:1186 Connected to Management Server at: localhost:1186
Node 1: started (Version 4.1.8) Node 1: started (Version 4.1.9)
Node 2: started (Version 4.1.8) Node 2: started (Version 4.1.9)
Node 1: started (Version 4.1.8) Node 1: started (Version 4.1.9)
Node 2: started (Version 4.1.8) Node 2: started (Version 4.1.9)
Executing CLUSTERLOG on node 1 OK! Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK! Executing CLUSTERLOG on node 2 OK!

View file

@ -1,242 +0,0 @@
SET CHARACTER SET koi8r;
DROP TABLE IF EXISTS ÔÁÂÌÉÃÁ, t1, t2;
SET CHARACTER SET koi8r;
CREATE TABLE t1 (a CHAR(10) CHARACTER SET cp1251) SELECT _koi8r'ÐÒÏÂÁ' AS a;
CREATE TABLE t2 (a CHAR(10) CHARACTER SET utf8);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(10) character set cp1251 default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT a FROM t1;
a
ÐÒÏÂÁ
SELECT HEX(a) FROM t1;
HEX(a)
EFF0EEE1E0
INSERT t2 SELECT * FROM t1;
SELECT HEX(a) FROM t2;
HEX(a)
D0BFD180D0BED0B1D0B0
DROP TABLE t1, t2;
CREATE TABLE t1 (description text character set cp1250 NOT NULL);
INSERT INTO t1 (description) VALUES (_latin2'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde');
SELECT description FROM t1;
description
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssssssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddde
DROP TABLE t1;
CREATE TABLE t1 (a TEXT CHARACTER SET cp1251) SELECT _koi8r'ÐÒÏÂÁ' AS a;
CREATE TABLE t2 (a TEXT CHARACTER SET utf8);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` text character set cp1251
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT HEX(a) FROM t1;
HEX(a)
EFF0EEE1E0
INSERT t2 SELECT * FROM t1;
SELECT HEX(a) FROM t2;
HEX(a)
D0BFD180D0BED0B1D0B0
DROP TABLE t1, t2;
CREATE TABLE `ÔÁÂÌÉÃÁ`
(
ÐÏÌÅ CHAR(32) CHARACTER SET koi8r NOT NULL COMMENT "ËÏÍÍÅÎÔÁÒÉÊ ÐÏÌÑ"
) COMMENT "ËÏÍÍÅÎÔÁÒÉÊ ÔÁÂÌÉÃÙ";
SHOW TABLES;
Tables_in_test
ÔÁÂÌÉÃÁ
SHOW CREATE TABLE ÔÁÂÌÉÃÁ;
Table Create Table
ÔÁÂÌÉÃÁ CREATE TABLE `ÔÁÂÌÉÃÁ` (
`ÐÏÌÅ` char(32) character set koi8r NOT NULL default '' COMMENT 'ËÏÍÍÅÎÔÁÒÉÊ ÐÏÌÑ'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='ËÏÍÍÅÎÔÁÒÉÊ ÔÁÂÌÉÃÙ'
SHOW FIELDS FROM ÔÁÂÌÉÃÁ;
Field Type Null Key Default Extra
ÐÏÌÅ char(32)
SET CHARACTER SET cp1251;
SHOW TABLES;
Tables_in_test
òàáëèöà
SHOW CREATE TABLE òàáëèöà;
Table Create Table
òàáëèöà CREATE TABLE `òàáëèöà` (
`ïîëå` char(32) character set koi8r NOT NULL default '' COMMENT 'êîììåíòàðèé ïîëÿ'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='êîììåíòàðèé òàáëèöû'
SHOW FIELDS FROM òàáëèöà;
Field Type Null Key Default Extra
ïîëå char(32)
SET CHARACTER SET utf8;
SHOW TABLES;
Tables_in_test
ÑаблиÑа
SHOW CREATE TABLE ÑаблиÑа;
Table Create Table
ÑаблиÑа CREATE TABLE `ÑаблиÑа` (
`поле` char(32) character set koi8r NOT NULL default '' COMMENT 'комменÑаÑий полÑ<EFBFBD>'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='комментарий таблицы'
SHOW FIELDS FROM ÑаблиÑа;
Field Type Null Key Default Extra
поле char(32)
SET CHARACTER SET koi8r;
DROP TABLE ÔÁÂÌÉÃÁ;
SET CHARACTER SET default;
SET NAMES UTF8;
CREATE TABLE t1 (t text) DEFAULT CHARSET UTF8;
INSERT INTO t1 (t) VALUES ('x');
SELECT 1 FROM t1 WHERE CONCAT(_latin1'x') = t;
1
1
DROP TABLE t1;
SET CHARACTER SET koi8r;
CREATE DATABASE ÔÅÓÔ;
USE ÔÅÓÔ;
SHOW TABLES;
Tables_in_ÑеÑ<EFBFBD>Ñ
SHOW TABLES IN ÔÅÓÔ;
Tables_in_ÑеÑ<EFBFBD>Ñ
SET CHARACTER SET cp1251;
SHOW TABLES;
Tables_in_ÑеÑ<EFBFBD>Ñ
SHOW TABLES IN òåñò;
Tables_in_ÑеÑ<EFBFBD>Ñ
SET CHARACTER SET koi8r;
DROP DATABASE ÔÅÓÔ;
SET NAMES koi8r;
SELECT hex('ÔÅÓÔ');
hex(еÑ<C2B5>Ñ')
D4C5D3D4
SET character_set_connection=cp1251;
SELECT hex('ÔÅÓÔ');
hex(еÑ<C2B5>Ñ')
F2E5F1F2
USE test;
SET NAMES binary;
CREATE TABLE `ÑеÑ<EFBFBD>Ñ` (`ÑеÑ<EFBFBD>Ñ` int);
SHOW CREATE TABLE `ÑеÑ<EFBFBD>Ñ`;
Table Create Table
ÑеÑ<EFBFBD>Ñ CREATE TABLE `ÑеÑ<EFBFBD>Ñ` (
`ÑеÑ<EFBFBD>Ñ` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SET NAMES utf8;
SHOW CREATE TABLE `ÑеÑ<EFBFBD>Ñ`;
Table Create Table
ÑеÑ<EFBFBD>Ñ CREATE TABLE `ÑеÑ<EFBFBD>Ñ` (
`ÑеÑ<EFBFBD>Ñ` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE `ÑеÑ<EFBFBD>Ñ`;
SET NAMES binary;
SET character_set_connection=utf8;
SELECT еÑ<C2B5>Ñ' as s;
s
ÑеÑ<EFBFBD>Ñ
SET NAMES utf8;
SET character_set_connection=binary;
SELECT еÑ<C2B5>Ñ' as s;
s
ÑеÑ<EFBFBD>Ñ
SET NAMES latin1;
CREATE TABLE t1 (`ä` CHAR(128) DEFAULT 'ä', `ä1` ENUM('ä1','ä2') DEFAULT 'ä2');
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`ä` char(128) default 'ä',
`ä1` enum('ä1','ä2') default 'ä2'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW COLUMNS FROM t1;
Field Type Null Key Default Extra
ä char(128) YES ä
ä1 enum('ä1','ä2') YES ä2
SET NAMES binary;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`ä` char(128) default 'ä',
`ä1` enum('ä1','ä2') default 'ä2'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW COLUMNS FROM t1;
Field Type Null Key Default Extra
ä char(128) YES ä
ä1 enum('ä1','ä2') YES ä2
DROP TABLE t1;
SET NAMES binary;
CREATE TABLE `goodÐÌÏÈÏ` (a int);
ERROR HY000: Invalid utf8 character string: 'ÐÌÏÈÏ'
SET NAMES utf8;
CREATE TABLE `goodÐÌÏÈÏ` (a int);
ERROR HY000: Invalid utf8 character string: 'ÐÌÏÈÏ` (a int)'
set names latin1;
create table t1 (a char(10) character set koi8r, b text character set koi8r);
insert into t1 values ('test','test');
insert into t1 values ('ÊÃÕË','ÊÃÕË');
Warnings:
Warning 1265 Data truncated for column 'a' at row 1
Warning 1265 Data truncated for column 'b' at row 1
drop table t1;
set names koi8r;
create table t1 (a char(10) character set cp1251);
insert into t1 values (_koi8r'×ÁÓÑ');
select * from t1 where a=_koi8r'×ÁÓÑ';
a
×ÁÓÑ
select * from t1 where a=concat(_koi8r'×ÁÓÑ');
ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '='
select * from t1 where a=_latin1'×ÁÓÑ';
ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '='
drop table t1;
set names latin1;
set names koi8r;
create table t1 (c1 char(10) character set cp1251);
insert into t1 values ('ß');
select c1 from t1 where c1 between 'ß' and 'ß';
c1
ß
select ifnull(c1,'ß'), ifnull(null,c1) from t1;
ifnull(c1,'ÑŠ') ifnull(null,c1)
ß ß
select if(1,c1,'ö'), if(0,c1,'ö') from t1;
if(1,c1,'Ж') if(0,c1,'Ж')
ß ö
select coalesce('ö',c1), coalesce(null,c1) from t1;
coalesce('Ж',c1) coalesce(null,c1)
ö ß
select least(c1,'ö'), greatest(c1,'ö') from t1;
least(c1,'Ж') greatest(c1,'Ж')
ö ß
select locate(c1,'ß'), locate('ß',c1) from t1;
locate(c1,'ÑŠ') locate('ÑŠ',c1)
1 1
select field(c1,'ß'),field('ß',c1) from t1;
field(c1,'ÑŠ') field('ÑŠ',c1)
1 1
select concat(c1,'ö'), concat('ö',c1) from t1;
concat(c1,'Ж') concat('Ж',c1)
ßö öß
select concat_ws(c1,'ö','ß'), concat_ws('ö',c1,'ß') from t1;
concat_ws(c1,'Ж','ъ') concat_ws('Ж',c1,'ъ')
ößß ßöß
select replace(c1,'ß','ö'), replace('ß',c1,'ö') from t1;
replace(c1,'ъ','Ж') replace('ъ',c1,'Ж')
ö ö
select substring_index(c1,'öößß',2) from t1;
substring_index(c1,'ЖЖъъ',2)
ß
select elt(1,c1,'ö'),elt(1,'ö',c1) from t1;
elt(1,c1,'Ж') elt(1,'Ж',c1)
ß ö
select make_set(3,c1,'ö'), make_set(3,'ö',c1) from t1;
make_set(3,c1,'Ж') make_set(3,'Ж',c1)
ß,ö ö,ß
select insert(c1,1,2,'ö'),insert('ö',1,2,c1) from t1;
insert(c1,1,2,'Ж') insert('Ж',1,2,c1)
ö ß
select trim(c1 from 'ß'),trim('ß' from c1) from t1;
trim(c1 from 'ÑŠ') trim('ÑŠ' from c1)
select lpad(c1,3,'ö'), lpad('ö',3,c1) from t1;
lpad(c1,3,'Ж') lpad('Ж',3,c1)
ööß ßßö
select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1;
rpad(c1,3,'Ж') rpad('Ж',3,c1)
ßöö ößß

View file

@ -581,3 +581,14 @@ x,y 0078002C0079
z 007A z 007A
x,y,z,ä,ö,ü 0078002C0079002C007A002C00E4002C00F6002C00FC x,y,z,ä,ö,ü 0078002C0079002C007A002C00E4002C00F6002C00FC
drop table t1; drop table t1;
create table t1(a enum('a','b','c')) default character set ucs2;
insert into t1 values('a'),('b'),('c');
alter table t1 add b char(1);
show warnings;
Level Code Message
select * from t1 order by a;
a b
a NULL
b NULL
c NULL
drop table t1;

View file

@ -296,6 +296,9 @@ Tuesday 52 2001 %W %V %X 00:00:00
15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00
15-01-20 %d-%m-%y 00:00:00 15-01-20 %d-%m-%y 00:00:00
15-2001-1 %d-%Y-%c 00:00:00 15-2001-1 %d-%Y-%c 00:00:00
select concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d'));
concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d'))
2003-01-02 08:11:02.123456
truncate table t1; truncate table t1;
insert into t1 values insert into t1 values
('2003-01-02 10:11:12 PM', '%Y-%m-%d %H:%i:%S %p'), ('2003-01-02 10:11:12 PM', '%Y-%m-%d %H:%i:%S %p'),

View file

@ -32,3 +32,39 @@ select * from t1 where concat(A,C,B,D) = 'AAAA2003-03-011051';
a b c d a b c d
AAAA 105 2003-03-01 1 AAAA 105 2003-03-01 1
drop table t1; drop table t1;
select 'a' union select concat('a', -4);
a
a
a-4
select 'a' union select concat('a', -4.5);
a
a
a-4.5
select 'a' union select concat('a', -(4 + 1));
a
a
a-5
select 'a' union select concat('a', 4 - 5);
a
a
a-1
select 'a' union select concat('a', -'3');
a
a
a-3
select 'a' union select concat('a', -concat('3',4));
a
a
a-34
select 'a' union select concat('a', -0);
a
a
a0
select 'a' union select concat('a', -0.0);
a
a
a-0.0
select 'a' union select concat('a', -0.0000);
a
a
a-0.0000

View file

@ -124,3 +124,5 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1003 select degrees(pi()) AS `degrees(pi())`,radians(360) AS `radians(360)` Note 1003 select degrees(pi()) AS `degrees(pi())`,radians(360) AS `radians(360)`
select rand(rand);
ERROR 42S22: Unknown column 'rand' in 'field list'

View file

@ -1,185 +0,0 @@
drop table if exists t1,t2;
select 0=0,1>0,1>=1,1<0,1<=0,1!=0,strcmp("abc","abcd"),strcmp("b","a"),strcmp("a","a") ;
0=0 1>0 1>=1 1<0 1<=0 1!=0 strcmp("abc","abcd") strcmp("b","a") strcmp("a","a")
1 1 1 0 0 1 -1 1 0
select "a"<"b","a"<="b","b">="a","b">"a","a"="A","a"<>"b";
"a"<"b" "a"<="b" "b">="a" "b">"a" "a"="A" "a"<>"b"
1 1 1 1 1 1
select "a "="A", "A "="a", "a " <= "A b";
"a "="A" "A "="a" "a " <= "A b"
1 1 1
select "abc" like "a%", "abc" not like "%d%", "a%" like "a\%","abc%" like "a%\%","abcd" like "a%b_%d", "a" like "%%a","abcde" like "a%_e","abc" like "abc%";
"abc" like "a%" "abc" not like "%d%" "a%" like "a\%" "abc%" like "a%\%" "abcd" like "a%b_%d" "a" like "%%a" "abcde" like "a%_e" "abc" like "abc%"
1 1 1 1 1 1 1 1
select "a" like "%%b","a" like "%%ab","ab" like "a\%", "ab" like "_", "ab" like "ab_", "abc" like "%_d", "abc" like "abc%d";
"a" like "%%b" "a" like "%%ab" "ab" like "a\%" "ab" like "_" "ab" like "ab_" "abc" like "%_d" "abc" like "abc%d"
0 0 0 0 0 0 0
select '?' like '|%', '?' like '|%' ESCAPE '|', '%' like '|%', '%' like '|%' ESCAPE '|', '%' like '%';
'?' like '|%' '?' like '|%' ESCAPE '|' '%' like '|%' '%' like '|%' ESCAPE '|' '%' like '%'
0 0 0 1 1
select 'abc' like '%c','abcabc' like '%c', "ab" like "", "ab" like "a", "ab" like "ab";
'abc' like '%c' 'abcabc' like '%c' "ab" like "" "ab" like "a" "ab" like "ab"
1 1 0 0 1
select "Det här är svenska" regexp "h[[:alpha:]]+r", "aba" regexp "^(a|b)*$";
"Det här är svenska" regexp "h[[:alpha:]]+r" "aba" regexp "^(a|b)*$"
1 1
select "aba" regexp concat("^","a");
"aba" regexp concat("^","a")
1
select !0,NOT 0=1,!(0=0),1 AND 1,1 && 0,0 OR 1,1 || NULL, 1=1 or 1=1 and 1=0;
!0 NOT 0=1 !(0=0) 1 AND 1 1 && 0 0 OR 1 1 || NULL 1=1 or 1=1 and 1=0
1 1 0 1 0 1 1 1
select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between "max" and "my" and 3=3;
2 between 1 and 3 "monty" between "max" and "my" 2=2 and "monty" between "max" and "my" and 3=3
1 1 1
select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
'b' between 'a' and 'c' 'B' between 'a' and 'c'
1 1
select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
2 in (3,2,5,9,5,1) "monty" in ("david","monty","allan") 1.2 in (1.4,1.2,1.0)
1 1 1
select -1.49 or -1.49,0.6 or 0.6;
-1.49 or -1.49 0.6 or 0.6
1 1
select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
3 ^ 11 1 ^ 1 1 ^ 0 1 ^ NULL NULL ^ 1
8 0 1 NULL NULL
explain extended select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select (3 ^ 11) AS `3 ^ 11`,(1 ^ 1) AS `1 ^ 1`,(1 ^ 0) AS `1 ^ 0`,(1 ^ NULL) AS `1 ^ NULL`,(NULL ^ 1) AS `NULL ^ 1`
select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
1 XOR 1 1 XOR 0 0 XOR 1 0 XOR 0 NULL XOR 1 1 XOR NULL 0 XOR NULL
0 1 1 0 NULL NULL NULL
select 1 like 2 xor 2 like 1;
1 like 2 xor 2 like 1
0
select 10 % 7, 10 mod 7, 10 div 3;
10 % 7 10 mod 7 10 div 3
3 3 3
explain extended select 10 % 7, 10 mod 7, 10 div 3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select (10 % 7) AS `10 % 7`,(10 % 7) AS `10 mod 7`,(10 DIV 3) AS `10 div 3`
select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2;
(1 << 64)-1 ((1 << 64)-1) DIV 1 ((1 << 64)-1) DIV 2
18446744073709551615 18446744073709551615 9223372036854775807
explain extended select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select ((1 << 64) - 1) AS `(1 << 64)-1`,(((1 << 64) - 1) DIV 1) AS `((1 << 64)-1) DIV 1`,(((1 << 64) - 1) DIV 2) AS `((1 << 64)-1) DIV 2`
create table t1 (a int);
insert t1 values (1);
select * from t1 where 1 xor 1;
a
explain extended select * from t1 where 1 xor 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select test.t1.a AS `a` from test.t1 where (1 xor 1)
select - a from t1;
- a
-1
explain extended select - a from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
Warnings:
Note 1003 select -(test.t1.a) AS `- a` from test.t1
drop table t1;
select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1
0 1
select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1;
1 and 2 between 2 and 10 2 between 2 and 10 and 1
1 1
select 1 and 0 or 2, 2 or 1 and 0;
1 and 0 or 2 2 or 1 and 0
1 1
select _koi8r'a' = _koi8r'A';
_koi8r'a' = _koi8r'A'
1
select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci;
_koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci
1
explain extended select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select (_koi8r'a' = (_koi8r'A' collate _latin1'koi8r_general_ci')) AS `_koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci`
select _koi8r'a' = _koi8r'A' COLLATE koi8r_bin;
_koi8r'a' = _koi8r'A' COLLATE koi8r_bin
0
select _koi8r'a' COLLATE koi8r_general_ci = _koi8r'A';
_koi8r'a' COLLATE koi8r_general_ci = _koi8r'A'
1
select _koi8r'a' COLLATE koi8r_bin = _koi8r'A';
_koi8r'a' COLLATE koi8r_bin = _koi8r'A'
0
select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci;
ERROR HY000: Illegal mix of collations (koi8r_bin,EXPLICIT) and (koi8r_general_ci,EXPLICIT) for operation '='
select _koi8r'a' = _latin1'A';
ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '='
select strcmp(_koi8r'a', _koi8r'A');
strcmp(_koi8r'a', _koi8r'A')
0
select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci);
strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci)
0
select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin);
strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin)
1
select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A');
strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A')
0
select strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A');
strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A')
1
select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin);
ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'strcmp'
select strcmp(_koi8r'a', _latin1'A');
ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'strcmp'
select _koi8r'a' LIKE _koi8r'A';
_koi8r'a' LIKE _koi8r'A'
1
select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci;
_koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci
1
select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin;
_koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin
0
select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A';
_koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A'
1
select _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A';
_koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A'
0
select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin;
ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'like'
select _koi8r'a' LIKE _latin1'A';
ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'like'
CREATE TABLE t1 ( faq_group_id int(11) NOT NULL default '0', faq_id int(11) NOT NULL default '0', title varchar(240) default NULL, keywords text, description longblob, solution longblob, status tinyint(4) NOT NULL default '0', access_id smallint(6) default NULL, lang_id smallint(6) NOT NULL default '0', created datetime NOT NULL default '0000-00-00 00:00:00', updated datetime default NULL, last_access datetime default NULL, last_notify datetime default NULL, solved_count int(11) NOT NULL default '0', static_solved int(11) default NULL, solved_1 int(11) default NULL, solved_2 int(11) default NULL, solved_3 int(11) default NULL, solved_4 int(11) default NULL, solved_5 int(11) default NULL, expires datetime default NULL, notes text, assigned_to smallint(6) default NULL, assigned_group smallint(6) default NULL, last_edited_by smallint(6) default NULL, orig_ref_no varchar(15) binary default NULL, c$fundstate smallint(6) default NULL, c$contributor smallint(6) default NULL, UNIQUE KEY t1$faq_id (faq_id), KEY t1$group_id$faq_id (faq_group_id,faq_id), KEY t1$c$fundstate (c$fundstate) ) ENGINE=MyISAM;
INSERT INTO t1 VALUES (82,82,'How to use the DynaVox Usage Counts Feature','usages count, number, corner, white, box, button','<as-html>\r\n<table width=\"100%\" border=\"0\">\r\n <tr>\r\n <td width=\"3%\"> </td>\r\n <td width=\"97%\">\r\n <h3><font face=\"Verdana, Arial, Helvetica, sans-serif\" color=\"#000000\">How \r\n To</font><!-- #BeginEditable \"CS_troubleshoot_question\" --><font face=\"Verdana, Arial, Helvetica, sans-serif\" color=\"#000099\"><font color=\"#000000\">: \r\n Display or Hide the Usage Counts to find out how many times each button is being selected. </font></font><!-- #EndEditable --></h3>\r\n </td>\r\n </tr>\r\n</table>','<as-html>\r\n <table width=\"100%\" border=\"0\">\r\n <tr>\r\n <td width=\"3%\"> </td>\r\n \r\n<td width=\"97%\"><!-- #BeginEditable \"CS_troubleshoot_answer\" --> \r\n \r\n<p><font color=\"#000000\" face=\"Verdana, Arial, Helvetica, sans-serif\">1. Select \r\n the <i>On/Setup</i> button to access the DynaVox Setup Menu.<br>\r\n 2. Select <b>Button Features.</b><br>\r\n 3. Below the <b>OK</b> button is the <b>Usage Counts</b> button.<br>\r\n a. If it says \"Hidden\" then the Usage Counts will not be displayed.<br>\r\n b. If it says \"Displayed\" then the Usage Counts will be shown.<br>\r\n c. Select the <b>Usage Counts</b> Option Ring once and it will toggle \r\n to the alternative option.<br>\r\n 4. Once the correct setting has been chosen, select <b>OK</b> to leave the <i>Button \r\n Features</i> menu.<br>\r\n 5. Select <b>OK</b> out of the <i>Setup</i> menu and return to the communication \r\n page.</font></p>\r\n <p><font color=\"#000000\" face=\"Verdana, Arial, Helvetica, sans-serif\">For \r\n further information on <i>Usage Counts,</i> see the <i>Button Features \r\n Menu Entry</i> in the DynaVox/DynaMyte Reference Manual.</font></p>\r\n<!-- #EndEditable --></td>\r\n </tr>\r\n</table>',4,1,1,'2001-11-16 16:43:34','2002-11-25 12:09:43','2003-07-24 01:04:48',NULL,11,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,11,NULL,NULL,NULL);
CREATE TABLE t2 ( access_id smallint(6) NOT NULL default '0', name varchar(20) binary default NULL, rank smallint(6) NOT NULL default '0', KEY t2$access_id (access_id) ) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1,'Everyone',2),(2,'Help',3),(3,'Customer Support',1);
SELECT f_acc.rank, a1.rank, a2.rank FROM t1 LEFT JOIN t1 f1 ON (f1.access_id=1 AND f1.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a1 ON (a1.access_id = f1.access_id) LEFT JOIN t1 f2 ON (f2.access_id=3 AND f2.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a2 ON (a2.access_id = f2.access_id), t2 f_acc WHERE LEAST(a1.rank,a2.rank) = f_acc.rank;
rank rank rank
2 2 NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (d varchar(6), k int);
INSERT INTO t1 VALUES (NULL, 2);
SELECT GREATEST(d,d) FROM t1 WHERE k=2;
GREATEST(d,d)
NULL
DROP TABLE t1;
select 1197.90 mod 50;
1197.90 mod 50
47.90
select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
5.1 mod 3 5.1 mod -3 -5.1 mod 3 -5.1 mod -3
2.1 2.1 -2.1 -2.1
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
5 mod 3 5 mod -3 -5 mod 3 -5 mod -3
2 2 -2 -2

View file

@ -651,3 +651,28 @@ ERROR HY000: You can't specify target table 't1' for update in FROM clause
create table t3 engine=merge union=(t1, t2) select * from t2; create table t3 engine=merge union=(t1, t2) select * from t2;
ERROR HY000: You can't specify target table 't2' for update in FROM clause ERROR HY000: You can't specify target table 't2' for update in FROM clause
drop table t1, t2; drop table t1, t2;
create table t1 (a int,b int,c int, index (a,b,c));
create table t2 (a int,b int,c int, index (a,b,c));
create table t3 (a int,b int,c int, index (a,b,c))
engine=merge union=(t1 ,t2);
insert into t1 (a,b,c) values (1,1,0),(1,2,0);
insert into t2 (a,b,c) values (1,1,1),(1,2,1);
explain select a,b,c from t3 force index (a) where a=1 order by a,b,c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 ref a a 5 const 2 Using where; Using index
select a,b,c from t3 force index (a) where a=1 order by a,b,c;
a b c
1 1 0
1 1 1
1 2 0
1 2 1
explain select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 ref a a 5 const 2 Using where; Using index
select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc;
a b c
1 2 1
1 2 0
1 1 1
1 1 0
drop table t1, t2, t3;

View file

@ -3,7 +3,7 @@ select 1, 1.0, -1, "hello", NULL;
Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr
def 1 8 1 1 N 32769 0 8 def 1 8 1 1 N 32769 0 8
def 1.0 5 3 3 N 32769 1 8 def 1.0 5 3 3 N 32769 1 8
def -1 8 1 2 N 32769 0 8 def -1 8 2 2 N 32769 0 8
def hello 254 5 5 N 1 31 8 def hello 254 5 5 N 1 31 8
def NULL 6 0 0 Y 32896 0 63 def NULL 6 0 0 Y 32896 0 63
1 1.0 -1 hello NULL 1 1.0 -1 hello NULL

View file

@ -374,3 +374,109 @@ USE `mysqldump_test_db`;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
drop database mysqldump_test_db; drop database mysqldump_test_db;
CREATE TABLE t1 (a CHAR(10));
INSERT INTO t1 VALUES (_latin1 'ÄÖÜß');
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` char(10) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
INSERT INTO `t1` VALUES ('ÄÖÜß');
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` char(10) default NULL
) TYPE=MyISAM;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
INSERT INTO `t1` VALUES ('ÄÖÜß');
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` char(10) default NULL
) TYPE=MyISAM;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
INSERT INTO `t1` VALUES ('Ž™šá');
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` char(10) default NULL
) TYPE=MyISAM;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
INSERT INTO `t1` VALUES ('Ž™šá');
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO,MYSQL323" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` char(10) default NULL
) TYPE=MyISAM;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
INSERT INTO `t1` VALUES ('ÄÖÜß');
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
DROP TABLE t1;

View file

@ -467,3 +467,21 @@ a b
1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 2 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
drop table t1; drop table t1;
create table t1 (
id int(11) unsigned primary key NOT NULL auto_increment,
msg text NOT NULL
) engine=ndbcluster default charset=utf8;
insert into t1 (msg) values(
'Tries to validate (8 byte length + inline bytes) as UTF8 :(
Fast fix: removed validation for Text. It is not yet indexable
so bad data will not crash kernel.
Proper fix: Set inline bytes to multiple of mbmaxlen and
validate it (after the 8 byte length).');
select * from t1;
id msg
1 Tries to validate (8 byte length + inline bytes) as UTF8 :(
Fast fix: removed validation for Text. It is not yet indexable
so bad data will not crash kernel.
Proper fix: Set inline bytes to multiple of mbmaxlen and
validate it (after the 8 byte length).
drop table t1;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -808,7 +808,7 @@ SET NAMES koi8r;
CREATE TABLE t1 (a char(1) character set koi8r); CREATE TABLE t1 (a char(1) character set koi8r);
INSERT INTO t1 VALUES (_koi8r'á'),(_koi8r'Á'); INSERT INTO t1 VALUES (_koi8r'á'),(_koi8r'Á');
SELECT a,'Â','â'='Â' FROM t1; SELECT a,'Â','â'='Â' FROM t1;
a б 'Б'='б' a В 'в'='В'
á Â 1 á Â 1
Á Â 1 Á Â 1
show status like "Qcache_hits"; show status like "Qcache_hits";
@ -819,7 +819,7 @@ Variable_name Value
Qcache_queries_in_cache 1 Qcache_queries_in_cache 1
set collation_connection=koi8r_bin; set collation_connection=koi8r_bin;
SELECT a,'Â','â'='Â' FROM t1; SELECT a,'Â','â'='Â' FROM t1;
a б 'Б'='б' a В 'в'='В'
á Â 0 á Â 0
Á Â 0 Á Â 0
show status like "Qcache_hits"; show status like "Qcache_hits";
@ -830,7 +830,7 @@ Variable_name Value
Qcache_queries_in_cache 2 Qcache_queries_in_cache 2
set character_set_client=cp1251; set character_set_client=cp1251;
SELECT a,'Â','â'='Â' FROM t1; SELECT a,'Â','â'='Â' FROM t1;
a В 'в'='В' a ч 'Ч'='
á ÷ 0 á ÷ 0
Á ÷ 0 Á ÷ 0
show status like "Qcache_hits"; show status like "Qcache_hits";
@ -841,7 +841,7 @@ Variable_name Value
Qcache_queries_in_cache 3 Qcache_queries_in_cache 3
set character_set_results=cp1251; set character_set_results=cp1251;
SELECT a,'Â','â'='Â' FROM t1; SELECT a,'Â','â'='Â' FROM t1;
a В 'в'='В' a В 'в'='В'
À Â 0 À Â 0
à Â 0 à Â 0
show status like "Qcache_hits"; show status like "Qcache_hits";

View file

@ -374,3 +374,13 @@ insert into t1 values ('x,y');
insert into t1 values ('x,y,z,Ä,Ö,Ü'); insert into t1 values ('x,y,z,Ä,Ö,Ü');
select a, hex(a) from t1 order by a; select a, hex(a) from t1 order by a;
drop table t1; drop table t1;
#
# Bug#7302 UCS2 data in ENUM fields get truncated when new column is added
#
create table t1(a enum('a','b','c')) default character set ucs2;
insert into t1 values('a'),('b'),('c');
alter table t1 add b char(1);
show warnings;
select * from t1 order by a;
drop table t1;

View file

@ -166,6 +166,8 @@ select date,format,cast(str_to_date(date, format) as datetime) as datetime from
select date,format,DATE(str_to_date(date, format)) as date2 from t1; select date,format,DATE(str_to_date(date, format)) as date2 from t1;
select date,format,TIME(str_to_date(date, format)) as time from t1; select date,format,TIME(str_to_date(date, format)) as time from t1;
select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1; select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1;
# Test small bug in %f handling
select concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d'));
# Test wrong dates or converion specifiers # Test wrong dates or converion specifiers

View file

@ -34,3 +34,19 @@ create table t1 (a char(4), b double, c date, d tinyint(4));
insert into t1 values ('AAAA', 105, '2003-03-01', 1); insert into t1 values ('AAAA', 105, '2003-03-01', 1);
select * from t1 where concat(A,C,B,D) = 'AAAA2003-03-011051'; select * from t1 where concat(A,C,B,D) = 'AAAA2003-03-011051';
drop table t1; drop table t1;
# BUG#6825
select 'a' union select concat('a', -4);
select 'a' union select concat('a', -4.5);
select 'a' union select concat('a', -(4 + 1));
select 'a' union select concat('a', 4 - 5);
select 'a' union select concat('a', -'3');
select 'a' union select concat('a', -concat('3',4));
select 'a' union select concat('a', -0);
select 'a' union select concat('a', -0.0);
select 'a' union select concat('a', -0.0000);

View file

@ -51,3 +51,10 @@ SELECT ASIN(1.2-0.2);
#select floor(log(16)/log(2)); #select floor(log(16)/log(2));
explain extended select degrees(pi()),radians(360); explain extended select degrees(pi()),radians(360);
#
# Bug #7281: problem with rand()
#
--error 1054
select rand(rand);

View file

@ -285,3 +285,21 @@ create table t3 engine=merge union=(t1, t2) select * from t1;
--error 1093 --error 1093
create table t3 engine=merge union=(t1, t2) select * from t2; create table t3 engine=merge union=(t1, t2) select * from t2;
drop table t1, t2; drop table t1, t2;
# BUG#6699 : no sorting on 'ref' retrieval
create table t1 (a int,b int,c int, index (a,b,c));
create table t2 (a int,b int,c int, index (a,b,c));
create table t3 (a int,b int,c int, index (a,b,c))
engine=merge union=(t1 ,t2);
insert into t1 (a,b,c) values (1,1,0),(1,2,0);
insert into t2 (a,b,c) values (1,1,1),(1,2,1);
explain select a,b,c from t3 force index (a) where a=1 order by a,b,c;
select a,b,c from t3 force index (a) where a=1 order by a,b,c;
# this actually wasn't affected:
explain select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc;
select a,b,c from t3 force index (a) where a=1 order by a desc, b desc, c desc;
drop table t1, t2, t3;

View file

@ -137,3 +137,19 @@ drop table t1;
create database mysqldump_test_db character set latin2 collate latin2_bin; create database mysqldump_test_db character set latin2 collate latin2_bin;
--exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db; --exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db;
drop database mysqldump_test_db; drop database mysqldump_test_db;
#
# Bug #7020
# Check that we don't dump in UTF8 in compatible mode by default,
# but use the default compiled values, or the values given in
# --default-character-set=xxx. However, we should dump in UTF8
# if it is explicitely set.
CREATE TABLE t1 (a CHAR(10));
INSERT INTO t1 VALUES (_latin1 'ÄÖÜß');
--exec $MYSQL_DUMP --skip-comments test t1
--exec $MYSQL_DUMP --skip-comments --compatible=mysql323 test t1
--exec $MYSQL_DUMP --skip-comments --compatible=mysql323 --default-character-set=cp850 test t1
--exec $MYSQL_DUMP --skip-comments --default-character-set=cp850 --compatible=mysql323 test t1
--exec $MYSQL_DUMP --skip-comments --default-character-set=utf8 --compatible=mysql323 test t1
DROP TABLE t1;

View file

@ -389,3 +389,17 @@ set autocommit=1;
alter table t1 engine=myisam; alter table t1 engine=myisam;
select * from t1 order by a; select * from t1 order by a;
drop table t1; drop table t1;
# -- bug #7340 --
create table t1 (
id int(11) unsigned primary key NOT NULL auto_increment,
msg text NOT NULL
) engine=ndbcluster default charset=utf8;
insert into t1 (msg) values(
'Tries to validate (8 byte length + inline bytes) as UTF8 :(
Fast fix: removed validation for Text. It is not yet indexable
so bad data will not crash kernel.
Proper fix: Set inline bytes to multiple of mbmaxlen and
validate it (after the 8 byte length).');
select * from t1;
drop table t1;

View file

@ -5,7 +5,7 @@ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/include/ndbapi \ -I$(top_srcdir)/ndb/include/ndbapi \
-I$(top_srcdir)/ndb/include/util \ -I$(top_srcdir)/ndb/include/util \

View file

@ -2,6 +2,7 @@
include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/common.mk.am
ndbinclude_HEADERS = \ ndbinclude_HEADERS = \
ndb_init.h \
ndb_types.h \ ndb_types.h \
ndb_version.h ndb_version.h

View file

@ -19,7 +19,6 @@
#include "Logger.hpp" #include "Logger.hpp"
/** /**
* This class is the base class for all log handlers. A log handler is * This class is the base class for all log handlers. A log handler is
* responsible for formatting and writing log messages to a specific output. * responsible for formatting and writing log messages to a specific output.
@ -68,7 +67,8 @@ public:
/** /**
* Append a log message to the output stream/file whatever. * Append a log message to the output stream/file whatever.
* append() will call writeHeader(), writeMessage() and writeFooter() for * append() will call writeHeader(), writeMessage() and writeFooter() for
* a child class and in that order. * a child class and in that order. Append checks for repeated messages.
* append_impl() does not check for repeats.
* *
* @param pCategory the category/name to tag the log entry with. * @param pCategory the category/name to tag the log entry with.
* @param level the log level. * @param level the log level.
@ -76,6 +76,8 @@ public:
*/ */
void append(const char* pCategory, Logger::LoggerLevel level, void append(const char* pCategory, Logger::LoggerLevel level,
const char* pMsg); const char* pMsg);
void append_impl(const char* pCategory, Logger::LoggerLevel level,
const char* pMsg);
/** /**
* Returns a default formatted header. It currently has the * Returns a default formatted header. It currently has the
@ -111,14 +113,6 @@ public:
*/ */
void setDateTimeFormat(const char* pFormat); void setDateTimeFormat(const char* pFormat);
/**
* Returns a string date and time string.
*
* @param pStr a string.
* @return a string with date and time.
*/
char* getTimeAsString(char* pStr) const;
/** /**
* Returns the error code. * Returns the error code.
*/ */
@ -185,6 +179,15 @@ protected:
virtual void writeFooter() = 0; virtual void writeFooter() = 0;
private: private:
/**
* Returns a string date and time string.
* @note does not update time, uses m_now as time
* @param pStr a string.
* @return a string with date and time.
*/
char* getTimeAsString(char* pStr) const;
time_t m_now;
/** Prohibit */ /** Prohibit */
LogHandler(const LogHandler&); LogHandler(const LogHandler&);
LogHandler* operator = (const LogHandler&); LogHandler* operator = (const LogHandler&);
@ -192,6 +195,14 @@ private:
const char* m_pDateTimeFormat; const char* m_pDateTimeFormat;
int m_errorCode; int m_errorCode;
// for handling repeated messages
unsigned m_count_repeated_messages;
unsigned m_max_repeat_frequency;
time_t m_last_log_time;
char m_last_category[MAX_HEADER_LENGTH];
char m_last_message[MAX_LOG_MESSAGE_SIZE];
Logger::LoggerLevel m_last_level;
}; };
#endif #endif

View file

@ -20,6 +20,8 @@
#include <ndb_global.h> #include <ndb_global.h>
#include <BaseString.hpp> #include <BaseString.hpp>
#define MAX_LOG_MESSAGE_SIZE 1024
class LogHandler; class LogHandler;
class LogHandlerList; class LogHandlerList;

View file

@ -1,3 +1,18 @@
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef NDBGLOBAL_H #ifndef NDBGLOBAL_H
#define NDBGLOBAL_H #define NDBGLOBAL_H
@ -96,15 +111,12 @@ extern "C" {
#include <assert.h> #include <assert.h>
/* call in main() - does not return on error */
extern int ndb_init(void);
extern void ndb_end(int);
#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#include "ndb_init.h"
#ifdef SCO #ifdef SCO
#ifndef PATH_MAX #ifndef PATH_MAX

32
ndb/include/ndb_init.h Normal file
View file

@ -0,0 +1,32 @@
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef NDB_INIT_H
#define NDB_INIT_H
#ifdef __cplusplus
extern "C" {
#endif
/* call in main() - does not return on error */
extern int ndb_init(void);
extern void ndb_end(int);
#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();}
#ifdef __cplusplus
}
#endif
#endif

View file

@ -17,6 +17,8 @@
#ifndef NdbApi_H #ifndef NdbApi_H
#define NdbApi_H #define NdbApi_H
#include "ndb_init.h"
#include "ndb_cluster_connection.hpp"
#include "ndbapi_limits.h" #include "ndbapi_limits.h"
#include "Ndb.hpp" #include "Ndb.hpp"
#include "NdbConnection.hpp" #include "NdbConnection.hpp"

View file

@ -182,27 +182,12 @@ public:
/** /**
* Get blob parts table name. Useful only to test programs. * Get blob parts table name. Useful only to test programs.
*/ */
STATIC_CONST( BlobTableNameSize = 40 );
static int getBlobTableName(char* btname, Ndb* anNdb, const char* tableName, const char* columnName); static int getBlobTableName(char* btname, Ndb* anNdb, const char* tableName, const char* columnName);
/** /**
* Return error object. The error may be blob specific (below) or may * Return error object. The error may be blob specific (below) or may
* be copied from a failed implicit operation. * be copied from a failed implicit operation.
*/ */
const NdbError& getNdbError() const; const NdbError& getNdbError() const;
// "Invalid blob attributes or invalid blob parts table"
STATIC_CONST( ErrTable = 4263 );
// "Invalid usage of blob attribute"
STATIC_CONST( ErrUsage = 4264 );
// "Method is not valid in current blob state"
STATIC_CONST( ErrState = 4265 );
// "Invalid blob seek position"
STATIC_CONST( ErrSeek = 4266 );
// "Corrupted blob value"
STATIC_CONST( ErrCorrupt = 4267 );
// "Error in blob head update forced rollback of transaction"
STATIC_CONST( ErrAbort = 4268 );
// "Unknown blob error"
STATIC_CONST( ErrUnknown = 4269 );
/** /**
* Return info about all blobs in this operation. * Return info about all blobs in this operation.
*/ */

View file

@ -19,7 +19,6 @@
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // Not part of public interface #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // Not part of public interface
#include <ndb_types.h> #include <ndb_types.h>
#include <ndb_global.h>
class Ndb; class Ndb;
class NdbConnection; class NdbConnection;
@ -131,7 +130,9 @@ int
NdbReceiver::execTCOPCONF(Uint32 len){ NdbReceiver::execTCOPCONF(Uint32 len){
Uint32 tmp = m_received_result_length; Uint32 tmp = m_received_result_length;
m_expected_result_length = len; m_expected_result_length = len;
#ifdef assert
assert(!(tmp && !len)); assert(!(tmp && !len));
#endif
return ((bool)len ^ (bool)tmp ? 0 : 1); return ((bool)len ^ (bool)tmp ? 0 : 1);
} }

View file

@ -18,28 +18,72 @@
#ifndef CLUSTER_CONNECTION_HPP #ifndef CLUSTER_CONNECTION_HPP
#define CLUSTER_CONNECTION_HPP #define CLUSTER_CONNECTION_HPP
struct Ndb_cluster_connection_node_iter; /**
* @class Ndb_cluster_connection
* @brief Represents a connection to a cluster of storage nodes
*
* Always start your application program by creating a
* Ndb_cluster_connection object. Your application should contain
* only one Ndb_cluster_connection. Your application connects to
* a cluster management server when method connect() is called.
* With the method wait_until_ready() it is possible to wait
* for the connection to one or several storage nodes.
*/
class Ndb_cluster_connection { class Ndb_cluster_connection {
public: public:
/**
* Create a connection to a cluster of storage nodes
*
* @param specify the connectstring for where to find the
* management server
*/
Ndb_cluster_connection(const char * connect_string = 0); Ndb_cluster_connection(const char * connect_string = 0);
~Ndb_cluster_connection(); ~Ndb_cluster_connection();
int connect(int no_retries, int retry_delay_in_seconds, int verbose);
int start_connect_thread(int (*connect_callback)(void)= 0);
// add check coupled to init state of cluster connection /**
// timeout_after_first_alive negative - ok only if all alive * Connect to a cluster management server
// timeout_after_first_alive positive - ok if some alive *
* @param no_retries specifies the number of retries to perform
* if the connect fails, negative number results in infinite
* number of retries
* @param retry_delay_in_seconds specifies how often retries should
* be performed
* @param verbose specifies if the method should print progess
*
* @return 0 if success,
* 1 if retriable error,
* -1 if non-retriable error
*/
int connect(int no_retries=0, int retry_delay_in_seconds=1, int verbose=0);
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
int start_connect_thread(int (*connect_callback)(void)= 0);
#endif
/**
* Wait until one or several storage nodes are connected
*
* @param time_out_for_first_alive number of seconds to wait until
* first alive node is detected
* @param timeout_after_first_alive number of seconds to wait after
* first alive node is detected
*
* @return 0 all nodes alive,
* > 0 at least one node alive,
* < 0 error
*/
int wait_until_ready(int timeout_for_first_alive, int wait_until_ready(int timeout_for_first_alive,
int timeout_after_first_alive); int timeout_after_first_alive);
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
const char *get_connectstring(char *buf, int buf_sz) const; const char *get_connectstring(char *buf, int buf_sz) const;
int get_connected_port() const; int get_connected_port() const;
const char *get_connected_host() const; const char *get_connected_host() const;
void set_optimized_node_selection(int val); void set_optimized_node_selection(int val);
Uint32 no_db_nodes(); unsigned no_db_nodes();
#endif
private: private:
friend class Ndb; friend class Ndb;

View file

@ -68,6 +68,8 @@ struct TCP_TransporterConfiguration {
*/ */
struct SHM_TransporterConfiguration { struct SHM_TransporterConfiguration {
Uint32 port; Uint32 port;
const char *remoteHostName;
const char *localHostName;
NodeId remoteNodeId; NodeId remoteNodeId;
NodeId localNodeId; NodeId localNodeId;
bool checksum; bool checksum;

View file

@ -100,6 +100,11 @@ public:
bool init(NodeId localNodeId); bool init(NodeId localNodeId);
/**
* after a connect from client, perform connection using correct transporter
*/
bool connect_server(NDB_SOCKET_TYPE sockfd);
/** /**
* Remove all transporters * Remove all transporters
*/ */

View file

@ -34,7 +34,7 @@ OPT_NDB_OPTIMIZED_NODE_SELECTION
#define OPT_NDB_CONNECTSTRING 'c' #define OPT_NDB_CONNECTSTRING 'c'
#ifdef NDB_SHM_TRANSPORTER #if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
#define OPT_NDB_SHM_DEFAULT 1 #define OPT_NDB_SHM_DEFAULT 1
#else #else
#define OPT_NDB_SHM_DEFAULT 0 #define OPT_NDB_SHM_DEFAULT 0

View file

@ -25,6 +25,12 @@ LogHandler::LogHandler() :
m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"), m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
m_errorCode(0) m_errorCode(0)
{ {
m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds
m_count_repeated_messages= 0;
m_last_category[0]= 0;
m_last_message[0]= 0;
m_last_log_time= 0;
m_now= 0;
} }
LogHandler::~LogHandler() LogHandler::~LogHandler()
@ -34,9 +40,51 @@ LogHandler::~LogHandler()
void void
LogHandler::append(const char* pCategory, Logger::LoggerLevel level, LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
const char* pMsg) const char* pMsg)
{
time_t now;
now= ::time((time_t*)NULL);
if (level != m_last_level ||
strcmp(pCategory, m_last_category) ||
strcmp(pMsg, m_last_message))
{
if (m_count_repeated_messages > 0) // print that message
append_impl(m_last_category, m_last_level, m_last_message);
m_last_level= level;
strncpy(m_last_category, pCategory, sizeof(m_last_category));
strncpy(m_last_message, pMsg, sizeof(m_last_message));
}
else // repeated message
{
if (now < m_last_log_time+m_max_repeat_frequency)
{
m_count_repeated_messages++;
m_now= now;
return;
}
}
m_now= now;
append_impl(pCategory, level, pMsg);
m_last_log_time= now;
}
void
LogHandler::append_impl(const char* pCategory, Logger::LoggerLevel level,
const char* pMsg)
{ {
writeHeader(pCategory, level); writeHeader(pCategory, level);
writeMessage(pMsg); if (m_count_repeated_messages == 0)
writeMessage(pMsg);
else
{
BaseString str(pMsg);
str.appfmt(" - Repeated %d times", m_count_repeated_messages);
writeMessage(str.c_str());
m_count_repeated_messages= 0;
}
writeFooter(); writeFooter();
} }
@ -76,12 +124,10 @@ char*
LogHandler::getTimeAsString(char* pStr) const LogHandler::getTimeAsString(char* pStr) const
{ {
struct tm* tm_now; struct tm* tm_now;
time_t now;
now = ::time((time_t*)NULL);
#ifdef NDB_WIN32 #ifdef NDB_WIN32
tm_now = localtime(&now); tm_now = localtime(&m_now);
#else #else
tm_now = ::localtime(&now); //uses the "current" timezone tm_now = ::localtime(&m_now); //uses the "current" timezone
#endif #endif
BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH, BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH,

View file

@ -355,7 +355,7 @@ Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const
LogHandler* pHandler = NULL; LogHandler* pHandler = NULL;
while ( (pHandler = m_pHandlerList->next()) != NULL) while ( (pHandler = m_pHandlerList->next()) != NULL)
{ {
char buf[1024]; char buf[MAX_LOG_MESSAGE_SIZE];
BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap); BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap);
pHandler->append(m_pCategory, logLevel, buf); pHandler->append(m_pCategory, logLevel, buf);
} }

View file

@ -383,6 +383,8 @@ IPCConfig::configureTransporters(Uint32 nodeId,
if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break; if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break;
conf.port= server_port; conf.port= server_port;
conf.localHostName = localHostName;
conf.remoteHostName = remoteHostName;
if(!tr.createTransporter(&conf)){ if(!tr.createTransporter(&conf)){
DBUG_PRINT("error", ("Failed to create SHM Transporter from %d to %d", DBUG_PRINT("error", ("Failed to create SHM Transporter from %d to %d",

View file

@ -13,7 +13,7 @@ EXTRA_libtransporter_la_SOURCES = SHM_Transporter.cpp SHM_Transporter.unix.cpp S
libtransporter_la_LIBADD = @ndb_transporter_opt_objs@ libtransporter_la_LIBADD = @ndb_transporter_opt_objs@
libtransporter_la_DEPENDENCIES = @ndb_transporter_opt_objs@ libtransporter_la_DEPENDENCIES = @ndb_transporter_opt_objs@
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter @NDB_SCI_INCLUDES@ INCLUDES_LOC = -I$(top_srcdir)/ndb/include/mgmapi -I$(top_srcdir)/ndb/include/debugger -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter @NDB_SCI_INCLUDES@
include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/common.mk.am
include $(top_srcdir)/ndb/config/type_util.mk.am include $(top_srcdir)/ndb/config/type_util.mk.am

View file

@ -44,7 +44,8 @@ SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg,
bool chksm, bool chksm,
bool signalId, bool signalId,
Uint32 reportFreq) : Uint32 reportFreq) :
Transporter(t_reg, lHostName, rHostName, r_port, _localNodeId, Transporter(t_reg, tt_SCI_TRANSPORTER,
lHostName, rHostName, r_port, _localNodeId,
_remoteNodeId, 0, false, chksm, signalId) _remoteNodeId, 0, false, chksm, signalId)
{ {
DBUG_ENTER("SCI_Transporter::SCI_Transporter"); DBUG_ENTER("SCI_Transporter::SCI_Transporter");

View file

@ -38,7 +38,8 @@ SHM_Transporter::SHM_Transporter(TransporterRegistry &t_reg,
bool signalId, bool signalId,
key_t _shmKey, key_t _shmKey,
Uint32 _shmSize) : Uint32 _shmSize) :
Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId, Transporter(t_reg, tt_SHM_TRANSPORTER,
lHostName, rHostName, r_port, lNodeId, rNodeId,
0, false, checksum, signalId), 0, false, checksum, signalId),
shmKey(_shmKey), shmKey(_shmKey),
shmSize(_shmSize) shmSize(_shmSize)
@ -256,6 +257,9 @@ SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
SocketOutputStream s_output(sockfd); SocketOutputStream s_output(sockfd);
char buf[256]; char buf[256];
#if 1
#endif
// Wait for server to create and attach // Wait for server to create and attach
if (s_input.gets(buf, 256) == 0) { if (s_input.gets(buf, 256) == 0) {
NDB_CLOSE_SOCKET(sockfd); NDB_CLOSE_SOCKET(sockfd);

View file

@ -72,7 +72,8 @@ TCP_Transporter::TCP_Transporter(TransporterRegistry &t_reg,
NodeId rNodeId, NodeId rNodeId,
bool chksm, bool signalId, bool chksm, bool signalId,
Uint32 _reportFreq) : Uint32 _reportFreq) :
Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId, Transporter(t_reg, tt_TCP_TRANSPORTER,
lHostName, rHostName, r_port, lNodeId, rNodeId,
0, false, chksm, signalId), 0, false, chksm, signalId),
m_sendBuffer(sendBufSize) m_sendBuffer(sendBufSize)
{ {

View file

@ -24,7 +24,11 @@
#include <InputStream.hpp> #include <InputStream.hpp>
#include <OutputStream.hpp> #include <OutputStream.hpp>
#include <EventLogger.hpp>
extern EventLogger g_eventLogger;
Transporter::Transporter(TransporterRegistry &t_reg, Transporter::Transporter(TransporterRegistry &t_reg,
TransporterType _type,
const char *lHostName, const char *lHostName,
const char *rHostName, const char *rHostName,
int r_port, int r_port,
@ -35,8 +39,10 @@ Transporter::Transporter(TransporterRegistry &t_reg,
: m_r_port(r_port), remoteNodeId(rNodeId), localNodeId(lNodeId), : m_r_port(r_port), remoteNodeId(rNodeId), localNodeId(lNodeId),
isServer(lNodeId < rNodeId), isServer(lNodeId < rNodeId),
m_packer(_signalId, _checksum), m_packer(_signalId, _checksum),
m_type(_type),
m_transporter_registry(t_reg) m_transporter_registry(t_reg)
{ {
DBUG_ENTER("Transporter::Transporter");
if (rHostName && strlen(rHostName) > 0){ if (rHostName && strlen(rHostName) > 0){
strncpy(remoteHostName, rHostName, sizeof(remoteHostName)); strncpy(remoteHostName, rHostName, sizeof(remoteHostName));
Ndb_getInAddr(&remoteHostAddress, rHostName); Ndb_getInAddr(&remoteHostAddress, rHostName);
@ -55,6 +61,11 @@ Transporter::Transporter(TransporterRegistry &t_reg,
if (strlen(lHostName) > 0) if (strlen(lHostName) > 0)
Ndb_getInAddr(&localHostAddress, lHostName); Ndb_getInAddr(&localHostAddress, lHostName);
DBUG_PRINT("info",("rId=%d lId=%d isServer=%d rHost=%s lHost=%s r_port=%d",
remoteNodeId, localNodeId, isServer,
remoteHostName, localHostName,
r_port));
byteOrder = _byteorder; byteOrder = _byteorder;
compressionUsed = _compression; compressionUsed = _compression;
checksumUsed = _checksum; checksumUsed = _checksum;
@ -67,7 +78,9 @@ Transporter::Transporter(TransporterRegistry &t_reg,
m_socket_client= 0; m_socket_client= 0;
else else
m_socket_client= new SocketClient(remoteHostName, r_port, m_socket_client= new SocketClient(remoteHostName, r_port,
new SocketAuthSimple("ndbd", "ndbd passwd")); new SocketAuthSimple("ndbd",
"ndbd passwd"));
DBUG_VOID_RETURN;
} }
Transporter::~Transporter(){ Transporter::~Transporter(){
@ -77,8 +90,13 @@ Transporter::~Transporter(){
bool bool
Transporter::connect_server(NDB_SOCKET_TYPE sockfd) { Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
// all initial negotiation is done in TransporterRegistry::connect_server
DBUG_ENTER("Transporter::connect_server");
if(m_connected) if(m_connected)
return true; // TODO assert(0); {
DBUG_RETURN(true); // TODO assert(0);
}
bool res = connect_server_impl(sockfd); bool res = connect_server_impl(sockfd);
if(res){ if(res){
@ -86,7 +104,7 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
m_errorCount = 0; m_errorCount = 0;
} }
return res; DBUG_RETURN(res);
} }
bool bool
@ -98,27 +116,60 @@ Transporter::connect_client() {
if (sockfd == NDB_INVALID_SOCKET) if (sockfd == NDB_INVALID_SOCKET)
return false; return false;
DBUG_ENTER("Transporter::connect_client");
// send info about own id // send info about own id
// send info about own transporter type
SocketOutputStream s_output(sockfd); SocketOutputStream s_output(sockfd);
s_output.println("%d", localNodeId); s_output.println("%d %d", localNodeId, m_type);
// get remote id // get remote id
int nodeId; int nodeId, remote_transporter_type= -1;
SocketInputStream s_input(sockfd); SocketInputStream s_input(sockfd);
char buf[256]; char buf[256];
if (s_input.gets(buf, 256) == 0) { if (s_input.gets(buf, 256) == 0) {
NDB_CLOSE_SOCKET(sockfd); NDB_CLOSE_SOCKET(sockfd);
return false; DBUG_RETURN(false);
} }
if (sscanf(buf, "%d", &nodeId) != 1) {
int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
switch (r) {
case 2:
break;
case 1:
// we're running version prior to 4.1.9
// ok, but with no checks on transporter configuration compatability
break;
default:
NDB_CLOSE_SOCKET(sockfd); NDB_CLOSE_SOCKET(sockfd);
return false; DBUG_RETURN(false);
} }
DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
nodeId, remote_transporter_type));
if (remote_transporter_type != -1)
{
if (remote_transporter_type != m_type)
{
DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
m_type, remote_transporter_type));
NDB_CLOSE_SOCKET(sockfd);
g_eventLogger.error("Incompatible configuration: transporter type "
"mismatch with node %d", nodeId);
DBUG_RETURN(false);
}
}
else if (m_type == tt_SHM_TRANSPORTER)
{
g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
}
bool res = connect_client_impl(sockfd); bool res = connect_client_impl(sockfd);
if(res){ if(res){
m_connected = true; m_connected = true;
m_errorCount = 0; m_errorCount = 0;
} }
return res; DBUG_RETURN(res);
} }
void void

View file

@ -71,6 +71,7 @@ public:
protected: protected:
Transporter(TransporterRegistry &, Transporter(TransporterRegistry &,
TransporterType,
const char *lHostName, const char *lHostName,
const char *rHostName, const char *rHostName,
int r_port, int r_port,
@ -127,6 +128,7 @@ protected:
protected: protected:
bool m_connected; // Are we connected bool m_connected; // Are we connected
TransporterType m_type;
TransporterRegistry &m_transporter_registry; TransporterRegistry &m_transporter_registry;
void *get_callback_obj() { return m_transporter_registry.callbackObj; }; void *get_callback_obj() { return m_transporter_registry.callbackObj; };
@ -149,7 +151,7 @@ Transporter::getRemoteNodeId() const {
inline inline
NodeId NodeId
Transporter::getLocalNodeId() const { Transporter::getLocalNodeId() const {
return remoteNodeId; return localNodeId;
} }
inline inline

View file

@ -47,6 +47,9 @@
#include <InputStream.hpp> #include <InputStream.hpp>
#include <OutputStream.hpp> #include <OutputStream.hpp>
#include <EventLogger.hpp>
extern EventLogger g_eventLogger;
int g_shm_pid = 0; int g_shm_pid = 0;
SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
@ -57,49 +60,10 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (!m_transporter_registry->connect_server(sockfd))
{ {
// read node id from client NDB_CLOSE_SOCKET(sockfd);
int nodeId; DBUG_RETURN(0);
SocketInputStream s_input(sockfd);
char buf[256];
if (s_input.gets(buf, 256) == 0) {
NDB_CLOSE_SOCKET(sockfd);
DBUG_PRINT("error", ("Could not get node id from client"));
DBUG_RETURN(0);
}
if (sscanf(buf, "%d", &nodeId) != 1) {
NDB_CLOSE_SOCKET(sockfd);
DBUG_PRINT("error", ("Error in node id from client"));
DBUG_RETURN(0);
}
//check that nodeid is valid and that there is an allocated transporter
if ( nodeId < 0 || nodeId >= (int)m_transporter_registry->maxTransporters) {
NDB_CLOSE_SOCKET(sockfd);
DBUG_PRINT("error", ("Node id out of range from client"));
DBUG_RETURN(0);
}
if (m_transporter_registry->theTransporters[nodeId] == 0) {
NDB_CLOSE_SOCKET(sockfd);
DBUG_PRINT("error", ("No transporter for this node id from client"));
DBUG_RETURN(0);
}
//check that the transporter should be connected
if (m_transporter_registry->performStates[nodeId] != TransporterRegistry::CONNECTING) {
NDB_CLOSE_SOCKET(sockfd);
DBUG_PRINT("error", ("Transporter in wrong state for this node id from client"));
DBUG_RETURN(0);
}
Transporter *t= m_transporter_registry->theTransporters[nodeId];
// send info about own id (just as response to acknowledge connection)
SocketOutputStream s_output(sockfd);
s_output.println("%d", t->getLocalNodeId());
// setup transporter (transporter responsible for closing sockfd)
t->connect_server(sockfd);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
@ -195,6 +159,91 @@ TransporterRegistry::init(NodeId nodeId) {
return true; return true;
} }
bool
TransporterRegistry::connect_server(NDB_SOCKET_TYPE sockfd)
{
DBUG_ENTER("TransporterRegistry::connect_server");
// read node id from client
// read transporter type
int nodeId, remote_transporter_type= -1;
SocketInputStream s_input(sockfd);
char buf[256];
if (s_input.gets(buf, 256) == 0) {
DBUG_PRINT("error", ("Could not get node id from client"));
DBUG_RETURN(false);
}
int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
switch (r) {
case 2:
break;
case 1:
// we're running version prior to 4.1.9
// ok, but with no checks on transporter configuration compatability
break;
default:
DBUG_PRINT("error", ("Error in node id from client"));
DBUG_RETURN(false);
}
DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
nodeId,remote_transporter_type));
//check that nodeid is valid and that there is an allocated transporter
if ( nodeId < 0 || nodeId >= (int)maxTransporters) {
DBUG_PRINT("error", ("Node id out of range from client"));
DBUG_RETURN(false);
}
if (theTransporters[nodeId] == 0) {
DBUG_PRINT("error", ("No transporter for this node id from client"));
DBUG_RETURN(false);
}
//check that the transporter should be connected
if (performStates[nodeId] != TransporterRegistry::CONNECTING) {
DBUG_PRINT("error", ("Transporter in wrong state for this node id from client"));
DBUG_RETURN(false);
}
Transporter *t= theTransporters[nodeId];
// send info about own id (just as response to acknowledge connection)
// send info on own transporter type
SocketOutputStream s_output(sockfd);
s_output.println("%d %d", t->getLocalNodeId(), t->m_type);
if (remote_transporter_type != -1)
{
if (remote_transporter_type != t->m_type)
{
DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
t->m_type, remote_transporter_type));
g_eventLogger.error("Incompatible configuration: Transporter type "
"mismatch with node %d", nodeId);
// wait for socket close for 1 second to let message arrive at client
{
fd_set a_set;
FD_ZERO(&a_set);
FD_SET(sockfd, &a_set);
struct timeval timeout;
timeout.tv_sec = 1; timeout.tv_usec = 0;
select(sockfd+1, &a_set, 0, 0, &timeout);
}
DBUG_RETURN(false);
}
}
else if (t->m_type == tt_SHM_TRANSPORTER)
{
g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
}
// setup transporter (transporter responsible for closing sockfd)
t->connect_server(sockfd);
DBUG_RETURN(true);
}
bool bool
TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) { TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) {
#ifdef NDB_TCP_TRANSPORTER #ifdef NDB_TCP_TRANSPORTER
@ -358,8 +407,8 @@ TransporterRegistry::createTransporter(SHM_TransporterConfiguration *config) {
return false; return false;
SHM_Transporter * t = new SHM_Transporter(*this, SHM_Transporter * t = new SHM_Transporter(*this,
"localhost", config->localHostName,
"localhost", config->remoteHostName,
config->port, config->port,
localNodeId, localNodeId,
config->remoteNodeId, config->remoteNodeId,

View file

@ -58,7 +58,7 @@ int main(int argc, char** argv)
// Print to stdout/console // Print to stdout/console
g_eventLogger.createConsoleHandler(); g_eventLogger.createConsoleHandler();
g_eventLogger.setCategory("NDB"); g_eventLogger.setCategory("NDB");
g_eventLogger.enable(Logger::LL_INFO, Logger::LL_ALERT); // Log INFO to ALERT g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
globalEmulatorData.create(); globalEmulatorData.create();

View file

@ -133,8 +133,7 @@ MgmtSrvr::signalRecvThreadRun()
} }
} }
extern EventLogger g_eventLogger;
EventLogger g_EventLogger;
static NdbOut& static NdbOut&
operator<<(NdbOut& out, const LogLevel & ll) operator<<(NdbOut& out, const LogLevel & ll)
@ -200,7 +199,7 @@ MgmtSrvr::logLevelThreadRun()
void void
MgmtSrvr::startEventLog() MgmtSrvr::startEventLog()
{ {
g_EventLogger.setCategory("MgmSrvr"); g_eventLogger.setCategory("MgmSrvr");
ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator
((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE); ((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE);
@ -226,7 +225,7 @@ MgmtSrvr::startEventLog()
logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
clusterLog); clusterLog);
} }
if(!g_EventLogger.addHandler(logdest)) { if(!g_eventLogger.addHandler(logdest)) {
ndbout << "Warning: could not add log destination \"" ndbout << "Warning: could not add log destination \""
<< logdest.c_str() << "\"" << endl; << logdest.c_str() << "\"" << endl;
} }
@ -250,21 +249,21 @@ MgmtSrvr::setEventLogFilter(int severity, int enable)
{ {
Logger::LoggerLevel level = (Logger::LoggerLevel)severity; Logger::LoggerLevel level = (Logger::LoggerLevel)severity;
if (enable > 0) { if (enable > 0) {
g_EventLogger.enable(level); g_eventLogger.enable(level);
} else if (enable == 0) { } else if (enable == 0) {
g_EventLogger.disable(level); g_eventLogger.disable(level);
} else if (g_EventLogger.isEnable(level)) { } else if (g_eventLogger.isEnable(level)) {
g_EventLogger.disable(level); g_eventLogger.disable(level);
} else { } else {
g_EventLogger.enable(level); g_eventLogger.enable(level);
} }
return g_EventLogger.isEnable(level); return g_eventLogger.isEnable(level);
} }
bool bool
MgmtSrvr::isEventLogFilterEnabled(int severity) MgmtSrvr::isEventLogFilterEnabled(int severity)
{ {
return g_EventLogger.isEnable((Logger::LoggerLevel)severity); return g_eventLogger.isEnable((Logger::LoggerLevel)severity);
} }
static ErrorItem errorTable[] = static ErrorItem errorTable[] =
@ -1990,7 +1989,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
} }
default: default:
g_EventLogger.error("Unknown signal received. SignalNumber: " g_eventLogger.error("Unknown signal received. SignalNumber: "
"%i from (%d, %x)", "%i from (%d, %x)",
gsn, gsn,
refToNode(signal->theSendersBlockRef), refToNode(signal->theSendersBlockRef),
@ -2066,7 +2065,7 @@ MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
error: error:
if(errCode != 0){ if(errCode != 0){
g_EventLogger.error("Unexpected signal received. SignalNumber: %i from %d", g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d",
GSN_STOP_REF, nodeId); GSN_STOP_REF, nodeId);
} }
} }
@ -2286,7 +2285,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
m_reserved_nodes.set(id_found); m_reserved_nodes.set(id_found);
char tmp_str[128]; char tmp_str[128];
m_reserved_nodes.getText(tmp_str); m_reserved_nodes.getText(tmp_str);
g_EventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.", g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.",
id_found, get_connect_address(id_found), tmp_str); id_found, get_connect_address(id_found), tmp_str);
DBUG_RETURN(true); DBUG_RETURN(true);
} }
@ -2346,7 +2345,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
*nodeId); *nodeId);
} }
g_EventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. " g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. "
"Returned error string \"%s\"", "Returned error string \"%s\"",
*nodeId, *nodeId,
client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "<none>", client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "<none>",
@ -2369,10 +2368,10 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
} }
} }
if (tmp_connected.length() > 0) if (tmp_connected.length() > 0)
g_EventLogger.info("Mgmt server state: node id's %s connected but not reserved", g_eventLogger.info("Mgmt server state: node id's %s connected but not reserved",
tmp_connected.c_str()); tmp_connected.c_str());
if (tmp_not_connected.length() > 0) if (tmp_not_connected.length() > 0)
g_EventLogger.info("Mgmt server state: node id's %s not connected but reserved", g_eventLogger.info("Mgmt server state: node id's %s not connected but reserved",
tmp_not_connected.c_str()); tmp_not_connected.c_str());
} }
DBUG_RETURN(false); DBUG_RETURN(false);
@ -2404,7 +2403,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
EventReport::EventType type = eventReport->getEventType(); EventReport::EventType type = eventReport->getEventType();
// Log event // Log event
g_EventLogger.log(type, theData, nodeId, g_eventLogger.log(type, theData, nodeId,
&m_event_listner[0].m_logLevel); &m_event_listner[0].m_logLevel);
m_event_listner.log(type, theData, nodeId); m_event_listner.log(type, theData, nodeId);
} }
@ -2647,7 +2646,7 @@ MgmtSrvr::Allocated_resources::~Allocated_resources()
char tmp_str[128]; char tmp_str[128];
m_mgmsrv.m_reserved_nodes.getText(tmp_str); m_mgmsrv.m_reserved_nodes.getText(tmp_str);
g_EventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.", g_eventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.",
get_nodeid(), tmp_str); get_nodeid(), tmp_str);
} }
} }

View file

@ -86,7 +86,7 @@ static MgmGlobals glob;
* Global variables * Global variables
*/ */
bool g_StopServer; bool g_StopServer;
extern EventLogger g_EventLogger; extern EventLogger g_eventLogger;
extern int global_mgmt_server_check; extern int global_mgmt_server_check;
@ -161,9 +161,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'V': case 'V':
print_version(); print_version();
exit(0); exit(0);
#if NDB_VERSION_MAJOR <= 4
case 'c': case 'c':
printf("Warning: -c will be removed in 5.0, use -f instead\n"); printf("Warning: -c will be removed in 5.0, use -f instead\n");
break; break;
#endif
case OPT_NDB_SHM: case OPT_NDB_SHM:
#ifndef NDB_SHM_TRANSPORTER #ifndef NDB_SHM_TRANSPORTER
printf("Warning: binary not compiled with shared memory support,\n" printf("Warning: binary not compiled with shared memory support,\n"
@ -301,12 +303,12 @@ int main(int argc, char** argv)
BaseString::snprintf(msg, sizeof(msg), BaseString::snprintf(msg, sizeof(msg),
"NDB Cluster Management Server. %s", NDB_VERSION_STRING); "NDB Cluster Management Server. %s", NDB_VERSION_STRING);
ndbout_c(msg); ndbout_c(msg);
g_EventLogger.info(msg); g_eventLogger.info(msg);
BaseString::snprintf(msg, 256, "Id: %d, Command port: %d", BaseString::snprintf(msg, 256, "Id: %d, Command port: %d",
glob.localNodeId, glob.port); glob.localNodeId, glob.port);
ndbout_c(msg); ndbout_c(msg);
g_EventLogger.info(msg); g_eventLogger.info(msg);
g_StopServer = false; g_StopServer = false;
glob.socketServer->startServer(); glob.socketServer->startServer();
@ -322,10 +324,10 @@ int main(int argc, char** argv)
NdbSleep_MilliSleep(500); NdbSleep_MilliSleep(500);
} }
g_EventLogger.info("Shutting down server..."); g_eventLogger.info("Shutting down server...");
glob.socketServer->stopServer(); glob.socketServer->stopServer();
glob.socketServer->stopSessions(); glob.socketServer->stopSessions();
g_EventLogger.info("Shutdown complete"); g_eventLogger.info("Shutdown complete");
return 0; return 0;
error_end: error_end:
return 1; return 1;

View file

@ -282,7 +282,7 @@ Ndb::waitUntilReady(int timeout)
} }
if (theImpl->m_ndb_cluster_connection.wait_until_ready if (theImpl->m_ndb_cluster_connection.wait_until_ready
(timeout-secondsCounter,30)) (timeout-secondsCounter,30) < 0)
{ {
theError.code = 4009; theError.code = 4009;
DBUG_RETURN(-1); DBUG_RETURN(-1);

View file

@ -21,6 +21,7 @@
#include <NdbIndexOperation.hpp> #include <NdbIndexOperation.hpp>
#include <NdbRecAttr.hpp> #include <NdbRecAttr.hpp>
#include <NdbBlob.hpp> #include <NdbBlob.hpp>
#include "NdbBlobImpl.hpp"
#include <NdbScanOperation.hpp> #include <NdbScanOperation.hpp>
#ifdef NDB_BLOB_DEBUG #ifdef NDB_BLOB_DEBUG
@ -85,14 +86,14 @@ void
NdbBlob::getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c) NdbBlob::getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c)
{ {
assert(t != 0 && c != 0 && c->getBlobType()); assert(t != 0 && c != 0 && c->getBlobType());
memset(btname, 0, BlobTableNameSize); memset(btname, 0, NdbBlobImpl::BlobTableNameSize);
sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_tableId, (int)c->m_attrId); sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_tableId, (int)c->m_attrId);
} }
void void
NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c) NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c)
{ {
char btname[BlobTableNameSize]; char btname[NdbBlobImpl::BlobTableNameSize];
getBlobTableName(btname, t, c); getBlobTableName(btname, t, c);
bt.setName(btname); bt.setName(btname);
bt.setLogging(t->getLogging()); bt.setLogging(t->getLogging());
@ -450,15 +451,15 @@ NdbBlob::getValue(void* data, Uint32 bytes)
{ {
DBG("getValue data=" << hex << data << " bytes=" << dec << bytes); DBG("getValue data=" << hex << data << " bytes=" << dec << bytes);
if (theGetFlag || theState != Prepared) { if (theGetFlag || theState != Prepared) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
if (! isReadOp() && ! isScanOp()) { if (! isReadOp() && ! isScanOp()) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
if (data == NULL && bytes != 0) { if (data == NULL && bytes != 0) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
theGetFlag = true; theGetFlag = true;
@ -472,15 +473,15 @@ NdbBlob::setValue(const void* data, Uint32 bytes)
{ {
DBG("setValue data=" << hex << data << " bytes=" << dec << bytes); DBG("setValue data=" << hex << data << " bytes=" << dec << bytes);
if (theSetFlag || theState != Prepared) { if (theSetFlag || theState != Prepared) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) { if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
if (data == NULL && bytes != 0) { if (data == NULL && bytes != 0) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
theSetFlag = true; theSetFlag = true;
@ -512,7 +513,7 @@ NdbBlob::setActiveHook(ActiveHook activeHook, void* arg)
{ {
DBG("setActiveHook hook=" << hex << (void*)activeHook << " arg=" << hex << arg); DBG("setActiveHook hook=" << hex << (void*)activeHook << " arg=" << hex << arg);
if (theState != Prepared) { if (theState != Prepared) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
theActiveHook = activeHook; theActiveHook = activeHook;
@ -531,7 +532,7 @@ NdbBlob::getNull(bool& isNull)
return 0; return 0;
} }
if (theNullFlag == -1) { if (theNullFlag == -1) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
isNull = theNullFlag; isNull = theNullFlag;
@ -546,7 +547,7 @@ NdbBlob::setNull()
if (theState == Prepared) { if (theState == Prepared) {
return setValue(0, 0); return setValue(0, 0);
} }
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
if (theNullFlag) if (theNullFlag)
@ -568,7 +569,7 @@ NdbBlob::getLength(Uint64& len)
return 0; return 0;
} }
if (theNullFlag == -1) { if (theNullFlag == -1) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
len = theLength; len = theLength;
@ -580,7 +581,7 @@ NdbBlob::truncate(Uint64 length)
{ {
DBG("truncate [in] length=" << length); DBG("truncate [in] length=" << length);
if (theNullFlag == -1) { if (theNullFlag == -1) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
if (theLength > length) { if (theLength > length) {
@ -608,7 +609,7 @@ NdbBlob::getPos(Uint64& pos)
{ {
DBG("getPos"); DBG("getPos");
if (theNullFlag == -1) { if (theNullFlag == -1) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
pos = thePos; pos = thePos;
@ -620,11 +621,11 @@ NdbBlob::setPos(Uint64 pos)
{ {
DBG("setPos pos=" << pos); DBG("setPos pos=" << pos);
if (theNullFlag == -1) { if (theNullFlag == -1) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
if (pos > theLength) { if (pos > theLength) {
setErrorCode(ErrSeek); setErrorCode(NdbBlobImpl::ErrSeek);
return -1; return -1;
} }
thePos = pos; thePos = pos;
@ -637,7 +638,7 @@ int
NdbBlob::readData(void* data, Uint32& bytes) NdbBlob::readData(void* data, Uint32& bytes)
{ {
if (theState != Active) { if (theState != Active) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
char* buf = static_cast<char*>(data); char* buf = static_cast<char*>(data);
@ -666,7 +667,7 @@ NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
} }
} }
if (len > 0 && thePartSize == 0) { if (len > 0 && thePartSize == 0) {
setErrorCode(ErrSeek); setErrorCode(NdbBlobImpl::ErrSeek);
return -1; return -1;
} }
if (len > 0) { if (len > 0) {
@ -731,7 +732,7 @@ int
NdbBlob::writeData(const void* data, Uint32 bytes) NdbBlob::writeData(const void* data, Uint32 bytes)
{ {
if (theState != Active) { if (theState != Active) {
setErrorCode(ErrState); setErrorCode(NdbBlobImpl::ErrState);
return -1; return -1;
} }
const char* buf = static_cast<const char*>(data); const char* buf = static_cast<const char*>(data);
@ -764,7 +765,7 @@ NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
} }
} }
if (len > 0 && thePartSize == 0) { if (len > 0 && thePartSize == 0) {
setErrorCode(ErrSeek); setErrorCode(NdbBlobImpl::ErrSeek);
return -1; return -1;
} }
if (len > 0) { if (len > 0) {
@ -1081,7 +1082,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
theFillChar = 0x20; theFillChar = 0x20;
break; break;
default: default:
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
// sizes // sizes
@ -1099,7 +1100,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
(bc = bt->getColumn("DATA")) == NULL || (bc = bt->getColumn("DATA")) == NULL ||
bc->getType() != partType || bc->getType() != partType ||
bc->getLength() != (int)thePartSize) { bc->getLength() != (int)thePartSize) {
setErrorCode(ErrTable); setErrorCode(NdbBlobImpl::ErrTable);
return -1; return -1;
} }
theBlobTable = &NdbTableImpl::getImpl(*bt); theBlobTable = &NdbTableImpl::getImpl(*bt);
@ -1120,7 +1121,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
Uint32* data = (Uint32*)theKeyBuf.data; Uint32* data = (Uint32*)theKeyBuf.data;
unsigned size = theTable->m_sizeOfKeysInWords; unsigned size = theTable->m_sizeOfKeysInWords;
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) { if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
} }
@ -1129,7 +1130,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
Uint32* data = (Uint32*)theAccessKeyBuf.data; Uint32* data = (Uint32*)theAccessKeyBuf.data;
unsigned size = theAccessTable->m_sizeOfKeysInWords; unsigned size = theAccessTable->m_sizeOfKeysInWords;
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) { if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
} }
@ -1158,7 +1159,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
supportedOp = true; supportedOp = true;
} }
if (! supportedOp) { if (! supportedOp) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
setState(Prepared); setState(Prepared);
@ -1204,7 +1205,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
tOp->updateTuple() == -1 || tOp->updateTuple() == -1 ||
setTableKeyValue(tOp) == -1 || setTableKeyValue(tOp) == -1 ||
setHeadInlineValue(tOp) == -1) { setHeadInlineValue(tOp) == -1) {
setErrorCode(ErrAbort); setErrorCode(NdbBlobImpl::ErrAbort);
return -1; return -1;
} }
DBG("add op to update head+inline"); DBG("add op to update head+inline");
@ -1434,7 +1435,7 @@ NdbBlob::postExecute(ExecType anExecType)
tOp->updateTuple() == -1 || tOp->updateTuple() == -1 ||
setTableKeyValue(tOp) == -1 || setTableKeyValue(tOp) == -1 ||
setHeadInlineValue(tOp) == -1) { setHeadInlineValue(tOp) == -1) {
setErrorCode(ErrAbort); setErrorCode(NdbBlobImpl::ErrAbort);
return -1; return -1;
} }
tOp->m_abortOption = AbortOnError; tOp->m_abortOption = AbortOnError;
@ -1464,7 +1465,7 @@ NdbBlob::preCommit()
tOp->updateTuple() == -1 || tOp->updateTuple() == -1 ||
setTableKeyValue(tOp) == -1 || setTableKeyValue(tOp) == -1 ||
setHeadInlineValue(tOp) == -1) { setHeadInlineValue(tOp) == -1) {
setErrorCode(ErrAbort); setErrorCode(NdbBlobImpl::ErrAbort);
return -1; return -1;
} }
tOp->m_abortOption = AbortOnError; tOp->m_abortOption = AbortOnError;
@ -1489,7 +1490,7 @@ NdbBlob::atNextResult()
{ Uint32* data = (Uint32*)theKeyBuf.data; { Uint32* data = (Uint32*)theKeyBuf.data;
unsigned size = theTable->m_sizeOfKeysInWords; unsigned size = theTable->m_sizeOfKeysInWords;
if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) { if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) {
setErrorCode(ErrUsage); setErrorCode(NdbBlobImpl::ErrUsage);
return -1; return -1;
} }
} }
@ -1545,7 +1546,7 @@ NdbBlob::setErrorCode(NdbOperation* anOp, bool invalidFlag)
else if ((code = theNdb->theError.code) != 0) else if ((code = theNdb->theError.code) != 0)
; ;
else else
code = ErrUnknown; code = NdbBlobImpl::ErrUnknown;
setErrorCode(code, invalidFlag); setErrorCode(code, invalidFlag);
} }
@ -1558,7 +1559,7 @@ NdbBlob::setErrorCode(NdbConnection* aCon, bool invalidFlag)
else if ((code = theNdb->theError.code) != 0) else if ((code = theNdb->theError.code) != 0)
; ;
else else
code = ErrUnknown; code = NdbBlobImpl::ErrUnknown;
setErrorCode(code, invalidFlag); setErrorCode(code, invalidFlag);
} }

View file

@ -0,0 +1,39 @@
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef NdbBlobImpl_H
#define NdbBlobImpl_H
class NdbBlobImpl {
public:
STATIC_CONST( BlobTableNameSize = 40 );
// "Invalid blob attributes or invalid blob parts table"
STATIC_CONST( ErrTable = 4263 );
// "Invalid usage of blob attribute"
STATIC_CONST( ErrUsage = 4264 );
// "Method is not valid in current blob state"
STATIC_CONST( ErrState = 4265 );
// "Invalid blob seek position"
STATIC_CONST( ErrSeek = 4266 );
// "Corrupted blob value"
STATIC_CONST( ErrCorrupt = 4267 );
// "Error in blob head update forced rollback of transaction"
STATIC_CONST( ErrAbort = 4268 );
// "Unknown blob error"
STATIC_CONST( ErrUnknown = 4269 );
};
#endif

View file

@ -361,11 +361,10 @@ NdbConnection::execute(ExecType aTypeOfExec,
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1) if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
ret = -1; ret = -1;
#ifndef VM_TRACE #ifdef ndb_api_crash_on_complex_blob_abort
// can happen in complex abort cases
theFirstOpInList = theLastOpInList = NULL;
#else
assert(theFirstOpInList == NULL && theLastOpInList == NULL); assert(theFirstOpInList == NULL && theLastOpInList == NULL);
#else
theFirstOpInList = theLastOpInList = NULL;
#endif #endif
{ {

View file

@ -34,7 +34,8 @@
#include <AttributeList.hpp> #include <AttributeList.hpp>
#include <NdbEventOperation.hpp> #include <NdbEventOperation.hpp>
#include "NdbEventOperationImpl.hpp" #include "NdbEventOperationImpl.hpp"
#include "NdbBlob.hpp" #include <NdbBlob.hpp>
#include "NdbBlobImpl.hpp"
#include <AttributeHeader.hpp> #include <AttributeHeader.hpp>
#include <my_sys.h> #include <my_sys.h>
@ -1385,7 +1386,7 @@ NdbDictionaryImpl::addBlobTables(NdbTableImpl &t)
if (! c.getBlobType() || c.getPartSize() == 0) if (! c.getBlobType() || c.getPartSize() == 0)
continue; continue;
n--; n--;
char btname[NdbBlob::BlobTableNameSize]; char btname[NdbBlobImpl::BlobTableNameSize];
NdbBlob::getBlobTableName(btname, &t, &c); NdbBlob::getBlobTableName(btname, &t, &c);
// Save BLOB table handle // Save BLOB table handle
NdbTableImpl * cachedBlobTable = getTable(btname); NdbTableImpl * cachedBlobTable = getTable(btname);
@ -1793,7 +1794,7 @@ NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
NdbColumnImpl & c = *t.m_columns[i]; NdbColumnImpl & c = *t.m_columns[i];
if (! c.getBlobType() || c.getPartSize() == 0) if (! c.getBlobType() || c.getPartSize() == 0)
continue; continue;
char btname[NdbBlob::BlobTableNameSize]; char btname[NdbBlobImpl::BlobTableNameSize];
NdbBlob::getBlobTableName(btname, &t, &c); NdbBlob::getBlobTableName(btname, &t, &c);
if (dropTable(btname) != 0) { if (dropTable(btname) != 0) {
if (m_error.code != 709){ if (m_error.code != 709){

View file

@ -528,7 +528,9 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo,
CHARSET_INFO* cs = tAttrInfo->m_cs; CHARSET_INFO* cs = tAttrInfo->m_cs;
// invalid data can crash kernel // invalid data can crash kernel
if (cs != NULL && if (cs != NULL &&
(*cs->cset->well_formed_len)(cs, // fast fix bug#7340
tAttrInfo->m_type != NdbDictionary::Column::Text &&
(*cs->cset->well_formed_len)(cs,
aValue, aValue,
aValue + sizeInBytes, aValue + sizeInBytes,
sizeInBytes) != sizeInBytes) { sizeInBytes) != sizeInBytes) {

View file

@ -15,21 +15,11 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/************************************************************************************************ #include <ndb_global.h>
Name: NdbOperationInt.C #include <NdbOperation.hpp>
Include:
Link:
Author: UABRONM Mikael Ronström UAB/M/MT
Date: 991029
Version: 0.1
Description: Interpreted operations in NDB API
Documentation:
Adjust: 991029 UABRONM First version.
************************************************************************************************/
#include "NdbOperation.hpp"
#include "NdbApiSignal.hpp" #include "NdbApiSignal.hpp"
#include "NdbConnection.hpp" #include <NdbConnection.hpp>
#include "Ndb.hpp" #include <Ndb.hpp>
#include "NdbRecAttr.hpp" #include "NdbRecAttr.hpp"
#include "NdbUtil.hpp" #include "NdbUtil.hpp"
#include "Interpreter.hpp" #include "Interpreter.hpp"

View file

@ -204,14 +204,6 @@ Ndb::~Ndb()
TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId); TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId);
} }
if (global_ndb_cluster_connection != 0) {
theNoOfNdbObjects--;
if(theNoOfNdbObjects == 0){
delete global_ndb_cluster_connection;
global_ndb_cluster_connection= 0;
}
}//if
// if (theSchemaConToNdbList != NULL) // if (theSchemaConToNdbList != NULL)
// closeSchemaTransaction(theSchemaConToNdbList); // closeSchemaTransaction(theSchemaConToNdbList);
while ( theConIdleList != NULL ) while ( theConIdleList != NULL )
@ -249,6 +241,19 @@ Ndb::~Ndb()
delete theImpl; delete theImpl;
/**
* This needs to be put after delete theImpl
* as TransporterFacade::instance is delete by global_ndb_cluster_connection
* and used by theImpl
*/
if (global_ndb_cluster_connection != 0) {
theNoOfNdbObjects--;
if(theNoOfNdbObjects == 0){
delete global_ndb_cluster_connection;
global_ndb_cluster_connection= 0;
}
}//if
/** /**
* This sleep is to make sure that the transporter * This sleep is to make sure that the transporter
* send thread will come in and send any * send thread will come in and send any

View file

@ -31,6 +31,9 @@
#include <Vector.hpp> #include <Vector.hpp>
#include <md5_hash.hpp> #include <md5_hash.hpp>
#include <EventLogger.hpp>
EventLogger g_eventLogger;
static int g_run_connect_thread= 0; static int g_run_connect_thread= 0;
#include <NdbMutex.h> #include <NdbMutex.h>
@ -174,7 +177,7 @@ Ndb_cluster_connection_impl::get_next_node(Ndb_cluster_connection_node_iter &ite
return node.id; return node.id;
} }
Uint32 unsigned
Ndb_cluster_connection::no_db_nodes() Ndb_cluster_connection::no_db_nodes()
{ {
return m_impl.m_all_nodes.size(); return m_impl.m_all_nodes.size();
@ -219,16 +222,8 @@ Ndb_cluster_connection::wait_until_ready(int timeout,
else if (foundAliveNode > 0) else if (foundAliveNode > 0)
{ {
noChecksSinceFirstAliveFound++; noChecksSinceFirstAliveFound++;
if (timeout_after_first_alive >= 0) if (noChecksSinceFirstAliveFound > timeout_after_first_alive)
{ DBUG_RETURN(1);
if (noChecksSinceFirstAliveFound > timeout_after_first_alive)
DBUG_RETURN(0);
}
else // timeout_after_first_alive < 0
{
if (noChecksSinceFirstAliveFound > -timeout_after_first_alive)
DBUG_RETURN(-1);
}
} }
else if (secondsCounter >= timeout) else if (secondsCounter >= timeout)
{ // no alive nodes and timed out { // no alive nodes and timed out
@ -256,6 +251,11 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char *
{ {
DBUG_ENTER("Ndb_cluster_connection"); DBUG_ENTER("Ndb_cluster_connection");
DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this)); DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this));
g_eventLogger.createConsoleHandler();
g_eventLogger.setCategory("NdbApi");
g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
m_transporter_facade= m_transporter_facade=
TransporterFacade::theFacadeInstance= new TransporterFacade(); TransporterFacade::theFacadeInstance= new TransporterFacade();

View file

@ -23,13 +23,14 @@
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <NdbTest.hpp> #include <NdbTest.hpp>
#include <NdbTick.h> #include <NdbTick.h>
#include <ndb/src/ndbapi/NdbBlobImpl.hpp>
struct Bcol { struct Bcol {
bool m_nullable; bool m_nullable;
unsigned m_inline; unsigned m_inline;
unsigned m_partsize; unsigned m_partsize;
unsigned m_stripe; unsigned m_stripe;
char m_btname[NdbBlob::BlobTableNameSize]; char m_btname[NdbBlobImpl::BlobTableNameSize];
Bcol(bool a, unsigned b, unsigned c, unsigned d) : Bcol(bool a, unsigned b, unsigned c, unsigned d) :
m_nullable(a), m_nullable(a),
m_inline(b), m_inline(b),
@ -153,6 +154,7 @@ testcase(char x)
(g_opt.m_skip == 0 || strchr(g_opt.m_skip, x) == 0); (g_opt.m_skip == 0 || strchr(g_opt.m_skip, x) == 0);
} }
static Ndb_cluster_connection* g_ncc = 0;
static Ndb* g_ndb = 0; static Ndb* g_ndb = 0;
static NdbDictionary::Dictionary* g_dic = 0; static NdbDictionary::Dictionary* g_dic = 0;
static NdbConnection* g_con = 0; static NdbConnection* g_con = 0;
@ -1258,7 +1260,7 @@ deleteScan(bool idx)
static int static int
testmain() testmain()
{ {
g_ndb = new Ndb("TEST_DB"); g_ndb = new Ndb(g_ncc, "TEST_DB");
CHK(g_ndb->init() == 0); CHK(g_ndb->init() == 0);
CHK(g_ndb->waitUntilReady() == 0); CHK(g_ndb->waitUntilReady() == 0);
g_dic = g_ndb->getDictionary(); g_dic = g_ndb->getDictionary();
@ -1447,7 +1449,7 @@ testperf()
if (! testcase('p')) if (! testcase('p'))
return 0; return 0;
DBG("=== perf test ==="); DBG("=== perf test ===");
g_ndb = new Ndb("TEST_DB"); g_ndb = new Ndb(g_ncc, "TEST_DB");
CHK(g_ndb->init() == 0); CHK(g_ndb->init() == 0);
CHK(g_ndb->waitUntilReady() == 0); CHK(g_ndb->waitUntilReady() == 0);
g_dic = g_ndb->getDictionary(); g_dic = g_ndb->getDictionary();
@ -1859,10 +1861,13 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
strcat(b, "r"); strcat(b, "r");
g_opt.m_skip = strdup(b); g_opt.m_skip = strdup(b);
} }
if (testmain() == -1 || testperf() == -1) { g_ncc = new Ndb_cluster_connection();
if (g_ncc->connect(30) != 0 || testmain() == -1 || testperf() == -1) {
ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl; ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl;
return NDBT_ProgramExit(NDBT_FAILED); return NDBT_ProgramExit(NDBT_FAILED);
} }
delete g_ncc;
g_ncc = 0;
return NDBT_ProgramExit(NDBT_OK); return NDBT_ProgramExit(NDBT_OK);
} }

View file

@ -59,7 +59,7 @@ struct Opt {
unsigned m_subloop; unsigned m_subloop;
const char* m_table; const char* m_table;
unsigned m_threads; unsigned m_threads;
unsigned m_v; int m_v;
Opt() : Opt() :
m_batch(32), m_batch(32),
m_bound("01234"), m_bound("01234"),
@ -672,6 +672,8 @@ tabcount = sizeof(tablist) / sizeof(tablist[0]);
// connections // connections
static Ndb_cluster_connection* g_ncc = 0;
struct Con { struct Con {
Ndb* m_ndb; Ndb* m_ndb;
NdbDictionary::Dictionary* m_dic; NdbDictionary::Dictionary* m_dic;
@ -720,7 +722,7 @@ int
Con::connect() Con::connect()
{ {
assert(m_ndb == 0); assert(m_ndb == 0);
m_ndb = new Ndb("TEST_DB"); m_ndb = new Ndb(g_ncc, "TEST_DB");
CHKCON(m_ndb->init() == 0, *this); CHKCON(m_ndb->init() == 0, *this);
CHKCON(m_ndb->waitUntilReady(30) == 0, *this); CHKCON(m_ndb->waitUntilReady(30) == 0, *this);
m_tx = 0, m_op = 0; m_tx = 0, m_op = 0;
@ -3514,8 +3516,11 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
} }
{ {
Par par(g_opt); Par par(g_opt);
if (runtest(par) < 0) g_ncc = new Ndb_cluster_connection();
if (g_ncc->connect(30) != 0 || runtest(par) < 0)
goto failed; goto failed;
delete g_ncc;
g_ncc = 0;
} }
// always exit with NDBT code // always exit with NDBT code
ok: ok:

View file

@ -275,6 +275,7 @@ parse_args(int argc, const char** argv){
int tmp = Logger::LL_WARNING - g_verbosity; int tmp = Logger::LL_WARNING - g_verbosity;
tmp = (tmp < Logger::LL_DEBUG ? Logger::LL_DEBUG : tmp); tmp = (tmp < Logger::LL_DEBUG ? Logger::LL_DEBUG : tmp);
g_logger.disable(Logger::LL_ALL); g_logger.disable(Logger::LL_ALL);
g_logger.enable(Logger::LL_ON);
g_logger.enable((Logger::LoggerLevel)tmp, Logger::LL_ALERT); g_logger.enable((Logger::LoggerLevel)tmp, Logger::LL_ALERT);
} }

View file

@ -5050,9 +5050,18 @@ ha_innobase::external_lock(
prebuilt->select_lock_type = LOCK_S; prebuilt->select_lock_type = LOCK_S;
} }
/* Starting from 4.1.9, no InnoDB table lock is taken in LOCK
TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
an InnoDB table lock if it is released immediately at the end
of LOCK TABLES, and InnoDB's table locks in that case cause
VERY easily deadlocks. */
if (prebuilt->select_lock_type != LOCK_NONE) { if (prebuilt->select_lock_type != LOCK_NONE) {
if (thd->in_lock_tables && if (thd->in_lock_tables &&
thd->variables.innodb_table_locks) { thd->variables.innodb_table_locks &&
(thd->options & OPTION_NOT_AUTOCOMMIT)) {
ulint error; ulint error;
error = row_lock_table_for_mysql(prebuilt, error = row_lock_table_for_mysql(prebuilt,
NULL, LOCK_TABLE_EXP); NULL, LOCK_TABLE_EXP);

View file

@ -775,9 +775,25 @@ longlong Item_func_neg::val_int()
void Item_func_neg::fix_length_and_dec() void Item_func_neg::fix_length_and_dec()
{ {
enum Item_result arg_result= args[0]->result_type();
enum Item::Type arg_type= args[0]->type();
decimals=args[0]->decimals; decimals=args[0]->decimals;
max_length=args[0]->max_length; max_length=args[0]->max_length;
hybrid_type= REAL_RESULT; hybrid_type= REAL_RESULT;
/*
We need to account for added '-' in the following cases:
A) argument is a real or integer positive constant - in this case
argument's max_length is set to actual number of bytes occupied, and not
maximum number of bytes real or integer may require. Note that all
constants are non negative so we don't need to account for removed '-'.
B) argument returns a string.
*/
if (arg_result == STRING_RESULT ||
(arg_type == REAL_ITEM && ((Item_real*)args[0])->value >= 0) ||
(arg_type == INT_ITEM && ((Item_int*)args[0])->value > 0))
max_length++;
if (args[0]->result_type() == INT_RESULT) if (args[0]->result_type() == INT_RESULT)
{ {
/* /*
@ -1091,7 +1107,8 @@ double Item_func_round::val()
bool Item_func_rand::fix_fields(THD *thd, struct st_table_list *tables, bool Item_func_rand::fix_fields(THD *thd, struct st_table_list *tables,
Item **ref) Item **ref)
{ {
Item_real_func::fix_fields(thd, tables, ref); if (Item_real_func::fix_fields(thd, tables, ref))
return TRUE;
used_tables_cache|= RAND_TABLE_BIT; used_tables_cache|= RAND_TABLE_BIT;
if (arg_count) if (arg_count)
{ // Only use argument once in query { // Only use argument once in query

View file

@ -149,6 +149,9 @@ static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
conversion specifiers that can be used in such sub-patterns is limited. conversion specifiers that can be used in such sub-patterns is limited.
Also most of checks are skipped in this case. Also most of checks are skipped in this case.
If one adds new format specifiers to this function he should also
consider adding them to get_date_time_result_type() function.
RETURN RETURN
0 ok 0 ok
1 error 1 error
@ -2595,25 +2598,31 @@ void Item_func_get_format::print(String *str)
/* /*
check_result_type(s, l) returns DATE/TIME type Get type of datetime value (DATE/TIME/...) which will be produced
according to format string according to format string.
s: DATE/TIME format string SYNOPSIS
l: length of s get_date_time_result_type()
Result: date_time_format_types value: format - format string
DATE_TIME_MICROSECOND, DATE_TIME, length - length of format string
TIME_MICROSECOND, TIME_ONLY
We don't process day format's characters('D', 'd', 'e') NOTE
because day may be a member of all date/time types. We don't process day format's characters('D', 'd', 'e') because day
If only day format's character and no time part present may be a member of all date/time types.
the result type is MYSQL_TYPE_DATE
Format specifiers supported by this function should be in sync with
specifiers supported by extract_date_time() function.
RETURN VALUE
One of date_time_format_types values:
DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY
*/ */
date_time_format_types check_result_type(const char *format, uint length) static date_time_format_types
get_date_time_result_type(const char *format, uint length)
{ {
const char *time_part_frms= "HISThiklrs"; const char *time_part_frms= "HISThiklrs";
const char *date_part_frms= "MUYWabcjmuyw"; const char *date_part_frms= "MVUXYWabcjmvuxyw";
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0; bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
const char *val= format; const char *val= format;
@ -2624,22 +2633,30 @@ date_time_format_types check_result_type(const char *format, uint length)
if (*val == '%' && val+1 != end) if (*val == '%' && val+1 != end)
{ {
val++; val++;
if ((frac_second_used= (*val == 'f')) || if (*val == 'f')
(!time_part_used && strchr(time_part_frms, *val))) frac_second_used= time_part_used= 1;
else if (!time_part_used && strchr(time_part_frms, *val))
time_part_used= 1; time_part_used= 1;
else if (!date_part_used && strchr(date_part_frms, *val)) else if (!date_part_used && strchr(date_part_frms, *val))
date_part_used= 1; date_part_used= 1;
if (time_part_used && date_part_used && frac_second_used) if (date_part_used && frac_second_used)
{
/*
frac_second_used implies time_part_used, and thus we already
have all types of date-time components and can end our search.
*/
return DATE_TIME_MICROSECOND; return DATE_TIME_MICROSECOND;
}
} }
} }
/* We don't have all three types of date-time components */
if (frac_second_used)
return TIME_MICROSECOND;
if (time_part_used) if (time_part_used)
{ {
if (date_part_used) if (date_part_used)
return DATE_TIME; return DATE_TIME;
if (frac_second_used)
return TIME_MICROSECOND;
return TIME_ONLY; return TIME_ONLY;
} }
return DATE_ONLY; return DATE_ONLY;
@ -2670,7 +2687,8 @@ void Item_func_str_to_date::fix_length_and_dec()
if ((const_item= args[1]->const_item())) if ((const_item= args[1]->const_item()))
{ {
format= args[1]->val_str(&format_str); format= args[1]->val_str(&format_str);
cached_format_type= check_result_type(format->ptr(), format->length()); cached_format_type= get_date_time_result_type(format->ptr(),
format->length());
switch (cached_format_type) { switch (cached_format_type) {
case DATE_ONLY: case DATE_ONLY:
cached_timestamp_type= MYSQL_TIMESTAMP_DATE; cached_timestamp_type= MYSQL_TIMESTAMP_DATE;

View file

@ -818,6 +818,7 @@ ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning); char **err_pos, uint *err_len, bool *set_warning);
uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs); uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
void unhex_type2(TYPELIB *lib);
uint check_word(TYPELIB *lib, const char *val, const char *end, uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word); const char **end_of_word);

View file

@ -53,7 +53,7 @@
#endif #endif
#ifdef HAVE_NDBCLUSTER_DB #ifdef HAVE_NDBCLUSTER_DB
#define OPT_NDBCLUSTER_DEFAULT 0 #define OPT_NDBCLUSTER_DEFAULT 0
#ifdef NDB_SHM_TRANSPORTER #if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
#define OPT_NDB_SHM_DEFAULT 1 #define OPT_NDB_SHM_DEFAULT 1
#else #else
#define OPT_NDB_SHM_DEFAULT 0 #define OPT_NDB_SHM_DEFAULT 0

View file

@ -2945,9 +2945,11 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
if (var->value->result_type() == STRING_RESULT) if (var->value->result_type() == STRING_RESULT)
{ {
enum db_type db_type;
if (!(res=var->value->val_str(&str)) || if (!(res=var->value->val_str(&str)) ||
!(var->save_result.ulong_value= !(var->save_result.ulong_value=
(ulong) ha_resolve_by_name(res->ptr(), res->length()))) (ulong) db_type= ha_resolve_by_name(res->ptr(), res->length())) ||
ha_checktype(db_type) != db_type)
{ {
value= res ? res->c_ptr() : "NULL"; value= res ? res->c_ptr() : "NULL";
goto err; goto err;

View file

@ -169,6 +169,43 @@ uint find_type2(TYPELIB *typelib, const char *x, uint length, CHARSET_INFO *cs)
} /* find_type */ } /* find_type */
/*
Un-hex all elements in a typelib
SYNOPSIS
unhex_type2()
interval TYPELIB (struct of pointer to values + lengths + count)
NOTES
RETURN
N/A
*/
void unhex_type2(TYPELIB *interval)
{
for (uint pos= 0; pos < interval->count; pos++)
{
char *from, *to;
for (from= to= (char*) interval->type_names[pos]; *from; )
{
/*
Note, hexchar_to_int(*from++) doesn't work
one some compilers, e.g. IRIX. Looks like a compiler
bug in inline functions in combination with arguments
that have a side effect. So, let's use from[0] and from[1]
and increment 'from' by two later.
*/
*to++= (char) (hexchar_to_int(from[0]) << 4) +
hexchar_to_int(from[1]);
from+= 2;
}
interval->type_lengths[pos] /= 2;
}
}
/* /*
Check if the first word in a string is one of the ones in TYPELIB Check if the first word in a string is one of the ones in TYPELIB

View file

@ -24,7 +24,8 @@
/* Functions defined in this file */ /* Functions defined in this file */
static void frm_error(int error,TABLE *form,const char *name,int errortype); static void frm_error(int error,TABLE *form,const char *name,
int errortype, int errarg);
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
uint types, char **names); uint types, char **names);
static uint find_field(TABLE *form,uint start,uint length); static uint find_field(TABLE *form,uint start,uint length);
@ -57,6 +58,7 @@ static byte* get_field_name(Field **buff,uint *length,
2 Error (see frm_error) 2 Error (see frm_error)
3 Wrong data in .frm file 3 Wrong data in .frm file
4 Error (see frm_error) 4 Error (see frm_error)
5 Error (see frm_error: charset unavailable)
*/ */
int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
@ -64,7 +66,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
{ {
reg1 uint i; reg1 uint i;
reg2 uchar *strpos; reg2 uchar *strpos;
int j,error; int j,error, errarg= 0;
uint rec_buff_length,n_length,int_length,records,key_parts,keys, uint rec_buff_length,n_length,int_length,records,key_parts,keys,
interval_count,interval_parts,read_length,db_create_options; interval_count,interval_parts,read_length,db_create_options;
uint key_info_length, com_length; uint key_info_length, com_length;
@ -436,10 +438,14 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
} }
else else
{ {
if (!strpos[14]) if (!strpos[14])
charset= &my_charset_bin; charset= &my_charset_bin;
else if (!(charset=get_charset((uint) strpos[14], MYF(0)))) else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
charset= outparam->table_charset; {
error= 5; // Unknown or unavailable charset
errarg= (int) strpos[14];
goto err_not_open;
}
} }
if (!comment_length) if (!comment_length)
{ {
@ -490,25 +496,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
{ {
/* Unescape UCS2 intervals from HEX notation */ /* Unescape UCS2 intervals from HEX notation */
TYPELIB *interval= outparam->intervals + interval_nr - 1; TYPELIB *interval= outparam->intervals + interval_nr - 1;
for (uint pos= 0; pos < interval->count; pos++) unhex_type2(interval);
{
char *from, *to;
for (from= to= (char*) interval->type_names[pos]; *from; )
{
/*
Note, hexchar_to_int(*from++) doesn't work
one some compilers, e.g. IRIX. Looks like a compiler
bug in inline functions in combination with arguments
that have a side effect. So, let's use from[0] and from[1]
and increment 'from' by two later.
*/
*to++= (char) (hexchar_to_int(from[0]) << 4) +
hexchar_to_int(from[1]);
from+= 2;
}
interval->type_lengths[pos] /= 2;
}
} }
*field_ptr=reg_field= *field_ptr=reg_field=
@ -799,7 +787,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
err_end: /* Here when no file */ err_end: /* Here when no file */
delete crypted; delete crypted;
*root_ptr= old_root; *root_ptr= old_root;
frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG); frm_error(error, outparam, name, ME_ERROR + ME_WAITTANG, errarg);
delete outparam->file; delete outparam->file;
outparam->file=0; // For easyer errorchecking outparam->file=0; // For easyer errorchecking
outparam->db_stat=0; outparam->db_stat=0;
@ -984,7 +972,8 @@ ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
/* error message when opening a form file */ /* error message when opening a form file */
static void frm_error(int error, TABLE *form, const char *name, myf errortype) static void frm_error(int error, TABLE *form, const char *name,
myf errortype, int errarg)
{ {
int err_no; int err_no;
char buff[FN_REFLEN]; char buff[FN_REFLEN];
@ -1015,6 +1004,20 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype)
fn_format(buff,form->real_name,form_dev,datext,2),my_errno); fn_format(buff,form->real_name,form_dev,datext,2),my_errno);
break; break;
} }
case 5:
{
const char *csname= get_charset_name((uint) errarg);
char tmp[10];
if (!csname || csname[0] =='?')
{
my_snprintf(tmp, sizeof(tmp), "#%d", errarg);
csname= tmp;
}
my_printf_error(ER_UNKNOWN_COLLATION,
"Unknown collation '%s' in table '%-.64s' definition",
MYF(0), csname, form->real_name);
break;
}
default: /* Better wrong error than none */ default: /* Better wrong error than none */
case 4: case 4:
my_error(ER_NOT_FORM_FILE,errortype, my_error(ER_NOT_FORM_FILE,errortype,

View file

@ -174,6 +174,17 @@ bool mysql_create_frm(THD *thd, my_string file_name,
goto err2; goto err2;
if (my_close(file,MYF(MY_WME))) if (my_close(file,MYF(MY_WME)))
goto err3; goto err3;
{
/* Unescape all UCS2 intervals: were escaped in pack_headers */
List_iterator<create_field> it(create_fields);
create_field *field;
while ((field=it++))
{
if (field->interval && field->charset->mbminlen > 1)
unhex_type2(field->interval);
}
}
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:

View file

@ -683,9 +683,7 @@ static void verify_prepare_field(MYSQL_RES *result,
as utf8. Field length is calculated as number of characters * maximum as utf8. Field length is calculated as number of characters * maximum
number of bytes a character can occupy. number of bytes a character can occupy.
*/ */
#ifndef EMBEDDED_LIBRARY
DIE_UNLESS(field->length == length * cs->mbmaxlen); DIE_UNLESS(field->length == length * cs->mbmaxlen);
#endif
if (def) if (def)
DIE_UNLESS(strcmp(field->def, def) == 0); DIE_UNLESS(strcmp(field->def, def) == 0);
} }