mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
ndb - rbr blobs works now (or again)
mysql-test/t/disabled.def: ndb_blob.test works again, sort of storage/ndb/include/ndbapi/NdbBlob.hpp: better getNull & replace+tinyblob forward-patch from 5.0 storage/ndb/src/ndbapi/NdbBlob.cpp: better getNull & replace+tinyblob forward-patch from 5.0 storage/ndb/test/ndbapi/test_event.cpp: getEvent()->getTable() sql/ha_ndbcluster.cc: return more error codes from blob calls sql/ha_ndbcluster_binlog.cc: return more error codes from blob calls storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp: return more error codes from blob calls storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp: copy and invalidate blob tables as part of main table. TODO: do not cache blob tables storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp: copy and invalidate blob tables as part of main table. TODO: do not cache blob tables
This commit is contained in:
126
mysql-test/r/rpl_ndb_blob.result
Normal file
126
mysql-test/r/rpl_ndb_blob.result
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
stop slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
reset master;
|
||||||
|
reset slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
start slave;
|
||||||
|
create table t1 (
|
||||||
|
a int not null primary key,
|
||||||
|
b text not null
|
||||||
|
) engine=ndb;
|
||||||
|
insert into t1 values(1, repeat('abc',10));
|
||||||
|
insert into t1 values(2, repeat('def',200));
|
||||||
|
insert into t1 values(3, repeat('ghi',3000));
|
||||||
|
select 'M', a, sha1(b) from t1
|
||||||
|
order by a;
|
||||||
|
M a sha1(b)
|
||||||
|
M 1 8a6c4cf7cf97e66c487c3e3b717e9ae13623d07d
|
||||||
|
M 2 0ccd08c0fa6ad6a4382b27b1d36586d6ceb4fffa
|
||||||
|
M 3 75e7b3299e0b776aeac2a4d1542d5b3c0ba2e05e
|
||||||
|
select 'S', a, sha1(b) from t1
|
||||||
|
order by a;
|
||||||
|
S a sha1(b)
|
||||||
|
S 1 8a6c4cf7cf97e66c487c3e3b717e9ae13623d07d
|
||||||
|
S 2 0ccd08c0fa6ad6a4382b27b1d36586d6ceb4fffa
|
||||||
|
S 3 75e7b3299e0b776aeac2a4d1542d5b3c0ba2e05e
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (
|
||||||
|
a int not null primary key,
|
||||||
|
b text not null,
|
||||||
|
c int,
|
||||||
|
d longblob,
|
||||||
|
e tinyblob
|
||||||
|
) engine=ndbcluster;
|
||||||
|
insert into t1 values (
|
||||||
|
0, repeat(@s2,454), 100, repeat(@s2,345), NULL);
|
||||||
|
insert into t1 values (
|
||||||
|
1, repeat(@s0,504), NULL, repeat(@s1,732), repeat(@s1,1));
|
||||||
|
insert into t1 values (
|
||||||
|
2, '', 102, '', repeat(@s2,1));
|
||||||
|
insert into t1 values (
|
||||||
|
3, repeat(@s0,545), 103, repeat(@s2,788), repeat(@s0,1));
|
||||||
|
insert into t1 values (
|
||||||
|
4, repeat(@s1,38), 104, repeat(@s0,260), repeat(@s0,1));
|
||||||
|
insert into t1 values (
|
||||||
|
5, repeat(@s2,12), 105, repeat(@s2,40), repeat(@s1,1));
|
||||||
|
insert into t1 values (
|
||||||
|
6, repeat(@s1,242), 106, NULL, repeat(@s1,1));
|
||||||
|
insert into t1 values (
|
||||||
|
7, repeat(@s1,30), 107, repeat(@s0,161), '');
|
||||||
|
insert into t1 values (
|
||||||
|
8, repeat(@s1,719), 108, repeat(@s2,104), NULL);
|
||||||
|
insert into t1 values (
|
||||||
|
9, repeat(@s2,427), NULL, NULL, NULL);
|
||||||
|
select 'M', a, sha1(b), c, sha1(d), sha1(e)
|
||||||
|
from t1 order by a;
|
||||||
|
M a sha1(b) c sha1(d) sha1(e)
|
||||||
|
M 0 9538f61e649383c0d1054de2a2f0171188129f33 100 2b6515f29c20b8e9e17cc597527e516c0de8d612 NULL
|
||||||
|
M 1 dcb9a12ca86e718ff2564be041b7c1b3ff5ea559 NULL f23e7439d9a73c3954979b85a7ef6ef35faf4e9d abfe8ae5212b22d023aa6de84beeb1344ac5668a
|
||||||
|
M 2 da39a3ee5e6b4b0d3255bfef95601890afd80709 102 da39a3ee5e6b4b0d3255bfef95601890afd80709 33deebe47470a40e960834bffa4cdc66790845a6
|
||||||
|
M 3 ec8e06d9ac4695d6a898b519ba840590263a9bff 103 278629ad080c3c4377978c006c2e54d0992e43cc 700915801f853603510aeb67b331866d996fdbda
|
||||||
|
M 4 0392fa8c425d293c79291f0f34779d1101d13fcb 104 5084b602c7203e0e9590a163415ac605da17ac32 700915801f853603510aeb67b331866d996fdbda
|
||||||
|
M 5 0f9653f0c7a69cd1c617792d546582e974a7a24d 105 566588a04ff26d05160d61c83435292bfda2978e abfe8ae5212b22d023aa6de84beeb1344ac5668a
|
||||||
|
M 6 a37e8b0ff4fc13a42be02cdecb36186436959bae 106 NULL abfe8ae5212b22d023aa6de84beeb1344ac5668a
|
||||||
|
M 7 a6bae0cfe6b45ff8c3c12d2ce577a1cd3931190f 107 39ee712b4b9e47f2cf3ba7c9790b2bf0d8f378e8 da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||||
|
M 8 e139adcb7b2974ee7ff227fd405709e5cb7c896c 108 ba8073b0e1a281d4111bd2d82c7722b01574c00b NULL
|
||||||
|
M 9 1fc5168fe4be566b17b658d94e7813f0b5032cdb NULL NULL NULL
|
||||||
|
select 'S', a, sha1(b), c, sha1(d), sha1(e)
|
||||||
|
from t1 order by a;
|
||||||
|
S a sha1(b) c sha1(d) sha1(e)
|
||||||
|
S 0 9538f61e649383c0d1054de2a2f0171188129f33 100 2b6515f29c20b8e9e17cc597527e516c0de8d612 NULL
|
||||||
|
S 1 dcb9a12ca86e718ff2564be041b7c1b3ff5ea559 NULL f23e7439d9a73c3954979b85a7ef6ef35faf4e9d abfe8ae5212b22d023aa6de84beeb1344ac5668a
|
||||||
|
S 2 da39a3ee5e6b4b0d3255bfef95601890afd80709 102 da39a3ee5e6b4b0d3255bfef95601890afd80709 33deebe47470a40e960834bffa4cdc66790845a6
|
||||||
|
S 3 ec8e06d9ac4695d6a898b519ba840590263a9bff 103 278629ad080c3c4377978c006c2e54d0992e43cc 700915801f853603510aeb67b331866d996fdbda
|
||||||
|
S 4 0392fa8c425d293c79291f0f34779d1101d13fcb 104 5084b602c7203e0e9590a163415ac605da17ac32 700915801f853603510aeb67b331866d996fdbda
|
||||||
|
S 5 0f9653f0c7a69cd1c617792d546582e974a7a24d 105 566588a04ff26d05160d61c83435292bfda2978e abfe8ae5212b22d023aa6de84beeb1344ac5668a
|
||||||
|
S 6 a37e8b0ff4fc13a42be02cdecb36186436959bae 106 NULL abfe8ae5212b22d023aa6de84beeb1344ac5668a
|
||||||
|
S 7 a6bae0cfe6b45ff8c3c12d2ce577a1cd3931190f 107 39ee712b4b9e47f2cf3ba7c9790b2bf0d8f378e8 da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||||
|
S 8 e139adcb7b2974ee7ff227fd405709e5cb7c896c 108 ba8073b0e1a281d4111bd2d82c7722b01574c00b NULL
|
||||||
|
S 9 1fc5168fe4be566b17b658d94e7813f0b5032cdb NULL NULL NULL
|
||||||
|
drop table t1;
|
||||||
|
show binlog events;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
|
||||||
|
master-bin.000001 102 Query 1 239 use `test`; create table t1 (
|
||||||
|
a int not null primary key,
|
||||||
|
b text not null
|
||||||
|
) engine=ndb
|
||||||
|
master-bin.000001 239 Query 1 303 BEGIN
|
||||||
|
master-bin.000001 303 Table_map 1 65 cluster_replication.apply_status
|
||||||
|
master-bin.000001 368 Write_rows 1 107
|
||||||
|
master-bin.000001 410 Table_map 1 147 test.t1
|
||||||
|
master-bin.000001 450 Write_rows 1 818
|
||||||
|
master-bin.000001 1121 Write_rows 1 9853
|
||||||
|
master-bin.000001 10156 Query 1 10221 COMMIT
|
||||||
|
master-bin.000001 10221 Query 1 10285 BEGIN
|
||||||
|
master-bin.000001 10285 Table_map 1 65 cluster_replication.apply_status
|
||||||
|
master-bin.000001 10350 Write_rows 1 107
|
||||||
|
master-bin.000001 10392 Query 1 10457 COMMIT
|
||||||
|
master-bin.000001 10457 Query 1 10533 use `test`; drop table t1
|
||||||
|
master-bin.000001 10533 Query 1 10708 use `test`; create table t1 (
|
||||||
|
a int not null primary key,
|
||||||
|
b text not null,
|
||||||
|
c int,
|
||||||
|
d longblob,
|
||||||
|
e tinyblob
|
||||||
|
) engine=ndbcluster
|
||||||
|
master-bin.000001 10708 Query 1 10772 BEGIN
|
||||||
|
master-bin.000001 10772 Table_map 1 65 cluster_replication.apply_status
|
||||||
|
master-bin.000001 10837 Write_rows 1 107
|
||||||
|
master-bin.000001 10879 Table_map 1 150 test.t1
|
||||||
|
master-bin.000001 10922 Write_rows 1 48934
|
||||||
|
master-bin.000001 59706 Write_rows 1 124436
|
||||||
|
master-bin.000001 135208 Write_rows 1 124542
|
||||||
|
master-bin.000001 135314 Write_rows 1 205961
|
||||||
|
master-bin.000001 216733 Write_rows 1 224245
|
||||||
|
master-bin.000001 235017 Write_rows 1 227523
|
||||||
|
master-bin.000001 238295 Write_rows 1 242391
|
||||||
|
master-bin.000001 253163 Write_rows 1 254087
|
||||||
|
master-bin.000001 264859 Write_rows 1 304335
|
||||||
|
master-bin.000001 315107 Write_rows 1 330427
|
||||||
|
master-bin.000001 341199 Query 1 341264 COMMIT
|
||||||
|
master-bin.000001 341264 Query 1 341328 BEGIN
|
||||||
|
master-bin.000001 341328 Table_map 1 65 cluster_replication.apply_status
|
||||||
|
master-bin.000001 341393 Write_rows 1 107
|
||||||
|
master-bin.000001 341435 Query 1 341500 COMMIT
|
||||||
|
master-bin.000001 341500 Query 1 341576 use `test`; drop table t1
|
@ -28,7 +28,6 @@ rpl_sp : Bug #16456
|
|||||||
#ndb_dd_disk2memory : Bug #16466
|
#ndb_dd_disk2memory : Bug #16466
|
||||||
ndb_autodiscover : Needs to be fixed w.r.t binlog
|
ndb_autodiscover : Needs to be fixed w.r.t binlog
|
||||||
ndb_autodiscover2 : Needs to be fixed w.r.t binlog
|
ndb_autodiscover2 : Needs to be fixed w.r.t binlog
|
||||||
ndb_blob : BLOB replication causes core in master1 (Pekka will fix)
|
|
||||||
#ndb_alter_table_row : sometimes wrong error 1015!=1046
|
#ndb_alter_table_row : sometimes wrong error 1015!=1046
|
||||||
ndb_gis : garbled msgs from corrupt THD*
|
ndb_gis : garbled msgs from corrupt THD*
|
||||||
ndb_binlog_ddl_multi : Bug #17038
|
ndb_binlog_ddl_multi : Bug #17038
|
||||||
|
93
mysql-test/t/rpl_ndb_blob.test
Normal file
93
mysql-test/t/rpl_ndb_blob.test
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
--source include/have_ndb.inc
|
||||||
|
--source include/have_binlog_format_row.inc
|
||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# basic test of blob replication for NDB
|
||||||
|
#
|
||||||
|
|
||||||
|
# easy test
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
create table t1 (
|
||||||
|
a int not null primary key,
|
||||||
|
b text not null
|
||||||
|
) engine=ndb;
|
||||||
|
|
||||||
|
insert into t1 values(1, repeat('abc',10));
|
||||||
|
insert into t1 values(2, repeat('def',200));
|
||||||
|
insert into t1 values(3, repeat('ghi',3000));
|
||||||
|
|
||||||
|
select 'M', a, sha1(b) from t1
|
||||||
|
order by a;
|
||||||
|
|
||||||
|
--sync_slave_with_master
|
||||||
|
--sleep 5
|
||||||
|
--connection slave
|
||||||
|
select 'S', a, sha1(b) from t1
|
||||||
|
order by a;
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
drop table t1;
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
# hard test
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
create table t1 (
|
||||||
|
a int not null primary key,
|
||||||
|
b text not null,
|
||||||
|
c int,
|
||||||
|
d longblob,
|
||||||
|
e tinyblob
|
||||||
|
) engine=ndbcluster;
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
# length 61
|
||||||
|
set @s0 = 'rggurloniukyehuxdbfkkyzlceixzrehqhvxvxbpwizzvjzpucqmzrhzxzfau';
|
||||||
|
set @s1 = 'ykyymbzqgqlcjhlhmyqelfoaaohvtbekvifukdtnvcrrjveevfakxarxexomz';
|
||||||
|
set @s2 = 'dbnfqyzgtqxalcrwtfsqabknvtfcbpoonxsjiqvmhnfikxxhcgoexlkoezvah';
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
insert into t1 values (
|
||||||
|
0, repeat(@s2,454), 100, repeat(@s2,345), NULL);
|
||||||
|
insert into t1 values (
|
||||||
|
1, repeat(@s0,504), NULL, repeat(@s1,732), repeat(@s1,1));
|
||||||
|
insert into t1 values (
|
||||||
|
2, '', 102, '', repeat(@s2,1));
|
||||||
|
insert into t1 values (
|
||||||
|
3, repeat(@s0,545), 103, repeat(@s2,788), repeat(@s0,1));
|
||||||
|
insert into t1 values (
|
||||||
|
4, repeat(@s1,38), 104, repeat(@s0,260), repeat(@s0,1));
|
||||||
|
insert into t1 values (
|
||||||
|
5, repeat(@s2,12), 105, repeat(@s2,40), repeat(@s1,1));
|
||||||
|
insert into t1 values (
|
||||||
|
6, repeat(@s1,242), 106, NULL, repeat(@s1,1));
|
||||||
|
insert into t1 values (
|
||||||
|
7, repeat(@s1,30), 107, repeat(@s0,161), '');
|
||||||
|
insert into t1 values (
|
||||||
|
8, repeat(@s1,719), 108, repeat(@s2,104), NULL);
|
||||||
|
insert into t1 values (
|
||||||
|
9, repeat(@s2,427), NULL, NULL, NULL);
|
||||||
|
|
||||||
|
select 'M', a, sha1(b), c, sha1(d), sha1(e)
|
||||||
|
from t1 order by a;
|
||||||
|
|
||||||
|
--sync_slave_with_master
|
||||||
|
--sleep 5
|
||||||
|
--connection slave
|
||||||
|
select 'S', a, sha1(b), c, sha1(d), sha1(e)
|
||||||
|
from t1 order by a;
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
drop table t1;
|
||||||
|
--sync_slave_with_master
|
||||||
|
|
||||||
|
#
|
||||||
|
# view the binlog
|
||||||
|
#
|
||||||
|
|
||||||
|
--connection master
|
||||||
|
let $VERSION=`select version()`;
|
||||||
|
--replace_result $VERSION VERSION
|
||||||
|
show binlog events;
|
@ -840,51 +840,51 @@ int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
|
|||||||
{
|
{
|
||||||
Field *field= table->field[i];
|
Field *field= table->field[i];
|
||||||
NdbValue value= value_array[i];
|
NdbValue value= value_array[i];
|
||||||
if (value.ptr != NULL && (field->flags & BLOB_FLAG))
|
if (! (field->flags & BLOB_FLAG))
|
||||||
|
continue;
|
||||||
|
if (value.blob == NULL)
|
||||||
{
|
{
|
||||||
Field_blob *field_blob= (Field_blob *)field;
|
DBUG_PRINT("info",("[%u] skipped", i));
|
||||||
NdbBlob *ndb_blob= value.blob;
|
continue;
|
||||||
int isNull;
|
}
|
||||||
ndb_blob->getDefined(isNull);
|
Field_blob *field_blob= (Field_blob *)field;
|
||||||
if (isNull == 0) { // XXX -1 should be allowed only for events
|
NdbBlob *ndb_blob= value.blob;
|
||||||
Uint64 blob_len= 0;
|
int isNull;
|
||||||
if (ndb_blob->getLength(blob_len) != 0)
|
if (ndb_blob->getNull(isNull) != 0)
|
||||||
DBUG_RETURN(-1);
|
ERR_RETURN(ndb_blob->getNdbError());
|
||||||
// Align to Uint64
|
if (isNull == 0) {
|
||||||
uint32 blob_size= blob_len;
|
Uint64 len64= 0;
|
||||||
if (blob_size % 8 != 0)
|
if (ndb_blob->getLength(len64) != 0)
|
||||||
blob_size+= 8 - blob_size % 8;
|
ERR_RETURN(ndb_blob->getNdbError());
|
||||||
if (loop == 1)
|
// Align to Uint64
|
||||||
{
|
uint32 size= len64;
|
||||||
char *buf= buffer + offset;
|
if (size % 8 != 0)
|
||||||
uint32 len= 0xffffffff; // Max uint32
|
size+= 8 - size % 8;
|
||||||
DBUG_PRINT("info", ("read blob ptr=%p len=%u",
|
if (loop == 1)
|
||||||
buf, (uint) blob_len));
|
|
||||||
if (ndb_blob->readData(buf, len) != 0)
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
DBUG_PRINT("info", ("blob field %d offset=%u len=%u [ptrdiff=%d]",
|
|
||||||
i, offset, len, (int)ptrdiff));
|
|
||||||
DBUG_ASSERT(len == blob_len);
|
|
||||||
// Ugly hack assumes only ptr needs to be changed
|
|
||||||
field_blob->ptr+= ptrdiff;
|
|
||||||
field_blob->set_ptr(len, buf);
|
|
||||||
field_blob->ptr-= ptrdiff;
|
|
||||||
}
|
|
||||||
offset+= blob_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (loop == 1)
|
char *buf= buffer + offset;
|
||||||
{
|
uint32 len= 0xffffffff; // Max uint32
|
||||||
// have to set length even in this case
|
if (ndb_blob->readData(buf, len) != 0)
|
||||||
char *buf= buffer + offset;
|
ERR_RETURN(ndb_blob->getNdbError());
|
||||||
uint32 len= 0;
|
DBUG_PRINT("info", ("[%u] offset=%u buf=%p len=%u [ptrdiff=%d]",
|
||||||
field_blob->ptr+= ptrdiff;
|
i, offset, buf, len, (int)ptrdiff));
|
||||||
field_blob->set_ptr(len, buf);
|
DBUG_ASSERT(len == len64);
|
||||||
field_blob->ptr-= ptrdiff;
|
// Ugly hack assumes only ptr needs to be changed
|
||||||
DBUG_PRINT("info", ("blob field %d isNull=%d", i, isNull));
|
field_blob->ptr+= ptrdiff;
|
||||||
}
|
field_blob->set_ptr(len, buf);
|
||||||
|
field_blob->ptr-= ptrdiff;
|
||||||
}
|
}
|
||||||
|
offset+= size;
|
||||||
|
}
|
||||||
|
else if (loop == 1) // undefined or null
|
||||||
|
{
|
||||||
|
// have to set length even in this case
|
||||||
|
char *buf= buffer + offset; // or maybe NULL
|
||||||
|
uint32 len= 0;
|
||||||
|
field_blob->ptr+= ptrdiff;
|
||||||
|
field_blob->set_ptr(len, buf);
|
||||||
|
field_blob->ptr-= ptrdiff;
|
||||||
|
DBUG_PRINT("info", ("[%u] isNull=%d", i, isNull));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loop == 0 && offset > buffer_size)
|
if (loop == 0 && offset > buffer_size)
|
||||||
|
@ -2084,6 +2084,20 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
|
|||||||
DBUG_PRINT("info", ("%s blob", col_name));
|
DBUG_PRINT("info", ("%s blob", col_name));
|
||||||
attr0.blob= op->getBlobHandle(col_name);
|
attr0.blob= op->getBlobHandle(col_name);
|
||||||
attr1.blob= op->getPreBlobHandle(col_name);
|
attr1.blob= op->getPreBlobHandle(col_name);
|
||||||
|
if (attr0.blob == NULL || attr1.blob == NULL)
|
||||||
|
{
|
||||||
|
sql_print_error("NDB Binlog: Creating NdbEventOperation"
|
||||||
|
" blob field %u handles failed (code=%d) for %s",
|
||||||
|
j, op->getNdbError().code, event_name);
|
||||||
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||||
|
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
|
||||||
|
op->getNdbError().code,
|
||||||
|
op->getNdbError().message,
|
||||||
|
"NDB");
|
||||||
|
ndb->dropEventOperation(op);
|
||||||
|
pthread_mutex_unlock(&injector_mutex);
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -76,8 +76,8 @@ class NdbEventOperationImpl;
|
|||||||
* handle can be read after next event on main table has been retrieved.
|
* handle can be read after next event on main table has been retrieved.
|
||||||
* The data is available immediately. See NdbEventOperation.
|
* The data is available immediately. See NdbEventOperation.
|
||||||
*
|
*
|
||||||
* NdbBlob methods return -1 on error and 0 on success, and use output
|
* Non-void NdbBlob methods return -1 on error and 0 on success. Output
|
||||||
* parameters when necessary.
|
* parameters are used when necessary.
|
||||||
*
|
*
|
||||||
* Operation types:
|
* Operation types:
|
||||||
* - insertTuple must use setValue if blob column is non-nullable
|
* - insertTuple must use setValue if blob column is non-nullable
|
||||||
@ -116,6 +116,11 @@ public:
|
|||||||
* Get the state of a NdbBlob object.
|
* Get the state of a NdbBlob object.
|
||||||
*/
|
*/
|
||||||
State getState();
|
State getState();
|
||||||
|
/**
|
||||||
|
* Returns -1 for normal statement based blob and 0/1 for event
|
||||||
|
* operation post/pre data blob. Always succeeds.
|
||||||
|
*/
|
||||||
|
void getVersion(int& version);
|
||||||
/**
|
/**
|
||||||
* Inline blob header.
|
* Inline blob header.
|
||||||
*/
|
*/
|
||||||
@ -150,16 +155,15 @@ public:
|
|||||||
* then the callback is invoked.
|
* then the callback is invoked.
|
||||||
*/
|
*/
|
||||||
int setActiveHook(ActiveHook* activeHook, void* arg);
|
int setActiveHook(ActiveHook* activeHook, void* arg);
|
||||||
/**
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
||||||
* Check if blob value is defined (NULL or not). Used as first call
|
|
||||||
* on event based blob. The argument is set to -1 for not defined.
|
|
||||||
* Unlike getNull() this does not cause error on the handle.
|
|
||||||
*/
|
|
||||||
int getDefined(int& isNull);
|
int getDefined(int& isNull);
|
||||||
/**
|
|
||||||
* Check if blob is null.
|
|
||||||
*/
|
|
||||||
int getNull(bool& isNull);
|
int getNull(bool& isNull);
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* Return -1, 0, 1 if blob is undefined, non-null, or null. For
|
||||||
|
* non-event blob, undefined causes a state error.
|
||||||
|
*/
|
||||||
|
int getNull(int& isNull);
|
||||||
/**
|
/**
|
||||||
* Set blob to NULL.
|
* Set blob to NULL.
|
||||||
*/
|
*/
|
||||||
@ -208,8 +212,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int getBlobEventName(char* bename, Ndb* anNdb, const char* eventName, const char* columnName);
|
static int getBlobEventName(char* bename, Ndb* anNdb, const char* eventName, const char* columnName);
|
||||||
/**
|
/**
|
||||||
* Return error object. The error may be blob specific (below) or may
|
* Return error object. The error may be blob specific or may be
|
||||||
* be copied from a failed implicit operation.
|
* copied from a failed implicit operation.
|
||||||
*/
|
*/
|
||||||
const NdbError& getNdbError() const;
|
const NdbError& getNdbError() const;
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +31,21 @@
|
|||||||
*/
|
*/
|
||||||
static const bool g_ndb_blob_ok_to_read_index_table = false;
|
static const bool g_ndb_blob_ok_to_read_index_table = false;
|
||||||
|
|
||||||
// state (inline)
|
// get state
|
||||||
|
|
||||||
|
NdbBlob::State
|
||||||
|
NdbBlob::getState()
|
||||||
|
{
|
||||||
|
return theState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NdbBlob::getVersion(int& version)
|
||||||
|
{
|
||||||
|
version = theEventBlobVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set state (inline)
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
NdbBlob::setState(State newState)
|
NdbBlob::setState(State newState)
|
||||||
@ -608,7 +622,7 @@ NdbBlob::setActiveHook(ActiveHook activeHook, void* arg)
|
|||||||
// misc operations
|
// misc operations
|
||||||
|
|
||||||
int
|
int
|
||||||
NdbBlob::getDefined(int& isNull)
|
NdbBlob::getDefined(int& isNull) // deprecated
|
||||||
{
|
{
|
||||||
DBUG_ENTER("NdbBlob::getDefined");
|
DBUG_ENTER("NdbBlob::getDefined");
|
||||||
if (theState == Prepared && theSetFlag) {
|
if (theState == Prepared && theSetFlag) {
|
||||||
@ -620,7 +634,7 @@ NdbBlob::getDefined(int& isNull)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NdbBlob::getNull(bool& isNull)
|
NdbBlob::getNull(bool& isNull) // deprecated
|
||||||
{
|
{
|
||||||
DBUG_ENTER("NdbBlob::getNull");
|
DBUG_ENTER("NdbBlob::getNull");
|
||||||
if (theState == Prepared && theSetFlag) {
|
if (theState == Prepared && theSetFlag) {
|
||||||
@ -635,6 +649,23 @@ NdbBlob::getNull(bool& isNull)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
NdbBlob::getNull(int& isNull)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("NdbBlob::getNull");
|
||||||
|
if (theState == Prepared && theSetFlag) {
|
||||||
|
isNull = (theSetBuf == NULL);
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
isNull = theNullFlag;
|
||||||
|
if (isNull == -1 && theEventBlobVersion == -1) {
|
||||||
|
setErrorCode(NdbBlobImpl::ErrState);
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
DBUG_PRINT("info", ("isNull=%d", isNull));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NdbBlob::setNull()
|
NdbBlob::setNull()
|
||||||
{
|
{
|
||||||
@ -1085,6 +1116,8 @@ NdbBlob::deletePartsUnknown(Uint32 part)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("NdbBlob::deletePartsUnknown");
|
DBUG_ENTER("NdbBlob::deletePartsUnknown");
|
||||||
DBUG_PRINT("info", ("part=%u count=all", part));
|
DBUG_PRINT("info", ("part=%u count=all", part));
|
||||||
|
if (thePartSize == 0) // tinyblob
|
||||||
|
DBUG_RETURN(0);
|
||||||
static const unsigned maxbat = 256;
|
static const unsigned maxbat = 256;
|
||||||
static const unsigned minbat = 1;
|
static const unsigned minbat = 1;
|
||||||
unsigned bat = minbat;
|
unsigned bat = minbat;
|
||||||
|
@ -87,7 +87,12 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col)
|
|||||||
m_arrayType = col.m_arrayType;
|
m_arrayType = col.m_arrayType;
|
||||||
m_storageType = col.m_storageType;
|
m_storageType = col.m_storageType;
|
||||||
m_keyInfoPos = col.m_keyInfoPos;
|
m_keyInfoPos = col.m_keyInfoPos;
|
||||||
m_blobTable = col.m_blobTable;
|
if (col.m_blobTable == NULL)
|
||||||
|
m_blobTable = NULL;
|
||||||
|
else {
|
||||||
|
m_blobTable = new NdbTableImpl();
|
||||||
|
m_blobTable->assign(*col.m_blobTable);
|
||||||
|
}
|
||||||
m_column_no = col.m_column_no;
|
m_column_no = col.m_column_no;
|
||||||
// Do not copy m_facade !!
|
// Do not copy m_facade !!
|
||||||
|
|
||||||
@ -2747,14 +2752,25 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl)
|
NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl, bool lock)
|
||||||
{
|
{
|
||||||
const char * internalTableName = impl.m_internalName.c_str();
|
const char * internalTableName = impl.m_internalName.c_str();
|
||||||
|
|
||||||
|
if (lock)
|
||||||
|
m_globalHash->lock();
|
||||||
|
if (impl.m_noOfBlobs != 0) {
|
||||||
|
for (uint i = 0; i < impl.m_columns.size(); i++) {
|
||||||
|
NdbColumnImpl& c = *impl.m_columns[i];
|
||||||
|
if (! c.getBlobType() || c.getPartSize() == 0)
|
||||||
|
continue;
|
||||||
|
assert(c.m_blobTable != NULL);
|
||||||
|
removeCachedObject(*c.m_blobTable, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
m_localHash.drop(internalTableName);
|
m_localHash.drop(internalTableName);
|
||||||
m_globalHash->lock();
|
|
||||||
m_globalHash->release(&impl);
|
m_globalHash->release(&impl);
|
||||||
m_globalHash->unlock();
|
if (lock)
|
||||||
|
m_globalHash->unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ public:
|
|||||||
int dropTable(NdbTableImpl &);
|
int dropTable(NdbTableImpl &);
|
||||||
int dropBlobTables(NdbTableImpl &);
|
int dropBlobTables(NdbTableImpl &);
|
||||||
int invalidateObject(NdbTableImpl &);
|
int invalidateObject(NdbTableImpl &);
|
||||||
int removeCachedObject(NdbTableImpl &);
|
int removeCachedObject(NdbTableImpl &, bool lock = true);
|
||||||
|
|
||||||
int createIndex(NdbIndexImpl &ix);
|
int createIndex(NdbIndexImpl &ix);
|
||||||
int dropIndex(const char * indexName,
|
int dropIndex(const char * indexName,
|
||||||
|
@ -342,15 +342,18 @@ NdbEventOperationImpl::getBlobHandle(const NdbColumnImpl *tAttrInfo, int n)
|
|||||||
tBlobOp = tBlobOp->m_next;
|
tBlobOp = tBlobOp->m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_PRINT("info", ("%s op %s", tBlobOp ? " reuse" : " create", bename));
|
DBUG_PRINT("info", ("%s blob event op for %s",
|
||||||
|
tBlobOp ? " reuse" : " create", bename));
|
||||||
|
|
||||||
// create blob event op if not found
|
// create blob event op if not found
|
||||||
if (tBlobOp == NULL) {
|
if (tBlobOp == NULL) {
|
||||||
// to hide blob op it is linked under main op, not under m_ndb
|
// to hide blob op it is linked under main op, not under m_ndb
|
||||||
NdbEventOperation* tmp =
|
NdbEventOperation* tmp =
|
||||||
m_ndb->theEventBuffer->createEventOperation(bename, m_error);
|
m_ndb->theEventBuffer->createEventOperation(bename, m_error);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL) {
|
||||||
|
m_error.code = m_ndb->theEventBuffer->m_error.code;
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
tBlobOp = &tmp->m_impl;
|
tBlobOp = &tmp->m_impl;
|
||||||
|
|
||||||
// pointer to main table op
|
// pointer to main table op
|
||||||
@ -367,11 +370,14 @@ NdbEventOperationImpl::getBlobHandle(const NdbColumnImpl *tAttrInfo, int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tBlob = m_ndb->getNdbBlob();
|
tBlob = m_ndb->getNdbBlob();
|
||||||
if (tBlob == NULL)
|
if (tBlob == NULL) {
|
||||||
|
m_error.code = m_ndb->getNdbError().code;
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// calls getValue on inline and blob part
|
// calls getValue on inline and blob part
|
||||||
if (tBlob->atPrepare(this, tBlobOp, tAttrInfo, n) == -1) {
|
if (tBlob->atPrepare(this, tBlobOp, tAttrInfo, n) == -1) {
|
||||||
|
m_error.code = tBlob->getNdbError().code;
|
||||||
m_ndb->releaseNdbBlob(tBlob);
|
m_ndb->releaseNdbBlob(tBlob);
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
@ -990,7 +990,7 @@ static int copy_events(Ndb *ndb)
|
|||||||
while ((pOp= ndb->nextEvent()))
|
while ((pOp= ndb->nextEvent()))
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
sprintf(buf, "%s_SHADOW", pOp->getTable()->getName());
|
sprintf(buf, "%s_SHADOW", pOp->getEvent()->getTable()->getName());
|
||||||
const NdbDictionary::Table *table= dict->getTable(buf);
|
const NdbDictionary::Table *table= dict->getTable(buf);
|
||||||
|
|
||||||
if (table == 0)
|
if (table == 0)
|
||||||
|
Reference in New Issue
Block a user