mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Merge mysql.com:/space/pekka/ndb/version/my50
into mysql.com:/space/pekka/ndb/version/my50-bug14509 ndb/src/ndbapi/DictCache.cpp: Auto merged ndb/src/ndbapi/DictCache.hpp: Auto merged sql/ha_ndbcluster.cc: Auto merged
This commit is contained in:
commit
69c80350dc
12 changed files with 326 additions and 228 deletions
|
@ -1,4 +1,4 @@
|
||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
drop database if exists mysqltest;
|
drop database if exists mysqltest;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
a INT NOT NULL,
|
a INT NOT NULL,
|
||||||
|
@ -315,3 +315,24 @@ unique key tx1 (c002, c003, c004, c005)) engine=ndb;
|
||||||
create index tx2
|
create index tx2
|
||||||
on t1 (c010, c011, c012, c013);
|
on t1 (c010, c011, c012, c013);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a int primary key auto_increment, b int) engine=ndb;
|
||||||
|
insert into t1 (b) values (101),(102),(103);
|
||||||
|
select * from t1 where a = 3;
|
||||||
|
a b
|
||||||
|
3 103
|
||||||
|
alter table t1 rename t2;
|
||||||
|
insert into t2 (b) values (201),(202),(203);
|
||||||
|
select * from t2 where a = 6;
|
||||||
|
a b
|
||||||
|
6 203
|
||||||
|
alter table t2 add c int;
|
||||||
|
insert into t2 (b) values (301),(302),(303);
|
||||||
|
select * from t2 where a = 9;
|
||||||
|
a b c
|
||||||
|
9 303 NULL
|
||||||
|
alter table t2 rename t1;
|
||||||
|
insert into t1 (b) values (401),(402),(403);
|
||||||
|
select * from t1 where a = 12;
|
||||||
|
a b c
|
||||||
|
12 403 NULL
|
||||||
|
drop table t1;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
-- source include/not_embedded.inc
|
-- source include/not_embedded.inc
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
drop database if exists mysqltest;
|
drop database if exists mysqltest;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
|
@ -326,5 +326,20 @@ on t1 (c010, c011, c012, c013);
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
# simple test that auto incr is not lost at rename or alter
|
||||||
|
create table t1 (a int primary key auto_increment, b int) engine=ndb;
|
||||||
|
insert into t1 (b) values (101),(102),(103);
|
||||||
|
select * from t1 where a = 3;
|
||||||
|
alter table t1 rename t2;
|
||||||
|
insert into t2 (b) values (201),(202),(203);
|
||||||
|
select * from t2 where a = 6;
|
||||||
|
alter table t2 add c int;
|
||||||
|
insert into t2 (b) values (301),(302),(303);
|
||||||
|
select * from t2 where a = 9;
|
||||||
|
alter table t2 rename t1;
|
||||||
|
insert into t1 (b) values (401),(402),(403);
|
||||||
|
select * from t1 where a = 12;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
|
|
@ -984,6 +984,7 @@ class BaseString;
|
||||||
class NdbEventOperation;
|
class NdbEventOperation;
|
||||||
class NdbBlob;
|
class NdbBlob;
|
||||||
class NdbReceiver;
|
class NdbReceiver;
|
||||||
|
class Ndb_local_table_info;
|
||||||
template <class T> struct Ndb_free_list_t;
|
template <class T> struct Ndb_free_list_t;
|
||||||
|
|
||||||
typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);
|
typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);
|
||||||
|
@ -1431,27 +1432,29 @@ public:
|
||||||
*
|
*
|
||||||
* @param cacheSize number of values to cache in this Ndb object
|
* @param cacheSize number of values to cache in this Ndb object
|
||||||
*
|
*
|
||||||
* @return tuple id or 0 on error
|
* @return 0 or -1 on error, and tupleId in out parameter
|
||||||
*/
|
*/
|
||||||
Uint64 getAutoIncrementValue(const char* aTableName,
|
int getAutoIncrementValue(const char* aTableName,
|
||||||
Uint32 cacheSize = 1);
|
Uint64 & tupleId, Uint32 cacheSize);
|
||||||
Uint64 getAutoIncrementValue(const NdbDictionary::Table * aTable,
|
int getAutoIncrementValue(const NdbDictionary::Table * aTable,
|
||||||
Uint32 cacheSize = 1);
|
Uint64 & tupleId, Uint32 cacheSize);
|
||||||
Uint64 readAutoIncrementValue(const char* aTableName);
|
int readAutoIncrementValue(const char* aTableName,
|
||||||
Uint64 readAutoIncrementValue(const NdbDictionary::Table * aTable);
|
Uint64 & tupleId);
|
||||||
bool setAutoIncrementValue(const char* aTableName, Uint64 val,
|
int readAutoIncrementValue(const NdbDictionary::Table * aTable,
|
||||||
bool increase = false);
|
Uint64 & tupleId);
|
||||||
bool setAutoIncrementValue(const NdbDictionary::Table * aTable, Uint64 val,
|
int setAutoIncrementValue(const char* aTableName,
|
||||||
bool increase = false);
|
Uint64 tupleId, bool increase);
|
||||||
Uint64 getTupleIdFromNdb(const char* aTableName,
|
int setAutoIncrementValue(const NdbDictionary::Table * aTable,
|
||||||
Uint32 cacheSize = 1000);
|
Uint64 tupleId, bool increase);
|
||||||
Uint64 getTupleIdFromNdb(Uint32 aTableId,
|
private:
|
||||||
Uint32 cacheSize = 1000);
|
int getTupleIdFromNdb(Ndb_local_table_info* info,
|
||||||
Uint64 readTupleIdFromNdb(Uint32 aTableId);
|
Uint64 & tupleId, Uint32 cacheSize);
|
||||||
bool setTupleIdInNdb(const char* aTableName, Uint64 val,
|
int readTupleIdFromNdb(Ndb_local_table_info* info,
|
||||||
bool increase);
|
Uint64 & tupleId);
|
||||||
bool setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase);
|
int setTupleIdInNdb(Ndb_local_table_info* info,
|
||||||
Uint64 opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op);
|
Uint64 tupleId, bool increase);
|
||||||
|
int opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op);
|
||||||
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
@ -1650,11 +1653,6 @@ private:
|
||||||
|
|
||||||
Uint64 the_last_check_time;
|
Uint64 the_last_check_time;
|
||||||
Uint64 theFirstTransId;
|
Uint64 theFirstTransId;
|
||||||
|
|
||||||
// The tupleId is retreived from DB the
|
|
||||||
// tupleId is unique for each tableid.
|
|
||||||
Uint64 theFirstTupleId[2048];
|
|
||||||
Uint64 theLastTupleId[2048];
|
|
||||||
|
|
||||||
Uint32 theRestartGCI; // the Restart GCI used by DIHNDBTAMPER
|
Uint32 theRestartGCI; // the Restart GCI used by DIHNDBTAMPER
|
||||||
|
|
||||||
|
|
|
@ -1607,10 +1607,9 @@ void Ndbcntr::systemErrorLab(Signal* signal, int line)
|
||||||
/* |-2048| # 1 00000001 | */
|
/* |-2048| # 1 00000001 | */
|
||||||
/* | : | : | */
|
/* | : | : | */
|
||||||
/* | -1 | # 1 00000001 | */
|
/* | -1 | # 1 00000001 | */
|
||||||
/* | 0 | 0 | */
|
/* | 1 | 0 | tupleid sequence now created on first use */
|
||||||
/* | 1 | 0 | */
|
/* | : | : | v */
|
||||||
/* | : | : | */
|
/* | 2048| 0 | v */
|
||||||
/* | 2047| 0 | */
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void Ndbcntr::createSystableLab(Signal* signal, unsigned index)
|
void Ndbcntr::createSystableLab(Signal* signal, unsigned index)
|
||||||
{
|
{
|
||||||
|
@ -1819,8 +1818,7 @@ void Ndbcntr::crSystab8Lab(Signal* signal)
|
||||||
jam();
|
jam();
|
||||||
ckey = 1;
|
ckey = 1;
|
||||||
ctransidPhase = ZFALSE;
|
ctransidPhase = ZFALSE;
|
||||||
crSystab7Lab(signal);
|
// skip 2nd loop - tupleid sequence now created on first use
|
||||||
return;
|
|
||||||
}//if
|
}//if
|
||||||
signal->theData[0] = ctcConnectionP;
|
signal->theData[0] = ctcConnectionP;
|
||||||
signal->theData[1] = reference();
|
signal->theData[1] = reference();
|
||||||
|
|
|
@ -45,6 +45,8 @@ void Ndb_local_table_info::destroy(Ndb_local_table_info *info)
|
||||||
Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl)
|
Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl)
|
||||||
{
|
{
|
||||||
m_table_impl= table_impl;
|
m_table_impl= table_impl;
|
||||||
|
m_first_tuple_id = ~(Uint64)0;
|
||||||
|
m_last_tuple_id = ~(Uint64)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ndb_local_table_info::~Ndb_local_table_info()
|
Ndb_local_table_info::~Ndb_local_table_info()
|
||||||
|
|
|
@ -33,6 +33,11 @@ public:
|
||||||
static Ndb_local_table_info *create(NdbTableImpl *table_impl, Uint32 sz=0);
|
static Ndb_local_table_info *create(NdbTableImpl *table_impl, Uint32 sz=0);
|
||||||
static void destroy(Ndb_local_table_info *);
|
static void destroy(Ndb_local_table_info *);
|
||||||
NdbTableImpl *m_table_impl;
|
NdbTableImpl *m_table_impl;
|
||||||
|
|
||||||
|
// range of cached tuple ids per thread
|
||||||
|
Uint64 m_first_tuple_id;
|
||||||
|
Uint64 m_last_tuple_id;
|
||||||
|
|
||||||
Uint64 m_local_data[1]; // Must be last member. Used to access extra space.
|
Uint64 m_local_data[1]; // Must be last member. Used to access extra space.
|
||||||
private:
|
private:
|
||||||
Ndb_local_table_info(NdbTableImpl *table_impl);
|
Ndb_local_table_info(NdbTableImpl *table_impl);
|
||||||
|
|
|
@ -760,172 +760,226 @@ Remark: Returns a new TupleId to the application.
|
||||||
The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId.
|
The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId.
|
||||||
It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp.
|
It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
Uint64
|
int
|
||||||
Ndb::getAutoIncrementValue(const char* aTableName, Uint32 cacheSize)
|
Ndb::getAutoIncrementValue(const char* aTableName,
|
||||||
|
Uint64 & tupleId, Uint32 cacheSize)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("getAutoIncrementValue");
|
DBUG_ENTER("Ndb::getAutoIncrementValue");
|
||||||
BaseString internal_tabname(internalize_table_name(aTableName));
|
|
||||||
|
|
||||||
Ndb_local_table_info *info=
|
|
||||||
theDictionary->get_local_table_info(internal_tabname, false);
|
|
||||||
if (info == 0)
|
|
||||||
DBUG_RETURN(~(Uint64)0);
|
|
||||||
const NdbTableImpl *table= info->m_table_impl;
|
|
||||||
Uint64 tupleId = getTupleIdFromNdb(table->m_tableId, cacheSize);
|
|
||||||
DBUG_PRINT("info", ("value %ul", (ulong) tupleId));
|
|
||||||
DBUG_RETURN(tupleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint64
|
|
||||||
Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, Uint32 cacheSize)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("getAutoIncrementValue");
|
|
||||||
if (aTable == 0)
|
|
||||||
DBUG_RETURN(~(Uint64)0);
|
|
||||||
const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
|
|
||||||
Uint64 tupleId = getTupleIdFromNdb(table->m_tableId, cacheSize);
|
|
||||||
DBUG_PRINT("info", ("value %ul", (ulong) tupleId));
|
|
||||||
DBUG_RETURN(tupleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint64
|
|
||||||
Ndb::getTupleIdFromNdb(const char* aTableName, Uint32 cacheSize)
|
|
||||||
{
|
|
||||||
const NdbTableImpl* table = theDictionary->getTable(aTableName);
|
|
||||||
if (table == 0)
|
|
||||||
return ~(Uint64)0;
|
|
||||||
return getTupleIdFromNdb(table->m_tableId, cacheSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint64
|
|
||||||
Ndb::getTupleIdFromNdb(Uint32 aTableId, Uint32 cacheSize)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("getTupleIdFromNdb");
|
|
||||||
if ( theFirstTupleId[aTableId] != theLastTupleId[aTableId] )
|
|
||||||
{
|
|
||||||
theFirstTupleId[aTableId]++;
|
|
||||||
DBUG_PRINT("info", ("next cached value %ul",
|
|
||||||
(ulong) theFirstTupleId[aTableId]));
|
|
||||||
DBUG_RETURN(theFirstTupleId[aTableId]);
|
|
||||||
}
|
|
||||||
else // theFirstTupleId == theLastTupleId
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info",("reading %u values from database",
|
|
||||||
(cacheSize == 0) ? 1 : cacheSize));
|
|
||||||
DBUG_RETURN(opTupleIdOnNdb(aTableId, (cacheSize == 0) ? 1 : cacheSize, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint64
|
|
||||||
Ndb::readAutoIncrementValue(const char* aTableName)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("readAutoIncrementValue");
|
|
||||||
const NdbTableImpl* table = theDictionary->getTable(aTableName);
|
|
||||||
if (table == 0) {
|
|
||||||
theError= theDictionary->getNdbError();
|
|
||||||
DBUG_RETURN(~(Uint64)0);
|
|
||||||
}
|
|
||||||
Uint64 tupleId = readTupleIdFromNdb(table->m_tableId);
|
|
||||||
DBUG_PRINT("info", ("value %ul", (ulong) tupleId));
|
|
||||||
DBUG_RETURN(tupleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint64
|
|
||||||
Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("readAutoIncrementValue");
|
|
||||||
if (aTable == 0)
|
|
||||||
DBUG_RETURN(~(Uint64)0);
|
|
||||||
const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
|
|
||||||
Uint64 tupleId = readTupleIdFromNdb(table->m_tableId);
|
|
||||||
DBUG_PRINT("info", ("value %ul", (ulong) tupleId));
|
|
||||||
DBUG_RETURN(tupleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint64
|
|
||||||
Ndb::readTupleIdFromNdb(Uint32 aTableId)
|
|
||||||
{
|
|
||||||
if ( theFirstTupleId[aTableId] == theLastTupleId[aTableId] )
|
|
||||||
// Cache is empty, check next in database
|
|
||||||
return opTupleIdOnNdb(aTableId, 0, 3);
|
|
||||||
|
|
||||||
return theFirstTupleId[aTableId] + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Ndb::setAutoIncrementValue(const char* aTableName, Uint64 val, bool increase)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("setAutoIncrementValue");
|
|
||||||
BaseString internal_tabname(internalize_table_name(aTableName));
|
BaseString internal_tabname(internalize_table_name(aTableName));
|
||||||
|
|
||||||
Ndb_local_table_info *info=
|
Ndb_local_table_info *info=
|
||||||
theDictionary->get_local_table_info(internal_tabname, false);
|
theDictionary->get_local_table_info(internal_tabname, false);
|
||||||
if (info == 0) {
|
if (info == 0) {
|
||||||
theError= theDictionary->getNdbError();
|
theError.code = theDictionary->getNdbError().code;
|
||||||
DBUG_RETURN(false);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
const NdbTableImpl* table= info->m_table_impl;
|
if (getTupleIdFromNdb(info, tupleId, cacheSize) == -1)
|
||||||
DBUG_RETURN(setTupleIdInNdb(table->m_tableId, val, increase));
|
DBUG_RETURN(-1);
|
||||||
|
DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId));
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable, Uint64 val, bool increase)
|
Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable,
|
||||||
|
Uint64 & tupleId, Uint32 cacheSize)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("setAutoIncrementValue");
|
DBUG_ENTER("Ndb::getAutoIncrementValue");
|
||||||
if (aTable == 0)
|
assert(aTable != 0);
|
||||||
DBUG_RETURN(~(Uint64)0);
|
|
||||||
const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
|
const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
|
||||||
DBUG_RETURN(setTupleIdInNdb(table->m_tableId, val, increase));
|
const BaseString& internal_tabname = table->m_internalName;
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
Ndb_local_table_info *info=
|
||||||
Ndb::setTupleIdInNdb(const char* aTableName, Uint64 val, bool increase )
|
theDictionary->get_local_table_info(internal_tabname, false);
|
||||||
{
|
if (info == 0) {
|
||||||
DBUG_ENTER("setTupleIdInNdb(const char*, ...)");
|
theError.code = theDictionary->getNdbError().code;
|
||||||
const NdbTableImpl* table = theDictionary->getTable(aTableName);
|
DBUG_RETURN(-1);
|
||||||
if (table == 0) {
|
|
||||||
theError= theDictionary->getNdbError();
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
}
|
}
|
||||||
DBUG_RETURN(setTupleIdInNdb(table->m_tableId, val, increase));
|
if (getTupleIdFromNdb(info, tupleId, cacheSize) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId));
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
Ndb::setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase )
|
Ndb::getTupleIdFromNdb(Ndb_local_table_info* info,
|
||||||
|
Uint64 & tupleId, Uint32 cacheSize)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("setTupleIdInNdb(Uint32, ...)");
|
DBUG_ENTER("Ndb::getTupleIdFromNdb");
|
||||||
if (increase)
|
if (info->m_first_tuple_id != info->m_last_tuple_id)
|
||||||
{
|
{
|
||||||
if (theFirstTupleId[aTableId] != theLastTupleId[aTableId])
|
assert(info->m_first_tuple_id < info->m_last_tuple_id);
|
||||||
{
|
tupleId = ++info->m_first_tuple_id;
|
||||||
// We have a cache sequence
|
DBUG_PRINT("info", ("next cached value %llu", (ulonglong)tupleId));
|
||||||
if (val <= theFirstTupleId[aTableId]+1)
|
|
||||||
DBUG_RETURN(false);
|
|
||||||
if (val <= theLastTupleId[aTableId])
|
|
||||||
{
|
|
||||||
theFirstTupleId[aTableId] = val - 1;
|
|
||||||
DBUG_RETURN(true);
|
|
||||||
}
|
|
||||||
// else continue;
|
|
||||||
}
|
|
||||||
DBUG_RETURN((opTupleIdOnNdb(aTableId, val, 2) == val));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DBUG_RETURN((opTupleIdOnNdb(aTableId, val, 1) == val));
|
{
|
||||||
|
if (cacheSize == 0)
|
||||||
|
cacheSize = 1;
|
||||||
|
DBUG_PRINT("info", ("reading %u values from database", (uint)cacheSize));
|
||||||
|
/*
|
||||||
|
* reserve next cacheSize entries in db. adds cacheSize to NEXTID
|
||||||
|
* and returns first tupleId in the new range.
|
||||||
|
*/
|
||||||
|
Uint64 opValue = cacheSize;
|
||||||
|
if (opTupleIdOnNdb(info, opValue, 0) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
tupleId = opValue;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint64
|
int
|
||||||
Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
|
Ndb::readAutoIncrementValue(const char* aTableName,
|
||||||
|
Uint64 & tupleId)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Ndb::readAutoIncrementValue");
|
||||||
|
BaseString internal_tabname(internalize_table_name(aTableName));
|
||||||
|
|
||||||
|
Ndb_local_table_info *info=
|
||||||
|
theDictionary->get_local_table_info(internal_tabname, false);
|
||||||
|
if (info == 0) {
|
||||||
|
theError.code = theDictionary->getNdbError().code;
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
if (readTupleIdFromNdb(info, tupleId) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable,
|
||||||
|
Uint64 & tupleId)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Ndb::readAutoIncrementValue");
|
||||||
|
assert(aTable != 0);
|
||||||
|
const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
|
||||||
|
const BaseString& internal_tabname = table->m_internalName;
|
||||||
|
|
||||||
|
Ndb_local_table_info *info=
|
||||||
|
theDictionary->get_local_table_info(internal_tabname, false);
|
||||||
|
if (info == 0) {
|
||||||
|
theError.code = theDictionary->getNdbError().code;
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
if (readTupleIdFromNdb(info, tupleId) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
DBUG_PRINT("info", ("value %llu", (ulonglong)tupleId));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Ndb::readTupleIdFromNdb(Ndb_local_table_info* info,
|
||||||
|
Uint64 & tupleId)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Ndb::readTupleIdFromNdb");
|
||||||
|
if (info->m_first_tuple_id != info->m_last_tuple_id)
|
||||||
|
{
|
||||||
|
assert(info->m_first_tuple_id < info->m_last_tuple_id);
|
||||||
|
tupleId = info->m_first_tuple_id + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* peek at NEXTID. does not reserve it so the value is valid
|
||||||
|
* only if no other transactions are allowed.
|
||||||
|
*/
|
||||||
|
Uint64 opValue = 0;
|
||||||
|
if (opTupleIdOnNdb(info, opValue, 3) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
tupleId = opValue;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Ndb::setAutoIncrementValue(const char* aTableName,
|
||||||
|
Uint64 tupleId, bool increase)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Ndb::setAutoIncrementValue");
|
||||||
|
BaseString internal_tabname(internalize_table_name(aTableName));
|
||||||
|
|
||||||
|
Ndb_local_table_info *info=
|
||||||
|
theDictionary->get_local_table_info(internal_tabname, false);
|
||||||
|
if (info == 0) {
|
||||||
|
theError.code = theDictionary->getNdbError().code;
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
if (setTupleIdInNdb(info, tupleId, increase) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable,
|
||||||
|
Uint64 tupleId, bool increase)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Ndb::setAutoIncrementValue");
|
||||||
|
assert(aTable != 0);
|
||||||
|
const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
|
||||||
|
const BaseString& internal_tabname = table->m_internalName;
|
||||||
|
|
||||||
|
Ndb_local_table_info *info=
|
||||||
|
theDictionary->get_local_table_info(internal_tabname, false);
|
||||||
|
if (info == 0) {
|
||||||
|
theError.code = theDictionary->getNdbError().code;
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
if (setTupleIdInNdb(info, tupleId, increase) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Ndb::setTupleIdInNdb(Ndb_local_table_info* info,
|
||||||
|
Uint64 tupleId, bool increase)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("Ndb::setTupleIdInNdb");
|
||||||
|
if (increase)
|
||||||
|
{
|
||||||
|
if (info->m_first_tuple_id != info->m_last_tuple_id)
|
||||||
|
{
|
||||||
|
assert(info->m_first_tuple_id < info->m_last_tuple_id);
|
||||||
|
if (tupleId <= info->m_first_tuple_id + 1)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
if (tupleId <= info->m_last_tuple_id)
|
||||||
|
{
|
||||||
|
info->m_first_tuple_id = tupleId - 1;
|
||||||
|
DBUG_PRINT("info",
|
||||||
|
("Setting next auto increment cached value to %llu",
|
||||||
|
(ulonglong)tupleId));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* if tupleId <= NEXTID, do nothing. otherwise update NEXTID to
|
||||||
|
* tupleId and set cached range to first = last = tupleId - 1.
|
||||||
|
*/
|
||||||
|
if (opTupleIdOnNdb(info, tupleId, 2) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* update NEXTID to given value. reset cached range.
|
||||||
|
*/
|
||||||
|
if (opTupleIdOnNdb(info, tupleId, 1) == -1)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Ndb::opTupleIdOnNdb");
|
DBUG_ENTER("Ndb::opTupleIdOnNdb");
|
||||||
|
Uint32 aTableId = info->m_table_impl->m_tableId;
|
||||||
DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op));
|
DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op));
|
||||||
|
|
||||||
NdbTransaction* tConnection;
|
NdbTransaction* tConnection;
|
||||||
NdbOperation* tOperation= 0; // Compiler warning if not initialized
|
NdbOperation* tOperation= 0; // Compiler warning if not initialized
|
||||||
Uint64 tValue;
|
Uint64 tValue;
|
||||||
NdbRecAttr* tRecAttrResult;
|
NdbRecAttr* tRecAttrResult;
|
||||||
int result;
|
|
||||||
Uint64 ret;
|
|
||||||
|
|
||||||
CHECK_STATUS_MACRO_ZERO;
|
CHECK_STATUS_MACRO_ZERO;
|
||||||
|
|
||||||
|
@ -958,42 +1012,45 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
|
||||||
|
|
||||||
tValue = tRecAttrResult->u_64_value();
|
tValue = tRecAttrResult->u_64_value();
|
||||||
|
|
||||||
theFirstTupleId[aTableId] = tValue - opValue;
|
info->m_first_tuple_id = tValue - opValue;
|
||||||
theLastTupleId[aTableId] = tValue - 1;
|
info->m_last_tuple_id = tValue - 1;
|
||||||
ret = theFirstTupleId[aTableId];
|
opValue = info->m_first_tuple_id; // out
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
tOperation->updateTuple();
|
// create on first use
|
||||||
|
tOperation->writeTuple();
|
||||||
tOperation->equal("SYSKEY_0", aTableId );
|
tOperation->equal("SYSKEY_0", aTableId );
|
||||||
tOperation->setValue("NEXTID", opValue);
|
tOperation->setValue("NEXTID", opValue);
|
||||||
|
|
||||||
if (tConnection->execute( Commit ) == -1 )
|
if (tConnection->execute( Commit ) == -1 )
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
|
|
||||||
theFirstTupleId[aTableId] = ~(Uint64)0;
|
info->m_first_tuple_id = ~(Uint64)0;
|
||||||
theLastTupleId[aTableId] = ~(Uint64)0;
|
info->m_last_tuple_id = ~(Uint64)0;
|
||||||
ret = opValue;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
tOperation->interpretedUpdateTuple();
|
tOperation->interpretedUpdateTuple();
|
||||||
tOperation->equal("SYSKEY_0", aTableId );
|
tOperation->equal("SYSKEY_0", aTableId );
|
||||||
tOperation->load_const_u64(1, opValue);
|
tOperation->load_const_u64(1, opValue);
|
||||||
tOperation->read_attr("NEXTID", 2);
|
tOperation->read_attr("NEXTID", 2);
|
||||||
|
// compare NEXTID >= opValue
|
||||||
tOperation->branch_le(2, 1, 0);
|
tOperation->branch_le(2, 1, 0);
|
||||||
tOperation->write_attr("NEXTID", 1);
|
tOperation->write_attr("NEXTID", 1);
|
||||||
tOperation->interpret_exit_ok();
|
tOperation->interpret_exit_ok();
|
||||||
tOperation->def_label(0);
|
tOperation->def_label(0);
|
||||||
tOperation->interpret_exit_nok(9999);
|
tOperation->interpret_exit_nok(9999);
|
||||||
|
|
||||||
if ( (result = tConnection->execute( Commit )) == -1 )
|
if (tConnection->execute( Commit ) == -1)
|
||||||
goto error_handler;
|
{
|
||||||
|
if (tConnection->theError.code != 9999)
|
||||||
if (result == 9999)
|
goto error_handler;
|
||||||
ret = ~(Uint64)0;
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
theFirstTupleId[aTableId] = theLastTupleId[aTableId] = opValue - 1;
|
DBUG_PRINT("info",
|
||||||
ret = opValue;
|
("Setting next auto increment value (db) to %llu",
|
||||||
|
(ulonglong)opValue));
|
||||||
|
info->m_first_tuple_id = info->m_last_tuple_id = opValue - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -1002,7 +1059,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
|
||||||
tRecAttrResult = tOperation->getValue("NEXTID");
|
tRecAttrResult = tOperation->getValue("NEXTID");
|
||||||
if (tConnection->execute( Commit ) == -1 )
|
if (tConnection->execute( Commit ) == -1 )
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
ret = tRecAttrResult->u_64_value();
|
opValue = tRecAttrResult->u_64_value(); // out
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
|
@ -1014,7 +1071,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
|
||||||
setDatabaseName(currentDb.c_str());
|
setDatabaseName(currentDb.c_str());
|
||||||
setDatabaseSchemaName(currentSchema.c_str());
|
setDatabaseSchemaName(currentSchema.c_str());
|
||||||
|
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
error_handler:
|
error_handler:
|
||||||
theError.code = tConnection->theError.code;
|
theError.code = tConnection->theError.code;
|
||||||
|
@ -1028,7 +1085,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
|
||||||
theError.code,
|
theError.code,
|
||||||
tConnection ? tConnection->theError.code : -1,
|
tConnection ? tConnection->theError.code : -1,
|
||||||
tOperation ? tOperation->theError.code : -1));
|
tOperation ? tOperation->theError.code : -1));
|
||||||
DBUG_RETURN(~(Uint64)0);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32
|
Uint32
|
||||||
|
|
|
@ -759,10 +759,6 @@ NdbDictionaryImpl::fetchGlobalTableImpl(const BaseString& internalTableName)
|
||||||
Ndb_local_table_info::create(impl, m_local_table_data_size);
|
Ndb_local_table_info::create(impl, m_local_table_data_size);
|
||||||
|
|
||||||
m_localHash.put(internalTableName.c_str(), info);
|
m_localHash.put(internalTableName.c_str(), info);
|
||||||
|
|
||||||
m_ndb.theFirstTupleId[impl->getTableId()] = ~0;
|
|
||||||
m_ndb.theLastTupleId[impl->getTableId()] = ~0;
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1746,14 +1742,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
|
|
||||||
if (haveAutoIncrement) {
|
if (haveAutoIncrement) {
|
||||||
if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(),
|
if (ndb.setAutoIncrementValue(impl.m_externalName.c_str(),
|
||||||
autoIncrementValue)) {
|
autoIncrementValue, false) == -1) {
|
||||||
if (ndb.theError.code == 0) {
|
DBUG_ASSERT(ndb.theError.code != 0);
|
||||||
m_error.code= 4336;
|
m_error= ndb.theError;
|
||||||
ndb.theError = m_error;
|
ret = -1;
|
||||||
} else
|
|
||||||
m_error= ndb.theError;
|
|
||||||
ret = -1; // errorcode set in initialize_autoincrement
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,10 +96,6 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
|
||||||
for (i = 0; i < MAX_NDB_NODES ; i++) {
|
for (i = 0; i < MAX_NDB_NODES ; i++) {
|
||||||
theConnectionArray[i] = NULL;
|
theConnectionArray[i] = NULL;
|
||||||
}//forg
|
}//forg
|
||||||
for (i = 0; i < 2048 ; i++) {
|
|
||||||
theFirstTupleId[i] = 0;
|
|
||||||
theLastTupleId[i] = 0;
|
|
||||||
}//for
|
|
||||||
|
|
||||||
theImpl->m_dbname.assign(aDataBase);
|
theImpl->m_dbname.assign(aDataBase);
|
||||||
theImpl->m_schemaname.assign(aSchema);
|
theImpl->m_schemaname.assign(aSchema);
|
||||||
|
|
|
@ -1139,9 +1139,13 @@ runCreateAutoincrementTable(NDBT_Context* ctx, NDBT_Step* step){
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
|
|
||||||
Uint64 value = myNdb->getAutoIncrementValue(tabname, 1);
|
Uint64 value;
|
||||||
|
if (myNdb->getAutoIncrementValue(tabname, value, 1) == -1) {
|
||||||
if (value != (startvalue+i)) {
|
g_err << "getAutoIncrementValue failed on " << tabname << endl;
|
||||||
|
APIERROR(myNdb->getNdbError());
|
||||||
|
return NDBT_FAILED;
|
||||||
|
}
|
||||||
|
else if (value != (startvalue+i)) {
|
||||||
g_err << "value = " << value << " expected " << startvalue+i << endl;;
|
g_err << "value = " << value << " expected " << startvalue+i << endl;;
|
||||||
APIERROR(myNdb->getNdbError());
|
APIERROR(myNdb->getNdbError());
|
||||||
// ret = NDBT_FAILED;
|
// ret = NDBT_FAILED;
|
||||||
|
|
|
@ -148,9 +148,12 @@ BackupRestore::finalize_table(const TableS & table){
|
||||||
if (table.have_auto_inc())
|
if (table.have_auto_inc())
|
||||||
{
|
{
|
||||||
Uint64 max_val= table.get_max_auto_val();
|
Uint64 max_val= table.get_max_auto_val();
|
||||||
Uint64 auto_val= m_ndb->readAutoIncrementValue(get_table(table.m_dictTable));
|
Uint64 auto_val;
|
||||||
if (max_val+1 > auto_val || auto_val == ~(Uint64)0)
|
int r= m_ndb->readAutoIncrementValue(get_table(table.m_dictTable), auto_val);
|
||||||
ret= m_ndb->setAutoIncrementValue(get_table(table.m_dictTable), max_val+1, false);
|
if (r == -1 && m_ndb->getNdbError().code != 626)
|
||||||
|
ret= false;
|
||||||
|
else if (r == -1 || max_val+1 > auto_val)
|
||||||
|
ret= m_ndb->setAutoIncrementValue(get_table(table.m_dictTable), max_val+1, false) != -1;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,6 @@ handlerton ndbcluster_hton = {
|
||||||
HTON_NO_FLAGS
|
HTON_NO_FLAGS
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NDB_FAILED_AUTO_INCREMENT ~(Uint64)0
|
|
||||||
#define NDB_AUTO_INCREMENT_RETRIES 10
|
#define NDB_AUTO_INCREMENT_RETRIES 10
|
||||||
|
|
||||||
#define NDB_INVALID_SCHEMA_OBJECT 241
|
#define NDB_INVALID_SCHEMA_OBJECT 241
|
||||||
|
@ -2112,14 +2111,15 @@ int ha_ndbcluster::write_row(byte *record)
|
||||||
{
|
{
|
||||||
// Table has hidden primary key
|
// Table has hidden primary key
|
||||||
Ndb *ndb= get_ndb();
|
Ndb *ndb= get_ndb();
|
||||||
Uint64 auto_value= NDB_FAILED_AUTO_INCREMENT;
|
int ret;
|
||||||
|
Uint64 auto_value;
|
||||||
uint retries= NDB_AUTO_INCREMENT_RETRIES;
|
uint retries= NDB_AUTO_INCREMENT_RETRIES;
|
||||||
do {
|
do {
|
||||||
auto_value= ndb->getAutoIncrementValue((const NDBTAB *) m_table);
|
ret= ndb->getAutoIncrementValue((const NDBTAB *) m_table, auto_value, 1);
|
||||||
} while (auto_value == NDB_FAILED_AUTO_INCREMENT &&
|
} while (ret == -1 &&
|
||||||
--retries &&
|
--retries &&
|
||||||
ndb->getNdbError().status == NdbError::TemporaryError);
|
ndb->getNdbError().status == NdbError::TemporaryError);
|
||||||
if (auto_value == NDB_FAILED_AUTO_INCREMENT)
|
if (ret == -1)
|
||||||
ERR_RETURN(ndb->getNdbError());
|
ERR_RETURN(ndb->getNdbError());
|
||||||
if (set_hidden_key(op, table->s->fields, (const byte*)&auto_value))
|
if (set_hidden_key(op, table->s->fields, (const byte*)&auto_value))
|
||||||
ERR_RETURN(op->getNdbError());
|
ERR_RETURN(op->getNdbError());
|
||||||
|
@ -2197,11 +2197,11 @@ int ha_ndbcluster::write_row(byte *record)
|
||||||
Ndb *ndb= get_ndb();
|
Ndb *ndb= get_ndb();
|
||||||
Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1;
|
Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1;
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("Trying to set next auto increment value to %lu",
|
("Trying to set next auto increment value to %llu",
|
||||||
(ulong) next_val));
|
(ulonglong) next_val));
|
||||||
if (ndb->setAutoIncrementValue((const NDBTAB *) m_table, next_val, TRUE))
|
if (ndb->setAutoIncrementValue((const NDBTAB *) m_table, next_val, TRUE)
|
||||||
DBUG_PRINT("info",
|
== -1)
|
||||||
("Setting next auto increment value to %u", next_val));
|
ERR_RETURN(ndb->getNdbError());
|
||||||
}
|
}
|
||||||
m_skip_auto_increment= TRUE;
|
m_skip_auto_increment= TRUE;
|
||||||
|
|
||||||
|
@ -3047,8 +3047,14 @@ void ha_ndbcluster::info(uint flag)
|
||||||
{
|
{
|
||||||
Ndb *ndb= get_ndb();
|
Ndb *ndb= get_ndb();
|
||||||
|
|
||||||
auto_increment_value=
|
if (ndb->readAutoIncrementValue((const NDBTAB *) m_table,
|
||||||
ndb->readAutoIncrementValue((const NDBTAB *) m_table);
|
auto_increment_value) == -1)
|
||||||
|
{
|
||||||
|
const NdbError err= ndb->getNdbError();
|
||||||
|
sql_print_error("Error %lu in readAutoIncrementValue(): %s",
|
||||||
|
(ulong) err.code, err.message);
|
||||||
|
auto_increment_value= ~(Uint64)0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@ -4375,17 +4381,17 @@ ulonglong ha_ndbcluster::get_auto_increment()
|
||||||
m_rows_to_insert - m_rows_inserted :
|
m_rows_to_insert - m_rows_inserted :
|
||||||
((m_rows_to_insert > m_autoincrement_prefetch) ?
|
((m_rows_to_insert > m_autoincrement_prefetch) ?
|
||||||
m_rows_to_insert : m_autoincrement_prefetch));
|
m_rows_to_insert : m_autoincrement_prefetch));
|
||||||
auto_value= NDB_FAILED_AUTO_INCREMENT;
|
int ret;
|
||||||
uint retries= NDB_AUTO_INCREMENT_RETRIES;
|
uint retries= NDB_AUTO_INCREMENT_RETRIES;
|
||||||
do {
|
do {
|
||||||
auto_value=
|
ret=
|
||||||
(m_skip_auto_increment) ?
|
m_skip_auto_increment ?
|
||||||
ndb->readAutoIncrementValue((const NDBTAB *) m_table)
|
ndb->readAutoIncrementValue((const NDBTAB *) m_table, auto_value) :
|
||||||
: ndb->getAutoIncrementValue((const NDBTAB *) m_table, cache_size);
|
ndb->getAutoIncrementValue((const NDBTAB *) m_table, auto_value, cache_size);
|
||||||
} while (auto_value == NDB_FAILED_AUTO_INCREMENT &&
|
} while (ret == -1 &&
|
||||||
--retries &&
|
--retries &&
|
||||||
ndb->getNdbError().status == NdbError::TemporaryError);
|
ndb->getNdbError().status == NdbError::TemporaryError);
|
||||||
if (auto_value == NDB_FAILED_AUTO_INCREMENT)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
const NdbError err= ndb->getNdbError();
|
const NdbError err= ndb->getNdbError();
|
||||||
sql_print_error("Error %lu in ::get_auto_increment(): %s",
|
sql_print_error("Error %lu in ::get_auto_increment(): %s",
|
||||||
|
|
Loading…
Reference in a new issue