Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
ba193367
Commit
ba193367
authored
Jan 12, 2005
by
tulin@build.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal:/home/bk/mysql-5.0-ndb
into build.mysql.com:/users/tulin/mysql-5.0-ndb
parents
7cc1926b
476265a1
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
337 additions
and
192 deletions
+337
-192
ndb/include/kernel/signaldata/SignalData.hpp
ndb/include/kernel/signaldata/SignalData.hpp
+7
-0
ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
+7
-1
ndb/src/common/debugger/signaldata/SignalNames.cpp
ndb/src/common/debugger/signaldata/SignalNames.cpp
+3
-0
ndb/src/common/debugger/signaldata/SumaImpl.cpp
ndb/src/common/debugger/signaldata/SumaImpl.cpp
+75
-1
ndb/src/kernel/blocks/suma/Suma.cpp
ndb/src/kernel/blocks/suma/Suma.cpp
+3
-1
ndb/src/ndbapi/NdbDictionaryImpl.cpp
ndb/src/ndbapi/NdbDictionaryImpl.cpp
+107
-115
ndb/src/ndbapi/NdbEventOperationImpl.cpp
ndb/src/ndbapi/NdbEventOperationImpl.cpp
+115
-68
ndb/test/src/HugoTransactions.cpp
ndb/test/src/HugoTransactions.cpp
+20
-6
No files found.
ndb/include/kernel/signaldata/SignalData.hpp
View file @
ba193367
...
@@ -177,9 +177,16 @@ GSN_PRINT_SIGNATURE(printFAIL_REP);
...
@@ -177,9 +177,16 @@ GSN_PRINT_SIGNATURE(printFAIL_REP);
GSN_PRINT_SIGNATURE
(
printDISCONNECT_REP
);
GSN_PRINT_SIGNATURE
(
printDISCONNECT_REP
);
GSN_PRINT_SIGNATURE
(
printSUB_CREATE_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_CREATE_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_CREATE_CONF
);
GSN_PRINT_SIGNATURE
(
printSUB_CREATE_CONF
);
GSN_PRINT_SIGNATURE
(
printSUB_CREATE_REF
);
GSN_PRINT_SIGNATURE
(
printSUB_REMOVE_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_REMOVE_CONF
);
GSN_PRINT_SIGNATURE
(
printSUB_REMOVE_REF
);
GSN_PRINT_SIGNATURE
(
printSUB_START_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_START_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_START_REF
);
GSN_PRINT_SIGNATURE
(
printSUB_START_REF
);
GSN_PRINT_SIGNATURE
(
printSUB_START_CONF
);
GSN_PRINT_SIGNATURE
(
printSUB_START_CONF
);
GSN_PRINT_SIGNATURE
(
printSUB_STOP_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_STOP_REF
);
GSN_PRINT_SIGNATURE
(
printSUB_STOP_CONF
);
GSN_PRINT_SIGNATURE
(
printSUB_SYNC_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_SYNC_REQ
);
GSN_PRINT_SIGNATURE
(
printSUB_SYNC_REF
);
GSN_PRINT_SIGNATURE
(
printSUB_SYNC_REF
);
GSN_PRINT_SIGNATURE
(
printSUB_SYNC_CONF
);
GSN_PRINT_SIGNATURE
(
printSUB_SYNC_CONF
);
...
...
ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
View file @
ba193367
...
@@ -151,11 +151,17 @@ SignalDataPrintFunctions[] = {
...
@@ -151,11 +151,17 @@ SignalDataPrintFunctions[] = {
{
GSN_DISCONNECT_REP
,
printDISCONNECT_REP
},
{
GSN_DISCONNECT_REP
,
printDISCONNECT_REP
},
{
GSN_SUB_CREATE_REQ
,
printSUB_CREATE_REQ
},
{
GSN_SUB_CREATE_REQ
,
printSUB_CREATE_REQ
},
//
{ GSN_SUB_CREATE_REF, printSUB_CREATE_REF },
{
GSN_SUB_CREATE_REF
,
printSUB_CREATE_REF
},
{
GSN_SUB_CREATE_CONF
,
printSUB_CREATE_CONF
},
{
GSN_SUB_CREATE_CONF
,
printSUB_CREATE_CONF
},
{
GSN_SUB_REMOVE_REQ
,
printSUB_REMOVE_REQ
},
{
GSN_SUB_REMOVE_REF
,
printSUB_REMOVE_REF
},
{
GSN_SUB_REMOVE_CONF
,
printSUB_REMOVE_CONF
},
{
GSN_SUB_START_REQ
,
printSUB_START_REQ
},
{
GSN_SUB_START_REQ
,
printSUB_START_REQ
},
{
GSN_SUB_START_REF
,
printSUB_START_REF
},
{
GSN_SUB_START_REF
,
printSUB_START_REF
},
{
GSN_SUB_START_CONF
,
printSUB_START_CONF
},
{
GSN_SUB_START_CONF
,
printSUB_START_CONF
},
{
GSN_SUB_STOP_REQ
,
printSUB_STOP_REQ
},
{
GSN_SUB_STOP_REF
,
printSUB_STOP_REF
},
{
GSN_SUB_STOP_CONF
,
printSUB_STOP_CONF
},
{
GSN_SUB_SYNC_REQ
,
printSUB_SYNC_REQ
},
{
GSN_SUB_SYNC_REQ
,
printSUB_SYNC_REQ
},
{
GSN_SUB_SYNC_REF
,
printSUB_SYNC_REF
},
{
GSN_SUB_SYNC_REF
,
printSUB_SYNC_REF
},
{
GSN_SUB_SYNC_CONF
,
printSUB_SYNC_CONF
},
{
GSN_SUB_SYNC_CONF
,
printSUB_SYNC_CONF
},
...
...
ndb/src/common/debugger/signaldata/SignalNames.cpp
View file @
ba193367
...
@@ -578,6 +578,9 @@ const GsnName SignalNames [] = {
...
@@ -578,6 +578,9 @@ const GsnName SignalNames [] = {
,{
GSN_SUB_CREATE_REQ
,
"SUB_CREATE_REQ"
}
,{
GSN_SUB_CREATE_REQ
,
"SUB_CREATE_REQ"
}
,{
GSN_SUB_CREATE_REF
,
"SUB_CREATE_REF"
}
,{
GSN_SUB_CREATE_REF
,
"SUB_CREATE_REF"
}
,{
GSN_SUB_CREATE_CONF
,
"SUB_CREATE_CONF"
}
,{
GSN_SUB_CREATE_CONF
,
"SUB_CREATE_CONF"
}
,{
GSN_SUB_REMOVE_REQ
,
"SUB_REMOVE_REQ"
}
,{
GSN_SUB_REMOVE_REF
,
"SUB_REMOVE_REF"
}
,{
GSN_SUB_REMOVE_CONF
,
"SUB_REMOVE_CONF"
}
,{
GSN_SUB_START_REQ
,
"SUB_START_REQ"
}
,{
GSN_SUB_START_REQ
,
"SUB_START_REQ"
}
,{
GSN_SUB_START_REF
,
"SUB_START_REF"
}
,{
GSN_SUB_START_REF
,
"SUB_START_REF"
}
,{
GSN_SUB_START_CONF
,
"SUB_START_CONF"
}
,{
GSN_SUB_START_CONF
,
"SUB_START_CONF"
}
...
...
ndb/src/common/debugger/signaldata/SumaImpl.cpp
View file @
ba193367
...
@@ -39,13 +39,56 @@ printSUB_CREATE_CONF(FILE * output, const Uint32 * theData,
...
@@ -39,13 +39,56 @@ printSUB_CREATE_CONF(FILE * output, const Uint32 * theData,
return
false
;
return
false
;
}
}
bool
printSUB_CREATE_REF
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubCreateRef
*
const
sig
=
(
SubCreateRef
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" subscriberData: %x
\n
"
,
sig
->
subscriberData
);
return
false
;
}
bool
printSUB_REMOVE_REQ
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubRemoveReq
*
const
sig
=
(
SubRemoveReq
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
return
false
;
}
bool
printSUB_REMOVE_CONF
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubRemoveConf
*
const
sig
=
(
SubRemoveConf
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" subscriberData: %x
\n
"
,
sig
->
subscriberData
);
return
false
;
}
bool
printSUB_REMOVE_REF
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubRemoveRef
*
const
sig
=
(
SubRemoveRef
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" subscriberData: %x
\n
"
,
sig
->
subscriberData
);
fprintf
(
output
,
" err: %x
\n
"
,
sig
->
err
);
return
false
;
}
bool
bool
printSUB_START_REQ
(
FILE
*
output
,
const
Uint32
*
theData
,
printSUB_START_REQ
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubStartReq
*
const
sig
=
(
SubStartReq
*
)
theData
;
const
SubStartReq
*
const
sig
=
(
SubStartReq
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" s
tartPart: %x
\n
"
,
sig
->
part
);
fprintf
(
output
,
" s
ubscriberData: %x
\n
"
,
sig
->
subscriberData
);
return
false
;
return
false
;
}
}
...
@@ -72,6 +115,37 @@ printSUB_START_CONF(FILE * output, const Uint32 * theData,
...
@@ -72,6 +115,37 @@ printSUB_START_CONF(FILE * output, const Uint32 * theData,
return
false
;
return
false
;
}
}
bool
printSUB_STOP_REQ
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubStopReq
*
const
sig
=
(
SubStopReq
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" subscriberData: %x
\n
"
,
sig
->
subscriberData
);
return
false
;
}
bool
printSUB_STOP_REF
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubStopRef
*
const
sig
=
(
SubStopRef
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" subscriberData: %x
\n
"
,
sig
->
subscriberData
);
fprintf
(
output
,
" err: %x
\n
"
,
sig
->
err
);
return
false
;
}
bool
printSUB_STOP_CONF
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
const
SubStopConf
*
const
sig
=
(
SubStopConf
*
)
theData
;
fprintf
(
output
,
" subscriptionId: %x
\n
"
,
sig
->
subscriptionId
);
fprintf
(
output
,
" subscriptionKey: %x
\n
"
,
sig
->
subscriptionKey
);
fprintf
(
output
,
" subscriberData: %x
\n
"
,
sig
->
subscriberData
);
return
false
;
}
bool
bool
printSUB_SYNC_REQ
(
FILE
*
output
,
const
Uint32
*
theData
,
printSUB_SYNC_REQ
(
FILE
*
output
,
const
Uint32
*
theData
,
Uint32
len
,
Uint16
receiverBlockNo
)
{
Uint32
len
,
Uint16
receiverBlockNo
)
{
...
...
ndb/src/kernel/blocks/suma/Suma.cpp
View file @
ba193367
...
@@ -3280,7 +3280,7 @@ SumaParticipant::execSUB_STOP_REQ(Signal* signal){
...
@@ -3280,7 +3280,7 @@ SumaParticipant::execSUB_STOP_REQ(Signal* signal){
for
(;
!
subbPtr
.
isNull
();
c_dataSubscribers
.
next
(
subbPtr
)){
for
(;
!
subbPtr
.
isNull
();
c_dataSubscribers
.
next
(
subbPtr
)){
jam
();
jam
();
if
(
subbPtr
.
p
->
m_subPtrI
==
subPtr
.
i
&&
if
(
subbPtr
.
p
->
m_subPtrI
==
subPtr
.
i
&&
subbPtr
.
p
->
m_subscriberRef
==
subscriberRef
&&
refToNode
(
subbPtr
.
p
->
m_subscriberRef
)
==
refToNode
(
subscriberRef
)
&&
subbPtr
.
p
->
m_subscriberData
==
subscriberData
){
subbPtr
.
p
->
m_subscriberData
==
subscriberData
){
// ndbout_c("STOP_REQ: before c_dataSubscribers.release");
// ndbout_c("STOP_REQ: before c_dataSubscribers.release");
jam
();
jam
();
...
@@ -3508,6 +3508,8 @@ SumaParticipant::sendSubRemoveRef(Signal* signal, const SubRemoveReq& req,
...
@@ -3508,6 +3508,8 @@ SumaParticipant::sendSubRemoveRef(Signal* signal, const SubRemoveReq& req,
jam
();
jam
();
SubRemoveRef
*
ref
=
(
SubRemoveRef
*
)
signal
->
getDataPtrSend
();
SubRemoveRef
*
ref
=
(
SubRemoveRef
*
)
signal
->
getDataPtrSend
();
ref
->
senderRef
=
reference
();
ref
->
senderRef
=
reference
();
ref
->
subscriptionId
=
req
.
subscriptionId
;
ref
->
subscriptionKey
=
req
.
subscriptionKey
;
ref
->
senderData
=
req
.
senderData
;
ref
->
senderData
=
req
.
senderData
;
ref
->
err
=
errCode
;
ref
->
err
=
errCode
;
if
(
temporary
)
if
(
temporary
)
...
...
ndb/src/ndbapi/NdbDictionaryImpl.cpp
View file @
ba193367
...
@@ -793,7 +793,7 @@ NdbDictInterface::setTransporter(class TransporterFacade * tf)
...
@@ -793,7 +793,7 @@ NdbDictInterface::setTransporter(class TransporterFacade * tf)
execNodeStatus);
execNodeStatus);
if ( m_blockNumber == -1 ) {
if ( m_blockNumber == -1 ) {
m_error.code
= 4105;
m_error.code= 4105;
return false; // no more free blocknumbers
return false; // no more free blocknumbers
}//if
}//if
Uint32 theNode = tf->ownId();
Uint32 theNode = tf->ownId();
...
@@ -947,7 +947,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
...
@@ -947,7 +947,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
aNodeId
=
m_transporter
->
get_an_alive_node
();
aNodeId
=
m_transporter
->
get_an_alive_node
();
}
}
if
(
aNodeId
==
0
){
if
(
aNodeId
==
0
){
m_error
.
code
=
4009
;
m_error
.
code
=
4009
;
m_transporter
->
unlock_mutex
();
m_transporter
->
unlock_mutex
();
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
...
@@ -974,7 +974,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
...
@@ -974,7 +974,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
}
}
}
}
m_error
.
code
=
0
;
m_error
.
code
=
0
;
m_waiter
.
m_node
=
aNodeId
;
m_waiter
.
m_node
=
aNodeId
;
m_waiter
.
m_state
=
wst
;
m_waiter
.
m_state
=
wst
;
...
@@ -1042,7 +1042,7 @@ NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames)
...
@@ -1042,7 +1042,7 @@ NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames)
const
Uint32
strLen
=
strlen
(
name
)
+
1
;
// NULL Terminated
const
Uint32
strLen
=
strlen
(
name
)
+
1
;
// NULL Terminated
if
(
strLen
>
MAX_TAB_NAME_SIZE
)
{
//sizeof(req->tableName)){
if
(
strLen
>
MAX_TAB_NAME_SIZE
)
{
//sizeof(req->tableName)){
m_error
.
code
=
4307
;
m_error
.
code
=
4307
;
return
0
;
return
0
;
}
}
...
@@ -1079,7 +1079,7 @@ NdbDictInterface::getTable(class NdbApiSignal * signal,
...
@@ -1079,7 +1079,7 @@ NdbDictInterface::getTable(class NdbApiSignal * signal,
if
(
r
)
return
0
;
if
(
r
)
return
0
;
NdbTableImpl
*
rt
=
0
;
NdbTableImpl
*
rt
=
0
;
m_error
.
code
=
parseTableInfo
(
&
rt
,
m_error
.
code
=
parseTableInfo
(
&
rt
,
(
Uint32
*
)
m_buffer
.
get_data
(),
(
Uint32
*
)
m_buffer
.
get_data
(),
m_buffer
.
length
()
/
4
,
fullyQualifiedNames
);
m_buffer
.
length
()
/
4
,
fullyQualifiedNames
);
rt
->
buildColumnHash
();
rt
->
buildColumnHash
();
...
@@ -1116,7 +1116,7 @@ NdbDictInterface::execGET_TABINFO_REF(NdbApiSignal * signal,
...
@@ -1116,7 +1116,7 @@ NdbDictInterface::execGET_TABINFO_REF(NdbApiSignal * signal,
{
{
const
GetTabInfoRef
*
ref
=
CAST_CONSTPTR
(
GetTabInfoRef
,
signal
->
getDataPtr
());
const
GetTabInfoRef
*
ref
=
CAST_CONSTPTR
(
GetTabInfoRef
,
signal
->
getDataPtr
());
m_error
.
code
=
ref
->
errorCode
;
m_error
.
code
=
ref
->
errorCode
;
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
}
}
...
@@ -1348,7 +1348,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
...
@@ -1348,7 +1348,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
if
(
tableDesc
.
FragmentDataLen
>
0
)
if
(
tableDesc
.
FragmentDataLen
>
0
)
{
{
int
i
;
unsigned
i
;
Uint32
replicaCount
=
tableDesc
.
FragmentData
[
0
];
Uint32
replicaCount
=
tableDesc
.
FragmentData
[
0
];
Uint32
fragCount
=
tableDesc
.
FragmentData
[
1
];
Uint32
fragCount
=
tableDesc
.
FragmentData
[
1
];
...
@@ -1396,13 +1396,13 @@ NdbDictionaryImpl::createTable(NdbTableImpl &t)
...
@@ -1396,13 +1396,13 @@ NdbDictionaryImpl::createTable(NdbTableImpl &t)
Ndb_local_table_info
*
info
=
Ndb_local_table_info
*
info
=
get_local_table_info
(
t
.
m_internalName
.
c_str
(),
false
);
get_local_table_info
(
t
.
m_internalName
.
c_str
(),
false
);
if
(
info
==
NULL
)
{
if
(
info
==
NULL
)
{
m_error
.
code
=
709
;
m_error
.
code
=
709
;
return
-
1
;
return
-
1
;
}
}
if
(
createBlobTables
(
*
(
info
->
m_table_impl
))
!=
0
)
{
if
(
createBlobTables
(
*
(
info
->
m_table_impl
))
!=
0
)
{
int
save_code
=
m_error
.
code
;
int
save_code
=
m_error
.
code
;
(
void
)
dropTable
(
t
);
(
void
)
dropTable
(
t
);
m_error
.
code
=
save_code
;
m_error
.
code
=
save_code
;
return
-
1
;
return
-
1
;
}
}
return
0
;
return
0
;
...
@@ -1472,7 +1472,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
...
@@ -1472,7 +1472,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
DBUG_ENTER
(
"NdbDictionaryImpl::alterTable"
);
DBUG_ENTER
(
"NdbDictionaryImpl::alterTable"
);
if
(
!
get_local_table_info
(
originalInternalName
,
false
)){
if
(
!
get_local_table_info
(
originalInternalName
,
false
)){
m_error
.
code
=
709
;
m_error
.
code
=
709
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
// Alter the table
// Alter the table
...
@@ -1508,12 +1508,12 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
...
@@ -1508,12 +1508,12 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
DBUG_ENTER
(
"NdbDictInterface::createOrAlterTable"
);
DBUG_ENTER
(
"NdbDictInterface::createOrAlterTable"
);
unsigned
i
;
unsigned
i
;
if
((
unsigned
)
impl
.
getNoOfPrimaryKeys
()
>
NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY
){
if
((
unsigned
)
impl
.
getNoOfPrimaryKeys
()
>
NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY
){
m_error
.
code
=
4317
;
m_error
.
code
=
4317
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
unsigned
sz
=
impl
.
m_columns
.
size
();
unsigned
sz
=
impl
.
m_columns
.
size
();
if
(
sz
>
NDB_MAX_ATTRIBUTES_IN_TABLE
){
if
(
sz
>
NDB_MAX_ATTRIBUTES_IN_TABLE
){
m_error
.
code
=
4318
;
m_error
.
code
=
4318
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
...
@@ -1538,7 +1538,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
...
@@ -1538,7 +1538,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
continue
;
continue
;
if
(
col
->
m_autoIncrement
)
{
if
(
col
->
m_autoIncrement
)
{
if
(
haveAutoIncrement
)
{
if
(
haveAutoIncrement
)
{
m_error
.
code
=
4335
;
m_error
.
code
=
4335
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
haveAutoIncrement
=
true
;
haveAutoIncrement
=
true
;
...
@@ -1548,7 +1548,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
...
@@ -1548,7 +1548,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
// Check max length of frm data
// Check max length of frm data
if
(
impl
.
m_frm
.
length
()
>
MAX_FRM_DATA_SIZE
){
if
(
impl
.
m_frm
.
length
()
>
MAX_FRM_DATA_SIZE
){
m_error
.
code
=
1229
;
m_error
.
code
=
1229
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
tmpTab
.
FrmLen
=
impl
.
m_frm
.
length
();
tmpTab
.
FrmLen
=
impl
.
m_frm
.
length
();
...
@@ -1596,22 +1596,22 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
...
@@ -1596,22 +1596,22 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
// check type and compute attribute size and array size
// check type and compute attribute size and array size
if
(
!
tmpAttr
.
translateExtType
())
{
if
(
!
tmpAttr
.
translateExtType
())
{
m_error
.
code
=
703
;
m_error
.
code
=
703
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
// charset is defined exactly for char types
// charset is defined exactly for char types
if
(
col
->
getCharType
()
!=
(
col
->
m_cs
!=
NULL
))
{
if
(
col
->
getCharType
()
!=
(
col
->
m_cs
!=
NULL
))
{
m_error
.
code
=
703
;
m_error
.
code
=
703
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
// primary key type check
// primary key type check
if
(
col
->
m_pk
&&
!
NdbSqlUtil
::
usable_in_pk
(
col
->
m_type
,
col
->
m_cs
))
{
if
(
col
->
m_pk
&&
!
NdbSqlUtil
::
usable_in_pk
(
col
->
m_type
,
col
->
m_cs
))
{
m_error
.
code
=
743
;
m_error
.
code
=
743
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
// distribution key not supported for Char attribute
// distribution key not supported for Char attribute
if
(
col
->
m_distributionKey
&&
col
->
m_cs
!=
NULL
)
{
if
(
col
->
m_distributionKey
&&
col
->
m_cs
!=
NULL
)
{
m_error
.
code
=
745
;
m_error
.
code
=
745
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
// charset in upper half of precision
// charset in upper half of precision
...
@@ -1669,7 +1669,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
...
@@ -1669,7 +1669,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
if
(
!
ndb
.
setAutoIncrementValue
(
impl
.
m_externalName
.
c_str
(),
if
(
!
ndb
.
setAutoIncrementValue
(
impl
.
m_externalName
.
c_str
(),
autoIncrementValue
))
{
autoIncrementValue
))
{
if
(
ndb
.
theError
.
code
==
0
)
{
if
(
ndb
.
theError
.
code
==
0
)
{
m_error
.
code
=
4336
;
m_error
.
code
=
4336
;
ndb
.
theError
=
m_error
;
ndb
.
theError
=
m_error
;
}
else
}
else
m_error
=
ndb
.
theError
;
m_error
=
ndb
.
theError
;
...
@@ -1719,7 +1719,7 @@ NdbDictInterface::execCREATE_TABLE_REF(NdbApiSignal * signal,
...
@@ -1719,7 +1719,7 @@ NdbDictInterface::execCREATE_TABLE_REF(NdbApiSignal * signal,
{
{
const
CreateTableRef
*
const
ref
=
const
CreateTableRef
*
const
ref
=
CAST_CONSTPTR
(
CreateTableRef
,
signal
->
getDataPtr
());
CAST_CONSTPTR
(
CreateTableRef
,
signal
->
getDataPtr
());
m_error
.
code
=
ref
->
errorCode
;
m_error
.
code
=
ref
->
errorCode
;
m_masterNodeId
=
ref
->
masterNodeId
;
m_masterNodeId
=
ref
->
masterNodeId
;
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
}
}
...
@@ -1763,7 +1763,7 @@ NdbDictInterface::execALTER_TABLE_REF(NdbApiSignal * signal,
...
@@ -1763,7 +1763,7 @@ NdbDictInterface::execALTER_TABLE_REF(NdbApiSignal * signal,
{
{
const
AlterTableRef
*
const
ref
=
const
AlterTableRef
*
const
ref
=
CAST_CONSTPTR
(
AlterTableRef
,
signal
->
getDataPtr
());
CAST_CONSTPTR
(
AlterTableRef
,
signal
->
getDataPtr
());
m_error
.
code
=
ref
->
errorCode
;
m_error
.
code
=
ref
->
errorCode
;
m_masterNodeId
=
ref
->
masterNodeId
;
m_masterNodeId
=
ref
->
masterNodeId
;
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
}
}
...
@@ -1808,7 +1808,7 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
...
@@ -1808,7 +1808,7 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
}
}
if
(
impl
.
m_indexType
!=
NdbDictionary
::
Index
::
Undefined
)
{
if
(
impl
.
m_indexType
!=
NdbDictionary
::
Index
::
Undefined
)
{
m_receiver
.
m_error
.
code
=
1228
;
m_receiver
.
m_error
.
code
=
1228
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1918,7 +1918,7 @@ NdbDictInterface::execDROP_TABLE_REF(NdbApiSignal * signal,
...
@@ -1918,7 +1918,7 @@ NdbDictInterface::execDROP_TABLE_REF(NdbApiSignal * signal,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
const
DropTableRef
*
const
ref
=
CAST_CONSTPTR
(
DropTableRef
,
signal
->
getDataPtr
());
const
DropTableRef
*
const
ref
=
CAST_CONSTPTR
(
DropTableRef
,
signal
->
getDataPtr
());
m_error
.
code
=
ref
->
errorCode
;
m_error
.
code
=
ref
->
errorCode
;
m_masterNodeId
=
ref
->
masterNodeId
;
m_masterNodeId
=
ref
->
masterNodeId
;
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
}
}
...
@@ -2370,7 +2370,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
...
@@ -2370,7 +2370,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
const
NdbColumnImpl
*
col
=
const
NdbColumnImpl
*
col
=
table
.
getColumn
(
evnt
.
m_columns
[
i
]
->
m_name
.
c_str
());
table
.
getColumn
(
evnt
.
m_columns
[
i
]
->
m_name
.
c_str
());
if
(
col
==
0
){
if
(
col
==
0
){
m_error
.
code
=
4247
;
m_error
.
code
=
4247
;
return
-
1
;
return
-
1
;
}
}
// Copy column definition
// Copy column definition
...
@@ -2396,7 +2396,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
...
@@ -2396,7 +2396,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
// Check for illegal duplicate attributes
// Check for illegal duplicate attributes
for
(
i
=
1
;
i
<
attributeList_sz
;
i
++
)
{
for
(
i
=
1
;
i
<
attributeList_sz
;
i
++
)
{
if
(
evnt
.
m_columns
[
i
-
1
]
->
m_attrId
==
evnt
.
m_columns
[
i
]
->
m_attrId
)
{
if
(
evnt
.
m_columns
[
i
-
1
]
->
m_attrId
==
evnt
.
m_columns
[
i
]
->
m_attrId
)
{
m_error
.
code
=
4258
;
m_error
.
code
=
4258
;
return
-
1
;
return
-
1
;
}
}
}
}
...
@@ -2444,7 +2444,7 @@ NdbDictInterface::createEvent(class Ndb & ndb,
...
@@ -2444,7 +2444,7 @@ NdbDictInterface::createEvent(class Ndb & ndb,
const
size_t
len
=
strlen
(
evnt
.
m_externalName
.
c_str
())
+
1
;
const
size_t
len
=
strlen
(
evnt
.
m_externalName
.
c_str
())
+
1
;
if
(
len
>
MAX_TAB_NAME_SIZE
)
{
if
(
len
>
MAX_TAB_NAME_SIZE
)
{
m_error
.
code
=
4241
;
m_error
.
code
=
4241
;
return
-
1
;
return
-
1
;
}
}
...
@@ -2557,9 +2557,7 @@ int
...
@@ -2557,9 +2557,7 @@ int
NdbDictInterface
::
stopSubscribeEvent
(
class
Ndb
&
ndb
,
NdbDictInterface
::
stopSubscribeEvent
(
class
Ndb
&
ndb
,
NdbEventImpl
&
evnt
)
NdbEventImpl
&
evnt
)
{
{
#ifdef EVENT_DEBUG
DBUG_ENTER
(
"NdbDictInterface::stopSubscribeEvent"
);
ndbout_c
(
"SUB_STOP_REQ"
);
#endif
NdbApiSignal
tSignal
(
m_reference
);
NdbApiSignal
tSignal
(
m_reference
);
// tSignal.theReceiversBlockNumber = SUMA;
// tSignal.theReceiversBlockNumber = SUMA;
...
@@ -2575,7 +2573,7 @@ NdbDictInterface::stopSubscribeEvent(class Ndb & ndb,
...
@@ -2575,7 +2573,7 @@ NdbDictInterface::stopSubscribeEvent(class Ndb & ndb,
sumaStop
->
part
=
(
Uint32
)
SubscriptionData
::
TableData
;
sumaStop
->
part
=
(
Uint32
)
SubscriptionData
::
TableData
;
sumaStop
->
subscriberRef
=
m_reference
;
sumaStop
->
subscriberRef
=
m_reference
;
return
stopSubscribeEvent
(
&
tSignal
,
NULL
);
DBUG_RETURN
(
stopSubscribeEvent
(
&
tSignal
,
NULL
)
);
}
}
int
int
...
@@ -2635,7 +2633,7 @@ NdbDictionaryImpl::getEvent(const char * eventName)
...
@@ -2635,7 +2633,7 @@ NdbDictionaryImpl::getEvent(const char * eventName)
#ifdef EVENT_DEBUG
#ifdef EVENT_DEBUG
ndbout_c
(
"NdbDictionaryImpl::getEvent could not find column id %d"
,
id
);
ndbout_c
(
"NdbDictionaryImpl::getEvent could not find column id %d"
,
id
);
#endif
#endif
m_error
.
code
=
4247
;
m_error
.
code
=
4247
;
delete
ev
;
delete
ev
;
return
NULL
;
return
NULL
;
}
}
...
@@ -2653,9 +2651,8 @@ void
...
@@ -2653,9 +2651,8 @@ void
NdbDictInterface
::
execCREATE_EVNT_CONF
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execCREATE_EVNT_CONF
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
#ifdef EVENT_DEBUG
DBUG_ENTER
(
"NdbDictInterface::execCREATE_EVNT_CONF"
);
ndbout
<<
"NdbDictionaryImpl.cpp: execCREATE_EVNT_CONF"
<<
endl
;
#endif
m_buffer
.
clear
();
m_buffer
.
clear
();
unsigned
int
len
=
signal
->
getLength
()
<<
2
;
unsigned
int
len
=
signal
->
getLength
()
<<
2
;
m_buffer
.
append
((
char
*
)
&
len
,
sizeof
(
len
));
m_buffer
.
append
((
char
*
)
&
len
,
sizeof
(
len
));
...
@@ -2665,45 +2662,49 @@ NdbDictInterface::execCREATE_EVNT_CONF(NdbApiSignal * signal,
...
@@ -2665,45 +2662,49 @@ NdbDictInterface::execCREATE_EVNT_CONF(NdbApiSignal * signal,
m_buffer
.
append
((
char
*
)
ptr
[
0
].
p
,
strlen
((
char
*
)
ptr
[
0
].
p
)
+
1
);
m_buffer
.
append
((
char
*
)
ptr
[
0
].
p
,
strlen
((
char
*
)
ptr
[
0
].
p
)
+
1
);
}
}
const
CreateEvntConf
*
const
createEvntConf
=
CAST_CONSTPTR
(
CreateEvntConf
,
signal
->
getDataPtr
());
Uint32
subscriptionId
=
createEvntConf
->
getEventId
();
Uint32
subscriptionKey
=
createEvntConf
->
getEventKey
();
DBUG_PRINT
(
"info"
,(
"subscriptionId=%d,subscriptionKey=%d"
,
subscriptionId
,
subscriptionKey
));
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
}
}
void
void
NdbDictInterface
::
execCREATE_EVNT_REF
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execCREATE_EVNT_REF
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
#ifdef EVENT_DEBUG
DBUG_ENTER
(
"NdbDictInterface::execCREATE_EVNT_REF"
);
ndbout
<<
"NdbDictionaryImpl.cpp: execCREATE_EVNT_REF"
<<
endl
;
ndbout
<<
"Exiting"
<<
endl
;
exit
(
-
1
);
#endif
const
CreateEvntRef
*
const
ref
=
CAST_CONSTPTR
(
CreateEvntRef
,
signal
->
getDataPtr
());
const
CreateEvntRef
*
const
ref
=
m_error
.
code
=
ref
->
getErrorCode
();
CAST_CONSTPTR
(
CreateEvntRef
,
signal
->
getDataPtr
());
#ifdef EVENT_DEBUG
m_error
.
code
=
ref
->
getErrorCode
();
ndbout_c
(
"execCREATE_EVNT_REF"
);
DBUG_PRINT
(
"error"
,(
"error=%d,line=%d,node=%d"
,
ref
->
getErrorCode
(),
ndbout_c
(
"ErrorCode %u"
,
ref
->
getErrorCode
());
ref
->
getErrorLine
(),
ref
->
getErrorNode
()));
ndbout_c
(
"Errorline %u"
,
ref
->
getErrorLine
());
ndbout_c
(
"ErrorNode %u"
,
ref
->
getErrorNode
());
#endif
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
}
}
void
void
NdbDictInterface
::
execSUB_STOP_CONF
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execSUB_STOP_CONF
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
DBUG_ENTER
(
"NdbDictInterface::execSUB_STOP_REF"
);
DBUG_ENTER
(
"NdbDictInterface::execSUB_STOP_CONF"
);
#ifdef EVENT_DEBUG
const
SubStopConf
*
const
subStopConf
=
ndbout
<<
"Got GSN_SUB_STOP_CONF"
<<
endl
;
CAST_CONSTPTR
(
SubStopConf
,
signal
->
getDataPtr
());
#endif
// SubRemoveConf * const sumaRemoveConf = CAST_CONSTPTR(SubRemoveConf, signal->getDataPtr());
// Uint32 subscriptionId = sumaRemove
Conf->subscriptionId;
Uint32
subscriptionId
=
subStop
Conf
->
subscriptionId
;
// Uint32 subscriptionKey = sumaRemove
Conf->subscriptionKey;
Uint32
subscriptionKey
=
subStop
Conf
->
subscriptionKey
;
// Uint32 senderData = sumaRemoveConf->send
erData;
Uint32
subscriberData
=
subStopConf
->
subscrib
erData
;
DBUG_PRINT
(
"info"
,(
"subscriptionId=%d,subscriptionKey=%d,subscriberData=%d"
,
subscriptionId
,
subscriptionKey
,
subscriberData
));
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
}
}
void
void
...
@@ -2711,19 +2712,17 @@ NdbDictInterface::execSUB_STOP_REF(NdbApiSignal * signal,
...
@@ -2711,19 +2712,17 @@ NdbDictInterface::execSUB_STOP_REF(NdbApiSignal * signal,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
DBUG_ENTER
(
"NdbDictInterface::execSUB_STOP_REF"
);
DBUG_ENTER
(
"NdbDictInterface::execSUB_STOP_REF"
);
#ifdef EVENT_DEBUG
const
SubStopRef
*
const
subStopRef
=
ndbout
<<
"Got GSN_SUB_STOP_REF"
<<
endl
;
CAST_CONSTPTR
(
SubStopRef
,
signal
->
getDataPtr
());
#endif
const
SubRemoveRef
*
const
sumaRemoveRef
=
CAST_CONSTPTR
(
SubRemoveRef
,
signal
->
getDataPtr
());
// Uint32 subscriptionId = sumaRemoveRef->subscriptionId;
Uint32
subscriptionId
=
subStopRef
->
subscriptionId
;
// Uint32 subscriptionKey = sumaRemoveRef->subscriptionKey;
Uint32
subscriptionKey
=
subStopRef
->
subscriptionKey
;
// Uint32 senderData = sumaRemoveRef->senderData;
Uint32
subscriberData
=
subStopRef
->
subscriberData
;
m_error
.
code
=
subStopRef
->
errorCode
;
m_error
.
code
=
sumaRemoveRef
->
errorCode
;
DBUG_PRINT
(
"error"
,(
"subscriptionId=%d,subscriptionKey=%d,subscriberData=%d,error=%d"
,
subscriptionId
,
subscriptionKey
,
subscriberData
,
m_error
.
code
));
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -2731,57 +2730,55 @@ void
...
@@ -2731,57 +2730,55 @@ void
NdbDictInterface
::
execSUB_START_CONF
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execSUB_START_CONF
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
#ifdef EVENT_DEBUG
DBUG_ENTER
(
"NdbDictInterface::execSUB_START_CONF"
);
ndbout
<<
"Got GSN_SUB_START_CONF"
<<
endl
;
const
SubStartConf
*
const
subStartConf
=
#endif
CAST_CONSTPTR
(
SubStartConf
,
signal
->
getDataPtr
());
const
SubStartConf
*
const
sumaStartConf
=
CAST_CONSTPTR
(
SubStartConf
,
signal
->
getDataPtr
());
// Uint32 subscriptionId = suma
StartConf->subscriptionId;
Uint32
subscriptionId
=
sub
StartConf
->
subscriptionId
;
// Uint32 subscriptionKey = suma
StartConf->subscriptionKey;
Uint32
subscriptionKey
=
sub
StartConf
->
subscriptionKey
;
SubscriptionData
::
Part
part
=
SubscriptionData
::
Part
part
=
(
SubscriptionData
::
Part
)
suma
StartConf
->
part
;
(
SubscriptionData
::
Part
)
sub
StartConf
->
part
;
// Uint32 subscriberData = suma
StartConf->subscriberData;
Uint32
subscriberData
=
sub
StartConf
->
subscriberData
;
switch
(
part
)
{
switch
(
part
)
{
case
SubscriptionData
:
:
MetaData
:
{
case
SubscriptionData
:
:
MetaData
:
{
#ifdef EVENT_DEBUG
DBUG_PRINT
(
"error"
,(
"SubscriptionData::MetaData"
));
ndbout
<<
"SubscriptionData::MetaData"
<<
endl
;
m_error
.
code
=
1
;
#endif
m_error
.
code
=
1
;
break
;
break
;
}
}
case
SubscriptionData
:
:
TableData
:
{
case
SubscriptionData
:
:
TableData
:
{
#ifdef EVENT_DEBUG
DBUG_PRINT
(
"info"
,(
"SubscriptionData::TableData"
));
ndbout
<<
"SubscriptionData::TableData"
<<
endl
;
#endif
break
;
break
;
}
}
default:
{
default:
{
#ifdef EVENT_DEBUG
DBUG_PRINT
(
"error"
,(
"wrong data"
));
ndbout_c
(
"NdbDictInterface::execSUB_START_CONF wrong data"
);
m_error
.
code
=
2
;
#endif
m_error
.
code
=
1
;
break
;
break
;
}
}
}
}
DBUG_PRINT
(
"info"
,(
"subscriptionId=%d,subscriptionKey=%d,subscriberData=%d"
,
subscriptionId
,
subscriptionKey
,
subscriberData
));
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
}
}
void
void
NdbDictInterface
::
execSUB_START_REF
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execSUB_START_REF
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
#ifdef EVENT_DEBUG
DBUG_ENTER
(
"NdbDictInterface::execSUB_START_REF"
);
ndbout
<<
"Got GSN_SUB_START_REF"
<<
endl
;
const
SubStartRef
*
const
subStartRef
=
#endif
CAST_CONSTPTR
(
SubStartRef
,
signal
->
getDataPtr
());
m_error
.
code
=
1
;
m_error
.
code
=
subStartRef
->
errorCode
;
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
}
}
void
void
NdbDictInterface
::
execSUB_GCP_COMPLETE_REP
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execSUB_GCP_COMPLETE_REP
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
const
SubGcpCompleteRep
*
const
rep
=
CAST_CONSTPTR
(
SubGcpCompleteRep
,
signal
->
getDataPtr
());
const
SubGcpCompleteRep
*
const
rep
=
CAST_CONSTPTR
(
SubGcpCompleteRep
,
signal
->
getDataPtr
());
const
Uint32
gci
=
rep
->
gci
;
const
Uint32
gci
=
rep
->
gci
;
// const Uint32 senderRef = rep->senderRef;
// const Uint32 senderRef = rep->senderRef;
...
@@ -2792,7 +2789,8 @@ NdbDictInterface::execSUB_GCP_COMPLETE_REP(NdbApiSignal * signal,
...
@@ -2792,7 +2789,8 @@ NdbDictInterface::execSUB_GCP_COMPLETE_REP(NdbApiSignal * signal,
const
Uint32
ref
=
signal
->
theSendersBlockRef
;
const
Uint32
ref
=
signal
->
theSendersBlockRef
;
NdbApiSignal
tSignal
(
m_reference
);
NdbApiSignal
tSignal
(
m_reference
);
SubGcpCompleteAcc
*
acc
=
CAST_PTR
(
SubGcpCompleteAcc
,
tSignal
.
getDataPtrSend
());
SubGcpCompleteAcc
*
acc
=
CAST_PTR
(
SubGcpCompleteAcc
,
tSignal
.
getDataPtrSend
());
acc
->
rep
=
*
rep
;
acc
->
rep
=
*
rep
;
...
@@ -2850,9 +2848,9 @@ NdbDictInterface::execSUB_TABLE_DATA(NdbApiSignal * signal,
...
@@ -2850,9 +2848,9 @@ NdbDictInterface::execSUB_TABLE_DATA(NdbApiSignal * signal,
int
int
NdbDictionaryImpl
::
dropEvent
(
const
char
*
eventName
)
NdbDictionaryImpl
::
dropEvent
(
const
char
*
eventName
)
{
{
NdbEventImpl
*
ev
=
new
NdbEventImpl
();
NdbEventImpl
*
ev
=
new
NdbEventImpl
();
ev
->
setName
(
eventName
);
ev
->
setName
(
eventName
);
int
ret
=
m_receiver
.
dropEvent
(
*
ev
);
int
ret
=
m_receiver
.
dropEvent
(
*
ev
);
delete
ev
;
delete
ev
;
// printf("__________________RET %u\n", ret);
// printf("__________________RET %u\n", ret);
...
@@ -2901,31 +2899,25 @@ void
...
@@ -2901,31 +2899,25 @@ void
NdbDictInterface
::
execDROP_EVNT_CONF
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execDROP_EVNT_CONF
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
#ifdef EVENT_DEBUG
DBUG_ENTER
(
"NdbDictInterface::execDROP_EVNT_CONF"
);
ndbout
<<
"NdbDictionaryImpl.cpp: execDROP_EVNT_CONF"
<<
endl
;
#endif
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
}
}
void
void
NdbDictInterface
::
execDROP_EVNT_REF
(
NdbApiSignal
*
signal
,
NdbDictInterface
::
execDROP_EVNT_REF
(
NdbApiSignal
*
signal
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
#ifdef EVENT_DEBUG
DBUG_ENTER
(
"NdbDictInterface::execDROP_EVNT_REF"
);
ndbout
<<
"NdbDictionaryImpl.cpp: execDROP_EVNT_REF"
<<
endl
;
const
DropEvntRef
*
const
ref
=
#endif
CAST_CONSTPTR
(
DropEvntRef
,
signal
->
getDataPtr
());
const
DropEvntRef
*
const
ref
=
CAST_CONSTPTR
(
DropEvntRef
,
signal
->
getDataPtr
());
m_error
.
code
=
ref
->
getErrorCode
();
m_error
.
code
=
ref
->
getErrorCode
();
#if 0
DBUG_PRINT
(
"info"
,(
"ErrorCode=%u Errorline=%u ErrorNode=%u"
,
ndbout_c("execDROP_EVNT_REF");
ref
->
getErrorCode
(),
ref
->
getErrorLine
(),
ref
->
getErrorNode
()));
ndbout_c("ErrorCode %u", ref->getErrorCode());
ndbout_c("Errorline %u", ref->getErrorLine());
ndbout_c("ErrorNode %u", ref->getErrorNode());
#endif
m_waiter
.
signal
(
NO_WAIT
);
m_waiter
.
signal
(
NO_WAIT
);
DBUG_VOID_RETURN
;
}
}
/*****************************************************************
/*****************************************************************
...
@@ -2990,7 +2982,7 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list,
...
@@ -2990,7 +2982,7 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list,
}
}
if
(
!
ok
)
{
if
(
!
ok
)
{
// bad signal data
// bad signal data
m_error
.
code
=
4213
;
m_error
.
code
=
4213
;
return
-
1
;
return
-
1
;
}
}
list
.
count
=
count
;
list
.
count
=
count
;
...
@@ -3056,7 +3048,7 @@ NdbDictInterface::listObjects(NdbApiSignal* signal)
...
@@ -3056,7 +3048,7 @@ NdbDictInterface::listObjects(NdbApiSignal* signal)
m_transporter
->
lock_mutex
();
m_transporter
->
lock_mutex
();
Uint16
aNodeId
=
m_transporter
->
get_an_alive_node
();
Uint16
aNodeId
=
m_transporter
->
get_an_alive_node
();
if
(
aNodeId
==
0
)
{
if
(
aNodeId
==
0
)
{
m_error
.
code
=
4009
;
m_error
.
code
=
4009
;
m_transporter
->
unlock_mutex
();
m_transporter
->
unlock_mutex
();
return
-
1
;
return
-
1
;
}
}
...
@@ -3064,7 +3056,7 @@ NdbDictInterface::listObjects(NdbApiSignal* signal)
...
@@ -3064,7 +3056,7 @@ NdbDictInterface::listObjects(NdbApiSignal* signal)
m_transporter
->
unlock_mutex
();
m_transporter
->
unlock_mutex
();
continue
;
continue
;
}
}
m_error
.
code
=
0
;
m_error
.
code
=
0
;
m_waiter
.
m_node
=
aNodeId
;
m_waiter
.
m_node
=
aNodeId
;
m_waiter
.
m_state
=
WAIT_LIST_TABLES_CONF
;
m_waiter
.
m_state
=
WAIT_LIST_TABLES_CONF
;
m_waiter
.
wait
(
WAITFOR_RESPONSE_TIMEOUT
);
m_waiter
.
wait
(
WAITFOR_RESPONSE_TIMEOUT
);
...
...
ndb/src/ndbapi/NdbEventOperationImpl.cpp
View file @
ba193367
...
@@ -120,24 +120,26 @@ NdbEventOperationImpl::getState()
...
@@ -120,24 +120,26 @@ NdbEventOperationImpl::getState()
NdbRecAttr
*
NdbRecAttr
*
NdbEventOperationImpl
::
getValue
(
const
char
*
colName
,
char
*
aValue
,
int
n
)
NdbEventOperationImpl
::
getValue
(
const
char
*
colName
,
char
*
aValue
,
int
n
)
{
{
DBUG_ENTER
(
"NdbEventOperationImpl::getValue"
);
if
(
m_state
!=
EO_CREATED
)
{
if
(
m_state
!=
EO_CREATED
)
{
ndbout_c
(
"NdbEventOperationImpl::getValue may only be called between instantiation and execute()"
);
ndbout_c
(
"NdbEventOperationImpl::getValue may only be called between instantiation and execute()"
);
return
NULL
;
DBUG_RETURN
(
NULL
)
;
}
}
NdbColumnImpl
*
tAttrInfo
=
m_eventImpl
->
m_tableImpl
->
getColumn
(
colName
);
NdbColumnImpl
*
tAttrInfo
=
m_eventImpl
->
m_tableImpl
->
getColumn
(
colName
);
if
(
tAttrInfo
==
NULL
)
{
if
(
tAttrInfo
==
NULL
)
{
ndbout_c
(
"NdbEventOperationImpl::getValue attribute %s not found"
,
colName
);
ndbout_c
(
"NdbEventOperationImpl::getValue attribute %s not found"
,
colName
);
return
NULL
;
DBUG_RETURN
(
NULL
)
;
}
}
return
NdbEventOperationImpl
::
getValue
(
tAttrInfo
,
aValue
,
n
);
DBUG_RETURN
(
NdbEventOperationImpl
::
getValue
(
tAttrInfo
,
aValue
,
n
)
);
}
}
NdbRecAttr
*
NdbRecAttr
*
NdbEventOperationImpl
::
getValue
(
const
NdbColumnImpl
*
tAttrInfo
,
char
*
aValue
,
int
n
)
NdbEventOperationImpl
::
getValue
(
const
NdbColumnImpl
*
tAttrInfo
,
char
*
aValue
,
int
n
)
{
{
DBUG_ENTER
(
"NdbEventOperationImpl::getValue"
);
// Insert Attribute Id into ATTRINFO part.
// Insert Attribute Id into ATTRINFO part.
NdbRecAttr
*&
theFirstRecAttr
=
theFirstRecAttrs
[
n
];
NdbRecAttr
*&
theFirstRecAttr
=
theFirstRecAttrs
[
n
];
NdbRecAttr
*&
theCurrentRecAttr
=
theCurrentRecAttrs
[
n
];
NdbRecAttr
*&
theCurrentRecAttr
=
theCurrentRecAttrs
[
n
];
...
@@ -149,7 +151,7 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
...
@@ -149,7 +151,7 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
if
(
tRecAttr
==
NULL
)
{
if
(
tRecAttr
==
NULL
)
{
exit
(
-
1
);
exit
(
-
1
);
//setErrorCodeAbort(4000);
//setErrorCodeAbort(4000);
return
NULL
;
DBUG_RETURN
(
NULL
)
;
}
}
/**********************************************************************
/**********************************************************************
...
@@ -161,7 +163,7 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
...
@@ -161,7 +163,7 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
//setErrorCodeAbort(4000);
//setErrorCodeAbort(4000);
m_ndb
->
releaseRecAttr
(
tRecAttr
);
m_ndb
->
releaseRecAttr
(
tRecAttr
);
exit
(
-
1
);
exit
(
-
1
);
return
NULL
;
DBUG_RETURN
(
NULL
)
;
}
}
//theErrorLine++;
//theErrorLine++;
...
@@ -193,7 +195,7 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
...
@@ -193,7 +195,7 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
tRecAttr
->
release
();
// do I need to do this?
tRecAttr
->
release
();
// do I need to do this?
m_ndb
->
releaseRecAttr
(
tRecAttr
);
m_ndb
->
releaseRecAttr
(
tRecAttr
);
exit
(
-
1
);
exit
(
-
1
);
return
NULL
;
DBUG_RETURN
(
NULL
)
;
}
}
// this is it, between p and p_next
// this is it, between p and p_next
p
->
next
(
tRecAttr
);
p
->
next
(
tRecAttr
);
...
@@ -201,16 +203,17 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
...
@@ -201,16 +203,17 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in
}
}
}
}
return
tRecAttr
;
DBUG_RETURN
(
tRecAttr
)
;
}
}
int
int
NdbEventOperationImpl
::
execute
()
NdbEventOperationImpl
::
execute
()
{
{
DBUG_ENTER
(
"NdbEventOperationImpl::execute"
);
NdbDictionary
::
Dictionary
*
myDict
=
m_ndb
->
getDictionary
();
NdbDictionary
::
Dictionary
*
myDict
=
m_ndb
->
getDictionary
();
if
(
!
myDict
)
{
if
(
!
myDict
)
{
m_error
.
code
=
m_ndb
->
getNdbError
().
code
;
m_error
.
code
=
m_ndb
->
getNdbError
().
code
;
return
-
1
;
DBUG_RETURN
(
-
1
)
;
}
}
if
(
theFirstRecAttrs
[
0
]
==
NULL
)
{
// defaults to get all
if
(
theFirstRecAttrs
[
0
]
==
NULL
)
{
// defaults to get all
...
@@ -227,7 +230,9 @@ NdbEventOperationImpl::execute()
...
@@ -227,7 +230,9 @@ NdbEventOperationImpl::execute()
m_error
.
code
=
4709
;
m_error
.
code
=
4709
;
if
(
r
<
0
)
if
(
r
<
0
)
return
-
1
;
{
DBUG_RETURN
(
-
1
);
}
m_eventImpl
->
m_bufferId
=
m_bufferId
=
(
Uint32
)
r
;
m_eventImpl
->
m_bufferId
=
m_bufferId
=
(
Uint32
)
r
;
...
@@ -252,7 +257,7 @@ NdbEventOperationImpl::execute()
...
@@ -252,7 +257,7 @@ NdbEventOperationImpl::execute()
//Error
//Error
m_state
=
EO_ERROR
;
m_state
=
EO_ERROR
;
}
}
return
r
;
DBUG_RETURN
(
r
)
;
}
}
int
int
...
@@ -260,7 +265,9 @@ NdbEventOperationImpl::stop()
...
@@ -260,7 +265,9 @@ NdbEventOperationImpl::stop()
{
{
DBUG_ENTER
(
"NdbEventOperationImpl::stop"
);
DBUG_ENTER
(
"NdbEventOperationImpl::stop"
);
if
(
m_state
!=
EO_EXECUTING
)
if
(
m_state
!=
EO_EXECUTING
)
{
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
// ndbout_c("NdbEventOperation::stopping()");
// ndbout_c("NdbEventOperation::stopping()");
...
@@ -330,6 +337,7 @@ NdbEventOperationImpl::getLatestGCI()
...
@@ -330,6 +337,7 @@ NdbEventOperationImpl::getLatestGCI()
int
int
NdbEventOperationImpl
::
next
(
int
*
pOverrun
)
NdbEventOperationImpl
::
next
(
int
*
pOverrun
)
{
{
DBUG_ENTER
(
"NdbEventOperationImpl::next"
);
int
nr
=
10000
;
// a high value
int
nr
=
10000
;
// a high value
int
tmpOverrun
=
0
;
int
tmpOverrun
=
0
;
int
*
ptmpOverrun
;
int
*
ptmpOverrun
;
...
@@ -346,7 +354,10 @@ NdbEventOperationImpl::next(int *pOverrun)
...
@@ -346,7 +354,10 @@ NdbEventOperationImpl::next(int *pOverrun)
*
pOverrun
=
tmpOverrun
;
*
pOverrun
=
tmpOverrun
;
}
}
if
(
r
<=
0
)
return
r
;
// no data
if
(
r
<=
0
)
{
DBUG_RETURN
(
r
);
// no data
}
if
(
r
<
nr
)
r
=
nr
;
else
nr
--
;
// we don't want to be stuck here forever
if
(
r
<
nr
)
r
=
nr
;
else
nr
--
;
// we don't want to be stuck here forever
...
@@ -356,7 +367,10 @@ NdbEventOperationImpl::next(int *pOverrun)
...
@@ -356,7 +367,10 @@ NdbEventOperationImpl::next(int *pOverrun)
// now move the data into the RecAttrs
// now move the data into the RecAttrs
if
((
theFirstRecAttrs
[
0
]
==
NULL
)
&&
if
((
theFirstRecAttrs
[
0
]
==
NULL
)
&&
(
theFirstRecAttrs
[
1
]
==
NULL
))
return
r
;
(
theFirstRecAttrs
[
1
]
==
NULL
))
{
DBUG_RETURN
(
r
);
}
// no copying since no RecAttr's
// no copying since no RecAttr's
...
@@ -464,9 +478,11 @@ NdbEventOperationImpl::next(int *pOverrun)
...
@@ -464,9 +478,11 @@ NdbEventOperationImpl::next(int *pOverrun)
}
}
if
(
hasSomeData
)
if
(
hasSomeData
)
return
r
;
{
DBUG_RETURN
(
r
);
}
}
return
0
;
}
DBUG_RETURN
(
0
);
}
}
NdbDictionary
::
Event
::
TableEvent
NdbDictionary
::
Event
::
TableEvent
...
@@ -641,23 +657,28 @@ NdbGlobalEventBufferHandle::~NdbGlobalEventBufferHandle()
...
@@ -641,23 +657,28 @@ NdbGlobalEventBufferHandle::~NdbGlobalEventBufferHandle()
void
void
NdbGlobalEventBufferHandle
::
addBufferId
(
int
bufferId
)
NdbGlobalEventBufferHandle
::
addBufferId
(
int
bufferId
)
{
{
DBUG_ENTER
(
"NdbGlobalEventBufferHandle::addBufferId"
);
DBUG_PRINT
(
"enter"
,(
"bufferId=%d"
,
bufferId
));
if
(
m_nids
>=
NDB_MAX_ACTIVE_EVENTS
)
{
if
(
m_nids
>=
NDB_MAX_ACTIVE_EVENTS
)
{
ndbout_c
(
"NdbGlobalEventBufferHandle::addBufferId error in paramerer setting"
);
ndbout_c
(
"NdbGlobalEventBufferHandle::addBufferId error in paramerer setting"
);
exit
(
-
1
);
exit
(
-
1
);
}
}
m_bufferIds
[
m_nids
]
=
bufferId
;
m_bufferIds
[
m_nids
]
=
bufferId
;
m_nids
++
;
m_nids
++
;
DBUG_VOID_RETURN
;
}
}
void
void
NdbGlobalEventBufferHandle
::
dropBufferId
(
int
bufferId
)
NdbGlobalEventBufferHandle
::
dropBufferId
(
int
bufferId
)
{
{
DBUG_ENTER
(
"NdbGlobalEventBufferHandle::dropBufferId"
);
DBUG_PRINT
(
"enter"
,(
"bufferId=%d"
,
bufferId
));
for
(
int
i
=
0
;
i
<
m_nids
;
i
++
)
for
(
int
i
=
0
;
i
<
m_nids
;
i
++
)
if
(
m_bufferIds
[
i
]
==
bufferId
)
{
if
(
m_bufferIds
[
i
]
==
bufferId
)
{
m_nids
--
;
m_nids
--
;
for
(;
i
<
m_nids
;
i
++
)
for
(;
i
<
m_nids
;
i
++
)
m_bufferIds
[
i
]
=
m_bufferIds
[
i
+
1
];
m_bufferIds
[
i
]
=
m_bufferIds
[
i
+
1
];
return
;
DBUG_VOID_RETURN
;
}
}
ndbout_c
(
"NdbGlobalEventBufferHandle::dropBufferId %d does not exist"
,
ndbout_c
(
"NdbGlobalEventBufferHandle::dropBufferId %d does not exist"
,
bufferId
);
bufferId
);
...
@@ -841,7 +862,7 @@ NdbGlobalEventBuffer::real_init (NdbGlobalEventBufferHandle *h,
...
@@ -841,7 +862,7 @@ NdbGlobalEventBuffer::real_init (NdbGlobalEventBufferHandle *h,
// (BufItem *)NdbMem_Allocate(m_max*sizeof(BufItem));
// (BufItem *)NdbMem_Allocate(m_max*sizeof(BufItem));
for
(
int
i
=
0
;
i
<
m_max
;
i
++
)
{
for
(
int
i
=
0
;
i
<
m_max
;
i
++
)
{
m_buf
[
i
].
gId
=
0
;
m_buf
[
i
].
gId
=
0
;
}
}
}
}
// TODO make sure we don't hit roof
// TODO make sure we don't hit roof
...
@@ -876,14 +897,14 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
...
@@ -876,14 +897,14 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_prepareAddSubscribeEvent"
);
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_prepareAddSubscribeEvent"
);
int
i
;
int
i
;
int
bufferId
=
-
1
;
int
bufferId
=
-
1
;
// add_drop_lock(); // only one thread can do add or drop at a time
// add_drop_lock(); // only one thread can do add or drop at a time
// Find place where eventId already set
// Find place where eventId already set
for
(
i
=
0
;
i
<
m_no
;
i
++
)
{
for
(
i
=
0
;
i
<
m_no
;
i
++
)
{
if
(
m_buf
[
i
].
gId
==
eventId
)
{
if
(
m_buf
[
i
].
gId
==
eventId
)
{
bufferId
=
i
;
bufferId
=
i
;
break
;
break
;
}
}
}
}
...
@@ -891,18 +912,17 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
...
@@ -891,18 +912,17 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
// find space for new bufferId
// find space for new bufferId
for
(
i
=
0
;
i
<
m_no
;
i
++
)
{
for
(
i
=
0
;
i
<
m_no
;
i
++
)
{
if
(
m_buf
[
i
].
gId
==
0
)
{
if
(
m_buf
[
i
].
gId
==
0
)
{
bufferId
=
i
;
// we found an empty spot
bufferId
=
i
;
// we found an empty spot
break
;
goto
found_bufferId
;
}
}
}
}
if
(
bufferId
<
0
&&
if
(
bufferId
<
0
&&
m_no
<
m_max
)
{
m_no
<
m_max
)
{
// room for more so get that
// room for more so get that
bufferId
=
m_no
;
bufferId
=
m_no
;
m_buf
[
m_no
].
gId
=
0
;
m_buf
[
m_no
].
gId
=
0
;
m_no
++
;
m_no
++
;
}
else
{
}
else
{
ndbout_c
(
"prepareAddSubscribeEvent: Can't accept more subscribers"
);
// add_drop_unlock();
// add_drop_unlock();
DBUG_PRINT
(
"error"
,(
"Can't accept more subscribers:"
DBUG_PRINT
(
"error"
,(
"Can't accept more subscribers:"
" bufferId=%d, m_no=%d, m_max=%d"
,
" bufferId=%d, m_no=%d, m_max=%d"
,
...
@@ -910,37 +930,36 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
...
@@ -910,37 +930,36 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
}
}
found_bufferId:
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
if
(
b
.
gId
==
0
)
{
// first subscriber needs some initialization
if
(
b
.
gId
==
0
)
{
// first subscriber needs some initialization
bufferId
=
NO_ID
(
0
,
bufferId
);
bufferId
=
NO_ID
(
0
,
bufferId
);
b
.
gId
=
eventId
;
b
.
gId
=
eventId
;
if
((
b
.
p_buf_mutex
=
NdbMutex_Create
())
==
NULL
)
{
if
((
b
.
p_buf_mutex
=
NdbMutex_Create
())
==
NULL
)
{
ndbout_c
(
"NdbGlobalEventBuffer: NdbMutex_Create() failed"
);
ndbout_c
(
"NdbGlobalEventBuffer: NdbMutex_Create() failed"
);
exit
(
-
1
);
abort
(
);
}
}
b
.
subs
=
0
;
b
.
subs
=
0
;
b
.
f
=
0
;
b
.
f
=
0
;
b
.
sz
=
0
;
b
.
sz
=
0
;
b
.
max_sz
=
aHandle
->
m_bufferL
;
b
.
max_sz
=
aHandle
->
m_bufferL
;
b
.
data
=
b
.
data
=
(
BufItem
::
Data
*
)
NdbMem_Allocate
(
b
.
max_sz
*
sizeof
(
BufItem
::
Data
));
(
BufItem
::
Data
*
)
NdbMem_Allocate
(
b
.
max_sz
*
sizeof
(
BufItem
::
Data
));
for
(
int
i
=
0
;
i
<
b
.
max_sz
;
i
++
)
{
for
(
int
i
=
0
;
i
<
b
.
max_sz
;
i
++
)
{
b
.
data
[
i
].
sdata
=
NULL
;
b
.
data
[
i
].
sdata
=
NULL
;
b
.
data
[
i
].
ptr
[
0
].
p
=
NULL
;
b
.
data
[
i
].
ptr
[
0
].
p
=
NULL
;
b
.
data
[
i
].
ptr
[
1
].
p
=
NULL
;
b
.
data
[
i
].
ptr
[
1
].
p
=
NULL
;
b
.
data
[
i
].
ptr
[
2
].
p
=
NULL
;
b
.
data
[
i
].
ptr
[
2
].
p
=
NULL
;
}
}
}
else
{
}
else
{
#ifdef EVENT_DEBUG
DBUG_PRINT
(
"info"
,
ndbout_c
(
"NdbGlobalEventBuffer::prepareAddSubscribeEvent: TRYING handle one subscriber per event b.subs = %u"
,
b
.
subs
);
(
"TRYING handle one subscriber per event b.subs=%u"
,
b
.
subs
));
#endif
int
ni
=
-
1
;
int
ni
=
-
1
;
for
(
int
i
=
0
;
i
<
b
.
subs
;
i
++
)
{
for
(
int
i
=
0
;
i
<
b
.
subs
;
i
++
)
{
if
(
b
.
ps
[
i
].
theHandle
==
NULL
)
{
if
(
b
.
ps
[
i
].
theHandle
==
NULL
)
{
...
@@ -952,7 +971,8 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
...
@@ -952,7 +971,8 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
if
(
b
.
subs
<
MAX_SUBSCRIBERS_PER_EVENT
)
{
if
(
b
.
subs
<
MAX_SUBSCRIBERS_PER_EVENT
)
{
ni
=
b
.
subs
;
ni
=
b
.
subs
;
}
else
{
}
else
{
ndbout_c
(
"prepareAddSubscribeEvent: Can't accept more subscribers"
);
DBUG_PRINT
(
"error"
,
(
"Can't accept more subscribers: b.subs=%d"
,
b
.
subs
));
// add_drop_unlock();
// add_drop_unlock();
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
...
@@ -975,10 +995,8 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
...
@@ -975,10 +995,8 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
else
else
hasSubscriber
=
0
;
hasSubscriber
=
0
;
#ifdef EVENT_DEBUG
DBUG_PRINT
(
"info"
,(
"handed out bufferId=%d for eventId=%d hasSubscriber=%d"
,
ndbout_c
(
"prepareAddSubscribeEvent: handed out bufferId %d for eventId %d"
,
bufferId
,
eventId
,
hasSubscriber
));
bufferId
,
eventId
);
#endif
/* we now have a lock on the prepare so that no one can mess with this
/* we now have a lock on the prepare so that no one can mess with this
* unlock comes in unprepareAddSubscribeEvent or addSubscribeEvent
* unlock comes in unprepareAddSubscribeEvent or addSubscribeEvent
...
@@ -989,9 +1007,13 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
...
@@ -989,9 +1007,13 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent
void
void
NdbGlobalEventBuffer
::
real_unprepareAddSubscribeEvent
(
int
bufferId
)
NdbGlobalEventBuffer
::
real_unprepareAddSubscribeEvent
(
int
bufferId
)
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent"
);
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
int
n
=
NO
(
bufferId
);
int
n
=
NO
(
bufferId
);
DBUG_PRINT
(
"enter"
,
(
"bufferId=%d,ID(bufferId)=%d,NO(bufferId)=%d"
,
bufferId
,
ID
(
bufferId
),
NO
(
bufferId
)));
b
.
ps
[
n
].
theHandle
=
NULL
;
b
.
ps
[
n
].
theHandle
=
NULL
;
// remove subscribers from the end,
// remove subscribers from the end,
...
@@ -1004,10 +1026,8 @@ NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent(int bufferId)
...
@@ -1004,10 +1026,8 @@ NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent(int bufferId)
break
;
break
;
if
(
b
.
subs
==
0
)
{
if
(
b
.
subs
==
0
)
{
#ifdef EVENT_DEBUG
DBUG_PRINT
(
"info"
,(
"no more subscribers left on eventId %d"
,
b
.
gId
));
ndbout_c
(
"unprepareAddSubscribeEvent: no more subscribers left on eventId %d"
,
b
.
gId
);
b
.
gId
=
0
;
// We don't have any subscribers, reuse BufItem
#endif
b
.
gId
=
0
;
// We don't have any subscribers, reuse BufItem
if
(
b
.
data
)
{
if
(
b
.
data
)
{
NdbMem_Free
((
void
*
)
b
.
data
);
NdbMem_Free
((
void
*
)
b
.
data
);
b
.
data
=
NULL
;
b
.
data
=
NULL
;
...
@@ -1018,12 +1038,14 @@ NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent(int bufferId)
...
@@ -1018,12 +1038,14 @@ NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent(int bufferId)
}
}
}
}
// add_drop_unlock();
// add_drop_unlock();
DBUG_VOID_RETURN
;
}
}
void
void
NdbGlobalEventBuffer
::
real_addSubscribeEvent
(
int
bufferId
,
NdbGlobalEventBuffer
::
real_addSubscribeEvent
(
int
bufferId
,
void
*
ndbEventOperation
)
void
*
ndbEventOperation
)
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_addSubscribeEvent"
);
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
int
n
=
NO
(
bufferId
);
int
n
=
NO
(
bufferId
);
...
@@ -1031,9 +1053,8 @@ NdbGlobalEventBuffer::real_addSubscribeEvent(int bufferId,
...
@@ -1031,9 +1053,8 @@ NdbGlobalEventBuffer::real_addSubscribeEvent(int bufferId,
b
.
ps
[
n
].
theHandle
->
addBufferId
(
bufferId
);
b
.
ps
[
n
].
theHandle
->
addBufferId
(
bufferId
);
// add_drop_unlock();
// add_drop_unlock();
#ifdef EVENT_DEBUG
DBUG_PRINT
(
"info"
,(
"added bufferId %d"
,
bufferId
));
ndbout_c
(
"addSubscribeEvent:: added bufferId %d"
,
bufferId
);
DBUG_VOID_RETURN
;
#endif
}
}
void
void
...
@@ -1062,7 +1083,9 @@ NdbGlobalEventBuffer::real_prepareDropSubscribeEvent(int bufferId,
...
@@ -1062,7 +1083,9 @@ NdbGlobalEventBuffer::real_prepareDropSubscribeEvent(int bufferId,
else
if
(
n
==
1
)
else
if
(
n
==
1
)
hasSubscriber
=
0
;
hasSubscriber
=
0
;
else
else
{
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -1070,6 +1093,7 @@ NdbGlobalEventBuffer::real_prepareDropSubscribeEvent(int bufferId,
...
@@ -1070,6 +1093,7 @@ NdbGlobalEventBuffer::real_prepareDropSubscribeEvent(int bufferId,
void
void
NdbGlobalEventBuffer
::
real_dropSubscribeEvent
(
int
bufferId
)
NdbGlobalEventBuffer
::
real_dropSubscribeEvent
(
int
bufferId
)
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_dropSubscribeEvent"
);
// add_drop_lock(); // only one thread can do add-drop at a time
// add_drop_lock(); // only one thread can do add-drop at a time
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
...
@@ -1085,6 +1109,7 @@ NdbGlobalEventBuffer::real_dropSubscribeEvent(int bufferId)
...
@@ -1085,6 +1109,7 @@ NdbGlobalEventBuffer::real_dropSubscribeEvent(int bufferId)
#ifdef EVENT_DEBUG
#ifdef EVENT_DEBUG
ndbout_c
(
"dropSubscribeEvent:: dropped bufferId %d"
,
bufferId
);
ndbout_c
(
"dropSubscribeEvent:: dropped bufferId %d"
,
bufferId
);
#endif
#endif
DBUG_VOID_RETURN
;
}
}
void
void
...
@@ -1107,6 +1132,7 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
...
@@ -1107,6 +1132,7 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
const
SubTableData
*
const
sdata
,
const
SubTableData
*
const
sdata
,
LinearSectionPtr
ptr
[
3
])
LinearSectionPtr
ptr
[
3
])
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_insertDataL"
);
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
#ifdef EVENT_DEBUG
#ifdef EVENT_DEBUG
int
n
=
NO
(
bufferId
);
int
n
=
NO
(
bufferId
);
...
@@ -1119,7 +1145,9 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
...
@@ -1119,7 +1145,9 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
// move front forward
// move front forward
if
(
copy_data_alloc
(
sdata
,
ptr
,
if
(
copy_data_alloc
(
sdata
,
ptr
,
b
.
data
[
b
.
f
].
sdata
,
b
.
data
[
b
.
f
].
ptr
))
b
.
data
[
b
.
f
].
sdata
,
b
.
data
[
b
.
f
].
ptr
))
return
-
1
;
{
DBUG_RETURN
(
-
1
);
}
for
(
int
i
=
0
;
i
<
b
.
subs
;
i
++
)
{
for
(
int
i
=
0
;
i
<
b
.
subs
;
i
++
)
{
NdbGlobalEventBuffer
::
BufItem
::
Ps
&
e
=
b
.
ps
[
i
];
NdbGlobalEventBuffer
::
BufItem
::
Ps
&
e
=
b
.
ps
[
i
];
if
(
e
.
theHandle
)
{
// active subscriber
if
(
e
.
theHandle
)
{
// active subscriber
...
@@ -1127,7 +1155,7 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
...
@@ -1127,7 +1155,7 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
if
(
e
.
bufferempty
==
0
)
{
if
(
e
.
bufferempty
==
0
)
{
e
.
overrun
++
;
// another item has been overwritten
e
.
overrun
++
;
// another item has been overwritten
e
.
b
++
;
// move next-to-read next since old item was overwritten
e
.
b
++
;
// move next-to-read next since old item was overwritten
if
(
e
.
b
==
b
.
max_sz
)
e
.
b
=
0
;
// start from beginning
if
(
e
.
b
==
b
.
max_sz
)
e
.
b
=
0
;
// start from beginning
}
}
}
}
e
.
bufferempty
=
0
;
e
.
bufferempty
=
0
;
...
@@ -1147,21 +1175,28 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
...
@@ -1147,21 +1175,28 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId,
#endif
#endif
}
}
}
}
return
0
;
DBUG_RETURN
(
0
)
;
}
}
int
NdbGlobalEventBuffer
::
hasData
(
int
bufferId
)
{
int
NdbGlobalEventBuffer
::
hasData
(
int
bufferId
)
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::hasData"
);
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
int
n
=
NO
(
bufferId
);
int
n
=
NO
(
bufferId
);
NdbGlobalEventBuffer
::
BufItem
::
Ps
&
e
=
b
.
ps
[
n
];
NdbGlobalEventBuffer
::
BufItem
::
Ps
&
e
=
b
.
ps
[
n
];
if
(
e
.
bufferempty
)
if
(
e
.
bufferempty
)
return
0
;
{
DBUG_RETURN
(
0
);
}
if
(
b
.
f
<=
e
.
b
)
if
(
b
.
f
<=
e
.
b
)
return
b
.
max_sz
-
e
.
b
+
b
.
f
;
{
DBUG_RETURN
(
b
.
max_sz
-
e
.
b
+
b
.
f
);
}
else
else
return
b
.
f
-
e
.
b
;
{
DBUG_RETURN
(
b
.
f
-
e
.
b
);
}
}
}
int
NdbGlobalEventBuffer
::
real_getDataL
(
const
int
bufferId
,
int
NdbGlobalEventBuffer
::
real_getDataL
(
const
int
bufferId
,
...
@@ -1169,6 +1204,7 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId,
...
@@ -1169,6 +1204,7 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId,
LinearSectionPtr
ptr
[
3
],
LinearSectionPtr
ptr
[
3
],
int
*
pOverrun
)
int
*
pOverrun
)
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_getDataL"
);
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
BufItem
&
b
=
m_buf
[
ID
(
bufferId
)];
int
n
=
NO
(
bufferId
);
int
n
=
NO
(
bufferId
);
NdbGlobalEventBuffer
::
BufItem
::
Ps
&
e
=
b
.
ps
[
n
];
NdbGlobalEventBuffer
::
BufItem
::
Ps
&
e
=
b
.
ps
[
n
];
...
@@ -1179,13 +1215,17 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId,
...
@@ -1179,13 +1215,17 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId,
}
}
if
(
e
.
bufferempty
)
if
(
e
.
bufferempty
)
return
0
;
// nothing to get
{
DBUG_RETURN
(
0
);
// nothing to get
}
if
(
copy_data_alloc
(
b
.
data
[
e
.
b
].
sdata
,
b
.
data
[
e
.
b
].
ptr
,
if
(
copy_data_alloc
(
b
.
data
[
e
.
b
].
sdata
,
b
.
data
[
e
.
b
].
ptr
,
sdata
,
ptr
))
sdata
,
ptr
))
return
-
1
;
{
DBUG_RETURN
(
-
1
);
}
e
.
b
++
;
if
(
e
.
b
==
b
.
max_sz
)
e
.
b
=
0
;
// move next-to-read forward
e
.
b
++
;
if
(
e
.
b
==
b
.
max_sz
)
e
.
b
=
0
;
// move next-to-read forward
if
(
b
.
f
==
e
.
b
)
// back has cought up with front
if
(
b
.
f
==
e
.
b
)
// back has cought up with front
e
.
bufferempty
=
1
;
e
.
bufferempty
=
1
;
...
@@ -1194,7 +1234,7 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId,
...
@@ -1194,7 +1234,7 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId,
ndbout_c
(
"getting data from buffer %d with eventId %d"
,
bufferId
,
b
.
gId
);
ndbout_c
(
"getting data from buffer %d with eventId %d"
,
bufferId
,
b
.
gId
);
#endif
#endif
return
hasData
(
bufferId
)
+
1
;
DBUG_RETURN
(
hasData
(
bufferId
)
+
1
)
;
}
}
int
int
NdbGlobalEventBuffer
::
copy_data_alloc
(
const
SubTableData
*
const
f_sdata
,
NdbGlobalEventBuffer
::
copy_data_alloc
(
const
SubTableData
*
const
f_sdata
,
...
@@ -1202,6 +1242,7 @@ NdbGlobalEventBuffer::copy_data_alloc(const SubTableData * const f_sdata,
...
@@ -1202,6 +1242,7 @@ NdbGlobalEventBuffer::copy_data_alloc(const SubTableData * const f_sdata,
SubTableData
*
&
t_sdata
,
SubTableData
*
&
t_sdata
,
LinearSectionPtr
t_ptr
[
3
])
LinearSectionPtr
t_ptr
[
3
])
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::copy_data_alloc"
);
if
(
t_sdata
==
NULL
)
{
if
(
t_sdata
==
NULL
)
{
t_sdata
=
(
SubTableData
*
)
NdbMem_Allocate
(
sizeof
(
SubTableData
));
t_sdata
=
(
SubTableData
*
)
NdbMem_Allocate
(
sizeof
(
SubTableData
));
}
}
...
@@ -1223,28 +1264,34 @@ NdbGlobalEventBuffer::copy_data_alloc(const SubTableData * const f_sdata,
...
@@ -1223,28 +1264,34 @@ NdbGlobalEventBuffer::copy_data_alloc(const SubTableData * const f_sdata,
}
}
t_p
.
sz
=
f_p
.
sz
;
t_p
.
sz
=
f_p
.
sz
;
}
}
return
0
;
DBUG_RETURN
(
0
)
;
}
}
int
int
NdbGlobalEventBuffer
::
real_wait
(
NdbGlobalEventBufferHandle
*
h
,
NdbGlobalEventBuffer
::
real_wait
(
NdbGlobalEventBufferHandle
*
h
,
int
aMillisecondNumber
)
int
aMillisecondNumber
)
{
{
DBUG_ENTER
(
"NdbGlobalEventBuffer::real_wait"
);
// check if there are anything in any of the buffers
// check if there are anything in any of the buffers
int
i
;
int
i
;
int
n
=
0
;
int
n
=
0
;
for
(
i
=
0
;
i
<
h
->
m_nids
;
i
++
)
for
(
i
=
0
;
i
<
h
->
m_nids
;
i
++
)
n
+=
hasData
(
h
->
m_bufferIds
[
i
]);
n
+=
hasData
(
h
->
m_bufferIds
[
i
]);
if
(
n
)
return
n
;
if
(
n
)
{
DBUG_RETURN
(
n
);
}
int
r
=
NdbCondition_WaitTimeout
(
h
->
p_cond
,
ndb_global_event_buffer_mutex
,
int
r
=
NdbCondition_WaitTimeout
(
h
->
p_cond
,
ndb_global_event_buffer_mutex
,
aMillisecondNumber
);
aMillisecondNumber
);
if
(
r
>
0
)
if
(
r
>
0
)
return
-
1
;
{
DBUG_RETURN
(
-
1
);
}
n
=
0
;
n
=
0
;
for
(
i
=
0
;
i
<
h
->
m_nids
;
i
++
)
for
(
i
=
0
;
i
<
h
->
m_nids
;
i
++
)
n
+=
hasData
(
h
->
m_bufferIds
[
i
]);
n
+=
hasData
(
h
->
m_bufferIds
[
i
]);
return
n
;
DBUG_RETURN
(
n
)
;
}
}
template
class
Vector
<
NdbGlobalEventBufferHandle
*
>;
template
class
Vector
<
NdbGlobalEventBufferHandle
*
>;
ndb/test/src/HugoTransactions.cpp
View file @
ba193367
...
@@ -775,7 +775,9 @@ HugoTransactions::createEvent(Ndb* pNdb){
...
@@ -775,7 +775,9 @@ HugoTransactions::createEvent(Ndb* pNdb){
NdbDictionary
::
Dictionary
*
myDict
=
pNdb
->
getDictionary
();
NdbDictionary
::
Dictionary
*
myDict
=
pNdb
->
getDictionary
();
if
(
!
myDict
)
{
if
(
!
myDict
)
{
printf
(
"Event Creation failedDictionary not found"
);
g_err
<<
"Dictionary not found "
<<
pNdb
->
getNdbError
().
code
<<
" "
<<
pNdb
->
getNdbError
().
message
<<
endl
;
return
NDBT_FAILED
;
return
NDBT_FAILED
;
}
}
...
@@ -796,21 +798,33 @@ HugoTransactions::createEvent(Ndb* pNdb){
...
@@ -796,21 +798,33 @@ HugoTransactions::createEvent(Ndb* pNdb){
if
(
res
==
0
)
if
(
res
==
0
)
myEvent
.
print
();
myEvent
.
print
();
else
{
else
if
(
myDict
->
getNdbError
().
classification
==
g_info
<<
"Event creation failed
\n
"
;
NdbError
::
SchemaObjectExists
)
g_info
<<
"trying drop Event, maybe event exists
\n
"
;
{
g_info
<<
"Event creation failed event exists
\n
"
;
res
=
myDict
->
dropEvent
(
eventName
);
res
=
myDict
->
dropEvent
(
eventName
);
if
(
res
)
{
if
(
res
)
{
g_err
<<
"failed to drop event
\n
"
;
g_err
<<
"Failed to drop event: "
<<
myDict
->
getNdbError
().
code
<<
" : "
<<
myDict
->
getNdbError
().
message
<<
endl
;
return
NDBT_FAILED
;
return
NDBT_FAILED
;
}
}
// try again
// try again
res
=
myDict
->
createEvent
(
myEvent
);
// Add event to database
res
=
myDict
->
createEvent
(
myEvent
);
// Add event to database
if
(
res
)
{
if
(
res
)
{
g_err
<<
"failed to create event
\n
"
;
g_err
<<
"Failed to create event (1): "
<<
myDict
->
getNdbError
().
code
<<
" : "
<<
myDict
->
getNdbError
().
message
<<
endl
;
return
NDBT_FAILED
;
return
NDBT_FAILED
;
}
}
}
}
else
{
g_err
<<
"Failed to create event (2): "
<<
myDict
->
getNdbError
().
code
<<
" : "
<<
myDict
->
getNdbError
().
message
<<
endl
;
return
NDBT_FAILED
;
}
return
NDBT_OK
;
return
NDBT_OK
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment