summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2005-01-09 05:03:33 +0100
committerunknown <joreland@mysql.com>2005-01-09 05:03:33 +0100
commit79192c23358c9604a8c854a1b626e61ecbd6b34c (patch)
tree2e9efb92a0336cd77303a613de2a714d86b22fea
parente7c19e9e00334b72e73d4070182712bd8bb0c7e7 (diff)
parent91a3e90baf0a515470622f7720fcea64745f70fa (diff)
downloadmariadb-git-79192c23358c9604a8c854a1b626e61ecbd6b34c.tar.gz
Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.0-ndb
into mysql.com:/home/jonas/src/mysql-5.0-ndb
-rw-r--r--client/completion_hash.cc3
-rw-r--r--client/mysql.cc9
-rw-r--r--cmd-line-utils/libedit/makelist.sh2
-rw-r--r--cmd-line-utils/libedit/parse.c3
-rw-r--r--mysql-test/r/ndb_index_ordered.result110
-rw-r--r--mysql-test/r/type_float.result36
-rw-r--r--mysql-test/r/type_float.result.es40
-rw-r--r--mysql-test/t/ndb_index_ordered.test64
-rw-r--r--mysql-test/t/type_float.test10
-rw-r--r--ndb/include/kernel/signaldata/DictTabInfo.hpp13
-rw-r--r--ndb/include/mgmapi/mgmapi.h324
-rw-r--r--ndb/include/ndb_constants.h7
-rw-r--r--ndb/include/ndbapi/Ndb.hpp312
-rw-r--r--ndb/include/ndbapi/NdbDictionary.hpp29
-rw-r--r--ndb/include/ndbapi/NdbEventOperation.hpp74
-rw-r--r--ndb/include/util/NdbSqlUtil.hpp8
-rw-r--r--ndb/src/common/util/NdbSqlUtil.cpp77
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp3
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp2
-rw-r--r--ndb/src/ndbapi/Ndb.cpp9
-rw-r--r--ndb/src/ndbapi/NdbDictionary.cpp7
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.cpp8
-rw-r--r--ndb/src/ndbapi/NdbEventOperationImpl.cpp34
-rw-r--r--ndb/test/include/NdbSchemaOp.hpp3
-rw-r--r--ndb/test/ndbapi/testOIBasic.cpp2
-rw-r--r--ndb/tools/restore/consumer.cpp5
-rw-r--r--pstack/pstack.c2
-rw-r--r--scripts/mysql_fix_privilege_tables.sql6
-rw-r--r--sql/field.cc36
-rw-r--r--sql/ha_innodb.cc2
-rw-r--r--sql/ha_ndbcluster.cc37
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/handler.h3
-rw-r--r--sql/lex.h2
-rw-r--r--sql/sql_yacc.yy8
35 files changed, 878 insertions, 414 deletions
diff --git a/client/completion_hash.cc b/client/completion_hash.cc
index 536e7f9373a..7a3b363c93c 100644
--- a/client/completion_hash.cc
+++ b/client/completion_hash.cc
@@ -79,7 +79,8 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
if (!memcmp(p->arKey, arKey, nKeyLength)) {
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->str = str;
p->pData = n;
diff --git a/client/mysql.cc b/client/mysql.cc
index ace595f9cad..e605c2d7db4 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -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,
sizeof(char *) *
(num_fields*2+1))))
- break;
+ {
+ mysql_free_result(fields);
+ break;
+ }
field_names[i][num_fields*2]= '\0';
j=0;
while ((sql_field=mysql_fetch_field(fields)))
@@ -2077,10 +2080,10 @@ print_table_data_html(MYSQL_RES *result)
}
while ((cur = mysql_fetch_row(result)))
{
+ ulong *lengths=mysql_fetch_lengths(result);
(void) tee_fputs("<TR>", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
- ulong *lengths=mysql_fetch_lengths(result);
(void) tee_fputs("<TD>", PAGER);
safe_put_field(cur[i],lengths[i]);
(void) tee_fputs("</TD>", PAGER);
@@ -2106,10 +2109,10 @@ print_table_data_xml(MYSQL_RES *result)
fields = mysql_fetch_fields(result);
while ((cur = mysql_fetch_row(result)))
{
+ ulong *lengths=mysql_fetch_lengths(result);
(void) tee_fputs("\n <row>\n", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
- ulong *lengths=mysql_fetch_lengths(result);
tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
(fields[i].name[0] ? fields[i].name :
" &nbsp; ") : "NULL"));
diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh
index fbce06fcc50..b2502d16ed1 100644
--- a/cmd-line-utils/libedit/makelist.sh
+++ b/cmd-line-utils/libedit/makelist.sh
@@ -145,7 +145,7 @@ case $FLAG in
#
-fh)
cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
- sort | tr '[a-z]' '[A-Z]' | $AWK '
+ sort | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c
index b113353d464..d09b890c1ab 100644
--- a/cmd-line-utils/libedit/parse.c
+++ b/cmd-line-utils/libedit/parse.c
@@ -87,7 +87,8 @@ parse_line(EditLine *el, const char *line)
int argc;
Tokenizer *tok;
- tok = tok_init(NULL);
+ if (!(tok = tok_init(NULL)))
+ return -1;
tok_line(tok, line, &argc, &argv);
argc = el_parse(el, argc, argv);
tok_end(tok);
diff --git a/mysql-test/r/ndb_index_ordered.result b/mysql-test/r/ndb_index_ordered.result
index 1cf2a97a6b3..ccb202b25a8 100644
--- a/mysql-test/r/ndb_index_ordered.result
+++ b/mysql-test/r/ndb_index_ordered.result
@@ -419,3 +419,113 @@ SubscrID SbclID
3 NULL
drop table test1;
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
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index 151ec404455..62aae177f6a 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -143,3 +143,39 @@ drop table t1;
create table t1 (f float(54));
ERROR 42000: Incorrect column specifier for column 'f'
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;
diff --git a/mysql-test/r/type_float.result.es b/mysql-test/r/type_float.result.es
index 4bfe644d7fb..d1c72a2ee53 100644
--- a/mysql-test/r/type_float.result.es
+++ b/mysql-test/r/type_float.result.es
@@ -15,8 +15,8 @@ f1 float 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);
Warnings:
-Warning 1264 Data truncated; out of range 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 7
+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);
select * from t1;
f1 f2
@@ -143,3 +143,39 @@ drop table t1;
create table t1 (f float(54));
ERROR 42000: Incorrect column specifier for column 'f'
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;
diff --git a/mysql-test/t/ndb_index_ordered.test b/mysql-test/t/ndb_index_ordered.test
index 42325e25ea3..b7a5b418f44 100644
--- a/mysql-test/t/ndb_index_ordered.test
+++ b/mysql-test/t/ndb_index_ordered.test
@@ -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;
drop table test1;
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';
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index 26ac272c6d4..3fe3afa3fac 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -93,3 +93,13 @@ create table t1 (f float(54)); # Should give an error
drop table if exists t1;
--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;
diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp
index cc8a647615c..93ad246a094 100644
--- a/ndb/include/kernel/signaldata/DictTabInfo.hpp
+++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp
@@ -266,12 +266,13 @@ public:
ExtBinary = NdbSqlUtil::Type::Binary,
ExtVarbinary = NdbSqlUtil::Type::Varbinary,
ExtDatetime = NdbSqlUtil::Type::Datetime,
- ExtTimespec = NdbSqlUtil::Type::Timespec,
+ ExtDate = NdbSqlUtil::Type::Date,
ExtBlob = NdbSqlUtil::Type::Blob,
ExtText = NdbSqlUtil::Type::Text,
ExtBit = NdbSqlUtil::Type::Bit,
ExtLongvarchar = NdbSqlUtil::Type::Longvarchar,
- ExtLongvarbinary = NdbSqlUtil::Type::Longvarbinary
+ ExtLongvarbinary = NdbSqlUtil::Type::Longvarbinary,
+ ExtTime = NdbSqlUtil::Type::Time
};
// Attribute data interpretation
@@ -358,10 +359,10 @@ public:
AttributeSize = DictTabInfo::an8Bit;
AttributeArraySize = 8 * AttributeExtLength;
break;
- case DictTabInfo::ExtTimespec:
+ case DictTabInfo::ExtDate:
// to fix
AttributeSize = DictTabInfo::an8Bit;
- AttributeArraySize = 12 * AttributeExtLength;
+ AttributeArraySize = 3 * AttributeExtLength;
break;
case DictTabInfo::ExtBlob:
case DictTabInfo::ExtText:
@@ -380,6 +381,10 @@ public:
AttributeSize = DictTabInfo::an8Bit;
AttributeArraySize = AttributeExtLength + 2;
break;
+ case DictTabInfo::ExtTime:
+ AttributeSize = DictTabInfo::an8Bit;
+ AttributeArraySize = 3 * AttributeExtLength;
+ break;
default:
return false;
};
diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h
index fb2a31d6ee2..5d426e5753b 100644
--- a/ndb/include/mgmapi/mgmapi.h
+++ b/ndb/include/mgmapi/mgmapi.h
@@ -22,7 +22,7 @@
*
* The NDB Cluster Management API (MGM API) is a C API
* that is used to:
- * - Start and stop database nodes (DB nodes)
+ * - Start and stop database nodes (ndbd processes)
* - Start and stop NDB Cluster backups
* - Control the NDB Cluster log
* - Perform other administrative tasks
@@ -30,18 +30,23 @@
* @section General Concepts
*
* 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
- * function ndb_mgm_create_handle().
+ * function ndb_mgm_create_handle() and freed by calling
+ * ndb_mgm_destroy_handle().
*
* A function can return:
* -# An integer value.
* A value of <b>-1</b> indicates an error.
- * -# A pointer value. A <var>NULL</var> value indicates an error;
- * otherwise, the return value must be freed by the user of the MGM API.
+ * -# 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
+ * -# 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-reporting functions.
+ * error-reporting functions ndb_mgm_get_latest_error() and
+ * @ref ndb_mgm_error.
*/
/** @addtogroup MGM_C_API
@@ -64,32 +69,54 @@ extern "C" {
* NDB Cluster node types
*/
enum ndb_mgm_node_type {
- 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_NDB = NODE_TYPE_DB, /*< A database node (DB)*/
- NDB_MGM_NODE_TYPE_MGM = NODE_TYPE_MGM,/*< A mgmt server node (MGM)*/
- 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*/
+ NDB_MGM_NODE_TYPE_UNKNOWN = -1 /** Node type not known*/
+ ,NDB_MGM_NODE_TYPE_API /** An application node (API) */
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
+ = NODE_TYPE_API
+#endif
+ ,NDB_MGM_NODE_TYPE_NDB /** A database node (DB) */
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
+ = 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
*/
enum ndb_mgm_node_status {
- NDB_MGM_NODE_STATUS_UNKNOWN = 0, /*< Node status not known*/
- NDB_MGM_NODE_STATUS_NO_CONTACT = 1, /*< No contact with node*/
- NDB_MGM_NODE_STATUS_NOT_STARTED = 2, /*< Has not run starting protocol*/
- NDB_MGM_NODE_STATUS_STARTING = 3, /*< Is running starting protocol*/
- NDB_MGM_NODE_STATUS_STARTED = 4, /*< Running*/
- NDB_MGM_NODE_STATUS_SHUTTING_DOWN = 5, /*< Is shutting down*/
- NDB_MGM_NODE_STATUS_RESTARTING = 6, /*< Is restarting*/
- NDB_MGM_NODE_STATUS_SINGLEUSER = 7, /*< Maintenance mode*/
- NDB_MGM_NODE_STATUS_RESUME = 8, /*< Resume mode*/
-
- NDB_MGM_NODE_STATUS_MIN = 0, /*< Min valid value*/
- NDB_MGM_NODE_STATUS_MAX = 6 /*< Max valid value*/
+ /** Node status not known*/
+ NDB_MGM_NODE_STATUS_UNKNOWN = 0,
+ /** No contact with node*/
+ NDB_MGM_NODE_STATUS_NO_CONTACT = 1,
+ /** Has not run starting protocol*/
+ NDB_MGM_NODE_STATUS_NOT_STARTED = 2,
+ /** Is running starting protocol*/
+ NDB_MGM_NODE_STATUS_STARTING = 3,
+ /** Running*/
+ NDB_MGM_NODE_STATUS_STARTED = 4,
+ /** Is shutting down*/
+ 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
};
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
struct Ndb_Mgm_Error_Msg {
enum ndb_mgm_error code;
const char * msg;
};
-
const struct Ndb_Mgm_Error_Msg ndb_mgm_error_msgs[] = {
{ NDB_MGM_NO_ERROR, "No error" },
+ /* Request for service errors */
{ NDB_MGM_ILLEGAL_CONNECT_STRING, "Illegal connect string" },
{ NDB_MGM_ILLEGAL_PORT_NUMBER, "Illegal port number" },
{ NDB_MGM_ILLEGAL_SOCKET, "Illegal socket" },
@@ -167,66 +195,86 @@ extern "C" {
{ NDB_MGM_USAGE_ERROR,
"Usage error" }
};
-
const int ndb_mgm_noOfErrorMsgs =
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 {
- int node_id; /*< NDB Cluster node id*/
- enum ndb_mgm_node_type node_type; /*< Type of NDB Cluster node*/
- enum ndb_mgm_node_status node_status; /*< State of node*/
- int start_phase; /*< Start phase.
- *< @note Start phase is only
- *< valid if
- *< node_type is
- *< NDB_MGM_NODE_TYPE_NDB and
- *< node_status is
- *< NDB_MGM_NODE_STATUS_STARTING
- */
- int dynamic_id; /*< Id for heartbeats and
- *< master take-over
- *< (only valid for DB nodes)
- */
- int node_group; /*< Node group of node
- *< (only valid for DB nodes)*/
- int version; /*< Internal version number*/
- int connect_count; /*< Number of times node has connected
- *< or disconnected to the mgm srv
- */
- char connect_address[sizeof("000.000.000.000")+1];
+ /** NDB Cluster node id*/
+ int node_id;
+ /** Type of NDB Cluster node*/
+ enum ndb_mgm_node_type node_type;
+ /** State of node*/
+ enum ndb_mgm_node_status node_status;
+ /** Start phase.
+ *
+ * @note Start phase is only valid if node_type is
+ * NDB_MGM_NODE_TYPE_NDB and node_status is
+ * NDB_MGM_NODE_STATUS_STARTING
+ */
+ int start_phase;
+ /** Id for heartbeats and master take-over (only valid for DB nodes)
+ */
+ int dynamic_id;
+ /** Node group of node (only valid for DB nodes)*/
+ int node_group;
+ /** Internal version number*/
+ int version;
+ /** Number of times node has connected or disconnected to the
+ * management server
+ */
+ 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 {
- int no_of_nodes; /*< No of entries in the
- *< node_states array
- */
- struct ndb_mgm_node_state /*< An array with node_states*/
- node_states[1];
- const char *hostname;
+ /** No of entries in the node_states array */
+ int no_of_nodes;
+ /** An array with node_states*/
+ struct ndb_mgm_node_state node_states[
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
+ 1
+#endif
+ ];
};
/**
- * Default reply from the server
+ * Default reply from the server (for future use, not used today)
*/
struct ndb_mgm_reply {
- int return_code; /*< 0 if successful,
- *< otherwise error code.
- */
- char message[256]; /*< Error or reply message.*/
+ /** 0 if successful, otherwise error code. */
+ int return_code;
+ /** Error or reply message.*/
+ char message[256];
};
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
* Default information types
*/
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.)
*/
enum ndb_mgm_signal_log_mode {
- NDB_MGM_SIGNAL_LOG_MODE_IN, /*< Log receiving signals */
- NDB_MGM_SIGNAL_LOG_MODE_OUT, /*< Log sending signals*/
- NDB_MGM_SIGNAL_LOG_MODE_INOUT, /*< Log both sending/receiving*/
- NDB_MGM_SIGNAL_LOG_MODE_OFF /*< Log off*/
+ /** Log receiving signals */
+ NDB_MGM_SIGNAL_LOG_MODE_IN,
+ /** Log sending signals*/
+ 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)
@@ -246,32 +299,31 @@ extern "C" {
enum ndb_mgm_clusterlog_level {
NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL = -1,
/* must range from 0 and up, indexes into an array */
- NDB_MGM_CLUSTERLOG_ON = 0, /*< Cluster log on*/
- NDB_MGM_CLUSTERLOG_DEBUG = 1, /*< Used in NDB Cluster
- *< developement
- */
- NDB_MGM_CLUSTERLOG_INFO = 2, /*< Informational messages*/
- NDB_MGM_CLUSTERLOG_WARNING = 3, /*< Conditions that are not
- *< error condition, but
- *< might require handling
- */
- NDB_MGM_CLUSTERLOG_ERROR = 4, /*< Conditions that should be
- *< corrected
- */
- 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
- */
+ /** Cluster log on*/
+ NDB_MGM_CLUSTERLOG_ON = 0,
+ /** 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_WARNING = 3,
+ /** Conditions that should be corrected */
+ NDB_MGM_CLUSTERLOG_ERROR = 4,
+ /** Critical conditions, like device errors or out of resources */
+ NDB_MGM_CLUSTERLOG_CRITICAL = 5,
+ /** 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 */
- 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 {
/**
@@ -282,28 +334,56 @@ extern "C" {
* Events during all kinds of startups
*/
NDB_MGM_EVENT_CATEGORY_STARTUP = CFG_LOGLEVEL_STARTUP,
-
/**
* Events during shutdown
*/
NDB_MGM_EVENT_CATEGORY_SHUTDOWN = CFG_LOGLEVEL_SHUTDOWN,
-
/**
* Transaction statistics (Job level, TCP/IP speed)
*/
NDB_MGM_EVENT_CATEGORY_STATISTIC = CFG_LOGLEVEL_STATISTICS,
+ /**
+ * Events regarding checkpoints
+ */
NDB_MGM_EVENT_CATEGORY_CHECKPOINT = CFG_LOGLEVEL_CHECKPOINT,
+ /**
+ * Events during node restart
+ */
NDB_MGM_EVENT_CATEGORY_NODE_RESTART = CFG_LOGLEVEL_NODERESTART,
+ /**
+ * Events on connection between cluster nodes
+ */
NDB_MGM_EVENT_CATEGORY_CONNECTION = CFG_LOGLEVEL_CONNECTION,
+ /**
+ * Backup events
+ */
+ 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,
- NDB_MGM_EVENT_CATEGORY_BACKUP = CFG_LOGLEVEL_BACKUP,
-
+#endif
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
NDB_MGM_MIN_EVENT_CATEGORY = CFG_MIN_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,
*
* @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,
const char *connect_string);
@@ -391,8 +480,8 @@ extern "C" {
/**
* Get connectstring used for connection
*
- * @note returns what the connectstring defaults to if the above call has
- * not been performed
+ * @note returns what the connectstring defaults to if the
+ * ndb_mgm_set_connectstring() call has not been performed
*
* @param handle Management handle
*
@@ -401,7 +490,8 @@ extern "C" {
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.
* @return -1 on error.
@@ -422,7 +512,8 @@ extern "C" {
*
* @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);
@@ -444,6 +535,7 @@ extern "C" {
*/
const char *ndb_mgm_get_connected_host(NdbMgmHandle handle);
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/** @} *********************************************************************/
/**
* @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_clusterlog_level_string(enum ndb_mgm_clusterlog_level);
-#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
ndb_mgm_event_category ndb_mgm_match_event_category(const char *);
const char * ndb_mgm_get_event_category_string(enum ndb_mgm_event_category);
#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,
int level,
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
/**
* Set log category and levels for the Node
@@ -708,9 +810,9 @@ extern "C" {
* Start backup
*
* @param handle NDB management handle.
- * @param wait_completed 0=don't wait for confirmation
- 1=wait for backup started
- 2=wait for backup completed
+ * @param wait_completed 0=don't wait for confirmation,
+ * 1=wait for backup started,
+ * 2=wait for backup completed
* @param backup_id Backup id is returned from function.
* @param reply Reply message.
* @return -1 on error.
@@ -760,25 +862,21 @@ extern "C" {
int ndb_mgm_exit_single_user(NdbMgmHandle handle,
struct ndb_mgm_reply* reply);
+ /** @} *********************************************************************/
/**
- * Listen event
- *
- * @param filter pairs of { level, category } that will be
- * pushed to fd, level=0 ends lists
- *
- * @return fd which events will be pushed to
+ * @name Configuration handling
+ * @{
*/
- int ndb_mgm_listen_event(NdbMgmHandle handle, int filter[]);
/**
* Get configuration
* @param handle NDB management handle.
* @param version Version of configuration, 0 means latest
- * @see MAKE_VERSION
+ * (which is the only supported input at this point)
*
* @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,
unsigned version);
diff --git a/ndb/include/ndb_constants.h b/ndb/include/ndb_constants.h
index 40a3d963955..491d0719a69 100644
--- a/ndb/include/ndb_constants.h
+++ b/ndb/include/ndb_constants.h
@@ -53,14 +53,15 @@
#define NDB_TYPE_VARCHAR 15
#define NDB_TYPE_BINARY 16
#define NDB_TYPE_VARBINARY 17
-#define NDB_TYPE_DATETIME 18 // need to fix
-#define NDB_TYPE_TIMESPEC 19 // need to fix
+#define NDB_TYPE_DATETIME 18
+#define NDB_TYPE_DATE 19
#define NDB_TYPE_BLOB 20
#define NDB_TYPE_TEXT 21
#define NDB_TYPE_BIT 22
#define NDB_TYPE_LONG_VARCHAR 23
#define NDB_TYPE_LONG_VARBINARY 24
+#define NDB_TYPE_TIME 25
-#define NDB_TYPE_MAX 25
+#define NDB_TYPE_MAX 26
#endif
diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp
index dcde0a66872..66cd15f190c 100644
--- a/ndb/include/ndbapi/Ndb.hpp
+++ b/ndb/include/ndbapi/Ndb.hpp
@@ -21,7 +21,7 @@
on http://dev.mysql.com/doc/mysql/en/NDBCluster.html .
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.
The NDB API consists of the following fundamental classes:
- Ndb_cluster_connection, representing a connection to a cluster,
@@ -36,39 +36,38 @@
- NdbDictionary represents meta information about tables and attributes.
- 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.
- 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:
- -# Construct and connect to a cluster using the Ndb_cluster_connection
+ -# Connect to a cluster using the Ndb_cluster_connection
object.
- -# Construct and initialize Ndb object(s) to connect to a database.
- -# Define and execute transactions using NdbTransaction.
+ -# Initiate a database connection by constructing and initialising one or more Ndb objects.
+ -# Define and execute transactions using the NdbTransaction class.
-# 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:
- -# Start transaction (an NdbTransaction)
- -# Add and define operations associated with the transaction using
- NdbOperation, NdbScanOperation, NdbIndexOperation, NdbIndexScanOperation
+ The procedure for using transactions is as follows:
+ -# Start transaction (instantiate an NdbTransaction object)
+ -# Add and define operations associated with the transaction using the
+ NdbOperation, NdbScanOperation, NdbIndexOperation, and NdbIndexScanOperation classes.
-# Execute transaction
The execution can be of two different types,
<var>Commit</var> or <var>NoCommit</var>.
If the execution is of type <var>NoCommit</var>,
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
to add and define more operations to the transaction
for later execution.
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
- operations is allowed.
-
+ operations for this transaction is allowed.
@section secSync Synchronous Transactions
@@ -94,12 +93,12 @@
To execute several parallel synchronous transactions, one can either
use multiple Ndb objects in several threads, or start multiple
- applications programs.
+ application programs.
@section secNdbOperations Operations
- Each NdbTransaction consists of a list of operations which are represented
- by instances of NdbOperation, NdbScanOperation, NdbIndexOperation, and/or
+ A NdbTransaction consists of a list of operations, each of which is represented
+ by an instance of NdbOperation, NdbScanOperation, NdbIndexOperation, or
NdbIndexScanOperation.
<h3>Single row operations</h3>
@@ -111,7 +110,7 @@
-# Specify attribute actions, using NdbOperation::getValue()
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:
@code
@@ -150,17 +149,17 @@
creation and use of synchronous transactions.
<h4>Step 1: Define single row operation type</h4>
- The following types of operations exist:
- -# NdbOperation::insertTuple :
+ The following operation types are supported:
+ -# NdbOperation::insertTuple() :
inserts a non-existing tuple
- -# NdbOperation::writeTuple :
+ -# NdbOperation::writeTuple() :
updates an existing tuple if is exists,
otherwise inserts a new tuple
- -# NdbOperation::updateTuple :
+ -# NdbOperation::updateTuple() :
updates an existing tuple
- -# NdbOperation::deleteTuple :
+ -# NdbOperation::deleteTuple() :
deletes an existing tuple
- -# NdbOperation::readTuple :
+ -# NdbOperation::readTuple() :
reads an existing tuple with specified lock mode
All of these operations operate on the unique tuple key.
@@ -172,20 +171,22 @@
NdbTransaction::getNdbIndexOperation() for each operation.
<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>
- Now it is time to define which attributes should be read or updated.
- Deletes can neither read nor set values, read can only read values and
- updates can only set values.
- Normally the attribute is defined by its name but it is
- also possible to use the attribute identity to define the
+ Next, it is necessary to determine which attributes should be read or updated.
+ It is important to remember that:
+ - Deletes can neither read nor set values, but only delete them
+ - Reads can only read values
+ - 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.
NdbOperation::getValue() returns an NdbRecAttr object
containing the read value.
- To get the value, there is actually two methods.
- The application can either
+ To obtain the actual value, one of two methods can be used;
+ 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
@@ -193,39 +194,40 @@
The NdbRecAttr object is released when Ndb::closeTransaction()
is called.
- Thus, the application can not reference this object after
- Ndb::closeTransaction() have been called.
- The result of reading data from an NdbRecAttr object before
- calling NdbTransaction::execute() is undefined.
+ Thus, the application cannot reference this object following
+ any subsequent call to Ndb::closeTransaction().
+ Attempting to read data from an NdbRecAttr object before
+ calling NdbTransaction::execute() yields an undefined result.
@subsection secScan Scan Operations
- Scans are roughly the equivalent of SQL cursors.
-
- Scans can either be performed on a table (@ref NdbScanOperation) or
- on an ordered index (@ref NdbIndexScanOperation).
+ 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).
- Scan operation are characteriesed by the following:
- - They can only perform reads (shared, exclusive or dirty)
+ Scan operations are characterised by the following:
+ - They can perform only reads (shared, exclusive or dirty)
- They can potentially work with 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()
(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()
-# Specify search conditions, using @ref NdbScanFilter and/or
@ref NdbIndexScanOperation::setBound()
-# Specify attribute actions, using NdbOperation::getValue()
-# 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
- brevity, we omit error-handling.
+ Here are two brief examples illustrating this process. Once again, in order
+ 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
// 1. Create
MyOperation= MyTransaction->getNdbScanOperation("MYTABLENAME");
@@ -244,7 +246,7 @@
MyRecAttr= MyOperation->getValue("ATTR2", NULL);
@endcode
- The second example uses an NdbIndexScanOperation:
+ Our second example uses an NdbIndexScanOperation to perform an index scan:
@code
// 1. Create
MyOperation= MyTransaction->getNdbIndexScanOperation("MYORDEREDINDEX", "MYTABLENAME");
@@ -261,98 +263,87 @@
MyRecAttr = MyOperation->getValue("ATTR2", NULL);
@endcode
- <h4>Step 1: Define scan operation operation type</h4>
- Scan operations only support 1 operation,
- @ref NdbScanOperation::readTuples()
- or @ref NdbIndexScanOperation::readTuples()
+ Some additional discussion of each step required to perform a scan follows:
+
+ <h4>Step 1: Define Scan Operation Type</h4>
+ 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
transaction, then you need to call
NdbTransaction::getNdbScanOperation() or
- NdbTransaction::getNdbIndexScanOperation() for each operation.
+ NdbTransaction::getNdbIndexScanOperation() separately for <b>each</b> operation.
<h4>Step 2: Specify Search Conditions</h4>
The search condition is used to select tuples.
If no search condition is specified, the scan will return all rows
in the table.
- Search condition can be @ref NdbScanFilter which can be used on both
- @ref NdbScanOperation and @ref NdbIndexScanOperation or bounds which
- can only be used on index scans, @ref NdbIndexScanOperation::setBound.
- An index scan can have both NdbScanFilter and bounds
+ The search condition can be an @ref NdbScanFilter (which can be used on both
+ @ref NdbScanOperation and @ref NdbIndexScanOperation) or bounds which
+ can only be used on index scans (@ref NdbIndexScanOperation::setBound()).
+ An index scan can use both NdbScanFilter and bounds.
- @note When NdbScanFilter is used each row is examined but maybe not
- returned. But when using bounds, only rows within bounds will be examined.
+ @note When NdbScanFilter is used, each row is examined, whether or not it is
+ actually returned. However, when using bounds, only rows within the bounds will be examined.
<h4>Step 3: Specify Attribute Actions</h4>
- Now it is time to define which attributes should be read.
- Normally the attribute is defined by its name but it is
- also possible to use the attribute identity to define the
- attribute.
+ Next, it is necessary to define which attributes should be read.
+ As with transaction attributes, scan attributes are defined by name but it is
+ also possible to use the attributes' identities to define attributes.
- NdbOperation::getValue() returns an NdbRecAttr object
- containing the read value.
- 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()
- is called. Thus, the application can not reference this object after
- Ndb::closeTransaction() have been called.
- The result of reading data from an NdbRecAttr object before
- calling NdbTransaction::execute() is undefined.
+ As previously discussed (see @ref secSync), the value read is returned as
+ an NdbRecAttr object by the NdbOperation::getValue() method.
- <h3> Using Scan to update/delete </h3>
- Scanning can also be used to update/delete rows.
+ <h3>Using Scan to Update/Delete</h3>
+ Scanning can also be used to update or delete rows.
This is performed by
- -# Scan using exclusive locks, NdbOperation::LM_Exclusive
- -# When iterating through the result set, for each row optionally call
+ -# Scanning using exclusive locks (using NdbOperation::LM_Exclusive)
+ -# When iterating through the result set, for each row optionally calling
either NdbScanOperation::updateCurrentTuple() or
NdbScanOperation::deleteCurrentTuple()
- -# If performing NdbScanOperation::updateCurrentTuple(),
- set new values on record using ordinary @ref NdbOperation::setValue().
- NdbOperation::equal() should <em>not</em> be called as the primary
- key is retreived from the scan.
-
- @note that the actual update/delete will not be performed until next
- NdbTransaction::execute (as with single row operations),
- NdbTransaction::execute needs to be called before locks are released,
- see @ref secScanLocks
-
- <h4> Index scans specific features </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.
+ -# (If performing NdbScanOperation::updateCurrentTuple():)
+ Setting new values for records simply by using @ref NdbOperation::setValue().
+ NdbOperation::equal() should <em>not</em> be called in such cases, as the primary
+ key is retrieved from the scan.
- @note When performing sorted scan, parameter parallelism to
- NdbIndexScanOperation::readTuples() will
- be ignored and max parallelism will be used instead.
+ @note The actual update or delete will not be performed until the next
+ call to NdbTransaction::execute(), just as with single row operations.
+ NdbTransaction::execute() also must be called before any locks are released;
+ see @ref secScanLocks for more information.
- @subsection secScanLocks Lock handling with scans
+ <h4>Features Specific to Index Scans</h4>
+
+ 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 a sorted scan, any value passed as the
+ NdbIndexScanOperation::readTuples() method's <code>parallel</code> argument
+ 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.
- When scanning a table or an index potentially
- a lot of records will be returned.
+ @subsection secScanLocks Lock handling with scans
- But Ndb will only lock a batch of rows per fragment at a time.
+ Performing scans on either a tables or an index has the potential
+ return a great many records; however, Ndb will lock only a predetermined
+ number of rows per fragment at a time.
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
- NdbScanOperation::nextResult() have a parameter fetch_allow.
- If NdbScanOperation::nextResult() is called with fetch_allow = false, no
- locks may be released as result of the function call. Otherwise the locks
- for the current batch may be released.
+ In order to allow the application to handle how locks are released,
+ NdbScanOperation::nextResult() has a Boolean parameter <var>fetch_allow</var>.
+ If NdbScanOperation::nextResult() is called with <var>fetch_allow</var> equal to
+ <b>false</b>, then no locks may be released as result of the function call.
+ 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.
@code
int check;
@@ -364,40 +355,31 @@
{
// Inner loop for each row within batch
MyScanOperation->deleteCurrentTuple();
- } while((check = MyScanOperation->nextResult(false) == 0));
+ } while((check = MyScanOperation->nextResult(false)) == 0);
// When no more rows in batch, exeute all defined deletes
MyTransaction->execute(NoCommit);
}
@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
- Errors can occur when
- -# operations are being defined, or when the
- -# transaction is being executed.
-
- One recommended way to handle a transaction failure
- (i.e. an error is reported) is to:
- -# Rollback transaction (NdbTransaction::execute() with a special parameter)
- -# 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.
+ Errors can occur either when operations making up a transaction are being
+ defined, or when the transaction is actually being executed. Catching and
+ 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:
+
+ - NdbTransaction::getNdbErrorOperation() returns a reference to the
+ operation causing the most recent error.
+ - NdbTransaction::getNdbErrorLine() yields the method number of the
+ erroneous method in the operation.
+
+ This short example illustrates how to detect an error and to use these
+ two methods to identify it:
@code
theTransaction = theNdb->startTransaction();
@@ -405,26 +387,43 @@
if (theOperation == NULL) goto error;
theOperation->readTuple(NdbOperation::LM_Read);
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_4", at1);
if (theTransaction->execute(Commit) == -1) {
errorLine = theTransaction->getNdbErrorLine();
errorOperation = theTransaction->getNdbErrorOperation();
+ }
@endcode
- Here errorLine will be 3 as the error occurred in the third method
- on the operation object.
- Getting errorLine == 0 means that the error occurred when executing the
- operations.
- Here errorOperation will be a pointer to the theOperation object.
- NdbTransaction::getNdbError() will return the NdbError object
- including holding information about the error.
+ Here <code>errorLine</code> will be 3, as the error occurred in the
+ third method called on the NdbOperation object (in this case,
+ <code>theOperation</code>); if the result of
+ NdbTransaction::getNdbErrorLine() is 0, this means that the error
+ occurred when the operations were executed. In this example,
+ <code>errorOperation</code> will be a pointer to the <code>theOperation</code>
+ 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,
- there is also a special method, NdbTransaction::commitStatus(),
- to check the commit status of the transaction.
+ @note Transactions are <b>not</b> automatically closed when an error occurs. Call
+ Ndb::closeTransaction() to close 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.
******************************************************************************/
@@ -435,6 +434,10 @@
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
+ * @page ndbapi_async.cpp ndbapi_async.cpp
+ * @include ndbapi_async.cpp
+ */
+/**
* @page ndbapi_async1.cpp ndbapi_async1.cpp
* @include ndbapi_async1.cpp
*/
@@ -455,6 +458,11 @@
* @include ndbapi_scan.cpp
*/
+/**
+ * @page ndbapi_event.cpp ndbapi_event.cpp
+ * @include ndbapi_event.cpp
+ */
+
/**
@page secAdapt Adaptive Send Algorithm
diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp
index 553d85f4129..2100260dab3 100644
--- a/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/ndb/include/ndbapi/NdbDictionary.hpp
@@ -52,6 +52,7 @@ typedef struct charset_info_st CHARSET_INFO;
* -# Dropping secondary indexes (Dictionary::dropIndex)
*
* NdbDictionary has several help (inner) classes to support this:
+ * -# NdbDictionary::Dictionary the dictionary handling dictionary objects
* -# NdbDictionary::Table for creating tables
* -# NdbDictionary::Column for creating table columns
* -# NdbDictionary::Index for creating secondary indexes
@@ -189,12 +190,13 @@ public:
Binary = NDB_TYPE_BINARY, ///< Len
Varbinary = NDB_TYPE_VARBINARY, ///< Length bytes: 1, Max: 255
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)
Text = NDB_TYPE_TEXT, ///< Text blob
Bit = NDB_TYPE_BIT, ///< Bit, length specifies no of bits
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 {
public:
+ /**
+ * Specifies the type of database operations an Event listens to
+ */
enum TableEvent {
TE_INSERT=1, ///< Insert 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
///< events are received)
};
+ /**
+ * Specifies the durability of an event
+ * (future version may supply other types)
+ */
enum EventDurability {
ED_UNDEFINED
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
@@ -930,8 +939,8 @@ public:
// All API's can use it,
// But's its removed when ndb is restarted
#endif
- ,ED_PERMANENT ///< All API's can use it,
- ///< It's still defined after a restart
+ ,ED_PERMANENT ///< All API's can use it.
+ ///< It's still defined after a cluster system restart
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
= 3
#endif
@@ -950,9 +959,12 @@ public:
Event(const char *name, const NdbDictionary::Table& table);
virtual ~Event();
/**
- * Set/get unique identifier for the event
+ * Set unique identifier for the event
*/
void setName(const char *name);
+ /**
+ * Get unique identifier for the event
+ */
const char *getName() const;
/**
* Define table on which events should be detected
@@ -967,7 +979,7 @@ public:
/**
* 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
*/
void setTable(const char *tableName);
@@ -1224,9 +1236,12 @@ public:
#endif
/**
- * Remove table/index from local cache
+ * Remove table from local cache
*/
void removeCachedTable(const char * table);
+ /**
+ * Remove index from local cache
+ */
void removeCachedIndex(const char * index, const char * table);
diff --git a/ndb/include/ndbapi/NdbEventOperation.hpp b/ndb/include/ndbapi/NdbEventOperation.hpp
index c695b5acd86..4f8a05d589c 100644
--- a/ndb/include/ndbapi/NdbEventOperation.hpp
+++ b/ndb/include/ndbapi/NdbEventOperation.hpp
@@ -24,73 +24,79 @@ class NdbEventOperationImpl;
* @class NdbEventOperation
* @brief Class of operations for getting change events from database.
*
- * An NdbEventOperation object is instantiated by
- * Ndb::createEventOperation
- *
- * Prior to that an event must have been created in the Database through
- * NdbDictionary::createEvent
- *
- * The instance is removed by Ndb::dropEventOperation
+ * Brief description on how to work with events:
+ *
+ * - An event, represented by an NdbDictionary::Event, i created in the
+ * Database through
+ * NdbDictionary::Dictionary::createEvent() (note that this can be done
+ * 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:
* @ref ndbapi_event.cpp
*
* 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.
- *
- * Maximum number of NdbEventOperations tied to same event are maximum 16
+ * - Maximum number of NdbEventOperations tied to same event are maximum 16
* per process.
*
* 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
* be the same for all and decided by the first NdbEventOperation
* 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.
* These are however hidden from the user and only relevant data is shown
* 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,
* 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
* 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
* again. Will be fixed in later versions.
*
* Test status:
- * Tests have been run on 1-node and 2-node systems
- *
- * Known bugs:
*
- * None, except if we can call some of the "issues" above bugs
+ * - Tests have been run on 1-node and 2-node systems
*
* Useful API programs:
*
- * ndb_select_all -d sys 'NDB$EVENTS_0'
- * Will show contents in the system table containing created events.
+ * - ndb_select_all -d sys 'NDB$EVENTS_0'
+ * shows contents in the system table containing created events.
*
+ * @note this is an inteface to viewing events that is subject to change
*/
class NdbEventOperation {
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
*/
- enum State {CREATED,EXECUTING,ERROR};
State getState();
/**
* Activates the NdbEventOperation to start receiving events. The
* 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().
*
* @return 0 if successful otherwise -1.
@@ -112,21 +118,21 @@ public:
* aligned appropriately. The buffer is used directly
* (avoiding a copy penalty) only if it is aligned on a
* 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).
*
- * @note There are two versions, NdbOperation::getValue and
- * NdbOperation::getPreValue for retrieving the current and
+ * @note There are two versions, getValue() and
+ * getPreValue() for retrieving the current and
* previous value repectively.
*
* @note This method does not fetch the attribute value from
* the database! The NdbRecAttr object returned by this method
* is <em>not</em> readable/printable before the
- * NdbEventConnection::execute has been made and
- * NdbEventConnection::next has returned a value greater than
+ * execute() has been made and
+ * next() has returned a value greater than
* zero. If a specific attribute has not changed the corresponding
* 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 aValue If this is non-NULL, then the attribute value
@@ -143,11 +149,11 @@ public:
/**
* Retrieves event resultset if available, inserted into the NdbRecAttrs
* 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
* 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
* overflow and *pOverRun will indicate the number of events that have
* overwritten.
diff --git a/ndb/include/util/NdbSqlUtil.hpp b/ndb/include/util/NdbSqlUtil.hpp
index feb2b97c54b..75e2a819174 100644
--- a/ndb/include/util/NdbSqlUtil.hpp
+++ b/ndb/include/util/NdbSqlUtil.hpp
@@ -86,12 +86,13 @@ public:
Binary = NDB_TYPE_BINARY,
Varbinary = NDB_TYPE_VARBINARY,
Datetime = NDB_TYPE_DATETIME,
- Timespec = NDB_TYPE_TIMESPEC,
+ Date = NDB_TYPE_DATE,
Blob = NDB_TYPE_BLOB,
Text = NDB_TYPE_TEXT,
Bit = NDB_TYPE_BIT,
Longvarchar = NDB_TYPE_LONG_VARCHAR,
- Longvarbinary = NDB_TYPE_LONG_VARBINARY
+ Longvarbinary = NDB_TYPE_LONG_VARBINARY,
+ Time = NDB_TYPE_TIME
};
Enum m_typeId; // redundant
Cmp* m_cmp; // comparison method
@@ -153,12 +154,13 @@ private:
static Cmp cmpBinary;
static Cmp cmpVarbinary;
static Cmp cmpDatetime;
- static Cmp cmpTimespec;
+ static Cmp cmpDate;
static Cmp cmpBlob;
static Cmp cmpText;
static Cmp cmpBit;
static Cmp cmpLongvarchar;
static Cmp cmpLongvarbinary;
+ static Cmp cmpTime;
};
#endif
diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp
index fd23781605c..1e280ae0fac 100644
--- a/ndb/src/common/util/NdbSqlUtil.cpp
+++ b/ndb/src/common/util/NdbSqlUtil.cpp
@@ -153,8 +153,8 @@ NdbSqlUtil::m_typeList[] = {
cmpDatetime
},
{
- Type::Timespec,
- NULL // cmpTimespec
+ Type::Date,
+ cmpDate
},
{
Type::Blob,
@@ -175,6 +175,10 @@ NdbSqlUtil::m_typeList[] = {
{
Type::Longvarbinary,
cmpLongvarbinary
+ },
+ {
+ Type::Time,
+ cmpTime
}
};
@@ -507,19 +511,57 @@ NdbSqlUtil::cmpVarbinary(const void* info, const void* p1, unsigned n1, const vo
return CmpUnknown;
}
-// allowed but ordering is wrong before wl-1442 done
int
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
-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);
- return 0;
+#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;
+ }
+ 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
@@ -538,6 +580,25 @@ NdbSqlUtil::cmpText(const void* info, const void* p1, unsigned n1, const void* p
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
int
NdbSqlUtil::cmpBit(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index 6d4ca2d9078..5e79fc1c28f 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -2364,7 +2364,8 @@ Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen,
*/
Uint32 dstLen = xmul * (srcBytes - lb);
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) {
dstPtr[n++] = 0;
}
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index 166bd45d48b..a5e01919781 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -629,7 +629,6 @@ ndb_mgm_get_status(NdbMgmHandle handle)
malloc(sizeof(ndb_mgm_cluster_state)+
noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#")));
- state->hostname= 0;
state->no_of_nodes= noOfNodes;
ndb_mgm_node_state * ptr = &state->node_states[0];
int nodeId = 0;
@@ -1046,6 +1045,7 @@ struct ndb_mgm_event_categories
{ "CHECKPOINT", NDB_MGM_EVENT_CATEGORY_CHECKPOINT },
{ "DEBUG", NDB_MGM_EVENT_CATEGORY_DEBUG },
{ "INFO", NDB_MGM_EVENT_CATEGORY_INFO },
+ { "WARNING", NDB_MGM_EVENT_CATEGORY_WARNING },
{ "ERROR", NDB_MGM_EVENT_CATEGORY_ERROR },
{ "GREP", NDB_MGM_EVENT_CATEGORY_GREP },
{ "BACKUP", NDB_MGM_EVENT_CATEGORY_BACKUP },
diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp
index baa34b2006e..5ffb087cde7 100644
--- a/ndb/src/ndbapi/Ndb.cpp
+++ b/ndb/src/ndbapi/Ndb.cpp
@@ -1177,7 +1177,14 @@ NdbEventOperation* Ndb::createEventOperation(const char* eventName,
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;
tOp = NULL;
}
diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp
index db912995b5f..4221c22121d 100644
--- a/ndb/src/ndbapi/NdbDictionary.cpp
+++ b/ndb/src/ndbapi/NdbDictionary.cpp
@@ -956,8 +956,8 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col)
case NdbDictionary::Column::Datetime:
out << "Datetime";
break;
- case NdbDictionary::Column::Timespec:
- out << "Timespec";
+ case NdbDictionary::Column::Date:
+ out << "Date";
break;
case NdbDictionary::Column::Blob:
out << "Blob(" << col.getInlineSize() << "," << col.getPartSize()
@@ -967,6 +967,9 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col)
out << "Text(" << col.getInlineSize() << "," << col.getPartSize()
<< ";" << col.getStripeSize() << ";" << csname << ")";
break;
+ case NdbDictionary::Column::Time:
+ out << "Time";
+ break;
case NdbDictionary::Column::Undefined:
out << "Undefined";
break;
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index 13f9d0c48e1..07a186d8850 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -125,7 +125,7 @@ NdbColumnImpl::init(Type t)
case Binary:
case Varbinary:
case Datetime:
- case Timespec:
+ case Date:
m_precision = 0;
m_scale = 0;
m_length = 1;
@@ -143,6 +143,12 @@ NdbColumnImpl::init(Type t)
m_length = 4;
m_cs = default_cs;
break;
+ case Time:
+ m_precision = 0;
+ m_scale = 0;
+ m_length = 1;
+ m_cs = NULL;
+ break;
case Bit:
m_precision = 0;
m_scale = 0;
diff --git a/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/ndb/src/ndbapi/NdbEventOperationImpl.cpp
index 813a3a5f861..69c05dcb0b7 100644
--- a/ndb/src/ndbapi/NdbEventOperationImpl.cpp
+++ b/ndb/src/ndbapi/NdbEventOperationImpl.cpp
@@ -55,9 +55,8 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N,
const char* eventName,
const int bufferLength)
: NdbEventOperation(*this), m_ndb(theNdb),
- m_state(ERROR), m_bufferL(bufferLength)
+ m_state(EO_ERROR), m_bufferL(bufferLength)
{
-
m_eventId = 0;
theFirstRecAttrs[0] = NULL;
theCurrentRecAttrs[0] = NULL;
@@ -71,16 +70,15 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N,
// we should lookup id in Dictionary, TODO
// 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();
- if (!myDict) { ndbout_c("getDictionary=NULL"); return; }
+ if (!myDict) { m_error.code= m_ndb->getNdbError().code; return; }
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;
- if (!m_eventImpl) { ndbout_c("m_impl=NULL"); return; }
m_bufferHandle = m_ndb->getGlobalEventBufferHandle();
if (m_bufferHandle->m_bufferL > 0)
@@ -88,7 +86,7 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N,
else
m_bufferHandle->m_bufferL = m_bufferL;
- m_state = CREATED;
+ m_state = EO_CREATED;
}
NdbEventOperationImpl::~NdbEventOperationImpl()
@@ -106,7 +104,7 @@ NdbEventOperationImpl::~NdbEventOperationImpl()
p = p_next;
}
}
- if (m_state == NdbEventOperation::EXECUTING) {
+ if (m_state == EO_EXECUTING) {
stop();
// m_bufferHandle->dropSubscribeEvent(m_bufferId);
; // We should send stop signal here
@@ -122,7 +120,7 @@ NdbEventOperationImpl::getState()
NdbRecAttr*
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()");
return NULL;
}
@@ -211,8 +209,8 @@ NdbEventOperationImpl::execute()
{
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
if (!myDict) {
- ndbout_c("NdbEventOperation::execute(): getDictionary=NULL");
- return 0;
+ m_error.code= m_ndb->getNdbError().code;
+ return -1;
}
if (theFirstRecAttrs[0] == NULL) { // defaults to get all
@@ -245,14 +243,14 @@ NdbEventOperationImpl::execute()
if (r) {
//Error
m_bufferHandle->unprepareAddSubscribeEvent(m_bufferId);
- m_state = NdbEventOperation::ERROR;
+ m_state = EO_ERROR;
} else {
m_bufferHandle->addSubscribeEvent(m_bufferId, this);
- m_state = NdbEventOperation::EXECUTING;
+ m_state = EO_EXECUTING;
}
} else {
//Error
- m_state = NdbEventOperation::ERROR;
+ m_state = EO_ERROR;
}
return r;
}
@@ -261,14 +259,14 @@ int
NdbEventOperationImpl::stop()
{
DBUG_ENTER("NdbEventOperationImpl::stop");
- if (m_state != NdbEventOperation::EXECUTING)
+ if (m_state != EO_EXECUTING)
DBUG_RETURN(-1);
// ndbout_c("NdbEventOperation::stopping()");
NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
if (!myDict) {
- ndbout_c("NdbEventOperation::stop(): getDictionary=NULL");
+ m_error.code= m_ndb->getNdbError().code;
DBUG_RETURN(-1);
}
@@ -299,13 +297,13 @@ NdbEventOperationImpl::stop()
//Error
m_bufferHandle->unprepareDropSubscribeEvent(m_bufferId);
m_error.code= myDictImpl.m_error.code;
- m_state = NdbEventOperation::ERROR;
+ m_state = EO_ERROR;
} else {
#ifdef EVENT_DEBUG
ndbout_c("NdbEventOperation::dropping()");
#endif
m_bufferHandle->dropSubscribeEvent(m_bufferId);
- m_state = NdbEventOperation::CREATED;
+ m_state = EO_CREATED;
}
DBUG_RETURN(r);
diff --git a/ndb/test/include/NdbSchemaOp.hpp b/ndb/test/include/NdbSchemaOp.hpp
index ac859f8abe8..e2fb4015b88 100644
--- a/ndb/test/include/NdbSchemaOp.hpp
+++ b/ndb/test/include/NdbSchemaOp.hpp
@@ -576,7 +576,8 @@ convertColumnTypeToAttrType(NdbDictionary::Column::Type _type)
case NdbDictionary::Column::Varbinary:
return String;
case NdbDictionary::Column::Datetime:
- case NdbDictionary::Column::Timespec:
+ case NdbDictionary::Column::Date:
+ case NdbDictionary::Column::Time:
case NdbDictionary::Column::Undefined:
default:
return NoAttrTypeDef;
diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp
index 8a09a2ec9d1..0f31a30f1a7 100644
--- a/ndb/test/ndbapi/testOIBasic.cpp
+++ b/ndb/test/ndbapi/testOIBasic.cpp
@@ -1978,7 +1978,7 @@ Val::cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned
unsigned len = maxxmulsize * col.m_bytelength;
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);
- assert(n1 == n2);
+ assert(n1 != -1 && n1 == n2);
k = memcmp(x1, x2, n1);
} else {
k = (*cs->coll->strnncollsp)(cs, buf1, len1, buf2, len2, false);
diff --git a/ndb/tools/restore/consumer.cpp b/ndb/tools/restore/consumer.cpp
index e94c31b2666..4d228230423 100644
--- a/ndb/tools/restore/consumer.cpp
+++ b/ndb/tools/restore/consumer.cpp
@@ -71,7 +71,10 @@ BackupConsumer::create_table_string(const TableS & table,
case NdbDictionary::Column::Datetime:
pos += sprintf(buf+pos, "%s", "datetime");
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");
break;
case NdbDictionary::Column::Undefined:
diff --git a/pstack/pstack.c b/pstack/pstack.c
index 75869686e35..4cdd80d68b5 100644
--- a/pstack/pstack.c
+++ b/pstack/pstack.c
@@ -1663,7 +1663,7 @@ pr_tag_type (p, name, id, kind)
{
struct pr_handle *info = (struct pr_handle *) p;
const char *t, *tag;
- char idbuf[20];
+ char idbuf[30];
switch (kind)
{
diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql
index 975d8dddbb0..9373a888bc2 100644
--- a/scripts/mysql_fix_privilege_tables.sql
+++ b/scripts/mysql_fix_privilege_tables.sql
@@ -93,10 +93,10 @@ CREATE TABLE IF NOT EXISTS tables_priv (
CREATE TABLE IF NOT EXISTS columns_priv (
Host char(60) DEFAULT '' NOT NULL,
- Db char(60) DEFAULT '' NOT NULL,
+ Db char(64) DEFAULT '' NOT NULL,
User char(16) DEFAULT '' NOT NULL,
- Table_name char(60) DEFAULT '' NOT NULL,
- Column_name char(59) DEFAULT '' NOT NULL,
+ Table_name char(64) DEFAULT '' NOT NULL,
+ Column_name char(64) DEFAULT '' NOT NULL,
Timestamp timestamp(14),
Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,
PRIMARY KEY (Host,Db,User,Table_name,Column_name)
diff --git a/sql/field.cc b/sql/field.cc
index d15db92e51f..8e0fddae332 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2440,23 +2440,7 @@ int Field_float::store(double nr)
int Field_float::store(longlong nr)
{
- int error= 0;
- 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;
+ return store((double)nr);
}
@@ -2738,23 +2722,7 @@ int Field_double::store(double nr)
int Field_double::store(longlong nr)
{
- double j= (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;
+ return store((double)nr);
}
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 31b15f89806..0bca8c21715 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -3907,7 +3907,7 @@ ha_innobase::create(
error = create_table_def(trx, form, norm_name,
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) {
innobase_commit_low(trx);
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 767ddc40400..b1fbe392940 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -2393,13 +2393,15 @@ void ha_ndbcluster::print_results()
break;
}
case NdbDictionary::Column::Datetime: {
- // todo
- my_snprintf(buf, sizeof(buf), "Datetime ?");
+ my_snprintf(buf, sizeof(buf), "Datetime ?"); // fix-me
break;
}
- case NdbDictionary::Column::Timespec: {
- // todo
- my_snprintf(buf, sizeof(buf), "Timespec ?");
+ case NdbDictionary::Column::Date: {
+ my_snprintf(buf, sizeof(buf), "Date ?"); // fix-me
+ break;
+ }
+ case NdbDictionary::Column::Time: {
+ my_snprintf(buf, sizeof(buf), "Time ?"); // fix-me
break;
}
case NdbDictionary::Column::Blob: {
@@ -3420,6 +3422,9 @@ int ndbcluster_rollback(THD *thd, void *ndb_transaction)
Define NDB column based on Field.
Returns 0 or mysql error code.
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,
@@ -3495,9 +3500,15 @@ static int create_ndb_column(NDBCOL &col,
col.setType(NDBCOL::Datetime);
col.setLength(1);
break;
- case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE:
+ col.setType(NDBCOL::Date);
+ col.setLength(1);
+ break;
case MYSQL_TYPE_TIME:
+ col.setType(NDBCOL::Time);
+ col.setLength(1);
+ break;
+ case MYSQL_TYPE_DATE: // ?
case MYSQL_TYPE_YEAR:
col.setType(NDBCOL::Char);
col.setLength(field->pack_length());
@@ -3509,7 +3520,7 @@ static int create_ndb_column(NDBCOL &col,
col.setType(NDBCOL::Bit);
col.setLength(1);
}
- else if (field->flags & BINARY_FLAG)
+ else if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
{
col.setType(NDBCOL::Binary);
col.setLength(field->pack_length());
@@ -3527,7 +3538,7 @@ static int create_ndb_column(NDBCOL &col,
Field_varstring* f= (Field_varstring*)field;
if (f->length_bytes == 1)
{
- if (field->flags & BINARY_FLAG)
+ if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
col.setType(NDBCOL::Varbinary);
else {
col.setType(NDBCOL::Varchar);
@@ -3536,7 +3547,7 @@ static int create_ndb_column(NDBCOL &col,
}
else if (f->length_bytes == 2)
{
- if (field->flags & BINARY_FLAG)
+ if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
col.setType(NDBCOL::Longvarbinary);
else {
col.setType(NDBCOL::Longvarchar);
@@ -3553,7 +3564,7 @@ static int create_ndb_column(NDBCOL &col,
// Blob types (all come in as MYSQL_TYPE_BLOB)
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);
else {
col.setType(NDBCOL::Text);
@@ -3566,7 +3577,7 @@ static int create_ndb_column(NDBCOL &col,
break;
//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);
else {
col.setType(NDBCOL::Text);
@@ -3588,7 +3599,7 @@ static int create_ndb_column(NDBCOL &col,
break;
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);
else {
col.setType(NDBCOL::Text);
@@ -3600,7 +3611,7 @@ static int create_ndb_column(NDBCOL &col,
break;
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);
else {
col.setType(NDBCOL::Text);
diff --git a/sql/handler.cc b/sql/handler.cc
index bbe01dd93d5..b1b741dfee9 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -101,7 +101,7 @@ struct show_table_type_st sys_table_types[]=
};
const char *ha_row_type[] = {
- "", "FIXED", "DYNAMIC", "COMPRESSED","?","?","?"
+ "", "FIXED", "DYNAMIC", "COMPRESSED", "REDUNDANT", "COMPACT", "?","?","?"
};
const char *tx_isolation_names[] =
diff --git a/sql/handler.h b/sql/handler.h
index b10e6bfe88c..e5a794ca1b2 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -167,7 +167,8 @@ struct show_table_type_st {
};
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 */
diff --git a/sql/lex.h b/sql/lex.h
index 56d824b7bb8..871d1d99750 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -116,6 +116,7 @@ static SYMBOL symbols[] = {
{ "COMMENT", SYM(COMMENT_SYM)},
{ "COMMIT", SYM(COMMIT_SYM)},
{ "COMMITTED", SYM(COMMITTED_SYM)},
+ { "COMPACT", SYM(COMPACT_SYM)},
{ "COMPRESSED", SYM(COMPRESSED_SYM)},
{ "CONCURRENT", SYM(CONCURRENT)},
{ "CONDITION", SYM(CONDITION_SYM)},
@@ -378,6 +379,7 @@ static SYMBOL symbols[] = {
{ "READ", SYM(READ_SYM)},
{ "READS", SYM(READS_SYM)},
{ "REAL", SYM(REAL)},
+ { "REDUNDANT", SYM(REDUNDANT_SYM)},
{ "REFERENCES", SYM(REFERENCES)},
{ "REGEXP", SYM(REGEXP)},
{ "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM)},
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fa23502ea93..6b1456dfbd3 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -227,6 +227,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token COLLATION_SYM
%token COLUMNS
%token COLUMN_SYM
+%token COMPACT_SYM
%token CONCURRENT
%token CONDITION_SYM
%token CONNECTION_SYM
@@ -381,6 +382,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token READ_SYM
%token READS_SYM
%token REAL_NUM
+%token REDUNDANT_SYM
%token REFERENCES
%token REGEXP
%token RELOAD
@@ -2628,7 +2630,9 @@ row_types:
DEFAULT { $$= ROW_TYPE_DEFAULT; }
| FIXED_SYM { $$= ROW_TYPE_FIXED; }
| 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_STRIPED_SYM { $$= RAID_TYPE_0; }
@@ -6915,6 +6919,7 @@ keyword:
| COMMENT_SYM {}
| COMMITTED_SYM {}
| COMMIT_SYM {}
+ | COMPACT_SYM {}
| COMPRESSED_SYM {}
| CONCURRENT {}
| CONSISTENT_SYM {}
@@ -7046,6 +7051,7 @@ keyword:
| RAID_CHUNKSIZE {}
| RAID_STRIPED_SYM {}
| RAID_TYPE {}
+ | REDUNDANT_SYM {}
| RELAY_LOG_FILE_SYM {}
| RELAY_LOG_POS_SYM {}
| RELOAD {}