Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.0-ndb
into mysql.com:/home/jonas/src/mysql-5.0-ndb
This commit is contained in:
commit
79192c2335
@ -79,7 +79,8 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
|
|||||||
if (!memcmp(p->arKey, arKey, nKeyLength)) {
|
if (!memcmp(p->arKey, arKey, nKeyLength)) {
|
||||||
entry *n;
|
entry *n;
|
||||||
|
|
||||||
n = (entry *) alloc_root(&ht->mem_root,sizeof(entry));
|
if (!(n = (entry *) alloc_root(&ht->mem_root,sizeof(entry))))
|
||||||
|
return FAILURE;
|
||||||
n->pNext = p->pData;
|
n->pNext = p->pData;
|
||||||
n->str = str;
|
n->str = str;
|
||||||
p->pData = n;
|
p->pData = n;
|
||||||
|
@ -1502,7 +1502,10 @@ You can turn off this feature to get a quicker startup with -A\n\n");
|
|||||||
if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
|
if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
|
||||||
sizeof(char *) *
|
sizeof(char *) *
|
||||||
(num_fields*2+1))))
|
(num_fields*2+1))))
|
||||||
|
{
|
||||||
|
mysql_free_result(fields);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
field_names[i][num_fields*2]= '\0';
|
field_names[i][num_fields*2]= '\0';
|
||||||
j=0;
|
j=0;
|
||||||
while ((sql_field=mysql_fetch_field(fields)))
|
while ((sql_field=mysql_fetch_field(fields)))
|
||||||
@ -2077,10 +2080,10 @@ print_table_data_html(MYSQL_RES *result)
|
|||||||
}
|
}
|
||||||
while ((cur = mysql_fetch_row(result)))
|
while ((cur = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
|
ulong *lengths=mysql_fetch_lengths(result);
|
||||||
(void) tee_fputs("<TR>", PAGER);
|
(void) tee_fputs("<TR>", PAGER);
|
||||||
for (uint i=0; i < mysql_num_fields(result); i++)
|
for (uint i=0; i < mysql_num_fields(result); i++)
|
||||||
{
|
{
|
||||||
ulong *lengths=mysql_fetch_lengths(result);
|
|
||||||
(void) tee_fputs("<TD>", PAGER);
|
(void) tee_fputs("<TD>", PAGER);
|
||||||
safe_put_field(cur[i],lengths[i]);
|
safe_put_field(cur[i],lengths[i]);
|
||||||
(void) tee_fputs("</TD>", PAGER);
|
(void) tee_fputs("</TD>", PAGER);
|
||||||
@ -2106,10 +2109,10 @@ print_table_data_xml(MYSQL_RES *result)
|
|||||||
fields = mysql_fetch_fields(result);
|
fields = mysql_fetch_fields(result);
|
||||||
while ((cur = mysql_fetch_row(result)))
|
while ((cur = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
|
ulong *lengths=mysql_fetch_lengths(result);
|
||||||
(void) tee_fputs("\n <row>\n", PAGER);
|
(void) tee_fputs("\n <row>\n", PAGER);
|
||||||
for (uint i=0; i < mysql_num_fields(result); i++)
|
for (uint i=0; i < mysql_num_fields(result); i++)
|
||||||
{
|
{
|
||||||
ulong *lengths=mysql_fetch_lengths(result);
|
|
||||||
tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
|
tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
|
||||||
(fields[i].name[0] ? fields[i].name :
|
(fields[i].name[0] ? fields[i].name :
|
||||||
" ") : "NULL"));
|
" ") : "NULL"));
|
||||||
|
@ -145,7 +145,7 @@ case $FLAG in
|
|||||||
#
|
#
|
||||||
-fh)
|
-fh)
|
||||||
cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
|
cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
|
||||||
sort | tr '[a-z]' '[A-Z]' | $AWK '
|
sort | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | $AWK '
|
||||||
BEGIN {
|
BEGIN {
|
||||||
printf("/* Automatically generated file, do not edit */\n");
|
printf("/* Automatically generated file, do not edit */\n");
|
||||||
printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
|
printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
|
||||||
|
@ -87,7 +87,8 @@ parse_line(EditLine *el, const char *line)
|
|||||||
int argc;
|
int argc;
|
||||||
Tokenizer *tok;
|
Tokenizer *tok;
|
||||||
|
|
||||||
tok = tok_init(NULL);
|
if (!(tok = tok_init(NULL)))
|
||||||
|
return -1;
|
||||||
tok_line(tok, line, &argc, &argv);
|
tok_line(tok, line, &argc, &argv);
|
||||||
argc = el_parse(el, argc, argv);
|
argc = el_parse(el, argc, argv);
|
||||||
tok_end(tok);
|
tok_end(tok);
|
||||||
|
@ -419,3 +419,113 @@ SubscrID SbclID
|
|||||||
3 NULL
|
3 NULL
|
||||||
drop table test1;
|
drop table test1;
|
||||||
drop table test2;
|
drop table test2;
|
||||||
|
create table t1 (
|
||||||
|
pk int primary key,
|
||||||
|
dt datetime not null,
|
||||||
|
da date not null,
|
||||||
|
ye year not null,
|
||||||
|
ti time not null,
|
||||||
|
ts timestamp not null,
|
||||||
|
index(dt),
|
||||||
|
index(da),
|
||||||
|
index(ye),
|
||||||
|
index(ti),
|
||||||
|
index(ts)
|
||||||
|
) engine=ndb;
|
||||||
|
insert into t1 (pk,dt,da,ye,ti) values
|
||||||
|
(1, '1901-05-05 23:00:59', '1901-05-05', '1901', '23:00:59'),
|
||||||
|
(2, '1912-09-05 13:00:59', '1912-09-05', '1912', '13:00:59'),
|
||||||
|
(3, '1945-12-31 00:00:00', '1945-12-31', '1945', '00:00:00'),
|
||||||
|
(4, '1955-12-31 00:00:00', '1955-12-31', '1955', '00:00:00'),
|
||||||
|
(5, '1963-06-06 06:06:06', '1963-06-06', '1963', '06:06:06'),
|
||||||
|
(6, '1993-06-06 06:06:06', '1993-06-06', '1993', '06:06:06'),
|
||||||
|
(7, '2001-01-01 10:11:10', '2001-01-01', '2001', '10:11:10'),
|
||||||
|
(8, '2001-01-01 10:11:11', '2001-01-01', '2001', '10:11:11'),
|
||||||
|
(9, '2005-01-31 23:59:59', '2005-01-31', '2005', '23:59:59');
|
||||||
|
select count(*)-9 from t1 use index (dt) where dt > '1900-01-01 00:00:00';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
select count(*)-6 from t1 use index (dt) where dt >= '1955-12-31 00:00:00';
|
||||||
|
count(*)-6
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (dt) where dt > '1955-12-31 00:00:00';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (dt) where dt < '1970-03-03 22:22:22';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-7 from t1 use index (dt) where dt < '2001-01-01 10:11:11';
|
||||||
|
count(*)-7
|
||||||
|
0
|
||||||
|
select count(*)-8 from t1 use index (dt) where dt <= '2001-01-01 10:11:11';
|
||||||
|
count(*)-8
|
||||||
|
0
|
||||||
|
select count(*)-9 from t1 use index (dt) where dt <= '2055-01-01 00:00:00';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
select count(*)-9 from t1 use index (da) where da > '1900-01-01';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
select count(*)-6 from t1 use index (da) where da >= '1955-12-31';
|
||||||
|
count(*)-6
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (da) where da > '1955-12-31';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (da) where da < '1970-03-03';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-6 from t1 use index (da) where da < '2001-01-01';
|
||||||
|
count(*)-6
|
||||||
|
0
|
||||||
|
select count(*)-8 from t1 use index (da) where da <= '2001-01-02';
|
||||||
|
count(*)-8
|
||||||
|
0
|
||||||
|
select count(*)-9 from t1 use index (da) where da <= '2055-01-01';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
select count(*)-9 from t1 use index (ye) where ye > '1900';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
select count(*)-6 from t1 use index (ye) where ye >= '1955';
|
||||||
|
count(*)-6
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (ye) where ye > '1955';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (ye) where ye < '1970';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-6 from t1 use index (ye) where ye < '2001';
|
||||||
|
count(*)-6
|
||||||
|
0
|
||||||
|
select count(*)-8 from t1 use index (ye) where ye <= '2001';
|
||||||
|
count(*)-8
|
||||||
|
0
|
||||||
|
select count(*)-9 from t1 use index (ye) where ye <= '2055';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
select count(*)-9 from t1 use index (ti) where ti >= '00:00:00';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
select count(*)-7 from t1 use index (ti) where ti > '00:00:00';
|
||||||
|
count(*)-7
|
||||||
|
0
|
||||||
|
select count(*)-7 from t1 use index (ti) where ti > '05:05:05';
|
||||||
|
count(*)-7
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (ti) where ti > '06:06:06';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-5 from t1 use index (ti) where ti < '10:11:11';
|
||||||
|
count(*)-5
|
||||||
|
0
|
||||||
|
select count(*)-6 from t1 use index (ti) where ti <= '10:11:11';
|
||||||
|
count(*)-6
|
||||||
|
0
|
||||||
|
select count(*)-8 from t1 use index (ti) where ti < '23:59:59';
|
||||||
|
count(*)-8
|
||||||
|
0
|
||||||
|
select count(*)-9 from t1 use index (ti) where ti <= '23:59:59';
|
||||||
|
count(*)-9
|
||||||
|
0
|
||||||
|
@ -143,3 +143,39 @@ drop table t1;
|
|||||||
create table t1 (f float(54));
|
create table t1 (f float(54));
|
||||||
ERROR 42000: Incorrect column specifier for column 'f'
|
ERROR 42000: Incorrect column specifier for column 'f'
|
||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
create table t1 (f float(4,3));
|
||||||
|
insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11");
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 1
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 2
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 3
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 4
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 5
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 6
|
||||||
|
select * from t1;
|
||||||
|
f
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
drop table if exists t1;
|
||||||
|
create table t1 (f double(4,3));
|
||||||
|
insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11");
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 1
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 2
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 3
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 4
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 5
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 6
|
||||||
|
select * from t1;
|
||||||
|
f
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
drop table if exists t1;
|
||||||
|
@ -15,8 +15,8 @@ f1 float NULL YES NULL
|
|||||||
f2 double NULL YES NULL
|
f2 double NULL YES NULL
|
||||||
insert into t1 values(10,10),(1e+5,1e+5),(1234567890,1234567890),(1e+10,1e+10),(1e+15,1e+15),(1e+20,1e+20),(1e+50,1e+50),(1e+150,1e+150);
|
insert into t1 values(10,10),(1e+5,1e+5),(1234567890,1234567890),(1e+10,1e+10),(1e+15,1e+15),(1e+20,1e+20),(1e+50,1e+50),(1e+150,1e+150);
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1264 Data truncated; out of range for column 'f1' at row 7
|
Warning 1264 Out of range value adjusted for column 'f1' at row 7
|
||||||
Warning 1264 Data truncated; out of range for column 'f1' at row 8
|
Warning 1264 Out of range value adjusted for column 'f1' at row 8
|
||||||
insert into t1 values(-10,-10),(1e-5,1e-5),(1e-10,1e-10),(1e-15,1e-15),(1e-20,1e-20),(1e-50,1e-50),(1e-150,1e-150);
|
insert into t1 values(-10,-10),(1e-5,1e-5),(1e-10,1e-10),(1e-15,1e-15),(1e-20,1e-20),(1e-50,1e-50),(1e-150,1e-150);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
f1 f2
|
f1 f2
|
||||||
@ -143,3 +143,39 @@ drop table t1;
|
|||||||
create table t1 (f float(54));
|
create table t1 (f float(54));
|
||||||
ERROR 42000: Incorrect column specifier for column 'f'
|
ERROR 42000: Incorrect column specifier for column 'f'
|
||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
create table t1 (f float(4,3));
|
||||||
|
insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11");
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 1
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 2
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 3
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 4
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 5
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 6
|
||||||
|
select * from t1;
|
||||||
|
f
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
drop table if exists t1;
|
||||||
|
create table t1 (f double(4,3));
|
||||||
|
insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11");
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 1
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 2
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 3
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 4
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 5
|
||||||
|
Warning 1264 Out of range value adjusted for column 'f' at row 6
|
||||||
|
select * from t1;
|
||||||
|
f
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
-9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
9.999
|
||||||
|
drop table if exists t1;
|
||||||
|
@ -203,3 +203,67 @@ SELECT s.SubscrID,l.SbclID FROM test1 s left JOIN test2 l ON
|
|||||||
l.SbcrID=s.SubscrID WHERE s.UsrID=224 order by 1, 2;
|
l.SbcrID=s.SubscrID WHERE s.UsrID=224 order by 1, 2;
|
||||||
drop table test1;
|
drop table test1;
|
||||||
drop table test2;
|
drop table test2;
|
||||||
|
|
||||||
|
# bug#7424 + bug#7725
|
||||||
|
|
||||||
|
create table t1 (
|
||||||
|
pk int primary key,
|
||||||
|
dt datetime not null,
|
||||||
|
da date not null,
|
||||||
|
ye year not null,
|
||||||
|
ti time not null,
|
||||||
|
ts timestamp not null,
|
||||||
|
index(dt),
|
||||||
|
index(da),
|
||||||
|
index(ye),
|
||||||
|
index(ti),
|
||||||
|
index(ts)
|
||||||
|
) engine=ndb;
|
||||||
|
|
||||||
|
insert into t1 (pk,dt,da,ye,ti) values
|
||||||
|
(1, '1901-05-05 23:00:59', '1901-05-05', '1901', '23:00:59'),
|
||||||
|
(2, '1912-09-05 13:00:59', '1912-09-05', '1912', '13:00:59'),
|
||||||
|
(3, '1945-12-31 00:00:00', '1945-12-31', '1945', '00:00:00'),
|
||||||
|
(4, '1955-12-31 00:00:00', '1955-12-31', '1955', '00:00:00'),
|
||||||
|
(5, '1963-06-06 06:06:06', '1963-06-06', '1963', '06:06:06'),
|
||||||
|
(6, '1993-06-06 06:06:06', '1993-06-06', '1993', '06:06:06'),
|
||||||
|
(7, '2001-01-01 10:11:10', '2001-01-01', '2001', '10:11:10'),
|
||||||
|
(8, '2001-01-01 10:11:11', '2001-01-01', '2001', '10:11:11'),
|
||||||
|
(9, '2005-01-31 23:59:59', '2005-01-31', '2005', '23:59:59');
|
||||||
|
|
||||||
|
# datetime
|
||||||
|
select count(*)-9 from t1 use index (dt) where dt > '1900-01-01 00:00:00';
|
||||||
|
select count(*)-6 from t1 use index (dt) where dt >= '1955-12-31 00:00:00';
|
||||||
|
select count(*)-5 from t1 use index (dt) where dt > '1955-12-31 00:00:00';
|
||||||
|
select count(*)-5 from t1 use index (dt) where dt < '1970-03-03 22:22:22';
|
||||||
|
select count(*)-7 from t1 use index (dt) where dt < '2001-01-01 10:11:11';
|
||||||
|
select count(*)-8 from t1 use index (dt) where dt <= '2001-01-01 10:11:11';
|
||||||
|
select count(*)-9 from t1 use index (dt) where dt <= '2055-01-01 00:00:00';
|
||||||
|
|
||||||
|
# date
|
||||||
|
select count(*)-9 from t1 use index (da) where da > '1900-01-01';
|
||||||
|
select count(*)-6 from t1 use index (da) where da >= '1955-12-31';
|
||||||
|
select count(*)-5 from t1 use index (da) where da > '1955-12-31';
|
||||||
|
select count(*)-5 from t1 use index (da) where da < '1970-03-03';
|
||||||
|
select count(*)-6 from t1 use index (da) where da < '2001-01-01';
|
||||||
|
select count(*)-8 from t1 use index (da) where da <= '2001-01-02';
|
||||||
|
select count(*)-9 from t1 use index (da) where da <= '2055-01-01';
|
||||||
|
|
||||||
|
# year
|
||||||
|
select count(*)-9 from t1 use index (ye) where ye > '1900';
|
||||||
|
select count(*)-6 from t1 use index (ye) where ye >= '1955';
|
||||||
|
select count(*)-5 from t1 use index (ye) where ye > '1955';
|
||||||
|
select count(*)-5 from t1 use index (ye) where ye < '1970';
|
||||||
|
select count(*)-6 from t1 use index (ye) where ye < '2001';
|
||||||
|
select count(*)-8 from t1 use index (ye) where ye <= '2001';
|
||||||
|
select count(*)-9 from t1 use index (ye) where ye <= '2055';
|
||||||
|
|
||||||
|
# time
|
||||||
|
select count(*)-9 from t1 use index (ti) where ti >= '00:00:00';
|
||||||
|
select count(*)-7 from t1 use index (ti) where ti > '00:00:00';
|
||||||
|
select count(*)-7 from t1 use index (ti) where ti > '05:05:05';
|
||||||
|
select count(*)-5 from t1 use index (ti) where ti > '06:06:06';
|
||||||
|
select count(*)-5 from t1 use index (ti) where ti < '10:11:11';
|
||||||
|
select count(*)-6 from t1 use index (ti) where ti <= '10:11:11';
|
||||||
|
select count(*)-8 from t1 use index (ti) where ti < '23:59:59';
|
||||||
|
select count(*)-9 from t1 use index (ti) where ti <= '23:59:59';
|
||||||
|
@ -93,3 +93,13 @@ create table t1 (f float(54)); # Should give an error
|
|||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
|
# Ensure that maximum values as the result of number of decimals
|
||||||
|
# being specified in table schema are enforced (Bug #7361)
|
||||||
|
create table t1 (f float(4,3));
|
||||||
|
insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11");
|
||||||
|
select * from t1;
|
||||||
|
drop table if exists t1;
|
||||||
|
create table t1 (f double(4,3));
|
||||||
|
insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11");
|
||||||
|
select * from t1;
|
||||||
|
drop table if exists t1;
|
||||||
|
@ -266,12 +266,13 @@ public:
|
|||||||
ExtBinary = NdbSqlUtil::Type::Binary,
|
ExtBinary = NdbSqlUtil::Type::Binary,
|
||||||
ExtVarbinary = NdbSqlUtil::Type::Varbinary,
|
ExtVarbinary = NdbSqlUtil::Type::Varbinary,
|
||||||
ExtDatetime = NdbSqlUtil::Type::Datetime,
|
ExtDatetime = NdbSqlUtil::Type::Datetime,
|
||||||
ExtTimespec = NdbSqlUtil::Type::Timespec,
|
ExtDate = NdbSqlUtil::Type::Date,
|
||||||
ExtBlob = NdbSqlUtil::Type::Blob,
|
ExtBlob = NdbSqlUtil::Type::Blob,
|
||||||
ExtText = NdbSqlUtil::Type::Text,
|
ExtText = NdbSqlUtil::Type::Text,
|
||||||
ExtBit = NdbSqlUtil::Type::Bit,
|
ExtBit = NdbSqlUtil::Type::Bit,
|
||||||
ExtLongvarchar = NdbSqlUtil::Type::Longvarchar,
|
ExtLongvarchar = NdbSqlUtil::Type::Longvarchar,
|
||||||
ExtLongvarbinary = NdbSqlUtil::Type::Longvarbinary
|
ExtLongvarbinary = NdbSqlUtil::Type::Longvarbinary,
|
||||||
|
ExtTime = NdbSqlUtil::Type::Time
|
||||||
};
|
};
|
||||||
|
|
||||||
// Attribute data interpretation
|
// Attribute data interpretation
|
||||||
@ -358,10 +359,10 @@ public:
|
|||||||
AttributeSize = DictTabInfo::an8Bit;
|
AttributeSize = DictTabInfo::an8Bit;
|
||||||
AttributeArraySize = 8 * AttributeExtLength;
|
AttributeArraySize = 8 * AttributeExtLength;
|
||||||
break;
|
break;
|
||||||
case DictTabInfo::ExtTimespec:
|
case DictTabInfo::ExtDate:
|
||||||
// to fix
|
// to fix
|
||||||
AttributeSize = DictTabInfo::an8Bit;
|
AttributeSize = DictTabInfo::an8Bit;
|
||||||
AttributeArraySize = 12 * AttributeExtLength;
|
AttributeArraySize = 3 * AttributeExtLength;
|
||||||
break;
|
break;
|
||||||
case DictTabInfo::ExtBlob:
|
case DictTabInfo::ExtBlob:
|
||||||
case DictTabInfo::ExtText:
|
case DictTabInfo::ExtText:
|
||||||
@ -380,6 +381,10 @@ public:
|
|||||||
AttributeSize = DictTabInfo::an8Bit;
|
AttributeSize = DictTabInfo::an8Bit;
|
||||||
AttributeArraySize = AttributeExtLength + 2;
|
AttributeArraySize = AttributeExtLength + 2;
|
||||||
break;
|
break;
|
||||||
|
case DictTabInfo::ExtTime:
|
||||||
|
AttributeSize = DictTabInfo::an8Bit;
|
||||||
|
AttributeArraySize = 3 * AttributeExtLength;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The NDB Cluster Management API (MGM API) is a C API
|
* The NDB Cluster Management API (MGM API) is a C API
|
||||||
* that is used to:
|
* that is used to:
|
||||||
* - Start and stop database nodes (DB nodes)
|
* - Start and stop database nodes (ndbd processes)
|
||||||
* - Start and stop NDB Cluster backups
|
* - Start and stop NDB Cluster backups
|
||||||
* - Control the NDB Cluster log
|
* - Control the NDB Cluster log
|
||||||
* - Perform other administrative tasks
|
* - Perform other administrative tasks
|
||||||
@ -30,18 +30,23 @@
|
|||||||
* @section General Concepts
|
* @section General Concepts
|
||||||
*
|
*
|
||||||
* Each MGM API function needs a management server handle
|
* Each MGM API function needs a management server handle
|
||||||
* of type Mgm_C_Api::NdbMgmHandle.
|
* of type @ref NdbMgmHandle.
|
||||||
* This handle is initally created by calling the
|
* This handle is initally created by calling the
|
||||||
* function ndb_mgm_create_handle().
|
* function ndb_mgm_create_handle() and freed by calling
|
||||||
|
* ndb_mgm_destroy_handle().
|
||||||
*
|
*
|
||||||
* A function can return:
|
* A function can return:
|
||||||
* -# An integer value.
|
* -# An integer value.
|
||||||
* A value of <b>-1</b> indicates an error.
|
* A value of <b>-1</b> indicates an error.
|
||||||
* -# A pointer value. A <var>NULL</var> value indicates an error;
|
* -# A non-const pointer value. A <var>NULL</var> value indicates an error;
|
||||||
* otherwise, the return value must be freed by the user of the MGM API.
|
* otherwise, the return value must be freed
|
||||||
|
* by the user of the MGM API
|
||||||
|
* -# A const pointer value. A <var>NULL</var> value indicates an error.
|
||||||
|
* Returned value should not be freed.
|
||||||
*
|
*
|
||||||
* Error conditions can be identified by using the appropriate
|
* Error conditions can be identified by using the appropriate
|
||||||
* error-reporting functions.
|
* error-reporting functions ndb_mgm_get_latest_error() and
|
||||||
|
* @ref ndb_mgm_error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @addtogroup MGM_C_API
|
/** @addtogroup MGM_C_API
|
||||||
@ -64,32 +69,54 @@ extern "C" {
|
|||||||
* NDB Cluster node types
|
* NDB Cluster node types
|
||||||
*/
|
*/
|
||||||
enum ndb_mgm_node_type {
|
enum ndb_mgm_node_type {
|
||||||
NDB_MGM_NODE_TYPE_UNKNOWN = -1, /*< Node type not known*/
|
NDB_MGM_NODE_TYPE_UNKNOWN = -1 /** Node type not known*/
|
||||||
NDB_MGM_NODE_TYPE_API = NODE_TYPE_API,/*< An application node (API)*/
|
,NDB_MGM_NODE_TYPE_API /** An application node (API) */
|
||||||
NDB_MGM_NODE_TYPE_NDB = NODE_TYPE_DB, /*< A database node (DB)*/
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
NDB_MGM_NODE_TYPE_MGM = NODE_TYPE_MGM,/*< A mgmt server node (MGM)*/
|
= NODE_TYPE_API
|
||||||
NDB_MGM_NODE_TYPE_REP = NODE_TYPE_REP,/*< A replication node */
|
#endif
|
||||||
|
,NDB_MGM_NODE_TYPE_NDB /** A database node (DB) */
|
||||||
NDB_MGM_NODE_TYPE_MIN = 0, /*< Min valid value*/
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
NDB_MGM_NODE_TYPE_MAX = 3 /*< Max valid value*/
|
= NODE_TYPE_DB
|
||||||
|
#endif
|
||||||
|
,NDB_MGM_NODE_TYPE_MGM /** A mgmt server node (MGM)*/
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
|
= NODE_TYPE_MGM
|
||||||
|
#endif
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
|
,NDB_MGM_NODE_TYPE_REP = NODE_TYPE_REP /** A replication node */
|
||||||
|
,NDB_MGM_NODE_TYPE_MIN = 0 /** Min valid value*/
|
||||||
|
,NDB_MGM_NODE_TYPE_MAX = 3 /** Max valid value*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database node status
|
* Database node status
|
||||||
*/
|
*/
|
||||||
enum ndb_mgm_node_status {
|
enum ndb_mgm_node_status {
|
||||||
NDB_MGM_NODE_STATUS_UNKNOWN = 0, /*< Node status not known*/
|
/** Node status not known*/
|
||||||
NDB_MGM_NODE_STATUS_NO_CONTACT = 1, /*< No contact with node*/
|
NDB_MGM_NODE_STATUS_UNKNOWN = 0,
|
||||||
NDB_MGM_NODE_STATUS_NOT_STARTED = 2, /*< Has not run starting protocol*/
|
/** No contact with node*/
|
||||||
NDB_MGM_NODE_STATUS_STARTING = 3, /*< Is running starting protocol*/
|
NDB_MGM_NODE_STATUS_NO_CONTACT = 1,
|
||||||
NDB_MGM_NODE_STATUS_STARTED = 4, /*< Running*/
|
/** Has not run starting protocol*/
|
||||||
NDB_MGM_NODE_STATUS_SHUTTING_DOWN = 5, /*< Is shutting down*/
|
NDB_MGM_NODE_STATUS_NOT_STARTED = 2,
|
||||||
NDB_MGM_NODE_STATUS_RESTARTING = 6, /*< Is restarting*/
|
/** Is running starting protocol*/
|
||||||
NDB_MGM_NODE_STATUS_SINGLEUSER = 7, /*< Maintenance mode*/
|
NDB_MGM_NODE_STATUS_STARTING = 3,
|
||||||
NDB_MGM_NODE_STATUS_RESUME = 8, /*< Resume mode*/
|
/** Running*/
|
||||||
|
NDB_MGM_NODE_STATUS_STARTED = 4,
|
||||||
NDB_MGM_NODE_STATUS_MIN = 0, /*< Min valid value*/
|
/** Is shutting down*/
|
||||||
NDB_MGM_NODE_STATUS_MAX = 6 /*< Max valid value*/
|
NDB_MGM_NODE_STATUS_SHUTTING_DOWN = 5,
|
||||||
|
/** Is restarting*/
|
||||||
|
NDB_MGM_NODE_STATUS_RESTARTING = 6,
|
||||||
|
/** Maintenance mode*/
|
||||||
|
NDB_MGM_NODE_STATUS_SINGLEUSER = 7,
|
||||||
|
/** Resume mode*/
|
||||||
|
NDB_MGM_NODE_STATUS_RESUME = 8,
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
|
/** Min valid value*/
|
||||||
|
NDB_MGM_NODE_STATUS_MIN = 0,
|
||||||
|
/** Max valid value*/
|
||||||
|
NDB_MGM_NODE_STATUS_MAX = 8
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,14 +155,15 @@ extern "C" {
|
|||||||
NDB_MGM_USAGE_ERROR = 5001
|
NDB_MGM_USAGE_ERROR = 5001
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
struct Ndb_Mgm_Error_Msg {
|
struct Ndb_Mgm_Error_Msg {
|
||||||
enum ndb_mgm_error code;
|
enum ndb_mgm_error code;
|
||||||
const char * msg;
|
const char * msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct Ndb_Mgm_Error_Msg ndb_mgm_error_msgs[] = {
|
const struct Ndb_Mgm_Error_Msg ndb_mgm_error_msgs[] = {
|
||||||
{ NDB_MGM_NO_ERROR, "No error" },
|
{ NDB_MGM_NO_ERROR, "No error" },
|
||||||
|
|
||||||
|
/* Request for service errors */
|
||||||
{ NDB_MGM_ILLEGAL_CONNECT_STRING, "Illegal connect string" },
|
{ NDB_MGM_ILLEGAL_CONNECT_STRING, "Illegal connect string" },
|
||||||
{ NDB_MGM_ILLEGAL_PORT_NUMBER, "Illegal port number" },
|
{ NDB_MGM_ILLEGAL_PORT_NUMBER, "Illegal port number" },
|
||||||
{ NDB_MGM_ILLEGAL_SOCKET, "Illegal socket" },
|
{ NDB_MGM_ILLEGAL_SOCKET, "Illegal socket" },
|
||||||
@ -167,66 +195,86 @@ extern "C" {
|
|||||||
{ NDB_MGM_USAGE_ERROR,
|
{ NDB_MGM_USAGE_ERROR,
|
||||||
"Usage error" }
|
"Usage error" }
|
||||||
};
|
};
|
||||||
|
|
||||||
const int ndb_mgm_noOfErrorMsgs =
|
const int ndb_mgm_noOfErrorMsgs =
|
||||||
sizeof(ndb_mgm_error_msgs)/sizeof(struct Ndb_Mgm_Error_Msg);
|
sizeof(ndb_mgm_error_msgs)/sizeof(struct Ndb_Mgm_Error_Msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure returned by ndb_mgm_get_status
|
* Status of a node in the cluster
|
||||||
|
*
|
||||||
|
* Sub-structure in enum ndb_mgm_cluster_state
|
||||||
|
* returned by ndb_mgm_get_status()
|
||||||
*/
|
*/
|
||||||
struct ndb_mgm_node_state {
|
struct ndb_mgm_node_state {
|
||||||
int node_id; /*< NDB Cluster node id*/
|
/** NDB Cluster node id*/
|
||||||
enum ndb_mgm_node_type node_type; /*< Type of NDB Cluster node*/
|
int node_id;
|
||||||
enum ndb_mgm_node_status node_status; /*< State of node*/
|
/** Type of NDB Cluster node*/
|
||||||
int start_phase; /*< Start phase.
|
enum ndb_mgm_node_type node_type;
|
||||||
*< @note Start phase is only
|
/** State of node*/
|
||||||
*< valid if
|
enum ndb_mgm_node_status node_status;
|
||||||
*< node_type is
|
/** Start phase.
|
||||||
*< NDB_MGM_NODE_TYPE_NDB and
|
*
|
||||||
*< node_status is
|
* @note Start phase is only valid if node_type is
|
||||||
*< NDB_MGM_NODE_STATUS_STARTING
|
* NDB_MGM_NODE_TYPE_NDB and node_status is
|
||||||
|
* NDB_MGM_NODE_STATUS_STARTING
|
||||||
*/
|
*/
|
||||||
int dynamic_id; /*< Id for heartbeats and
|
int start_phase;
|
||||||
*< master take-over
|
/** Id for heartbeats and master take-over (only valid for DB nodes)
|
||||||
*< (only valid for DB nodes)
|
|
||||||
*/
|
*/
|
||||||
int node_group; /*< Node group of node
|
int dynamic_id;
|
||||||
*< (only valid for DB nodes)*/
|
/** Node group of node (only valid for DB nodes)*/
|
||||||
int version; /*< Internal version number*/
|
int node_group;
|
||||||
int connect_count; /*< Number of times node has connected
|
/** Internal version number*/
|
||||||
*< or disconnected to the mgm srv
|
int version;
|
||||||
|
/** Number of times node has connected or disconnected to the
|
||||||
|
* management server
|
||||||
*/
|
*/
|
||||||
char connect_address[sizeof("000.000.000.000")+1];
|
int connect_count;
|
||||||
|
/** Ip adress of node when it connected to the management server.
|
||||||
|
* @note it will be empty if the management server has restarted
|
||||||
|
* after the node connected.
|
||||||
|
*/
|
||||||
|
char connect_address[
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
|
sizeof("000.000.000.000")+1
|
||||||
|
#endif
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cluster status
|
* State of all nodes in the cluster returned from
|
||||||
|
* ndb_mgm_get_status()
|
||||||
*/
|
*/
|
||||||
struct ndb_mgm_cluster_state {
|
struct ndb_mgm_cluster_state {
|
||||||
int no_of_nodes; /*< No of entries in the
|
/** No of entries in the node_states array */
|
||||||
*< node_states array
|
int no_of_nodes;
|
||||||
*/
|
/** An array with node_states*/
|
||||||
struct ndb_mgm_node_state /*< An array with node_states*/
|
struct ndb_mgm_node_state node_states[
|
||||||
node_states[1];
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
const char *hostname;
|
1
|
||||||
|
#endif
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default reply from the server
|
* Default reply from the server (for future use, not used today)
|
||||||
*/
|
*/
|
||||||
struct ndb_mgm_reply {
|
struct ndb_mgm_reply {
|
||||||
int return_code; /*< 0 if successful,
|
/** 0 if successful, otherwise error code. */
|
||||||
*< otherwise error code.
|
int return_code;
|
||||||
*/
|
/** Error or reply message.*/
|
||||||
char message[256]; /*< Error or reply message.*/
|
char message[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
/**
|
/**
|
||||||
* Default information types
|
* Default information types
|
||||||
*/
|
*/
|
||||||
enum ndb_mgm_info {
|
enum ndb_mgm_info {
|
||||||
NDB_MGM_INFO_CLUSTER, /*< ?*/
|
/** ?*/
|
||||||
NDB_MGM_INFO_CLUSTERLOG /*< Cluster log*/
|
NDB_MGM_INFO_CLUSTER,
|
||||||
|
/** Cluster log*/
|
||||||
|
NDB_MGM_INFO_CLUSTERLOG
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -234,11 +282,16 @@ extern "C" {
|
|||||||
* (Used only in the development of NDB Cluster.)
|
* (Used only in the development of NDB Cluster.)
|
||||||
*/
|
*/
|
||||||
enum ndb_mgm_signal_log_mode {
|
enum ndb_mgm_signal_log_mode {
|
||||||
NDB_MGM_SIGNAL_LOG_MODE_IN, /*< Log receiving signals */
|
/** Log receiving signals */
|
||||||
NDB_MGM_SIGNAL_LOG_MODE_OUT, /*< Log sending signals*/
|
NDB_MGM_SIGNAL_LOG_MODE_IN,
|
||||||
NDB_MGM_SIGNAL_LOG_MODE_INOUT, /*< Log both sending/receiving*/
|
/** Log sending signals*/
|
||||||
NDB_MGM_SIGNAL_LOG_MODE_OFF /*< Log off*/
|
NDB_MGM_SIGNAL_LOG_MODE_OUT,
|
||||||
|
/** Log both sending/receiving*/
|
||||||
|
NDB_MGM_SIGNAL_LOG_MODE_INOUT,
|
||||||
|
/** Log off*/
|
||||||
|
NDB_MGM_SIGNAL_LOG_MODE_OFF
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log severities (used to filter the cluster log)
|
* Log severities (used to filter the cluster log)
|
||||||
@ -246,32 +299,31 @@ extern "C" {
|
|||||||
enum ndb_mgm_clusterlog_level {
|
enum ndb_mgm_clusterlog_level {
|
||||||
NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL = -1,
|
NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL = -1,
|
||||||
/* must range from 0 and up, indexes into an array */
|
/* must range from 0 and up, indexes into an array */
|
||||||
NDB_MGM_CLUSTERLOG_ON = 0, /*< Cluster log on*/
|
/** Cluster log on*/
|
||||||
NDB_MGM_CLUSTERLOG_DEBUG = 1, /*< Used in NDB Cluster
|
NDB_MGM_CLUSTERLOG_ON = 0,
|
||||||
*< developement
|
/** Used in NDB Cluster developement */
|
||||||
|
NDB_MGM_CLUSTERLOG_DEBUG = 1,
|
||||||
|
/** Informational messages*/
|
||||||
|
NDB_MGM_CLUSTERLOG_INFO = 2,
|
||||||
|
/** Conditions that are not error condition, but might require handling
|
||||||
*/
|
*/
|
||||||
NDB_MGM_CLUSTERLOG_INFO = 2, /*< Informational messages*/
|
NDB_MGM_CLUSTERLOG_WARNING = 3,
|
||||||
NDB_MGM_CLUSTERLOG_WARNING = 3, /*< Conditions that are not
|
/** Conditions that should be corrected */
|
||||||
*< error condition, but
|
NDB_MGM_CLUSTERLOG_ERROR = 4,
|
||||||
*< might require handling
|
/** Critical conditions, like device errors or out of resources */
|
||||||
*/
|
NDB_MGM_CLUSTERLOG_CRITICAL = 5,
|
||||||
NDB_MGM_CLUSTERLOG_ERROR = 4, /*< Conditions that should be
|
/** A condition that should be corrected immediately,
|
||||||
*< corrected
|
* such as a corrupted system
|
||||||
*/
|
|
||||||
NDB_MGM_CLUSTERLOG_CRITICAL = 5, /*< Critical conditions, like
|
|
||||||
*< device errors or out of
|
|
||||||
*< resources
|
|
||||||
*/
|
|
||||||
NDB_MGM_CLUSTERLOG_ALERT = 6, /*< A condition that should be
|
|
||||||
*< corrected immediately,
|
|
||||||
*< such as a corrupted system
|
|
||||||
*/
|
*/
|
||||||
|
NDB_MGM_CLUSTERLOG_ALERT = 6,
|
||||||
/* must be next number, works as bound in loop */
|
/* must be next number, works as bound in loop */
|
||||||
NDB_MGM_CLUSTERLOG_ALL = 7 /*< All severities */
|
/** All severities */
|
||||||
|
NDB_MGM_CLUSTERLOG_ALL = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log categories
|
* Log categories, used to set filter on the clusterlog using
|
||||||
|
* ndb_mgm_set_loglevel_clusterlog()
|
||||||
*/
|
*/
|
||||||
enum ndb_mgm_event_category {
|
enum ndb_mgm_event_category {
|
||||||
/**
|
/**
|
||||||
@ -282,28 +334,56 @@ extern "C" {
|
|||||||
* Events during all kinds of startups
|
* Events during all kinds of startups
|
||||||
*/
|
*/
|
||||||
NDB_MGM_EVENT_CATEGORY_STARTUP = CFG_LOGLEVEL_STARTUP,
|
NDB_MGM_EVENT_CATEGORY_STARTUP = CFG_LOGLEVEL_STARTUP,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Events during shutdown
|
* Events during shutdown
|
||||||
*/
|
*/
|
||||||
NDB_MGM_EVENT_CATEGORY_SHUTDOWN = CFG_LOGLEVEL_SHUTDOWN,
|
NDB_MGM_EVENT_CATEGORY_SHUTDOWN = CFG_LOGLEVEL_SHUTDOWN,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction statistics (Job level, TCP/IP speed)
|
* Transaction statistics (Job level, TCP/IP speed)
|
||||||
*/
|
*/
|
||||||
NDB_MGM_EVENT_CATEGORY_STATISTIC = CFG_LOGLEVEL_STATISTICS,
|
NDB_MGM_EVENT_CATEGORY_STATISTIC = CFG_LOGLEVEL_STATISTICS,
|
||||||
|
/**
|
||||||
|
* Events regarding checkpoints
|
||||||
|
*/
|
||||||
NDB_MGM_EVENT_CATEGORY_CHECKPOINT = CFG_LOGLEVEL_CHECKPOINT,
|
NDB_MGM_EVENT_CATEGORY_CHECKPOINT = CFG_LOGLEVEL_CHECKPOINT,
|
||||||
|
/**
|
||||||
|
* Events during node restart
|
||||||
|
*/
|
||||||
NDB_MGM_EVENT_CATEGORY_NODE_RESTART = CFG_LOGLEVEL_NODERESTART,
|
NDB_MGM_EVENT_CATEGORY_NODE_RESTART = CFG_LOGLEVEL_NODERESTART,
|
||||||
|
/**
|
||||||
|
* Events on connection between cluster nodes
|
||||||
|
*/
|
||||||
NDB_MGM_EVENT_CATEGORY_CONNECTION = CFG_LOGLEVEL_CONNECTION,
|
NDB_MGM_EVENT_CATEGORY_CONNECTION = CFG_LOGLEVEL_CONNECTION,
|
||||||
NDB_MGM_EVENT_CATEGORY_DEBUG = CFG_LOGLEVEL_DEBUG,
|
/**
|
||||||
NDB_MGM_EVENT_CATEGORY_INFO = CFG_LOGLEVEL_INFO,
|
* Backup events
|
||||||
NDB_MGM_EVENT_CATEGORY_WARNING = CFG_LOGLEVEL_WARNING,
|
*/
|
||||||
NDB_MGM_EVENT_CATEGORY_ERROR = CFG_LOGLEVEL_ERROR,
|
|
||||||
NDB_MGM_EVENT_CATEGORY_GREP = CFG_LOGLEVEL_GREP,
|
|
||||||
NDB_MGM_EVENT_CATEGORY_BACKUP = CFG_LOGLEVEL_BACKUP,
|
NDB_MGM_EVENT_CATEGORY_BACKUP = CFG_LOGLEVEL_BACKUP,
|
||||||
|
/**
|
||||||
|
* Loglevel debug
|
||||||
|
*/
|
||||||
|
NDB_MGM_EVENT_CATEGORY_DEBUG = CFG_LOGLEVEL_DEBUG,
|
||||||
|
/**
|
||||||
|
* Loglevel info
|
||||||
|
*/
|
||||||
|
NDB_MGM_EVENT_CATEGORY_INFO = CFG_LOGLEVEL_INFO,
|
||||||
|
/**
|
||||||
|
* Loglevel warning
|
||||||
|
*/
|
||||||
|
NDB_MGM_EVENT_CATEGORY_WARNING = CFG_LOGLEVEL_WARNING,
|
||||||
|
/**
|
||||||
|
* Loglevel error
|
||||||
|
*/
|
||||||
|
NDB_MGM_EVENT_CATEGORY_ERROR = CFG_LOGLEVEL_ERROR,
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
NDB_MGM_EVENT_CATEGORY_GREP = CFG_LOGLEVEL_GREP,
|
||||||
|
#endif
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
NDB_MGM_MIN_EVENT_CATEGORY = CFG_MIN_LOGLEVEL,
|
NDB_MGM_MIN_EVENT_CATEGORY = CFG_MIN_LOGLEVEL,
|
||||||
NDB_MGM_MAX_EVENT_CATEGORY = CFG_MAX_LOGLEVEL
|
NDB_MGM_MAX_EVENT_CATEGORY = CFG_MAX_LOGLEVEL
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@ -384,6 +464,15 @@ extern "C" {
|
|||||||
* @param connect_string Connect string to the management server,
|
* @param connect_string Connect string to the management server,
|
||||||
*
|
*
|
||||||
* @return -1 on error.
|
* @return -1 on error.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* <connectstring> := [<nodeid-specification>,]<host-specification>[,<host-specification>]
|
||||||
|
* <nodeid-specification> := nodeid=<id>
|
||||||
|
* <host-specification> := <host>[:<port>]
|
||||||
|
* <id> is an integer larger than 1 identifying a node in config.ini
|
||||||
|
* <port> is an integer referring to a regular unix port
|
||||||
|
* <host> is a string which is a valid Internet host address
|
||||||
|
* @endcode
|
||||||
*/
|
*/
|
||||||
int ndb_mgm_set_connectstring(NdbMgmHandle handle,
|
int ndb_mgm_set_connectstring(NdbMgmHandle handle,
|
||||||
const char *connect_string);
|
const char *connect_string);
|
||||||
@ -391,8 +480,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* Get connectstring used for connection
|
* Get connectstring used for connection
|
||||||
*
|
*
|
||||||
* @note returns what the connectstring defaults to if the above call has
|
* @note returns what the connectstring defaults to if the
|
||||||
* not been performed
|
* ndb_mgm_set_connectstring() call has not been performed
|
||||||
*
|
*
|
||||||
* @param handle Management handle
|
* @param handle Management handle
|
||||||
*
|
*
|
||||||
@ -401,7 +490,8 @@ extern "C" {
|
|||||||
const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz);
|
const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to a management server
|
* Connect to a management server. Coonect string is set by
|
||||||
|
* ndb_mgm_set_connectstring().
|
||||||
*
|
*
|
||||||
* @param handle Management handle.
|
* @param handle Management handle.
|
||||||
* @return -1 on error.
|
* @return -1 on error.
|
||||||
@ -422,7 +512,8 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @param handle Management handle
|
* @param handle Management handle
|
||||||
*
|
*
|
||||||
* @return node id
|
* @return node id, 0 indicated that no nodeid has been
|
||||||
|
* specified
|
||||||
*/
|
*/
|
||||||
int ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle);
|
int ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle);
|
||||||
|
|
||||||
@ -444,6 +535,7 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
const char *ndb_mgm_get_connected_host(NdbMgmHandle handle);
|
const char *ndb_mgm_get_connected_host(NdbMgmHandle handle);
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
/** @} *********************************************************************/
|
/** @} *********************************************************************/
|
||||||
/**
|
/**
|
||||||
* @name Functions: Convert between different data formats
|
* @name Functions: Convert between different data formats
|
||||||
@ -492,7 +584,6 @@ extern "C" {
|
|||||||
const char * ndb_mgm_get_node_status_string(enum ndb_mgm_node_status status);
|
const char * ndb_mgm_get_node_status_string(enum ndb_mgm_node_status status);
|
||||||
|
|
||||||
const char * ndb_mgm_get_clusterlog_level_string(enum ndb_mgm_clusterlog_level);
|
const char * ndb_mgm_get_clusterlog_level_string(enum ndb_mgm_clusterlog_level);
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
||||||
ndb_mgm_event_category ndb_mgm_match_event_category(const char *);
|
ndb_mgm_event_category ndb_mgm_match_event_category(const char *);
|
||||||
const char * ndb_mgm_get_event_category_string(enum ndb_mgm_event_category);
|
const char * ndb_mgm_get_event_category_string(enum ndb_mgm_event_category);
|
||||||
#endif
|
#endif
|
||||||
@ -618,7 +709,7 @@ extern "C" {
|
|||||||
|
|
||||||
/** @} *********************************************************************/
|
/** @} *********************************************************************/
|
||||||
/**
|
/**
|
||||||
* @name Functions: Logging and Statistics
|
* @name Functions: Logging
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -670,6 +761,17 @@ extern "C" {
|
|||||||
enum ndb_mgm_event_category category,
|
enum ndb_mgm_event_category category,
|
||||||
int level,
|
int level,
|
||||||
struct ndb_mgm_reply* reply);
|
struct ndb_mgm_reply* reply);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to log events
|
||||||
|
*
|
||||||
|
* @param filter pairs of { level, ndb_mgm_event_category } that will be
|
||||||
|
* pushed to fd, level=0 ends lists
|
||||||
|
*
|
||||||
|
* @return fd which events will be pushed to
|
||||||
|
*/
|
||||||
|
int ndb_mgm_listen_event(NdbMgmHandle handle, int filter[]);
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
/**
|
/**
|
||||||
* Set log category and levels for the Node
|
* Set log category and levels for the Node
|
||||||
@ -708,9 +810,9 @@ extern "C" {
|
|||||||
* Start backup
|
* Start backup
|
||||||
*
|
*
|
||||||
* @param handle NDB management handle.
|
* @param handle NDB management handle.
|
||||||
* @param wait_completed 0=don't wait for confirmation
|
* @param wait_completed 0=don't wait for confirmation,
|
||||||
1=wait for backup started
|
* 1=wait for backup started,
|
||||||
2=wait for backup completed
|
* 2=wait for backup completed
|
||||||
* @param backup_id Backup id is returned from function.
|
* @param backup_id Backup id is returned from function.
|
||||||
* @param reply Reply message.
|
* @param reply Reply message.
|
||||||
* @return -1 on error.
|
* @return -1 on error.
|
||||||
@ -760,25 +862,21 @@ extern "C" {
|
|||||||
int ndb_mgm_exit_single_user(NdbMgmHandle handle,
|
int ndb_mgm_exit_single_user(NdbMgmHandle handle,
|
||||||
struct ndb_mgm_reply* reply);
|
struct ndb_mgm_reply* reply);
|
||||||
|
|
||||||
|
/** @} *********************************************************************/
|
||||||
/**
|
/**
|
||||||
* Listen event
|
* @name Configuration handling
|
||||||
*
|
* @{
|
||||||
* @param filter pairs of { level, category } that will be
|
|
||||||
* pushed to fd, level=0 ends lists
|
|
||||||
*
|
|
||||||
* @return fd which events will be pushed to
|
|
||||||
*/
|
*/
|
||||||
int ndb_mgm_listen_event(NdbMgmHandle handle, int filter[]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get configuration
|
* Get configuration
|
||||||
* @param handle NDB management handle.
|
* @param handle NDB management handle.
|
||||||
* @param version Version of configuration, 0 means latest
|
* @param version Version of configuration, 0 means latest
|
||||||
* @see MAKE_VERSION
|
* (which is the only supported input at this point)
|
||||||
*
|
*
|
||||||
* @return configuration
|
* @return configuration
|
||||||
*
|
*
|
||||||
* @note the caller must call ndb_mgm_detroy_configuration
|
* @note the caller must call ndb_mgm_destroy_configuration()
|
||||||
*/
|
*/
|
||||||
struct ndb_mgm_configuration * ndb_mgm_get_configuration(NdbMgmHandle handle,
|
struct ndb_mgm_configuration * ndb_mgm_get_configuration(NdbMgmHandle handle,
|
||||||
unsigned version);
|
unsigned version);
|
||||||
|
@ -53,14 +53,15 @@
|
|||||||
#define NDB_TYPE_VARCHAR 15
|
#define NDB_TYPE_VARCHAR 15
|
||||||
#define NDB_TYPE_BINARY 16
|
#define NDB_TYPE_BINARY 16
|
||||||
#define NDB_TYPE_VARBINARY 17
|
#define NDB_TYPE_VARBINARY 17
|
||||||
#define NDB_TYPE_DATETIME 18 // need to fix
|
#define NDB_TYPE_DATETIME 18
|
||||||
#define NDB_TYPE_TIMESPEC 19 // need to fix
|
#define NDB_TYPE_DATE 19
|
||||||
#define NDB_TYPE_BLOB 20
|
#define NDB_TYPE_BLOB 20
|
||||||
#define NDB_TYPE_TEXT 21
|
#define NDB_TYPE_TEXT 21
|
||||||
#define NDB_TYPE_BIT 22
|
#define NDB_TYPE_BIT 22
|
||||||
#define NDB_TYPE_LONG_VARCHAR 23
|
#define NDB_TYPE_LONG_VARCHAR 23
|
||||||
#define NDB_TYPE_LONG_VARBINARY 24
|
#define NDB_TYPE_LONG_VARBINARY 24
|
||||||
|
#define NDB_TYPE_TIME 25
|
||||||
|
|
||||||
#define NDB_TYPE_MAX 25
|
#define NDB_TYPE_MAX 26
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
on http://dev.mysql.com/doc/mysql/en/NDBCluster.html .
|
on http://dev.mysql.com/doc/mysql/en/NDBCluster.html .
|
||||||
Some of the fundamental ones are also described in section @ref secConcepts.
|
Some of the fundamental ones are also described in section @ref secConcepts.
|
||||||
|
|
||||||
The <em>NDB API</em> is a MySQL Cluster application interface
|
The NDB API is a MySQL Cluster application interface
|
||||||
that implements transactions.
|
that implements transactions.
|
||||||
The NDB API consists of the following fundamental classes:
|
The NDB API consists of the following fundamental classes:
|
||||||
- Ndb_cluster_connection, representing a connection to a cluster,
|
- Ndb_cluster_connection, representing a connection to a cluster,
|
||||||
@ -36,39 +36,38 @@
|
|||||||
- NdbDictionary represents meta information about tables and attributes.
|
- NdbDictionary represents meta information about tables and attributes.
|
||||||
- NdbError contains the specification for an error.
|
- NdbError contains the specification for an error.
|
||||||
|
|
||||||
It is also possible to receive "events" on changed data in the database.
|
It is also possible to receive "events" triggered when data in the database in changed.
|
||||||
This is done through the NdbEventOperation class.
|
This is done through the NdbEventOperation class.
|
||||||
|
|
||||||
There are also some auxiliary classes.
|
There are also some auxiliary classes, which are listed in the class hierarchy.
|
||||||
|
|
||||||
The main structure of an application program is as follows:
|
The main structure of an application program is as follows:
|
||||||
-# Construct and connect to a cluster using the Ndb_cluster_connection
|
-# Connect to a cluster using the Ndb_cluster_connection
|
||||||
object.
|
object.
|
||||||
-# Construct and initialize Ndb object(s) to connect to a database.
|
-# Initiate a database connection by constructing and initialising one or more Ndb objects.
|
||||||
-# Define and execute transactions using NdbTransaction.
|
-# Define and execute transactions using the NdbTransaction class.
|
||||||
-# Delete Ndb objects.
|
-# Delete Ndb objects.
|
||||||
-# Delete cluster connection.
|
-# Terminate the connection to the cluster (terminate instance of Ndb_cluster_connection).
|
||||||
|
|
||||||
The main structure of a transaction is as follows:
|
The procedure for using transactions is as follows:
|
||||||
-# Start transaction (an NdbTransaction)
|
-# Start transaction (instantiate an NdbTransaction object)
|
||||||
-# Add and define operations associated with the transaction using
|
-# Add and define operations associated with the transaction using the
|
||||||
NdbOperation, NdbScanOperation, NdbIndexOperation, NdbIndexScanOperation
|
NdbOperation, NdbScanOperation, NdbIndexOperation, and NdbIndexScanOperation classes.
|
||||||
-# Execute transaction
|
-# Execute transaction
|
||||||
|
|
||||||
The execution can be of two different types,
|
The execution can be of two different types,
|
||||||
<var>Commit</var> or <var>NoCommit</var>.
|
<var>Commit</var> or <var>NoCommit</var>.
|
||||||
If the execution is of type <var>NoCommit</var>,
|
If the execution is of type <var>NoCommit</var>,
|
||||||
then the application program executes part of a transaction,
|
then the application program executes part of a transaction,
|
||||||
but without committing the transaction.
|
but without actually committing the transaction.
|
||||||
After executing a <var>NoCommit</var> transaction, the program can continue
|
After executing a <var>NoCommit</var> transaction, the program can continue
|
||||||
to add and define more operations to the transaction
|
to add and define more operations to the transaction
|
||||||
for later execution.
|
for later execution.
|
||||||
|
|
||||||
If the execute is of type <var>Commit</var>, then the transaction is
|
If the execute is of type <var>Commit</var>, then the transaction is
|
||||||
committed. The transaction <em>must</em> be closed after it has been
|
immediately committed. The transaction <em>must</em> be closed after it has been
|
||||||
commited (event if commit fails), and no further addition or definition of
|
commited (event if commit fails), and no further addition or definition of
|
||||||
operations is allowed.
|
operations for this transaction is allowed.
|
||||||
|
|
||||||
|
|
||||||
@section secSync Synchronous Transactions
|
@section secSync Synchronous Transactions
|
||||||
|
|
||||||
@ -94,12 +93,12 @@
|
|||||||
|
|
||||||
To execute several parallel synchronous transactions, one can either
|
To execute several parallel synchronous transactions, one can either
|
||||||
use multiple Ndb objects in several threads, or start multiple
|
use multiple Ndb objects in several threads, or start multiple
|
||||||
applications programs.
|
application programs.
|
||||||
|
|
||||||
@section secNdbOperations Operations
|
@section secNdbOperations Operations
|
||||||
|
|
||||||
Each NdbTransaction consists of a list of operations which are represented
|
A NdbTransaction consists of a list of operations, each of which is represented
|
||||||
by instances of NdbOperation, NdbScanOperation, NdbIndexOperation, and/or
|
by an instance of NdbOperation, NdbScanOperation, NdbIndexOperation, or
|
||||||
NdbIndexScanOperation.
|
NdbIndexScanOperation.
|
||||||
|
|
||||||
<h3>Single row operations</h3>
|
<h3>Single row operations</h3>
|
||||||
@ -111,7 +110,7 @@
|
|||||||
-# Specify attribute actions, using NdbOperation::getValue()
|
-# Specify attribute actions, using NdbOperation::getValue()
|
||||||
|
|
||||||
Here are two brief examples illustrating this process. For the sake of
|
Here are two brief examples illustrating this process. For the sake of
|
||||||
brevity, we omit error-handling.
|
brevity, we omit error handling.
|
||||||
|
|
||||||
This first example uses an NdbOperation:
|
This first example uses an NdbOperation:
|
||||||
@code
|
@code
|
||||||
@ -150,17 +149,17 @@
|
|||||||
creation and use of synchronous transactions.
|
creation and use of synchronous transactions.
|
||||||
|
|
||||||
<h4>Step 1: Define single row operation type</h4>
|
<h4>Step 1: Define single row operation type</h4>
|
||||||
The following types of operations exist:
|
The following operation types are supported:
|
||||||
-# NdbOperation::insertTuple :
|
-# NdbOperation::insertTuple() :
|
||||||
inserts a non-existing tuple
|
inserts a non-existing tuple
|
||||||
-# NdbOperation::writeTuple :
|
-# NdbOperation::writeTuple() :
|
||||||
updates an existing tuple if is exists,
|
updates an existing tuple if is exists,
|
||||||
otherwise inserts a new tuple
|
otherwise inserts a new tuple
|
||||||
-# NdbOperation::updateTuple :
|
-# NdbOperation::updateTuple() :
|
||||||
updates an existing tuple
|
updates an existing tuple
|
||||||
-# NdbOperation::deleteTuple :
|
-# NdbOperation::deleteTuple() :
|
||||||
deletes an existing tuple
|
deletes an existing tuple
|
||||||
-# NdbOperation::readTuple :
|
-# NdbOperation::readTuple() :
|
||||||
reads an existing tuple with specified lock mode
|
reads an existing tuple with specified lock mode
|
||||||
|
|
||||||
All of these operations operate on the unique tuple key.
|
All of these operations operate on the unique tuple key.
|
||||||
@ -172,20 +171,22 @@
|
|||||||
NdbTransaction::getNdbIndexOperation() for each operation.
|
NdbTransaction::getNdbIndexOperation() for each operation.
|
||||||
|
|
||||||
<h4>Step 2: Specify Search Conditions</h4>
|
<h4>Step 2: Specify Search Conditions</h4>
|
||||||
The search condition is used to select tuples using NdbOperation::equal()
|
The search condition is used to select tuples. Search conditions are set using NdbOperation::equal().
|
||||||
|
|
||||||
<h4>Step 3: Specify Attribute Actions</h4>
|
<h4>Step 3: Specify Attribute Actions</h4>
|
||||||
Now it is time to define which attributes should be read or updated.
|
Next, it is necessary to determine which attributes should be read or updated.
|
||||||
Deletes can neither read nor set values, read can only read values and
|
It is important to remember that:
|
||||||
updates can only set values.
|
- Deletes can neither read nor set values, but only delete them
|
||||||
Normally the attribute is defined by its name but it is
|
- Reads can only read values
|
||||||
also possible to use the attribute identity to define the
|
- Updates can only set values
|
||||||
|
Normally the attribute is identified by name, but it is
|
||||||
|
also possible to use the attribute's identity to determine the
|
||||||
attribute.
|
attribute.
|
||||||
|
|
||||||
NdbOperation::getValue() returns an NdbRecAttr object
|
NdbOperation::getValue() returns an NdbRecAttr object
|
||||||
containing the read value.
|
containing the read value.
|
||||||
To get the value, there is actually two methods.
|
To obtain the actual value, one of two methods can be used;
|
||||||
The application can either
|
the application can either
|
||||||
- use its own memory (passed through a pointer aValue) to
|
- use its own memory (passed through a pointer aValue) to
|
||||||
NdbOperation::getValue(), or
|
NdbOperation::getValue(), or
|
||||||
- receive the attribute value in an NdbRecAttr object allocated
|
- receive the attribute value in an NdbRecAttr object allocated
|
||||||
@ -193,39 +194,40 @@
|
|||||||
|
|
||||||
The NdbRecAttr object is released when Ndb::closeTransaction()
|
The NdbRecAttr object is released when Ndb::closeTransaction()
|
||||||
is called.
|
is called.
|
||||||
Thus, the application can not reference this object after
|
Thus, the application cannot reference this object following
|
||||||
Ndb::closeTransaction() have been called.
|
any subsequent call to Ndb::closeTransaction().
|
||||||
The result of reading data from an NdbRecAttr object before
|
Attempting to read data from an NdbRecAttr object before
|
||||||
calling NdbTransaction::execute() is undefined.
|
calling NdbTransaction::execute() yields an undefined result.
|
||||||
|
|
||||||
|
|
||||||
@subsection secScan Scan Operations
|
@subsection secScan Scan Operations
|
||||||
|
|
||||||
Scans are roughly the equivalent of SQL cursors.
|
Scans are roughly the equivalent of SQL cursors, providing a means to
|
||||||
|
preform high-speed row processing. A scan can be performed
|
||||||
|
on either a table (using @ref NdbScanOperation) or
|
||||||
|
an ordered index (by means of an @ref NdbIndexScanOperation).
|
||||||
|
|
||||||
Scans can either be performed on a table (@ref NdbScanOperation) or
|
Scan operations are characterised by the following:
|
||||||
on an ordered index (@ref NdbIndexScanOperation).
|
- They can perform only reads (shared, exclusive or dirty)
|
||||||
|
|
||||||
Scan operation are characteriesed by the following:
|
|
||||||
- They can only perform reads (shared, exclusive or dirty)
|
|
||||||
- They can potentially work with multiple rows
|
- They can potentially work with multiple rows
|
||||||
- They can be used to update or delete multiple rows
|
- They can be used to update or delete multiple rows
|
||||||
- They can operate on several nodes in parallell
|
- They can operate on several nodes in parallel
|
||||||
|
|
||||||
After the operation is created using NdbTransaction::getNdbScanOperation()
|
After the operation is created using NdbTransaction::getNdbScanOperation()
|
||||||
(or NdbTransaction::getNdbIndexScanOperation()),
|
(or NdbTransaction::getNdbIndexScanOperation()),
|
||||||
it is defined in the following three steps:
|
it is carried out in the following three steps:
|
||||||
-# Define the standard operation type, using NdbScanOperation::readTuples()
|
-# Define the standard operation type, using NdbScanOperation::readTuples()
|
||||||
-# Specify search conditions, using @ref NdbScanFilter and/or
|
-# Specify search conditions, using @ref NdbScanFilter and/or
|
||||||
@ref NdbIndexScanOperation::setBound()
|
@ref NdbIndexScanOperation::setBound()
|
||||||
-# Specify attribute actions, using NdbOperation::getValue()
|
-# Specify attribute actions, using NdbOperation::getValue()
|
||||||
-# Executing the transaction, using NdbTransaction::execute()
|
-# Executing the transaction, using NdbTransaction::execute()
|
||||||
-# Iterating through the result set using NdbScanOperation::nextResult()
|
-# Traversing the result set by means of succssive calls to
|
||||||
|
NdbScanOperation::nextResult()
|
||||||
|
|
||||||
Here are two brief examples illustrating this process. For the sake of
|
Here are two brief examples illustrating this process. Once again, in order
|
||||||
brevity, we omit error-handling.
|
to keep things relatively short and simple, we will forego any error handling.
|
||||||
|
|
||||||
This first example uses an NdbScanOperation:
|
This first example performs a table scan, using an NdbScanOperation:
|
||||||
@code
|
@code
|
||||||
// 1. Create
|
// 1. Create
|
||||||
MyOperation= MyTransaction->getNdbScanOperation("MYTABLENAME");
|
MyOperation= MyTransaction->getNdbScanOperation("MYTABLENAME");
|
||||||
@ -244,7 +246,7 @@
|
|||||||
MyRecAttr= MyOperation->getValue("ATTR2", NULL);
|
MyRecAttr= MyOperation->getValue("ATTR2", NULL);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The second example uses an NdbIndexScanOperation:
|
Our second example uses an NdbIndexScanOperation to perform an index scan:
|
||||||
@code
|
@code
|
||||||
// 1. Create
|
// 1. Create
|
||||||
MyOperation= MyTransaction->getNdbIndexScanOperation("MYORDEREDINDEX", "MYTABLENAME");
|
MyOperation= MyTransaction->getNdbIndexScanOperation("MYORDEREDINDEX", "MYTABLENAME");
|
||||||
@ -261,98 +263,87 @@
|
|||||||
MyRecAttr = MyOperation->getValue("ATTR2", NULL);
|
MyRecAttr = MyOperation->getValue("ATTR2", NULL);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
<h4>Step 1: Define scan operation operation type</h4>
|
Some additional discussion of each step required to perform a scan follows:
|
||||||
Scan operations only support 1 operation,
|
|
||||||
@ref NdbScanOperation::readTuples()
|
<h4>Step 1: Define Scan Operation Type</h4>
|
||||||
or @ref NdbIndexScanOperation::readTuples()
|
It is important to remember that only a single operation is supported for each scan operation
|
||||||
|
(@ref NdbScanOperation::readTuples() or @ref NdbIndexScanOperation::readTuples()).
|
||||||
|
|
||||||
@note If you want to define multiple scan operations within the same
|
@note If you want to define multiple scan operations within the same
|
||||||
transaction, then you need to call
|
transaction, then you need to call
|
||||||
NdbTransaction::getNdbScanOperation() or
|
NdbTransaction::getNdbScanOperation() or
|
||||||
NdbTransaction::getNdbIndexScanOperation() for each operation.
|
NdbTransaction::getNdbIndexScanOperation() separately for <b>each</b> operation.
|
||||||
|
|
||||||
<h4>Step 2: Specify Search Conditions</h4>
|
<h4>Step 2: Specify Search Conditions</h4>
|
||||||
The search condition is used to select tuples.
|
The search condition is used to select tuples.
|
||||||
If no search condition is specified, the scan will return all rows
|
If no search condition is specified, the scan will return all rows
|
||||||
in the table.
|
in the table.
|
||||||
|
|
||||||
Search condition can be @ref NdbScanFilter which can be used on both
|
The search condition can be an @ref NdbScanFilter (which can be used on both
|
||||||
@ref NdbScanOperation and @ref NdbIndexScanOperation or bounds which
|
@ref NdbScanOperation and @ref NdbIndexScanOperation) or bounds which
|
||||||
can only be used on index scans, @ref NdbIndexScanOperation::setBound.
|
can only be used on index scans (@ref NdbIndexScanOperation::setBound()).
|
||||||
An index scan can have both NdbScanFilter and bounds
|
An index scan can use both NdbScanFilter and bounds.
|
||||||
|
|
||||||
@note When NdbScanFilter is used each row is examined but maybe not
|
@note When NdbScanFilter is used, each row is examined, whether or not it is
|
||||||
returned. But when using bounds, only rows within bounds will be examined.
|
actually returned. However, when using bounds, only rows within the bounds will be examined.
|
||||||
|
|
||||||
<h4>Step 3: Specify Attribute Actions</h4>
|
<h4>Step 3: Specify Attribute Actions</h4>
|
||||||
|
|
||||||
Now it is time to define which attributes should be read.
|
Next, it is necessary to define which attributes should be read.
|
||||||
Normally the attribute is defined by its name but it is
|
As with transaction attributes, scan attributes are defined by name but it is
|
||||||
also possible to use the attribute identity to define the
|
also possible to use the attributes' identities to define attributes.
|
||||||
attribute.
|
|
||||||
|
|
||||||
NdbOperation::getValue() returns an NdbRecAttr object
|
As previously discussed (see @ref secSync), the value read is returned as
|
||||||
containing the read value.
|
an NdbRecAttr object by the NdbOperation::getValue() method.
|
||||||
To get the value, there is actually two methods.
|
|
||||||
The application can either
|
|
||||||
- use its own memory (passed through a pointer aValue) to
|
|
||||||
NdbOperation::getValue(), or
|
|
||||||
- receive the attribute value in an NdbRecAttr object allocated
|
|
||||||
by the NDB API.
|
|
||||||
|
|
||||||
The NdbRecAttr object is released when Ndb::closeTransaction()
|
<h3>Using Scan to Update/Delete</h3>
|
||||||
is called. Thus, the application can not reference this object after
|
Scanning can also be used to update or delete rows.
|
||||||
Ndb::closeTransaction() have been called.
|
|
||||||
The result of reading data from an NdbRecAttr object before
|
|
||||||
calling NdbTransaction::execute() is undefined.
|
|
||||||
|
|
||||||
<h3> Using Scan to update/delete </h3>
|
|
||||||
Scanning can also be used to update/delete rows.
|
|
||||||
This is performed by
|
This is performed by
|
||||||
-# Scan using exclusive locks, NdbOperation::LM_Exclusive
|
-# Scanning using exclusive locks (using NdbOperation::LM_Exclusive)
|
||||||
-# When iterating through the result set, for each row optionally call
|
-# When iterating through the result set, for each row optionally calling
|
||||||
either NdbScanOperation::updateCurrentTuple() or
|
either NdbScanOperation::updateCurrentTuple() or
|
||||||
NdbScanOperation::deleteCurrentTuple()
|
NdbScanOperation::deleteCurrentTuple()
|
||||||
-# If performing NdbScanOperation::updateCurrentTuple(),
|
-# (If performing NdbScanOperation::updateCurrentTuple():)
|
||||||
set new values on record using ordinary @ref NdbOperation::setValue().
|
Setting new values for records simply by using @ref NdbOperation::setValue().
|
||||||
NdbOperation::equal() should <em>not</em> be called as the primary
|
NdbOperation::equal() should <em>not</em> be called in such cases, as the primary
|
||||||
key is retreived from the scan.
|
key is retrieved from the scan.
|
||||||
|
|
||||||
@note that the actual update/delete will not be performed until next
|
@note The actual update or delete will not be performed until the next
|
||||||
NdbTransaction::execute (as with single row operations),
|
call to NdbTransaction::execute(), just as with single row operations.
|
||||||
NdbTransaction::execute needs to be called before locks are released,
|
NdbTransaction::execute() also must be called before any locks are released;
|
||||||
see @ref secScanLocks
|
see @ref secScanLocks for more information.
|
||||||
|
|
||||||
<h4> Index scans specific features </h4>
|
<h4>Features Specific to Index Scans</h4>
|
||||||
The following features are available when performing an index scan
|
|
||||||
- Scan subset of table using @ref NdbIndexScanOperation::setBound()
|
|
||||||
- Ordering result set ascending or descending,
|
|
||||||
@ref NdbIndexScanOperation::readTuples()
|
|
||||||
- When using NdbIndexScanOperation::BoundEQ on partition key
|
|
||||||
only fragments containing rows will be scanned.
|
|
||||||
|
|
||||||
Rows are returned unordered unless sorted is set to true.
|
When performing an index scan, it is possible to
|
||||||
|
scan only a subset of a table using @ref NdbIndexScanOperation::setBound().
|
||||||
|
In addition, result sets can be sorted in either ascending or descending order, using
|
||||||
|
@ref NdbIndexScanOperation::readTuples(). Note that rows are returned unordered
|
||||||
|
by default, that is, unless <var>sorted</var> is set to <b>true</b>.
|
||||||
|
It is also important to note that, when using NdbIndexScanOperation::BoundEQ
|
||||||
|
on a partition key, only fragments containing rows will actually be scanned.
|
||||||
|
|
||||||
@note When performing sorted scan, parameter parallelism to
|
@note When performing a sorted scan, any value passed as the
|
||||||
NdbIndexScanOperation::readTuples() will
|
NdbIndexScanOperation::readTuples() method's <code>parallel</code> argument
|
||||||
be ignored and max parallelism will be used instead.
|
will be ignored and maximum parallelism will be used instead. In other words, all
|
||||||
|
fragments which it is possible to scan will be scanned simultaneously and in parallel
|
||||||
|
in such cases.
|
||||||
|
|
||||||
@subsection secScanLocks Lock handling with scans
|
@subsection secScanLocks Lock handling with scans
|
||||||
|
|
||||||
When scanning a table or an index potentially
|
Performing scans on either a tables or an index has the potential
|
||||||
a lot of records will be returned.
|
return a great many records; however, Ndb will lock only a predetermined
|
||||||
|
number of rows per fragment at a time.
|
||||||
But Ndb will only lock a batch of rows per fragment at a time.
|
|
||||||
How many rows will be locked per fragment is controlled by the
|
How many rows will be locked per fragment is controlled by the
|
||||||
batch parameter to NdbScanOperation::readTuples().
|
<var>batch</var> parameter passed to NdbScanOperation::readTuples().
|
||||||
|
|
||||||
To let the application handle how locks are released
|
In order to allow the application to handle how locks are released,
|
||||||
NdbScanOperation::nextResult() have a parameter fetch_allow.
|
NdbScanOperation::nextResult() has a Boolean parameter <var>fetch_allow</var>.
|
||||||
If NdbScanOperation::nextResult() is called with fetch_allow = false, no
|
If NdbScanOperation::nextResult() is called with <var>fetch_allow</var> equal to
|
||||||
locks may be released as result of the function call. Otherwise the locks
|
<b>false</b>, then no locks may be released as result of the function call.
|
||||||
for the current batch may be released.
|
Otherwise the locks for the current batch may be released.
|
||||||
|
|
||||||
This example shows scan delete, handling locks in an efficient manner.
|
This next example shows a scan delete that handle locks in an efficient manner.
|
||||||
For the sake of brevity, we omit error-handling.
|
For the sake of brevity, we omit error-handling.
|
||||||
@code
|
@code
|
||||||
int check;
|
int check;
|
||||||
@ -364,67 +355,75 @@
|
|||||||
{
|
{
|
||||||
// Inner loop for each row within batch
|
// Inner loop for each row within batch
|
||||||
MyScanOperation->deleteCurrentTuple();
|
MyScanOperation->deleteCurrentTuple();
|
||||||
} while((check = MyScanOperation->nextResult(false) == 0));
|
} while((check = MyScanOperation->nextResult(false)) == 0);
|
||||||
|
|
||||||
// When no more rows in batch, exeute all defined deletes
|
// When no more rows in batch, exeute all defined deletes
|
||||||
MyTransaction->execute(NoCommit);
|
MyTransaction->execute(NoCommit);
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
See @ref ndbapi_scan.cpp for full example of scan.
|
See @ref ndbapi_scan.cpp for a more complete example of a scan.
|
||||||
|
|
||||||
@section secError Error Handling
|
@section secError Error Handling
|
||||||
|
|
||||||
Errors can occur when
|
Errors can occur either when operations making up a transaction are being
|
||||||
-# operations are being defined, or when the
|
defined, or when the transaction is actually being executed. Catching and
|
||||||
-# transaction is being executed.
|
handling either sort of error requires testing the value returned by
|
||||||
|
NdbTransaction::execute(), and then, if an error is indicated (that is,
|
||||||
|
if this value is equal to -1), using the following two methods in order to
|
||||||
|
identify the error's type and location:
|
||||||
|
|
||||||
One recommended way to handle a transaction failure
|
- NdbTransaction::getNdbErrorOperation() returns a reference to the
|
||||||
(i.e. an error is reported) is to:
|
operation causing the most recent error.
|
||||||
-# Rollback transaction (NdbTransaction::execute() with a special parameter)
|
- NdbTransaction::getNdbErrorLine() yields the method number of the
|
||||||
-# Close transaction
|
|
||||||
-# Restart transaction (if the error was temporary)
|
|
||||||
|
|
||||||
@note Transactions are not automatically closed when an error occur. Call
|
|
||||||
Ndb::closeTransaction() to close.
|
|
||||||
|
|
||||||
Several errors can occur when a transaction holds multiple
|
|
||||||
operations which are simultaneously executed.
|
|
||||||
In this case the application has to go through the operation
|
|
||||||
objects and query for their NdbError objects to find out what really
|
|
||||||
happened.
|
|
||||||
|
|
||||||
NdbTransaction::getNdbErrorOperation() returns a reference to the
|
|
||||||
operation causing the latest error.
|
|
||||||
NdbTransaction::getNdbErrorLine() delivers the method number of the
|
|
||||||
erroneous method in the operation.
|
erroneous method in the operation.
|
||||||
|
|
||||||
|
This short example illustrates how to detect an error and to use these
|
||||||
|
two methods to identify it:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
theTransaction = theNdb->startTransaction();
|
theTransaction = theNdb->startTransaction();
|
||||||
theOperation = theTransaction->getNdbOperation("TEST_TABLE");
|
theOperation = theTransaction->getNdbOperation("TEST_TABLE");
|
||||||
if (theOperation == NULL) goto error;
|
if (theOperation == NULL) goto error;
|
||||||
theOperation->readTuple(NdbOperation::LM_Read);
|
theOperation->readTuple(NdbOperation::LM_Read);
|
||||||
theOperation->setValue("ATTR_1", at1);
|
theOperation->setValue("ATTR_1", at1);
|
||||||
theOperation->setValue("ATTR_2", at1); //Here an error occurs
|
theOperation->setValue("ATTR_2", at1); // Error occurs here
|
||||||
theOperation->setValue("ATTR_3", at1);
|
theOperation->setValue("ATTR_3", at1);
|
||||||
theOperation->setValue("ATTR_4", at1);
|
theOperation->setValue("ATTR_4", at1);
|
||||||
|
|
||||||
if (theTransaction->execute(Commit) == -1) {
|
if (theTransaction->execute(Commit) == -1) {
|
||||||
errorLine = theTransaction->getNdbErrorLine();
|
errorLine = theTransaction->getNdbErrorLine();
|
||||||
errorOperation = theTransaction->getNdbErrorOperation();
|
errorOperation = theTransaction->getNdbErrorOperation();
|
||||||
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Here errorLine will be 3 as the error occurred in the third method
|
Here <code>errorLine</code> will be 3, as the error occurred in the
|
||||||
on the operation object.
|
third method called on the NdbOperation object (in this case,
|
||||||
Getting errorLine == 0 means that the error occurred when executing the
|
<code>theOperation</code>); if the result of
|
||||||
operations.
|
NdbTransaction::getNdbErrorLine() is 0, this means that the error
|
||||||
Here errorOperation will be a pointer to the theOperation object.
|
occurred when the operations were executed. In this example,
|
||||||
NdbTransaction::getNdbError() will return the NdbError object
|
<code>errorOperation</code> will be a pointer to the <code>theOperation</code>
|
||||||
including holding information about the error.
|
object. The NdbTransaction::getNdbError() method returns an NdbError
|
||||||
|
object providing information about the error.
|
||||||
|
|
||||||
Since errors could have occurred even when a commit was reported,
|
@note Transactions are <b>not</b> automatically closed when an error occurs. Call
|
||||||
there is also a special method, NdbTransaction::commitStatus(),
|
Ndb::closeTransaction() to close the transaction.
|
||||||
to check the commit status of the transaction.
|
|
||||||
|
One recommended way to handle a transaction failure
|
||||||
|
(i.e. an error is reported) is to:
|
||||||
|
-# Rollback transaction (call NdbTransaction::execute() with a special parameter)
|
||||||
|
-# Close transaction (call NdbTransaction::closeTransaction())
|
||||||
|
-# If the error was temporary, attempt to restart the transaction
|
||||||
|
|
||||||
|
Several errors can occur when a transaction contains multiple
|
||||||
|
operations which are simultaneously executed.
|
||||||
|
In this case the application has to go through all operations
|
||||||
|
and query their NdbError objects to find out what really happened.
|
||||||
|
|
||||||
|
It is also important to note that errors can occur even when a commit is
|
||||||
|
reported as successful. In order to handle such situations, the NDB API
|
||||||
|
provides an additional NdbTransaction::commitStatus() method to check the
|
||||||
|
transactions's commit status.
|
||||||
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
@ -434,6 +433,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
|
/**
|
||||||
|
* @page ndbapi_async.cpp ndbapi_async.cpp
|
||||||
|
* @include ndbapi_async.cpp
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* @page ndbapi_async1.cpp ndbapi_async1.cpp
|
* @page ndbapi_async1.cpp ndbapi_async1.cpp
|
||||||
* @include ndbapi_async1.cpp
|
* @include ndbapi_async1.cpp
|
||||||
@ -455,6 +458,11 @@
|
|||||||
* @include ndbapi_scan.cpp
|
* @include ndbapi_scan.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page ndbapi_event.cpp ndbapi_event.cpp
|
||||||
|
* @include ndbapi_event.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@page secAdapt Adaptive Send Algorithm
|
@page secAdapt Adaptive Send Algorithm
|
||||||
|
@ -52,6 +52,7 @@ typedef struct charset_info_st CHARSET_INFO;
|
|||||||
* -# Dropping secondary indexes (Dictionary::dropIndex)
|
* -# Dropping secondary indexes (Dictionary::dropIndex)
|
||||||
*
|
*
|
||||||
* NdbDictionary has several help (inner) classes to support this:
|
* NdbDictionary has several help (inner) classes to support this:
|
||||||
|
* -# NdbDictionary::Dictionary the dictionary handling dictionary objects
|
||||||
* -# NdbDictionary::Table for creating tables
|
* -# NdbDictionary::Table for creating tables
|
||||||
* -# NdbDictionary::Column for creating table columns
|
* -# NdbDictionary::Column for creating table columns
|
||||||
* -# NdbDictionary::Index for creating secondary indexes
|
* -# NdbDictionary::Index for creating secondary indexes
|
||||||
@ -189,12 +190,13 @@ public:
|
|||||||
Binary = NDB_TYPE_BINARY, ///< Len
|
Binary = NDB_TYPE_BINARY, ///< Len
|
||||||
Varbinary = NDB_TYPE_VARBINARY, ///< Length bytes: 1, Max: 255
|
Varbinary = NDB_TYPE_VARBINARY, ///< Length bytes: 1, Max: 255
|
||||||
Datetime = NDB_TYPE_DATETIME, ///< Precision down to 1 sec (sizeof(Datetime) == 8 bytes )
|
Datetime = NDB_TYPE_DATETIME, ///< Precision down to 1 sec (sizeof(Datetime) == 8 bytes )
|
||||||
Timespec = NDB_TYPE_TIMESPEC, ///< Precision down to 1 nsec(sizeof(Datetime) == 12 bytes )
|
Date = NDB_TYPE_DATE, ///< Precision down to 1 day(sizeof(Date) == 4 bytes )
|
||||||
Blob = NDB_TYPE_BLOB, ///< Binary large object (see NdbBlob)
|
Blob = NDB_TYPE_BLOB, ///< Binary large object (see NdbBlob)
|
||||||
Text = NDB_TYPE_TEXT, ///< Text blob
|
Text = NDB_TYPE_TEXT, ///< Text blob
|
||||||
Bit = NDB_TYPE_BIT, ///< Bit, length specifies no of bits
|
Bit = NDB_TYPE_BIT, ///< Bit, length specifies no of bits
|
||||||
Longvarchar = NDB_TYPE_LONG_VARCHAR, ///< Length bytes: 2, little-endian
|
Longvarchar = NDB_TYPE_LONG_VARCHAR, ///< Length bytes: 2, little-endian
|
||||||
Longvarbinary = NDB_TYPE_LONG_VARBINARY ///< Length bytes: 2, little-endian
|
Longvarbinary = NDB_TYPE_LONG_VARBINARY, ///< Length bytes: 2, little-endian
|
||||||
|
Time = NDB_TYPE_TIME ///< Time without date
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -909,6 +911,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
class Event : public Object {
|
class Event : public Object {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Specifies the type of database operations an Event listens to
|
||||||
|
*/
|
||||||
enum TableEvent {
|
enum TableEvent {
|
||||||
TE_INSERT=1, ///< Insert event on table
|
TE_INSERT=1, ///< Insert event on table
|
||||||
TE_DELETE=2, ///< Delete event on table
|
TE_DELETE=2, ///< Delete event on table
|
||||||
@ -916,6 +921,10 @@ public:
|
|||||||
TE_ALL=7 ///< Any/all event on table (not relevant when
|
TE_ALL=7 ///< Any/all event on table (not relevant when
|
||||||
///< events are received)
|
///< events are received)
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Specifies the durability of an event
|
||||||
|
* (future version may supply other types)
|
||||||
|
*/
|
||||||
enum EventDurability {
|
enum EventDurability {
|
||||||
ED_UNDEFINED
|
ED_UNDEFINED
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
@ -930,8 +939,8 @@ public:
|
|||||||
// All API's can use it,
|
// All API's can use it,
|
||||||
// But's its removed when ndb is restarted
|
// But's its removed when ndb is restarted
|
||||||
#endif
|
#endif
|
||||||
,ED_PERMANENT ///< All API's can use it,
|
,ED_PERMANENT ///< All API's can use it.
|
||||||
///< It's still defined after a restart
|
///< It's still defined after a cluster system restart
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||||
= 3
|
= 3
|
||||||
#endif
|
#endif
|
||||||
@ -950,9 +959,12 @@ public:
|
|||||||
Event(const char *name, const NdbDictionary::Table& table);
|
Event(const char *name, const NdbDictionary::Table& table);
|
||||||
virtual ~Event();
|
virtual ~Event();
|
||||||
/**
|
/**
|
||||||
* Set/get unique identifier for the event
|
* Set unique identifier for the event
|
||||||
*/
|
*/
|
||||||
void setName(const char *name);
|
void setName(const char *name);
|
||||||
|
/**
|
||||||
|
* Get unique identifier for the event
|
||||||
|
*/
|
||||||
const char *getName() const;
|
const char *getName() const;
|
||||||
/**
|
/**
|
||||||
* Define table on which events should be detected
|
* Define table on which events should be detected
|
||||||
@ -967,7 +979,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Set table for which events should be detected
|
* Set table for which events should be detected
|
||||||
*
|
*
|
||||||
* @note preferred way is using setTable(const NdbDictionary::Table)
|
* @note preferred way is using setTable(const NdbDictionary::Table&)
|
||||||
* or constructor with table object parameter
|
* or constructor with table object parameter
|
||||||
*/
|
*/
|
||||||
void setTable(const char *tableName);
|
void setTable(const char *tableName);
|
||||||
@ -1224,9 +1236,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove table/index from local cache
|
* Remove table from local cache
|
||||||
*/
|
*/
|
||||||
void removeCachedTable(const char * table);
|
void removeCachedTable(const char * table);
|
||||||
|
/**
|
||||||
|
* Remove index from local cache
|
||||||
|
*/
|
||||||
void removeCachedIndex(const char * index, const char * table);
|
void removeCachedIndex(const char * index, const char * table);
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,73 +24,79 @@ class NdbEventOperationImpl;
|
|||||||
* @class NdbEventOperation
|
* @class NdbEventOperation
|
||||||
* @brief Class of operations for getting change events from database.
|
* @brief Class of operations for getting change events from database.
|
||||||
*
|
*
|
||||||
* An NdbEventOperation object is instantiated by
|
* Brief description on how to work with events:
|
||||||
* Ndb::createEventOperation
|
|
||||||
*
|
*
|
||||||
* Prior to that an event must have been created in the Database through
|
* - An event, represented by an NdbDictionary::Event, i created in the
|
||||||
* NdbDictionary::createEvent
|
* Database through
|
||||||
*
|
* NdbDictionary::Dictionary::createEvent() (note that this can be done
|
||||||
* The instance is removed by Ndb::dropEventOperation
|
* by any application or thread and not necessarily by the "listener")
|
||||||
|
* - To listen to events, an NdbEventOperation object is instantiated by
|
||||||
|
* Ndb::createEventOperation()
|
||||||
|
* - execute() starts the event flow. Use Ndb::pollEvents() to wait
|
||||||
|
* for an event to occur. Use next() to iterate
|
||||||
|
* through the events that have occured.
|
||||||
|
* - The instance is removed by Ndb::dropEventOperation()
|
||||||
*
|
*
|
||||||
* For more info see:
|
* For more info see:
|
||||||
* @ref ndbapi_event.cpp
|
* @ref ndbapi_event.cpp
|
||||||
*
|
*
|
||||||
* Known limitations:
|
* Known limitations:
|
||||||
*
|
*
|
||||||
* Maximum number of active NdbEventOperations are now set at compile time.
|
* - Maximum number of active NdbEventOperations are now set at compile time.
|
||||||
* Today 100. This will become a configuration parameter later.
|
* Today 100. This will become a configuration parameter later.
|
||||||
*
|
* - Maximum number of NdbEventOperations tied to same event are maximum 16
|
||||||
* Maximum number of NdbEventOperations tied to same event are maximum 16
|
|
||||||
* per process.
|
* per process.
|
||||||
*
|
*
|
||||||
* Known issues:
|
* Known issues:
|
||||||
*
|
*
|
||||||
* When several NdbEventOperation's are tied to the same event in the same
|
* - When several NdbEventOperation's are tied to the same event in the same
|
||||||
* process they will share the circular buffer. The BufferLength will then
|
* process they will share the circular buffer. The BufferLength will then
|
||||||
* be the same for all and decided by the first NdbEventOperation
|
* be the same for all and decided by the first NdbEventOperation
|
||||||
* instantiation. Just make sure to instantiate the "largest" one first.
|
* instantiation. Just make sure to instantiate the "largest" one first.
|
||||||
*
|
* - Today all events INSERT/DELETE/UPDATE and all changed attributes are
|
||||||
* Today all events INSERT/DELETE/UPDATE and all changed attributes are
|
|
||||||
* sent to the API, even if only specific attributes have been specified.
|
* sent to the API, even if only specific attributes have been specified.
|
||||||
* These are however hidden from the user and only relevant data is shown
|
* These are however hidden from the user and only relevant data is shown
|
||||||
* after next().
|
* after next().
|
||||||
* However false exits from Ndb::pollEvents() may occur and thus
|
* - "False" exits from Ndb::pollEvents() may occur and thus
|
||||||
* the subsequent next() will return zero,
|
* the subsequent next() will return zero,
|
||||||
* since there was no available data. Just do Ndb::pollEvents() again.
|
* since there was no available data. Just do Ndb::pollEvents() again.
|
||||||
*
|
* - Event code does not check table schema version. Make sure to drop events
|
||||||
* Event code does not check table schema version. Make sure to drop events
|
|
||||||
* after table is dropped. Will be fixed in later
|
* after table is dropped. Will be fixed in later
|
||||||
* versions.
|
* versions.
|
||||||
*
|
* - If a node failure has occured not all events will be recieved
|
||||||
* If a node failure has occured not all events will be recieved
|
|
||||||
* anymore. Drop NdbEventOperation and Create again after nodes are up
|
* anymore. Drop NdbEventOperation and Create again after nodes are up
|
||||||
* again. Will be fixed in later versions.
|
* again. Will be fixed in later versions.
|
||||||
*
|
*
|
||||||
* Test status:
|
* Test status:
|
||||||
* Tests have been run on 1-node and 2-node systems
|
|
||||||
*
|
*
|
||||||
* Known bugs:
|
* - Tests have been run on 1-node and 2-node systems
|
||||||
*
|
|
||||||
* None, except if we can call some of the "issues" above bugs
|
|
||||||
*
|
*
|
||||||
* Useful API programs:
|
* Useful API programs:
|
||||||
*
|
*
|
||||||
* ndb_select_all -d sys 'NDB$EVENTS_0'
|
* - ndb_select_all -d sys 'NDB$EVENTS_0'
|
||||||
* Will show contents in the system table containing created events.
|
* shows contents in the system table containing created events.
|
||||||
*
|
*
|
||||||
|
* @note this is an inteface to viewing events that is subject to change
|
||||||
*/
|
*/
|
||||||
class NdbEventOperation {
|
class NdbEventOperation {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* State of the NdbEventOperation object
|
||||||
|
*/
|
||||||
|
enum State {
|
||||||
|
EO_CREATED, ///< Created but execute() not called
|
||||||
|
EO_EXECUTING, ///< execute() called
|
||||||
|
EO_ERROR ///< An error has occurred. Object unusable.
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Retrieve current state of the NdbEventOperation object
|
* Retrieve current state of the NdbEventOperation object
|
||||||
*/
|
*/
|
||||||
enum State {CREATED,EXECUTING,ERROR};
|
|
||||||
State getState();
|
State getState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates the NdbEventOperation to start receiving events. The
|
* Activates the NdbEventOperation to start receiving events. The
|
||||||
* changed attribute values may be retrieved after next() has returned
|
* changed attribute values may be retrieved after next() has returned
|
||||||
* a value greater than zero. The getValue() methods below must be called
|
* a value greater than zero. The getValue() methods must be called
|
||||||
* prior to execute().
|
* prior to execute().
|
||||||
*
|
*
|
||||||
* @return 0 if successful otherwise -1.
|
* @return 0 if successful otherwise -1.
|
||||||
@ -112,21 +118,21 @@ public:
|
|||||||
* aligned appropriately. The buffer is used directly
|
* aligned appropriately. The buffer is used directly
|
||||||
* (avoiding a copy penalty) only if it is aligned on a
|
* (avoiding a copy penalty) only if it is aligned on a
|
||||||
* 4-byte boundary and the attribute size in bytes
|
* 4-byte boundary and the attribute size in bytes
|
||||||
* (i.e. NdbRecAttr::attrSize times NdbRecAttr::arraySize is
|
* (i.e. NdbRecAttr::attrSize() times NdbRecAttr::arraySize() is
|
||||||
* a multiple of 4).
|
* a multiple of 4).
|
||||||
*
|
*
|
||||||
* @note There are two versions, NdbOperation::getValue and
|
* @note There are two versions, getValue() and
|
||||||
* NdbOperation::getPreValue for retrieving the current and
|
* getPreValue() for retrieving the current and
|
||||||
* previous value repectively.
|
* previous value repectively.
|
||||||
*
|
*
|
||||||
* @note This method does not fetch the attribute value from
|
* @note This method does not fetch the attribute value from
|
||||||
* the database! The NdbRecAttr object returned by this method
|
* the database! The NdbRecAttr object returned by this method
|
||||||
* is <em>not</em> readable/printable before the
|
* is <em>not</em> readable/printable before the
|
||||||
* NdbEventConnection::execute has been made and
|
* execute() has been made and
|
||||||
* NdbEventConnection::next has returned a value greater than
|
* next() has returned a value greater than
|
||||||
* zero. If a specific attribute has not changed the corresponding
|
* zero. If a specific attribute has not changed the corresponding
|
||||||
* NdbRecAttr will be in state UNDEFINED. This is checked by
|
* NdbRecAttr will be in state UNDEFINED. This is checked by
|
||||||
* NdbRecAttr::isNull which then returns -1.
|
* NdbRecAttr::isNull() which then returns -1.
|
||||||
*
|
*
|
||||||
* @param anAttrName Attribute name
|
* @param anAttrName Attribute name
|
||||||
* @param aValue If this is non-NULL, then the attribute value
|
* @param aValue If this is non-NULL, then the attribute value
|
||||||
@ -143,11 +149,11 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Retrieves event resultset if available, inserted into the NdbRecAttrs
|
* Retrieves event resultset if available, inserted into the NdbRecAttrs
|
||||||
* specified in getValue() and getPreValue(). To avoid polling for
|
* specified in getValue() and getPreValue(). To avoid polling for
|
||||||
* a resultset, one can use Ndb::pollEvents
|
* a resultset, one can use Ndb::pollEvents()
|
||||||
* which will wait on a mutex until an event occurs or the specified
|
* which will wait on a mutex until an event occurs or the specified
|
||||||
* timeout occurs.
|
* timeout occurs.
|
||||||
*
|
*
|
||||||
* @return >=0 if successful otherwise -1. Return value inicates number
|
* @return >=0 if successful otherwise -1. Return value indicates number
|
||||||
* of available events. By sending pOverRun one may query for buffer
|
* of available events. By sending pOverRun one may query for buffer
|
||||||
* overflow and *pOverRun will indicate the number of events that have
|
* overflow and *pOverRun will indicate the number of events that have
|
||||||
* overwritten.
|
* overwritten.
|
||||||
|
@ -86,12 +86,13 @@ public:
|
|||||||
Binary = NDB_TYPE_BINARY,
|
Binary = NDB_TYPE_BINARY,
|
||||||
Varbinary = NDB_TYPE_VARBINARY,
|
Varbinary = NDB_TYPE_VARBINARY,
|
||||||
Datetime = NDB_TYPE_DATETIME,
|
Datetime = NDB_TYPE_DATETIME,
|
||||||
Timespec = NDB_TYPE_TIMESPEC,
|
Date = NDB_TYPE_DATE,
|
||||||
Blob = NDB_TYPE_BLOB,
|
Blob = NDB_TYPE_BLOB,
|
||||||
Text = NDB_TYPE_TEXT,
|
Text = NDB_TYPE_TEXT,
|
||||||
Bit = NDB_TYPE_BIT,
|
Bit = NDB_TYPE_BIT,
|
||||||
Longvarchar = NDB_TYPE_LONG_VARCHAR,
|
Longvarchar = NDB_TYPE_LONG_VARCHAR,
|
||||||
Longvarbinary = NDB_TYPE_LONG_VARBINARY
|
Longvarbinary = NDB_TYPE_LONG_VARBINARY,
|
||||||
|
Time = NDB_TYPE_TIME
|
||||||
};
|
};
|
||||||
Enum m_typeId; // redundant
|
Enum m_typeId; // redundant
|
||||||
Cmp* m_cmp; // comparison method
|
Cmp* m_cmp; // comparison method
|
||||||
@ -153,12 +154,13 @@ private:
|
|||||||
static Cmp cmpBinary;
|
static Cmp cmpBinary;
|
||||||
static Cmp cmpVarbinary;
|
static Cmp cmpVarbinary;
|
||||||
static Cmp cmpDatetime;
|
static Cmp cmpDatetime;
|
||||||
static Cmp cmpTimespec;
|
static Cmp cmpDate;
|
||||||
static Cmp cmpBlob;
|
static Cmp cmpBlob;
|
||||||
static Cmp cmpText;
|
static Cmp cmpText;
|
||||||
static Cmp cmpBit;
|
static Cmp cmpBit;
|
||||||
static Cmp cmpLongvarchar;
|
static Cmp cmpLongvarchar;
|
||||||
static Cmp cmpLongvarbinary;
|
static Cmp cmpLongvarbinary;
|
||||||
|
static Cmp cmpTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -153,8 +153,8 @@ NdbSqlUtil::m_typeList[] = {
|
|||||||
cmpDatetime
|
cmpDatetime
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type::Timespec,
|
Type::Date,
|
||||||
NULL // cmpTimespec
|
cmpDate
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type::Blob,
|
Type::Blob,
|
||||||
@ -175,6 +175,10 @@ NdbSqlUtil::m_typeList[] = {
|
|||||||
{
|
{
|
||||||
Type::Longvarbinary,
|
Type::Longvarbinary,
|
||||||
cmpLongvarbinary
|
cmpLongvarbinary
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type::Time,
|
||||||
|
cmpTime
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -507,19 +511,57 @@ NdbSqlUtil::cmpVarbinary(const void* info, const void* p1, unsigned n1, const vo
|
|||||||
return CmpUnknown;
|
return CmpUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allowed but ordering is wrong before wl-1442 done
|
|
||||||
int
|
int
|
||||||
NdbSqlUtil::cmpDatetime(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
|
NdbSqlUtil::cmpDatetime(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
|
||||||
{
|
{
|
||||||
return cmpBinary(info, p1, n1, p2, n2, full);
|
if (n2 >= sizeof(Int64)) {
|
||||||
|
Int64 v1, v2;
|
||||||
|
memcpy(&v1, p1, sizeof(Int64));
|
||||||
|
memcpy(&v2, p2, sizeof(Int64));
|
||||||
|
if (v1 < v2)
|
||||||
|
return -1;
|
||||||
|
if (v1 > v2)
|
||||||
|
return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
assert(! full);
|
||||||
|
return CmpUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not used by MySQL or NDB
|
|
||||||
int
|
int
|
||||||
NdbSqlUtil::cmpTimespec(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
|
NdbSqlUtil::cmpDate(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
|
||||||
{
|
{
|
||||||
assert(false);
|
#ifdef ndb_date_is_4_byte_native_int
|
||||||
|
if (n2 >= sizeof(Int32)) {
|
||||||
|
Int32 v1, v2;
|
||||||
|
memcpy(&v1, p1, sizeof(Int32));
|
||||||
|
memcpy(&v2, p2, sizeof(Int32));
|
||||||
|
if (v1 < v2)
|
||||||
|
return -1;
|
||||||
|
if (v1 > v2)
|
||||||
|
return +1;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
assert(! full);
|
||||||
|
return CmpUnknown;
|
||||||
|
#else
|
||||||
|
if (n2 >= 4) { // may access 4-th byte
|
||||||
|
const uchar* v1 = (const uchar*)p1;
|
||||||
|
const uchar* v2 = (const uchar*)p2;
|
||||||
|
// from Field_newdate::val_int
|
||||||
|
Uint64 j1 = uint3korr(v1);
|
||||||
|
Uint64 j2 = uint3korr(v2);
|
||||||
|
j1 = (j1 % 32L)+(j1 / 32L % 16L)*100L + (j1/(16L*32L))*10000L;
|
||||||
|
j2 = (j2 % 32L)+(j2 / 32L % 16L)*100L + (j2/(16L*32L))*10000L;
|
||||||
|
if (j1 < j2)
|
||||||
|
return -1;
|
||||||
|
if (j1 > j2)
|
||||||
|
return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
assert(! full);
|
||||||
|
return CmpUnknown;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// not supported
|
// not supported
|
||||||
@ -538,6 +580,25 @@ NdbSqlUtil::cmpText(const void* info, const void* p1, unsigned n1, const void* p
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
NdbSqlUtil::cmpTime(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
|
||||||
|
{
|
||||||
|
if (n2 >= 4) { // may access 4-th byte
|
||||||
|
const uchar* v1 = (const uchar*)p1;
|
||||||
|
const uchar* v2 = (const uchar*)p2;
|
||||||
|
// from Field_time::val_int
|
||||||
|
Int32 j1 = sint3korr(v1);
|
||||||
|
Int32 j2 = sint3korr(v2);
|
||||||
|
if (j1 < j2)
|
||||||
|
return -1;
|
||||||
|
if (j1 > j2)
|
||||||
|
return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
assert(! full);
|
||||||
|
return CmpUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
// not yet
|
// not yet
|
||||||
int
|
int
|
||||||
NdbSqlUtil::cmpBit(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
|
NdbSqlUtil::cmpBit(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
|
||||||
|
@ -2364,7 +2364,8 @@ Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen,
|
|||||||
*/
|
*/
|
||||||
Uint32 dstLen = xmul * (srcBytes - lb);
|
Uint32 dstLen = xmul * (srcBytes - lb);
|
||||||
ndbrequire(dstLen <= ((dstSize - dstPos) << 2));
|
ndbrequire(dstLen <= ((dstSize - dstPos) << 2));
|
||||||
uint n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
|
int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
|
||||||
|
ndbrequire(n != -1);
|
||||||
while ((n & 3) != 0) {
|
while ((n & 3) != 0) {
|
||||||
dstPtr[n++] = 0;
|
dstPtr[n++] = 0;
|
||||||
}
|
}
|
||||||
|
@ -629,7 +629,6 @@ ndb_mgm_get_status(NdbMgmHandle handle)
|
|||||||
malloc(sizeof(ndb_mgm_cluster_state)+
|
malloc(sizeof(ndb_mgm_cluster_state)+
|
||||||
noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#")));
|
noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#")));
|
||||||
|
|
||||||
state->hostname= 0;
|
|
||||||
state->no_of_nodes= noOfNodes;
|
state->no_of_nodes= noOfNodes;
|
||||||
ndb_mgm_node_state * ptr = &state->node_states[0];
|
ndb_mgm_node_state * ptr = &state->node_states[0];
|
||||||
int nodeId = 0;
|
int nodeId = 0;
|
||||||
@ -1046,6 +1045,7 @@ struct ndb_mgm_event_categories
|
|||||||
{ "CHECKPOINT", NDB_MGM_EVENT_CATEGORY_CHECKPOINT },
|
{ "CHECKPOINT", NDB_MGM_EVENT_CATEGORY_CHECKPOINT },
|
||||||
{ "DEBUG", NDB_MGM_EVENT_CATEGORY_DEBUG },
|
{ "DEBUG", NDB_MGM_EVENT_CATEGORY_DEBUG },
|
||||||
{ "INFO", NDB_MGM_EVENT_CATEGORY_INFO },
|
{ "INFO", NDB_MGM_EVENT_CATEGORY_INFO },
|
||||||
|
{ "WARNING", NDB_MGM_EVENT_CATEGORY_WARNING },
|
||||||
{ "ERROR", NDB_MGM_EVENT_CATEGORY_ERROR },
|
{ "ERROR", NDB_MGM_EVENT_CATEGORY_ERROR },
|
||||||
{ "GREP", NDB_MGM_EVENT_CATEGORY_GREP },
|
{ "GREP", NDB_MGM_EVENT_CATEGORY_GREP },
|
||||||
{ "BACKUP", NDB_MGM_EVENT_CATEGORY_BACKUP },
|
{ "BACKUP", NDB_MGM_EVENT_CATEGORY_BACKUP },
|
||||||
|
@ -1177,7 +1177,14 @@ NdbEventOperation* Ndb::createEventOperation(const char* eventName,
|
|||||||
|
|
||||||
tOp = new NdbEventOperation(this, eventName, bufferLength);
|
tOp = new NdbEventOperation(this, eventName, bufferLength);
|
||||||
|
|
||||||
if (tOp->getState() != NdbEventOperation::CREATED) {
|
if (tOp == 0)
|
||||||
|
{
|
||||||
|
theError.code= 4000;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tOp->getState() != NdbEventOperation::EO_CREATED) {
|
||||||
|
theError.code= tOp->getNdbError().code;
|
||||||
delete tOp;
|
delete tOp;
|
||||||
tOp = NULL;
|
tOp = NULL;
|
||||||
}
|
}
|
||||||
|
@ -956,8 +956,8 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col)
|
|||||||
case NdbDictionary::Column::Datetime:
|
case NdbDictionary::Column::Datetime:
|
||||||
out << "Datetime";
|
out << "Datetime";
|
||||||
break;
|
break;
|
||||||
case NdbDictionary::Column::Timespec:
|
case NdbDictionary::Column::Date:
|
||||||
out << "Timespec";
|
out << "Date";
|
||||||
break;
|
break;
|
||||||
case NdbDictionary::Column::Blob:
|
case NdbDictionary::Column::Blob:
|
||||||
out << "Blob(" << col.getInlineSize() << "," << col.getPartSize()
|
out << "Blob(" << col.getInlineSize() << "," << col.getPartSize()
|
||||||
@ -967,6 +967,9 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col)
|
|||||||
out << "Text(" << col.getInlineSize() << "," << col.getPartSize()
|
out << "Text(" << col.getInlineSize() << "," << col.getPartSize()
|
||||||
<< ";" << col.getStripeSize() << ";" << csname << ")";
|
<< ";" << col.getStripeSize() << ";" << csname << ")";
|
||||||
break;
|
break;
|
||||||
|
case NdbDictionary::Column::Time:
|
||||||
|
out << "Time";
|
||||||
|
break;
|
||||||
case NdbDictionary::Column::Undefined:
|
case NdbDictionary::Column::Undefined:
|
||||||
out << "Undefined";
|
out << "Undefined";
|
||||||
break;
|
break;
|
||||||
|
@ -125,7 +125,7 @@ NdbColumnImpl::init(Type t)
|
|||||||
case Binary:
|
case Binary:
|
||||||
case Varbinary:
|
case Varbinary:
|
||||||
case Datetime:
|
case Datetime:
|
||||||
case Timespec:
|
case Date:
|
||||||
m_precision = 0;
|
m_precision = 0;
|
||||||
m_scale = 0;
|
m_scale = 0;
|
||||||
m_length = 1;
|
m_length = 1;
|
||||||
@ -143,6 +143,12 @@ NdbColumnImpl::init(Type t)
|
|||||||
m_length = 4;
|
m_length = 4;
|
||||||
m_cs = default_cs;
|
m_cs = default_cs;
|
||||||
break;
|
break;
|
||||||
|
case Time:
|
||||||
|
m_precision = 0;
|
||||||
|
m_scale = 0;
|
||||||
|
m_length = 1;
|
||||||
|
m_cs = NULL;
|
||||||
|
break;
|
||||||
case Bit:
|
case Bit:
|
||||||
m_precision = 0;
|
m_precision = 0;
|
||||||
m_scale = 0;
|
m_scale = 0;
|
||||||
|
@ -55,9 +55,8 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N,
|
|||||||
const char* eventName,
|
const char* eventName,
|
||||||
const int bufferLength)
|
const int bufferLength)
|
||||||
: NdbEventOperation(*this), m_ndb(theNdb),
|
: NdbEventOperation(*this), m_ndb(theNdb),
|
||||||
m_state(ERROR), m_bufferL(bufferLength)
|
m_state(EO_ERROR), m_bufferL(bufferLength)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_eventId = 0;
|
m_eventId = 0;
|
||||||
theFirstRecAttrs[0] = NULL;
|
theFirstRecAttrs[0] = NULL;
|
||||||
theCurrentRecAttrs[0] = NULL;
|
theCurrentRecAttrs[0] = NULL;
|
||||||
@ -71,16 +70,15 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N,
|
|||||||
// we should lookup id in Dictionary, TODO
|
// we should lookup id in Dictionary, TODO
|
||||||
// also make sure we only have one listener on each event
|
// also make sure we only have one listener on each event
|
||||||
|
|
||||||
if (!m_ndb) { ndbout_c("m_ndb=NULL"); return; }
|
if (!m_ndb) abort();
|
||||||
|
|
||||||
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
|
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
|
||||||
if (!myDict) { ndbout_c("getDictionary=NULL"); return; }
|
if (!myDict) { m_error.code= m_ndb->getNdbError().code; return; }
|
||||||
|
|
||||||
const NdbDictionary::Event *myEvnt = myDict->getEvent(eventName);
|
const NdbDictionary::Event *myEvnt = myDict->getEvent(eventName);
|
||||||
if (!myEvnt) { ndbout_c("getEvent()=NULL"); return; }
|
if (!myEvnt) { m_error.code= myDict->getNdbError().code; return; }
|
||||||
|
|
||||||
m_eventImpl = &myEvnt->m_impl;
|
m_eventImpl = &myEvnt->m_impl;
|
||||||
if (!m_eventImpl) { ndbout_c("m_impl=NULL"); return; }
|
|
||||||
|
|
||||||
m_bufferHandle = m_ndb->getGlobalEventBufferHandle();
|
m_bufferHandle = m_ndb->getGlobalEventBufferHandle();
|
||||||
if (m_bufferHandle->m_bufferL > 0)
|
if (m_bufferHandle->m_bufferL > 0)
|
||||||
@ -88,7 +86,7 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N,
|
|||||||
else
|
else
|
||||||
m_bufferHandle->m_bufferL = m_bufferL;
|
m_bufferHandle->m_bufferL = m_bufferL;
|
||||||
|
|
||||||
m_state = CREATED;
|
m_state = EO_CREATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NdbEventOperationImpl::~NdbEventOperationImpl()
|
NdbEventOperationImpl::~NdbEventOperationImpl()
|
||||||
@ -106,7 +104,7 @@ NdbEventOperationImpl::~NdbEventOperationImpl()
|
|||||||
p = p_next;
|
p = p_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_state == NdbEventOperation::EXECUTING) {
|
if (m_state == EO_EXECUTING) {
|
||||||
stop();
|
stop();
|
||||||
// m_bufferHandle->dropSubscribeEvent(m_bufferId);
|
// m_bufferHandle->dropSubscribeEvent(m_bufferId);
|
||||||
; // We should send stop signal here
|
; // We should send stop signal here
|
||||||
@ -122,7 +120,7 @@ NdbEventOperationImpl::getState()
|
|||||||
NdbRecAttr*
|
NdbRecAttr*
|
||||||
NdbEventOperationImpl::getValue(const char *colName, char *aValue, int n)
|
NdbEventOperationImpl::getValue(const char *colName, char *aValue, int n)
|
||||||
{
|
{
|
||||||
if (m_state != NdbEventOperation::CREATED) {
|
if (m_state != EO_CREATED) {
|
||||||
ndbout_c("NdbEventOperationImpl::getValue may only be called between instantiation and execute()");
|
ndbout_c("NdbEventOperationImpl::getValue may only be called between instantiation and execute()");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -211,8 +209,8 @@ NdbEventOperationImpl::execute()
|
|||||||
{
|
{
|
||||||
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
|
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
|
||||||
if (!myDict) {
|
if (!myDict) {
|
||||||
ndbout_c("NdbEventOperation::execute(): getDictionary=NULL");
|
m_error.code= m_ndb->getNdbError().code;
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theFirstRecAttrs[0] == NULL) { // defaults to get all
|
if (theFirstRecAttrs[0] == NULL) { // defaults to get all
|
||||||
@ -245,14 +243,14 @@ NdbEventOperationImpl::execute()
|
|||||||
if (r) {
|
if (r) {
|
||||||
//Error
|
//Error
|
||||||
m_bufferHandle->unprepareAddSubscribeEvent(m_bufferId);
|
m_bufferHandle->unprepareAddSubscribeEvent(m_bufferId);
|
||||||
m_state = NdbEventOperation::ERROR;
|
m_state = EO_ERROR;
|
||||||
} else {
|
} else {
|
||||||
m_bufferHandle->addSubscribeEvent(m_bufferId, this);
|
m_bufferHandle->addSubscribeEvent(m_bufferId, this);
|
||||||
m_state = NdbEventOperation::EXECUTING;
|
m_state = EO_EXECUTING;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Error
|
//Error
|
||||||
m_state = NdbEventOperation::ERROR;
|
m_state = EO_ERROR;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -261,14 +259,14 @@ int
|
|||||||
NdbEventOperationImpl::stop()
|
NdbEventOperationImpl::stop()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("NdbEventOperationImpl::stop");
|
DBUG_ENTER("NdbEventOperationImpl::stop");
|
||||||
if (m_state != NdbEventOperation::EXECUTING)
|
if (m_state != EO_EXECUTING)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
// ndbout_c("NdbEventOperation::stopping()");
|
// ndbout_c("NdbEventOperation::stopping()");
|
||||||
|
|
||||||
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
|
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
|
||||||
if (!myDict) {
|
if (!myDict) {
|
||||||
ndbout_c("NdbEventOperation::stop(): getDictionary=NULL");
|
m_error.code= m_ndb->getNdbError().code;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,13 +297,13 @@ NdbEventOperationImpl::stop()
|
|||||||
//Error
|
//Error
|
||||||
m_bufferHandle->unprepareDropSubscribeEvent(m_bufferId);
|
m_bufferHandle->unprepareDropSubscribeEvent(m_bufferId);
|
||||||
m_error.code= myDictImpl.m_error.code;
|
m_error.code= myDictImpl.m_error.code;
|
||||||
m_state = NdbEventOperation::ERROR;
|
m_state = EO_ERROR;
|
||||||
} else {
|
} else {
|
||||||
#ifdef EVENT_DEBUG
|
#ifdef EVENT_DEBUG
|
||||||
ndbout_c("NdbEventOperation::dropping()");
|
ndbout_c("NdbEventOperation::dropping()");
|
||||||
#endif
|
#endif
|
||||||
m_bufferHandle->dropSubscribeEvent(m_bufferId);
|
m_bufferHandle->dropSubscribeEvent(m_bufferId);
|
||||||
m_state = NdbEventOperation::CREATED;
|
m_state = EO_CREATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(r);
|
DBUG_RETURN(r);
|
||||||
|
@ -576,7 +576,8 @@ convertColumnTypeToAttrType(NdbDictionary::Column::Type _type)
|
|||||||
case NdbDictionary::Column::Varbinary:
|
case NdbDictionary::Column::Varbinary:
|
||||||
return String;
|
return String;
|
||||||
case NdbDictionary::Column::Datetime:
|
case NdbDictionary::Column::Datetime:
|
||||||
case NdbDictionary::Column::Timespec:
|
case NdbDictionary::Column::Date:
|
||||||
|
case NdbDictionary::Column::Time:
|
||||||
case NdbDictionary::Column::Undefined:
|
case NdbDictionary::Column::Undefined:
|
||||||
default:
|
default:
|
||||||
return NoAttrTypeDef;
|
return NoAttrTypeDef;
|
||||||
|
@ -1978,7 +1978,7 @@ Val::cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned
|
|||||||
unsigned len = maxxmulsize * col.m_bytelength;
|
unsigned len = maxxmulsize * col.m_bytelength;
|
||||||
int n1 = NdbSqlUtil::strnxfrm_bug7284(cs, x1, chs->m_xmul * len, buf1, len1);
|
int n1 = NdbSqlUtil::strnxfrm_bug7284(cs, x1, chs->m_xmul * len, buf1, len1);
|
||||||
int n2 = NdbSqlUtil::strnxfrm_bug7284(cs, x2, chs->m_xmul * len, buf2, len2);
|
int n2 = NdbSqlUtil::strnxfrm_bug7284(cs, x2, chs->m_xmul * len, buf2, len2);
|
||||||
assert(n1 == n2);
|
assert(n1 != -1 && n1 == n2);
|
||||||
k = memcmp(x1, x2, n1);
|
k = memcmp(x1, x2, n1);
|
||||||
} else {
|
} else {
|
||||||
k = (*cs->coll->strnncollsp)(cs, buf1, len1, buf2, len2, false);
|
k = (*cs->coll->strnncollsp)(cs, buf1, len1, buf2, len2, false);
|
||||||
|
@ -71,7 +71,10 @@ BackupConsumer::create_table_string(const TableS & table,
|
|||||||
case NdbDictionary::Column::Datetime:
|
case NdbDictionary::Column::Datetime:
|
||||||
pos += sprintf(buf+pos, "%s", "datetime");
|
pos += sprintf(buf+pos, "%s", "datetime");
|
||||||
break;
|
break;
|
||||||
case NdbDictionary::Column::Timespec:
|
case NdbDictionary::Column::Date:
|
||||||
|
pos += sprintf(buf+pos, "%s", "date");
|
||||||
|
break;
|
||||||
|
case NdbDictionary::Column::Time:
|
||||||
pos += sprintf(buf+pos, "%s", "time");
|
pos += sprintf(buf+pos, "%s", "time");
|
||||||
break;
|
break;
|
||||||
case NdbDictionary::Column::Undefined:
|
case NdbDictionary::Column::Undefined:
|
||||||
|
@ -1663,7 +1663,7 @@ pr_tag_type (p, name, id, kind)
|
|||||||
{
|
{
|
||||||
struct pr_handle *info = (struct pr_handle *) p;
|
struct pr_handle *info = (struct pr_handle *) p;
|
||||||
const char *t, *tag;
|
const char *t, *tag;
|
||||||
char idbuf[20];
|
char idbuf[30];
|
||||||
|
|
||||||
switch (kind)
|
switch (kind)
|
||||||
{
|
{
|
||||||
|
@ -93,10 +93,10 @@ CREATE TABLE IF NOT EXISTS tables_priv (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS columns_priv (
|
CREATE TABLE IF NOT EXISTS columns_priv (
|
||||||
Host char(60) DEFAULT '' NOT NULL,
|
Host char(60) DEFAULT '' NOT NULL,
|
||||||
Db char(60) DEFAULT '' NOT NULL,
|
Db char(64) DEFAULT '' NOT NULL,
|
||||||
User char(16) DEFAULT '' NOT NULL,
|
User char(16) DEFAULT '' NOT NULL,
|
||||||
Table_name char(60) DEFAULT '' NOT NULL,
|
Table_name char(64) DEFAULT '' NOT NULL,
|
||||||
Column_name char(59) DEFAULT '' NOT NULL,
|
Column_name char(64) DEFAULT '' NOT NULL,
|
||||||
Timestamp timestamp(14),
|
Timestamp timestamp(14),
|
||||||
Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,
|
Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,
|
||||||
PRIMARY KEY (Host,Db,User,Table_name,Column_name)
|
PRIMARY KEY (Host,Db,User,Table_name,Column_name)
|
||||||
|
36
sql/field.cc
36
sql/field.cc
@ -2440,23 +2440,7 @@ int Field_float::store(double nr)
|
|||||||
|
|
||||||
int Field_float::store(longlong nr)
|
int Field_float::store(longlong nr)
|
||||||
{
|
{
|
||||||
int error= 0;
|
return store((double)nr);
|
||||||
float j= (float) nr;
|
|
||||||
if (unsigned_flag && j < 0)
|
|
||||||
{
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
j=0;
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
if (table->db_low_byte_first)
|
|
||||||
{
|
|
||||||
float4store(ptr,j);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
memcpy_fixed(ptr,(byte*) &j,sizeof(j));
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2738,23 +2722,7 @@ int Field_double::store(double nr)
|
|||||||
|
|
||||||
int Field_double::store(longlong nr)
|
int Field_double::store(longlong nr)
|
||||||
{
|
{
|
||||||
double j= (double) nr;
|
return store((double)nr);
|
||||||
int error= 0;
|
|
||||||
if (unsigned_flag && j < 0)
|
|
||||||
{
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
j=0;
|
|
||||||
}
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
if (table->db_low_byte_first)
|
|
||||||
{
|
|
||||||
float8store(ptr,j);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
doublestore(ptr,j);
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3907,7 +3907,7 @@ ha_innobase::create(
|
|||||||
|
|
||||||
error = create_table_def(trx, form, norm_name,
|
error = create_table_def(trx, form, norm_name,
|
||||||
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
||||||
!(form->s->db_options_in_use & HA_OPTION_PACK_RECORD));
|
form->s->row_type != ROW_TYPE_REDUNDANT);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
innobase_commit_low(trx);
|
innobase_commit_low(trx);
|
||||||
|
@ -2393,13 +2393,15 @@ void ha_ndbcluster::print_results()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NdbDictionary::Column::Datetime: {
|
case NdbDictionary::Column::Datetime: {
|
||||||
// todo
|
my_snprintf(buf, sizeof(buf), "Datetime ?"); // fix-me
|
||||||
my_snprintf(buf, sizeof(buf), "Datetime ?");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NdbDictionary::Column::Timespec: {
|
case NdbDictionary::Column::Date: {
|
||||||
// todo
|
my_snprintf(buf, sizeof(buf), "Date ?"); // fix-me
|
||||||
my_snprintf(buf, sizeof(buf), "Timespec ?");
|
break;
|
||||||
|
}
|
||||||
|
case NdbDictionary::Column::Time: {
|
||||||
|
my_snprintf(buf, sizeof(buf), "Time ?"); // fix-me
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NdbDictionary::Column::Blob: {
|
case NdbDictionary::Column::Blob: {
|
||||||
@ -3420,6 +3422,9 @@ int ndbcluster_rollback(THD *thd, void *ndb_transaction)
|
|||||||
Define NDB column based on Field.
|
Define NDB column based on Field.
|
||||||
Returns 0 or mysql error code.
|
Returns 0 or mysql error code.
|
||||||
Not member of ha_ndbcluster because NDBCOL cannot be declared.
|
Not member of ha_ndbcluster because NDBCOL cannot be declared.
|
||||||
|
|
||||||
|
MySQL text types with character set "binary" are mapped to true
|
||||||
|
NDB binary types without a character set. This may change.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int create_ndb_column(NDBCOL &col,
|
static int create_ndb_column(NDBCOL &col,
|
||||||
@ -3495,9 +3500,15 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
col.setType(NDBCOL::Datetime);
|
col.setType(NDBCOL::Datetime);
|
||||||
col.setLength(1);
|
col.setLength(1);
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_DATE:
|
|
||||||
case MYSQL_TYPE_NEWDATE:
|
case MYSQL_TYPE_NEWDATE:
|
||||||
|
col.setType(NDBCOL::Date);
|
||||||
|
col.setLength(1);
|
||||||
|
break;
|
||||||
case MYSQL_TYPE_TIME:
|
case MYSQL_TYPE_TIME:
|
||||||
|
col.setType(NDBCOL::Time);
|
||||||
|
col.setLength(1);
|
||||||
|
break;
|
||||||
|
case MYSQL_TYPE_DATE: // ?
|
||||||
case MYSQL_TYPE_YEAR:
|
case MYSQL_TYPE_YEAR:
|
||||||
col.setType(NDBCOL::Char);
|
col.setType(NDBCOL::Char);
|
||||||
col.setLength(field->pack_length());
|
col.setLength(field->pack_length());
|
||||||
@ -3509,7 +3520,7 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
col.setType(NDBCOL::Bit);
|
col.setType(NDBCOL::Bit);
|
||||||
col.setLength(1);
|
col.setLength(1);
|
||||||
}
|
}
|
||||||
else if (field->flags & BINARY_FLAG)
|
else if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
|
||||||
{
|
{
|
||||||
col.setType(NDBCOL::Binary);
|
col.setType(NDBCOL::Binary);
|
||||||
col.setLength(field->pack_length());
|
col.setLength(field->pack_length());
|
||||||
@ -3527,7 +3538,7 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
Field_varstring* f= (Field_varstring*)field;
|
Field_varstring* f= (Field_varstring*)field;
|
||||||
if (f->length_bytes == 1)
|
if (f->length_bytes == 1)
|
||||||
{
|
{
|
||||||
if (field->flags & BINARY_FLAG)
|
if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
|
||||||
col.setType(NDBCOL::Varbinary);
|
col.setType(NDBCOL::Varbinary);
|
||||||
else {
|
else {
|
||||||
col.setType(NDBCOL::Varchar);
|
col.setType(NDBCOL::Varchar);
|
||||||
@ -3536,7 +3547,7 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
}
|
}
|
||||||
else if (f->length_bytes == 2)
|
else if (f->length_bytes == 2)
|
||||||
{
|
{
|
||||||
if (field->flags & BINARY_FLAG)
|
if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
|
||||||
col.setType(NDBCOL::Longvarbinary);
|
col.setType(NDBCOL::Longvarbinary);
|
||||||
else {
|
else {
|
||||||
col.setType(NDBCOL::Longvarchar);
|
col.setType(NDBCOL::Longvarchar);
|
||||||
@ -3553,7 +3564,7 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
// Blob types (all come in as MYSQL_TYPE_BLOB)
|
// Blob types (all come in as MYSQL_TYPE_BLOB)
|
||||||
mysql_type_tiny_blob:
|
mysql_type_tiny_blob:
|
||||||
case MYSQL_TYPE_TINY_BLOB:
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
if (field->flags & BINARY_FLAG)
|
if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
|
||||||
col.setType(NDBCOL::Blob);
|
col.setType(NDBCOL::Blob);
|
||||||
else {
|
else {
|
||||||
col.setType(NDBCOL::Text);
|
col.setType(NDBCOL::Text);
|
||||||
@ -3566,7 +3577,7 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
break;
|
break;
|
||||||
//mysql_type_blob:
|
//mysql_type_blob:
|
||||||
case MYSQL_TYPE_BLOB:
|
case MYSQL_TYPE_BLOB:
|
||||||
if (field->flags & BINARY_FLAG)
|
if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
|
||||||
col.setType(NDBCOL::Blob);
|
col.setType(NDBCOL::Blob);
|
||||||
else {
|
else {
|
||||||
col.setType(NDBCOL::Text);
|
col.setType(NDBCOL::Text);
|
||||||
@ -3588,7 +3599,7 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
break;
|
break;
|
||||||
mysql_type_medium_blob:
|
mysql_type_medium_blob:
|
||||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
if (field->flags & BINARY_FLAG)
|
if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
|
||||||
col.setType(NDBCOL::Blob);
|
col.setType(NDBCOL::Blob);
|
||||||
else {
|
else {
|
||||||
col.setType(NDBCOL::Text);
|
col.setType(NDBCOL::Text);
|
||||||
@ -3600,7 +3611,7 @@ static int create_ndb_column(NDBCOL &col,
|
|||||||
break;
|
break;
|
||||||
mysql_type_long_blob:
|
mysql_type_long_blob:
|
||||||
case MYSQL_TYPE_LONG_BLOB:
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
if (field->flags & BINARY_FLAG)
|
if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
|
||||||
col.setType(NDBCOL::Blob);
|
col.setType(NDBCOL::Blob);
|
||||||
else {
|
else {
|
||||||
col.setType(NDBCOL::Text);
|
col.setType(NDBCOL::Text);
|
||||||
|
@ -101,7 +101,7 @@ struct show_table_type_st sys_table_types[]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char *ha_row_type[] = {
|
const char *ha_row_type[] = {
|
||||||
"", "FIXED", "DYNAMIC", "COMPRESSED","?","?","?"
|
"", "FIXED", "DYNAMIC", "COMPRESSED", "REDUNDANT", "COMPACT", "?","?","?"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *tx_isolation_names[] =
|
const char *tx_isolation_names[] =
|
||||||
|
@ -167,7 +167,8 @@ struct show_table_type_st {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
|
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
|
||||||
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED};
|
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
|
||||||
|
ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT };
|
||||||
|
|
||||||
/* struct to hold information about the table that should be created */
|
/* struct to hold information about the table that should be created */
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "COMMENT", SYM(COMMENT_SYM)},
|
{ "COMMENT", SYM(COMMENT_SYM)},
|
||||||
{ "COMMIT", SYM(COMMIT_SYM)},
|
{ "COMMIT", SYM(COMMIT_SYM)},
|
||||||
{ "COMMITTED", SYM(COMMITTED_SYM)},
|
{ "COMMITTED", SYM(COMMITTED_SYM)},
|
||||||
|
{ "COMPACT", SYM(COMPACT_SYM)},
|
||||||
{ "COMPRESSED", SYM(COMPRESSED_SYM)},
|
{ "COMPRESSED", SYM(COMPRESSED_SYM)},
|
||||||
{ "CONCURRENT", SYM(CONCURRENT)},
|
{ "CONCURRENT", SYM(CONCURRENT)},
|
||||||
{ "CONDITION", SYM(CONDITION_SYM)},
|
{ "CONDITION", SYM(CONDITION_SYM)},
|
||||||
@ -378,6 +379,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "READ", SYM(READ_SYM)},
|
{ "READ", SYM(READ_SYM)},
|
||||||
{ "READS", SYM(READS_SYM)},
|
{ "READS", SYM(READS_SYM)},
|
||||||
{ "REAL", SYM(REAL)},
|
{ "REAL", SYM(REAL)},
|
||||||
|
{ "REDUNDANT", SYM(REDUNDANT_SYM)},
|
||||||
{ "REFERENCES", SYM(REFERENCES)},
|
{ "REFERENCES", SYM(REFERENCES)},
|
||||||
{ "REGEXP", SYM(REGEXP)},
|
{ "REGEXP", SYM(REGEXP)},
|
||||||
{ "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM)},
|
{ "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM)},
|
||||||
|
@ -227,6 +227,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token COLLATION_SYM
|
%token COLLATION_SYM
|
||||||
%token COLUMNS
|
%token COLUMNS
|
||||||
%token COLUMN_SYM
|
%token COLUMN_SYM
|
||||||
|
%token COMPACT_SYM
|
||||||
%token CONCURRENT
|
%token CONCURRENT
|
||||||
%token CONDITION_SYM
|
%token CONDITION_SYM
|
||||||
%token CONNECTION_SYM
|
%token CONNECTION_SYM
|
||||||
@ -381,6 +382,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token READ_SYM
|
%token READ_SYM
|
||||||
%token READS_SYM
|
%token READS_SYM
|
||||||
%token REAL_NUM
|
%token REAL_NUM
|
||||||
|
%token REDUNDANT_SYM
|
||||||
%token REFERENCES
|
%token REFERENCES
|
||||||
%token REGEXP
|
%token REGEXP
|
||||||
%token RELOAD
|
%token RELOAD
|
||||||
@ -2628,7 +2630,9 @@ row_types:
|
|||||||
DEFAULT { $$= ROW_TYPE_DEFAULT; }
|
DEFAULT { $$= ROW_TYPE_DEFAULT; }
|
||||||
| FIXED_SYM { $$= ROW_TYPE_FIXED; }
|
| FIXED_SYM { $$= ROW_TYPE_FIXED; }
|
||||||
| DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; }
|
| DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; }
|
||||||
| COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; };
|
| COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
|
||||||
|
| REDUNDANT_SYM { $$= ROW_TYPE_REDUNDANT; }
|
||||||
|
| COMPACT_SYM { $$= ROW_TYPE_COMPACT; };
|
||||||
|
|
||||||
raid_types:
|
raid_types:
|
||||||
RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
|
RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
|
||||||
@ -6915,6 +6919,7 @@ keyword:
|
|||||||
| COMMENT_SYM {}
|
| COMMENT_SYM {}
|
||||||
| COMMITTED_SYM {}
|
| COMMITTED_SYM {}
|
||||||
| COMMIT_SYM {}
|
| COMMIT_SYM {}
|
||||||
|
| COMPACT_SYM {}
|
||||||
| COMPRESSED_SYM {}
|
| COMPRESSED_SYM {}
|
||||||
| CONCURRENT {}
|
| CONCURRENT {}
|
||||||
| CONSISTENT_SYM {}
|
| CONSISTENT_SYM {}
|
||||||
@ -7046,6 +7051,7 @@ keyword:
|
|||||||
| RAID_CHUNKSIZE {}
|
| RAID_CHUNKSIZE {}
|
||||||
| RAID_STRIPED_SYM {}
|
| RAID_STRIPED_SYM {}
|
||||||
| RAID_TYPE {}
|
| RAID_TYPE {}
|
||||||
|
| REDUNDANT_SYM {}
|
||||||
| RELAY_LOG_FILE_SYM {}
|
| RELAY_LOG_FILE_SYM {}
|
||||||
| RELAY_LOG_POS_SYM {}
|
| RELAY_LOG_POS_SYM {}
|
||||||
| RELOAD {}
|
| RELOAD {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user