Below is the list of changes that have just been committed into a local
5.1 repository of frazer. When frazer does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-07 14:59:11+00:00, frazer@stripped +13 -0
WL 4086 code inspection changes.
Recommitted in different clone to separate from pseudo-column and read-packed changes.
sql/ha_ndbcluster.cc@stripped, 2008-02-07 14:59:05+00:00, frazer@stripped +2 -2
WL 4086 code inspection changes
storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp@stripped, 2008-02-07 14:59:05+00:00, frazer@stripped +3 -1
WL 4086 code inspection changes
storage/ndb/include/ndbapi/NdbInterpretedCode.hpp@stripped, 2008-02-07 14:59:05+00:00, frazer@stripped +14 -0
WL 4086 code inspection changes
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp@stripped, 2008-02-07 14:59:05+00:00, frazer@stripped +2 -2
WL 4086 code inspection changes
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp@stripped, 2008-02-07 14:59:05+00:00, frazer@stripped +7 -5
WL 4086 code inspection changes
storage/ndb/src/ndbapi/NdbInterpretedCode.cpp@stripped, 2008-02-07 14:59:05+00:00, frazer@stripped +65 -29
WL 4086 code inspection changes
storage/ndb/src/ndbapi/NdbOperationDefine.cpp@stripped, 2008-02-07 14:59:06+00:00, frazer@stripped +5 -4
WL 4086 code inspection changes
storage/ndb/src/ndbapi/NdbOperationInt.cpp@stripped, 2008-02-07 14:59:06+00:00, frazer@stripped +2 -2
WL 4086 code inspection changes
storage/ndb/src/ndbapi/NdbReceiver.cpp@stripped, 2008-02-07 14:59:06+00:00, frazer@stripped +2 -1
WL 4086 code inspection changes
storage/ndb/src/ndbapi/NdbScanOperation.cpp@stripped, 2008-02-07 14:59:06+00:00, frazer@stripped +85 -61
WL 4086 code inspection changes
storage/ndb/src/ndbapi/ndberror.c@stripped, 2008-02-07 14:59:06+00:00, frazer@stripped +1 -1
WL 4086 code inspection changes
storage/ndb/test/ndbapi/testIndexStat.cpp@stripped, 2008-02-07 14:59:06+00:00, frazer@stripped +23 -16
WL 4086 code inspection changes
storage/ndb/test/ndbapi/testScanFilter.cpp@stripped, 2008-02-07 14:59:06+00:00, frazer@stripped +1 -1
WL 4086 code inspection changes
diff -Nrup a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
--- a/sql/ha_ndbcluster.cc 2008-01-31 14:11:30 +00:00
+++ b/sql/ha_ndbcluster.cc 2008-02-07 14:59:05 +00:00
@@ -3123,7 +3123,7 @@ int ha_ndbcluster::full_table_scan(const
}
if (!(op= trans->scanTable(m_ndb_record, lm,
- (uchar *)(table->read_set->bitmap),
+ (uchar *)(table->read_set->bitmap),
&options, sizeof(NdbScanOperation::ScanOptions))))
ERR_RETURN(trans->getNdbError());
}
@@ -3932,7 +3932,7 @@ int ha_ndbcluster::ndb_update_row(const
*/
Uint32 buffer[16];
NdbInterpretedCode code(m_table, buffer,
- sizeof(buffer)/sizeof(buffer[0]));
+ sizeof(buffer)/sizeof(buffer[0]));
enum_conflict_fn_type cft= m_share->m_cfn_share->m_resolve_cft;
if (update_row_conflict_fn(cft, old_data, new_data, &code))
{
diff -Nrup a/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
--- a/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp 2008-01-25 13:39:16 +00:00
+++ b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp 2008-02-07 14:59:05 +00:00
@@ -237,7 +237,9 @@ private:
const NdbScanOperation::ScanOptions *options,
Uint32 sizeOfOptions);
- /* Old-scan-API bound definition space */
+ /* Structure used to collect information about an IndexBound
+ * as it is provided by the old Api setBound() calls
+ */
struct OldApiScanBoundInfo
{
Uint32 highestKey;
diff -Nrup a/storage/ndb/include/ndbapi/NdbInterpretedCode.hpp b/storage/ndb/include/ndbapi/NdbInterpretedCode.hpp
--- a/storage/ndb/include/ndbapi/NdbInterpretedCode.hpp 2008-01-14 12:54:41 +00:00
+++ b/storage/ndb/include/ndbapi/NdbInterpretedCode.hpp 2008-02-07 14:59:05 +00:00
@@ -452,6 +452,9 @@ public:
* It uses the label and subroutine meta information to
* resolve branch jumps and subroutine calls.
* It can only be called once.
+ * If no instructions have been defined, then it will attempt
+ * to add a single interpret_exit_ok instruction before
+ * finalisation.
*/
int finalise();
@@ -471,6 +474,14 @@ public:
*/
const class NdbError & getNdbError() const;
+
+ /**
+ * getWordsUsed
+ * Returns the number of words of the supplied or internal
+ * buffer that have been used.
+ */
+ Uint32 getWordsUsed() const;
+
private:
friend class NdbOperation;
friend class NdbScanOperation;
@@ -562,6 +573,9 @@ private:
// from start of subs section for
// subs defs
};
+
+ static const Uint32 CODEMETAINFO_WORDS= (sizeof(CodeMetaInfo) + 3)/4;
+
enum Errors
{
diff -Nrup a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2008-01-14 12:54:57 +00:00
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2008-02-07 14:59:05 +00:00
@@ -2628,8 +2628,8 @@ int Dbtup::interpreterNextLab(Signal* si
#endif
RstackPtr++;
if (RstackPtr < 32) {
- TstackMemBuffer[RstackPtr]= TprogramCounter;
- TprogramCounter= theInstruction >> 16;
+ TstackMemBuffer[RstackPtr]= TprogramCounter;
+ TprogramCounter= theInstruction >> 16;
if (TprogramCounter < TsubroutineLen) {
TcurrentProgram= subroutineProg;
TcurrentSize= TsubroutineLen;
diff -Nrup a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2008-01-31 14:11:31 +00:00
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2008-02-07 14:59:05 +00:00
@@ -5034,9 +5034,11 @@ cmp_ndbrec_attr(const void *a, const voi
* for the given column in the given table.
* The column is placed at the storageOffset given, and a new
* storageOffset, beyond the end of this column, is returned.
- * Null bits, if applicable, are placed at bit offset (0 + field num)
- * (i.e. at the start of the record). The caller must ensure that
- * sufficient space is reserved before the offset of the first column.
+ * Null bits are stored at the start of the row, in attrid position.
+ * Note that non nullable columns must therefore still have
+ * space reserved.
+ * The caller must ensure that sufficient space is reserved before the
+ * offset of the first column.
* The new storageOffset is returned.
*/
static Uint32
@@ -5077,9 +5079,9 @@ NdbDictionaryImpl::createDefaultNdbRecor
NdbDictionary::RecordSpecification spec[NDB_MAX_ATTRIBUTES_IN_TABLE];
NdbRecord *rec;
Uint32 i;
- // Reserve space for Null bits at the start
- Uint32 offset= (NDB_MAX_ATTRIBUTES_IN_TABLE + 7) / 8;
Uint32 numCols= table->m_columns.size();
+ // Reserve space for Null bits at the start
+ Uint32 offset= (numCols +7) /8;
Uint32 baseTabCols= numCols;
unsigned char* pkMask= NULL;
unsigned char* emptyMask= NULL;
diff -Nrup a/storage/ndb/src/ndbapi/NdbInterpretedCode.cpp b/storage/ndb/src/ndbapi/NdbInterpretedCode.cpp
--- a/storage/ndb/src/ndbapi/NdbInterpretedCode.cpp 2008-01-14 12:55:08 +00:00
+++ b/storage/ndb/src/ndbapi/NdbInterpretedCode.cpp 2008-02-07 14:59:05 +00:00
@@ -181,13 +181,14 @@ NdbInterpretedCode::addN(Uint32 *data, U
if (unlikely(! have_space_for(length)))
return error(TooManyInstructions);
-
- for(Uint32 pos=0; pos < length; pos++)
- {
- m_buffer[m_instructions_length++]=
- data[pos];
- }
-
+ /* data* may be unaligned, so we do a byte copy
+ * using memcpy
+ */
+ memcpy(&m_buffer[m_instructions_length],
+ data,
+ length << 2);
+
+ m_instructions_length+= length;
m_available_length-= length;
return 0;
@@ -196,15 +197,15 @@ NdbInterpretedCode::addN(Uint32 *data, U
inline int
NdbInterpretedCode::addMeta(CodeMetaInfo& info)
{
- if (unlikely(! have_space_for(2)))
+ if (unlikely(! have_space_for(CODEMETAINFO_WORDS)))
return error(TooManyInstructions);
- m_buffer[--m_last_meta_pos]= *(((Uint32 *)&info) + 1);
- m_buffer[--m_last_meta_pos]= *(((Uint32 *)&info) );
+ m_buffer[--m_last_meta_pos]= (Uint32)info.number << 16 | info.type;
+ m_buffer[--m_last_meta_pos]= info.firstInstrPos;
- m_available_length-= 2;
+ m_available_length-= CODEMETAINFO_WORDS;
- return 0;
+ return 0;
}
int
@@ -791,7 +792,7 @@ NdbInterpretedCode::def_sub(Uint32 Subro
info.number= SubroutineNumber;
info.firstInstrPos=
m_instructions_length - m_first_sub_instruction_pos;
-
+
// Note, no check for whether the label's already defined here.
return addMeta(info);
}
@@ -828,9 +829,12 @@ NdbInterpretedCode::getInfo(Uint32 numbe
if (number >= (m_number_of_labels + m_number_of_subs))
return -1;
- Uint32 pos= m_buffer_length - 2 - (number << 1);
- *(((Uint32 *)&info) )= m_buffer[pos ];
- *(((Uint32 *)&info) + 1)= m_buffer[pos + 1];
+ Uint32 pos= m_buffer_length
+ - ((number+1) * CODEMETAINFO_WORDS);
+
+ info.number= (m_buffer[pos + 1] >> 16) & 0xffff;
+ info.type= m_buffer[pos + 1] & 0xffff;
+ info.firstInstrPos= m_buffer[pos];
return 0;
}
@@ -863,32 +867,60 @@ NdbInterpretedCode::getNdbError() const
return m_error;
}
+Uint32
+NdbInterpretedCode::getWordsUsed() const
+{
+ return (m_buffer_length - m_available_length);
-/* CodeMetaInfo comparator for qsort */
+}
+
+/* CodeMetaInfo comparator for qsort
+ * Sort order is highest numbered sub to lowest,
+ * then highest numbered label to lowest
+ * *va < *vb : -1 *va first
+ * *va == *vb : 0
+ * *va > *vb : 1 *vb first
+ */
int
NdbInterpretedCode::compareMetaInfo(const void *va,
const void *vb)
{
- const CodeMetaInfo *a= (const CodeMetaInfo*) va;
- const CodeMetaInfo *b= (const CodeMetaInfo*) vb;
- /* Sort in reverse order (Subs, Labels) */
- if (a->type != b->type)
- return (b->type - a->type);
+ Uint32 aWord= *(((Uint32 *) va) + 1); // number || type
+ Uint32 bWord= *(((Uint32 *) vb) + 1); // number || type
+ Uint16 aType= aWord & 0xffff;
+ Uint16 bType= bWord & 0xffff;
+ const int AFirst= -1;
+ const int BFirst= 1;
+
+ /* Sort in order (Subs, Labels) */
+ if (aType != bType)
+ return (aType == Subroutine)? AFirst : BFirst;
+
+ Uint16 aNumber= (aWord >> 16) & 0xffff;
+ Uint16 bNumber= (bWord >> 16) & 0xffff;
/* Sort in reverse order within type, highest number
- * first
+ * first.
*/
- return (b->number - a->number);
+ if (aNumber != bNumber)
+ return (bNumber > aNumber)? BFirst : AFirst;
+
+ return 0; // Should never happen
}
+
int
NdbInterpretedCode::finalise()
{
if (m_instructions_length == 0)
{
- /* No instructions in Interpreted Program */
- m_error.code= 4523;
- return -1;
+ /* We will attempt to add a single EXIT_OK instruction
+ * rather than returning an error.
+ * This may simplify client code.
+ */
+ int res= 0;
+ if (0 != (res= interpret_exit_ok()))
+ return -1;
}
assert (m_buffer != NULL);
@@ -900,13 +932,13 @@ NdbInterpretedCode::finalise()
*/
Uint32 numOfMetaInfos= m_number_of_labels +
m_number_of_subs;
- Uint32 sizeOfMetaInfo= numOfMetaInfos << 1;
+ Uint32 sizeOfMetaInfo= numOfMetaInfos * CODEMETAINFO_WORDS;
Uint32 startOfMetaInfo= m_buffer_length - sizeOfMetaInfo;
/* Sort different types of meta info into order in place */
qsort( &m_buffer[ startOfMetaInfo ],
numOfMetaInfos,
- 8, // sizeof(CodeMetaInfo) rounded up to nearest 32-bit word
+ CODEMETAINFO_WORDS << 2,
&compareMetaInfo);
/* Loop over instructions, patching up branches
@@ -949,6 +981,8 @@ NdbInterpretedCode::finalise()
m_error.code= 4222; // Label was not found, internal error
return -1;
}
+
+ assert(info.type == Label);
Uint32 currOffset = ip - firstInstruction;
Uint32 labelOffset= info.firstInstrPos;
@@ -992,6 +1026,8 @@ NdbInterpretedCode::finalise()
m_error.code= 4521; // Call to undefined subroutine, internal error
return -1;
}
+
+ assert(info.type == Subroutine);
Uint32 subOffset= info.firstInstrPos;
diff -Nrup a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp b/storage/ndb/src/ndbapi/NdbOperationDefine.cpp
--- a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp 2008-01-17 08:06:40 +00:00
+++ b/storage/ndb/src/ndbapi/NdbOperationDefine.cpp 2008-02-07 14:59:06 +00:00
@@ -387,7 +387,8 @@ NdbOperation::getValue_impl(const NdbCol
m_no_disk_flag &= (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
if (theStatus != GetValue) {
if (theStatus == UseNdbRecord)
- return getValue_NdbRecord(tAttrInfo, aValue); /* OperationOptions::extraGetValues */
+ /* This path for extra GetValues for NdbRecord */
+ return getValue_NdbRecord(tAttrInfo, aValue);
if (theInterpretIndicator == 1) {
if (theStatus == FinalGetValue) {
; // Simply continue with getValue
@@ -675,11 +676,11 @@ NdbOperation::getBlobHandle(NdbTransacti
}
/*
- * For NdbRecord PK, IK and scan operations, we only fetch existing blob
- * handles here, creation must be done by requesting the blob in the
+ * For NdbRecord PK, unique index and scan operations, we only fetch existing
+ * blob handles here, creation must be done by requesting the blob in the
* NdbRecord and mask when creating the operation.
* For NdbRecAttr PK, IK and scan operations, we allow Blob handles
- * to be created here. Note that NdbRecAttr PK and IK ops are handled
+ * to be created here. Note that NdbRecAttr PK and unique index ops are handled
* differently to NdbRecAttr scan operations.
*/
if (m_attribute_record)
diff -Nrup a/storage/ndb/src/ndbapi/NdbOperationInt.cpp b/storage/ndb/src/ndbapi/NdbOperationInt.cpp
--- a/storage/ndb/src/ndbapi/NdbOperationInt.cpp 2008-01-14 12:55:14 +00:00
+++ b/storage/ndb/src/ndbapi/NdbOperationInt.cpp 2008-02-07 14:59:06 +00:00
@@ -89,7 +89,7 @@ NdbOperation::incCheck(const NdbColumnIm
}
return -1;
- inc_check_error1:
+ inc_check_error1:
if (theStatus == UseNdbRecord) {
/* Wrong API. Use NdbInterpretedCode for NdbRecord operations */
setErrorCodeAbort(4537);
@@ -98,7 +98,7 @@ NdbOperation::incCheck(const NdbColumnIm
setErrorCodeAbort(4004);
return -1;
- inc_check_error2:
+ inc_check_error2:
if (tNdbColumnImpl->m_pk){
setErrorCodeAbort(4202);
return -1;
diff -Nrup a/storage/ndb/src/ndbapi/NdbReceiver.cpp b/storage/ndb/src/ndbapi/NdbReceiver.cpp
--- a/storage/ndb/src/ndbapi/NdbReceiver.cpp 2008-01-14 12:55:20 +00:00
+++ b/storage/ndb/src/ndbapi/NdbReceiver.cpp 2008-02-07 14:59:06 +00:00
@@ -468,7 +468,8 @@ NdbReceiver::execTRANSID_AI(const Uint32
if (!ndbrecord_part_done)
{
- /* Special case for RANGE_NO, which is stored just after the row. */
+ /* Special case for RANGE_NO, which is received first and is
+ * stored just after the row. */
if (attrId==AttributeHeader::RANGE_NO)
{
assert(m_record.m_read_range_no);
diff -Nrup a/storage/ndb/src/ndbapi/NdbScanOperation.cpp b/storage/ndb/src/ndbapi/NdbScanOperation.cpp
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-01-25 13:39:23 +00:00
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-02-07 14:59:06 +00:00
@@ -287,6 +287,10 @@ NdbScanOperation::handleScanOptions(cons
{
/* Check the program's for the same table as the
* operation
+ * TODO : Online alter tables that don't affect InterpretedCode objects
+ * (i.e. extra columns at end of table, new indices), should not affect
+ * pre-finalised NdbInterpretedCode objects. How do we tell if two
+ * tables are the same except for insignificant schema changes?
*/
const NdbDictionary::Table* codeTable= options->interpretedCode->getTable();
if ((codeTable != NULL) &&
@@ -402,9 +406,6 @@ NdbScanOperation::scanTableImpl(const Nd
}
theReceiver.m_record.m_column_count= column_count;
- /*
- We set theStatus=UseNdbRecord
- */
theInitialReadSize= theTotalCurrAI_Len - AttrInfo::SectionSizeInfoLength;
theStatus= NdbOperation::UseNdbRecord;
m_attribute_record= result_record;
@@ -1123,8 +1124,8 @@ NdbScanOperation::fix_receivers(Uint32 p
for (Uint32 i = m_allocated_receivers; i < parallel; i ++) {
tScanRec = theNdb->getNdbScanRec();
if (tScanRec == NULL) {
- setErrorCodeAbort(4000);
- return -1;
+ setErrorCodeAbort(4000);
+ return -1;
}//if
m_receivers[i] = tScanRec;
tScanRec->init(NdbReceiver::NDB_SCANRECEIVER, false, this);
@@ -1185,8 +1186,8 @@ NdbScanOperation::receiver_completed(Ndb
* int getFirstATTRINFOScan( U_int32 aData )
*
* Return Value: Return 0: Successful
- * Return -1: All other cases
- * Parameters: None: Only allocate the first signal.
+ * Return -1: All other cases
+ * Parameters: None: Only allocate the first signal.
* Remark: When a scan is defined we need to use this method instead
* of insertATTRINFO for the first signal.
* This is because we need not to mess up the code in
@@ -1204,7 +1205,7 @@ NdbScanOperation::getFirstATTRINFOScan()
return -1;
}
tSignal->setSignal(m_attrInfoGSN);
- /* The offset 8 is for 3 words of header + 5 words of section sizes. */
+
theAI_LenInCurrAI = AttrInfo::HeaderLength + AttrInfo::SectionSizeInfoLength;
theATTRINFOptr = &tSignal->getDataPtrSend()[8];
theFirstATTRINFO = tSignal;
@@ -1243,7 +1244,7 @@ NdbScanOperation::executeCursor(int node
return 0;
} else {
if (!(tp->get_node_stopping(nodeId) &&
- (tp->getNodeSequence(nodeId) == seq))){
+ (tp->getNodeSequence(nodeId) == seq))){
TRACE_DEBUG("The node is hard dead when attempting to start a scan");
setErrorCode(4029);
tCon->theReleaseOnClose = true;
@@ -1500,14 +1501,14 @@ NdbScanOperation::send_next_scan(Uint32
NdbReceiver * tRec = m_api_receivers[i];
if((prep_array[sent] = tRec->m_tcPtrI) != RNIL)
{
- m_sent_receivers[last+sent] = tRec;
- tRec->m_list_index = last+sent;
- tRec->prepareSend();
- sent++;
+ m_sent_receivers[last+sent] = tRec;
+ tRec->m_list_index = last+sent;
+ tRec->prepareSend();
+ sent++;
}
}
memmove(m_api_receivers, m_api_receivers+cnt,
- (theParallelism-cnt) * sizeof(char*));
+ (theParallelism-cnt) * sizeof(char*));
int ret = 0;
if(sent)
@@ -1515,14 +1516,14 @@ NdbScanOperation::send_next_scan(Uint32
Uint32 nodeId = theNdbCon->theDBnode;
TransporterFacade * tp = theNdb->theImpl->m_transporter_facade;
if(cnt > 21){
- tSignal.setLength(4);
- LinearSectionPtr ptr[3];
- ptr[0].p = prep_array;
- ptr[0].sz = sent;
- ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
+ tSignal.setLength(4);
+ LinearSectionPtr ptr[3];
+ ptr[0].p = prep_array;
+ ptr[0].sz = sent;
+ ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
} else {
- tSignal.setLength(4+sent);
- ret = tp->sendSignal(&tSignal, nodeId);
+ tSignal.setLength(4+sent);
+ ret = tp->sendSignal(&tSignal, nodeId);
}
}
m_sent_receivers_count = last + sent;
@@ -1558,13 +1559,13 @@ void NdbScanOperation::close(bool forceS
if(m_transConnection){
if(DEBUG_NEXT_RESULT)
ndbout_c("close() theError.code = %d "
- "m_api_receivers_count = %d "
- "m_conf_receivers_count = %d "
- "m_sent_receivers_count = %d",
- theError.code,
- m_api_receivers_count,
- m_conf_receivers_count,
- m_sent_receivers_count);
+ "m_api_receivers_count = %d "
+ "m_conf_receivers_count = %d "
+ "m_sent_receivers_count = %d",
+ theError.code,
+ m_api_receivers_count,
+ m_conf_receivers_count,
+ m_sent_receivers_count);
TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
/*
@@ -1594,14 +1595,14 @@ void NdbScanOperation::close(bool forceS
* Not executed yet
*/
ret =
- tTransCon->releaseScanOperation(&tTransCon->m_theFirstScanOperation,
- &tTransCon->m_theLastScanOperation,
- tOp);
+ tTransCon->releaseScanOperation(&tTransCon->m_theFirstScanOperation,
+ &tTransCon->m_theLastScanOperation,
+ tOp);
}
else
{
ret = tTransCon->releaseScanOperation(&tTransCon->m_firstExecutedScanOp,
- 0, tOp);
+ 0, tOp);
}
assert(ret);
}
@@ -1732,12 +1733,12 @@ int prepareSendScan(Uint32 aTC_ConnectPt
Return Value: Return 0 : preparation of send was succesful.
Return -1: In all other case.
Parameters: aTC_ConnectPtr: the Connect pointer to TC.
- aTransactionId: the Transaction identity of the transaction.
+ aTransactionId: the Transaction identity of the transaction.
Remark: Puts the the final data into ATTRINFO signal(s) after this
we know the how many signal to send and their sizes
***************************************************************************/
int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr,
- Uint64 aTransactionId){
+ Uint64 aTransactionId){
if (theInterpretIndicator != 1 ||
(theOperationType != OpenScanRequest &&
theOperationType != OpenRangeScanRequest)) {
@@ -1931,8 +1932,8 @@ NdbScanOperation::doSendScan(int aProces
keyInfo->transId[1] = Uint32(transId >> 32);
if (tp->sendSignal(tSignal,aProcessorId) == -1){
- setErrorCode(4002);
- return -1;
+ setErrorCode(4002);
+ return -1;
}
tSignalCount++;
@@ -2001,7 +2002,7 @@ NdbScanOperation::getKeyFromKEYINFO20(Ui
* Remark: Take over the scanning transactions NdbOperation
* object for a tuple to an update transaction,
* which is the last operation read in nextScanResult()
- * (theNdbCon->thePreviousScanRec)
+ * (theNdbCon->thePreviousScanRec)
*
* FUTURE IMPLEMENTATION: (This note was moved from header file.)
* In the future, it will even be possible to transfer
@@ -2279,7 +2280,7 @@ NdbScanOperation::getBlobHandle(const ch
m_keyInfo= 1;
return NdbOperation::getBlobHandle(m_transConnection,
- m_currentTable->getColumn(anAttrName));
+ m_currentTable->getColumn(anAttrName));
}
NdbBlob*
@@ -2294,7 +2295,7 @@ NdbScanOperation::getBlobHandle(Uint32 a
m_keyInfo= 1;
return NdbOperation::getBlobHandle(m_transConnection,
- m_currentTable->getColumn(anAttrId));
+ m_currentTable->getColumn(anAttrId));
}
NdbRecAttr*
@@ -2383,6 +2384,9 @@ NdbIndexScanOperation::initScanBoundStor
oldApiBoundDefined=false;
lowBound.highestKey= 0;
lowBound.highestSoFarIsStrict= false;
+ /* Need to modify old Api scan bound handling code
+ * if max attributes in key becomes > 32
+ */
assert(NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY == 32);
lowBound.keysPresentBitmap= 0;
@@ -2391,28 +2395,28 @@ NdbIndexScanOperation::initScanBoundStor
int
NdbIndexScanOperation::setBound(const char* anAttrName, int type,
- const void* aValue)
+ const void* aValue)
{
return setBound(m_accessTable->getColumn(anAttrName), type, aValue);
}
int
NdbIndexScanOperation::setBound(Uint32 anAttrId, int type,
- const void* aValue)
+ const void* aValue)
{
return setBound(m_accessTable->getColumn(anAttrId), type, aValue);
}
int
NdbIndexScanOperation::equal_impl(const NdbColumnImpl* anAttrObject,
- const char* aValue)
+ const char* aValue)
{
return setBound(anAttrObject, BoundEQ, aValue);
}
NdbRecAttr*
NdbIndexScanOperation::getValue_impl(const NdbColumnImpl* attrInfo,
- char* aValue){
+ char* aValue){
/* Defer to ScanOperation implementation */
// TODO : IndexScans always fetch PK columns via their key NdbRecord
// If the user also requests them, we should avoid fetching them
@@ -2477,6 +2481,16 @@ NdbIndexScanOperation::setBoundHelperOld
boundInfo.highestKey= (index_attrId + 1);
boundInfo.highestSoFarIsStrict= !inclusive;
}
+ else
+ {
+ /* Not highest, key, better not be strict */
+ if (!inclusive)
+ {
+ /* Invalid set of range scan bounds */
+ setErrorCodeAbort(4259);
+ return -1;
+ }
+ }
/* Copy data into correct part of RecAttr */
assert(byteOffset + valueLen <= maxKeyRecordBytes);
@@ -2500,7 +2514,7 @@ NdbIndexScanOperation::setBoundHelperOld
*/
int
NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
- int type, const void* aValue)
+ int type, const void* aValue)
{
if (!tAttrInfo)
{
@@ -2610,9 +2624,7 @@ NdbIndexScanOperation::buildIndexBoundOl
* Check that a contiguous set of keys are supplied.
* Setup low part of IndexBound
*/
- Uint32 expectedValue=
- ( (!(lowBound.highestKey >>5)) // 0 for < 32, 1 for 32
- << lowBound.highestKey) -1; // Set all lsbs
+ Uint32 expectedValue= (~(Uint32) 0) >> (32 - lowBound.highestKey);
if (lowBound.keysPresentBitmap != expectedValue)
{
@@ -2637,9 +2649,7 @@ NdbIndexScanOperation::buildIndexBoundOl
/* Have a high bound
* Check that a contiguous set of keys are supplied.
*/
- Uint32 expectedValue=
- ( (!(highBound.highestKey >>5)) // 0 for < 32, 1 for 32
- << highBound.highestKey) -1; // Set all lsbs
+ Uint32 expectedValue= (~(Uint32) 0) >> (32 - highBound.highestKey);
if (highBound.keysPresentBitmap != expectedValue)
{
@@ -2681,6 +2691,9 @@ NdbIndexScanOperation::releaseIndexBound
highBound.keyRecAttr= NULL;
}
+ /* Re-initialise scan bound storage for the next
+ * use of this NdbIndexScanOperation object
+ */
initScanBoundStorageOldApi();
}
@@ -2705,14 +2718,14 @@ NdbIndexScanOperation::insertBOUNDS(Uint
tCurr->setLength(KeyInfo::MaxSignalLength);
NdbApiSignal* tSignal = tCurr->next();
if(tSignal)
- ;
+ ;
else if((tSignal = theNdb->getSignal()) != 0)
{
/* Link new signal into train and set type */
- tCurr->next(tSignal);
- tSignal->setSignal(GSN_KEYINFO);
+ tCurr->next(tSignal);
+ tSignal->setSignal(GSN_KEYINFO);
} else {
- goto error;
+ goto error;
}
theLastKEYINFO = tSignal;
theKEYINFOptr = dst = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
@@ -2818,9 +2831,9 @@ NdbIndexScanOperation::ndbrecord_insert_
*/
int
NdbIndexScanOperation::readTuples(LockMode lm,
- Uint32 scan_flags,
- Uint32 parallel,
- Uint32 batch)
+ Uint32 scan_flags,
+ Uint32 parallel,
+ Uint32 batch)
{
/* Defer to Scan Operation's readTuples */
int res= NdbScanOperation::readTuples(lm, scan_flags, parallel, batch);
@@ -2965,7 +2978,18 @@ NdbIndexScanOperation::compare_ndbrecord
return 0;
}
-/* NdbRecord version of next_result_ordered. */
+/* This function performs the merge sort of the parallel ordered index scans
+ * to produce a single sorted stream of rows to the application.
+ *
+ * To ensure the correct ordering, before a row can be returned, the function
+ * must ensure that all fragments have either returned at least one row, or
+ * indicated that they have no more rows to return.
+ *
+ * The function maintains an array of receivers, one per fragment, sorted by
+ * the relative ordering of their next rows. Each time a row is taken from
+ * the 'top' receiver, it is re-inserted in the ordered list of receivers
+ * which requires O(log2(NumReceivers)) comparisons.
+ */
int
NdbIndexScanOperation::next_result_ordered_ndbrecord(const char * & out_row,
bool fetchAllowed,
@@ -3226,15 +3250,15 @@ NdbScanOperation::close_impl(Transporter
* Ordered scan, keep the m_api_receivers "to the right"
*/
memmove(m_api_receivers, m_api_receivers+m_current_api_receiver,
- (theParallelism - m_current_api_receiver) * sizeof(char*));
+ (theParallelism - m_current_api_receiver) * sizeof(char*));
api = (theParallelism - m_current_api_receiver);
m_api_receivers_count = api;
}
if(DEBUG_NEXT_RESULT)
ndbout_c("close_impl: [order api conf sent curr parr] %d %d %d %d %d %d",
- m_ordered, api, conf,
- m_sent_receivers_count, m_current_api_receiver, theParallelism);
+ m_ordered, api, conf,
+ m_sent_receivers_count, m_current_api_receiver, theParallelism);
if(api+conf)
{
diff -Nrup a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c
--- a/storage/ndb/src/ndbapi/ndberror.c 2008-01-31 14:11:31 +00:00
+++ b/storage/ndb/src/ndbapi/ndberror.c 2008-02-07 14:59:06 +00:00
@@ -567,7 +567,7 @@ ErrorBundle ErrorCodes[] = {
{ 4520, DMEC, AE, "Call to undefined subroutine" },
{ 4521, DMEC, AE, "Call to undefined subroutine, internal error" },
{ 4522, DMEC, AE, "setBound() called twice for same key" },
- { 4523, DMEC, AE, "No instructions in Interpreted Program" },
+ // 4523 available
{ 4524, DMEC, AE, "NdbInterpretedCode is for different table" },
{ 4535, DMEC, AE, "Attempt to set bound on non key column" },
{ 4536, DMEC, AE, "NdbScanFilter constructor taking NdbOperation is not supported for NdbRecord" },
diff -Nrup a/storage/ndb/test/ndbapi/testIndexStat.cpp b/storage/ndb/test/ndbapi/testIndexStat.cpp
--- a/storage/ndb/test/ndbapi/testIndexStat.cpp 2008-01-25 13:39:27 +00:00
+++ b/storage/ndb/test/ndbapi/testIndexStat.cpp 2008-02-07 14:59:06 +00:00
@@ -108,14 +108,24 @@ static const NdbDictionary::Index* g_ind
static const NdbRecord* g_tab_rec = 0;
static const NdbRecord* g_ind_rec = 0;
-/* Nasty consts for NdbRecord Api offsets */
-static const Uint32 g_ndbrec_a_offset=4;
-static const Uint32 g_ndbrec_b_offset=8;
-static const Uint32 g_ndbrec_c_offset=12;
+
+struct my_record
+{
+ Uint32 m_null_bm;
+ Uint32 m_a;
+ Uint16 m_b;
+ char m_c[1+g_charlen];
+ Uint32 m_d;
+};
+
+
+static const Uint32 g_ndbrec_a_offset=offsetof(my_record, m_a);
+static const Uint32 g_ndbrec_b_offset=offsetof(my_record, m_b);
+static const Uint32 g_ndbrec_c_offset=offsetof(my_record, m_c);
static const Uint32 g_ndbrec_c_nb_offset=2;
-static const Uint32 g_ndbrec_d_offset=24;
+static const Uint32 g_ndbrec_d_offset=offsetof(my_record, m_d);
static const Uint32 g_ndbrec_d_nb_offset=3;
-static const Uint32 g_ndbrecord_bytes=28;
+static const Uint32 g_ndbrecord_bytes=sizeof(my_record);
static NdbIndexStat* g_stat = 0;
@@ -1108,7 +1118,7 @@ initialiseIndexBound(const Range& range,
}
for (j = 0; j <= 1; j++) {
/* Get ptr to key storage space for this bound */
- char* keyBuf= const_cast<char *>( (j==0) ? ib.low_key : ib.high_key);
+ my_record* keyBuf= (my_record *)( (j==0) ? ib.low_key : ib.high_key);
int t = type[j];
if (t == -1)
continue;
@@ -1122,29 +1132,26 @@ initialiseIndexBound(const Range& range,
const Val& val = bnd[j].val;
if (no == 0)
// b, not nullable
- memcpy(&keyBuf[g_ndbrec_b_offset],
- (const void*)&val.b,
- 2);
+ keyBuf->m_b= val.b;
else if (no == 1)
{
// c, nullable
if (! val.c_null)
- memcpy(&keyBuf[g_ndbrec_c_offset],
+ memcpy(&keyBuf->m_c[0],
(const void*)&val.c,
1+ g_charlen);
// Set null bit
- keyBuf[0] |= ((val.c_null?1:0) << g_ndbrec_c_nb_offset);
+ keyBuf->m_null_bm |= ((val.c_null?1:0) << g_ndbrec_c_nb_offset);
}
else if (no == 2)
{
// d, nullable
if (! val.d_null)
- memcpy(&keyBuf[g_ndbrec_d_offset],
- (const void*)&val.d,
- 4);
+ keyBuf->m_d= val.d;
+
// Set null bit
- keyBuf[0] |= ((val.d_null?1:0) << g_ndbrec_d_nb_offset);
+ keyBuf->m_null_bm |= ((val.d_null?1:0) << g_ndbrec_d_nb_offset);
}
else
assert(false);
diff -Nrup a/storage/ndb/test/ndbapi/testScanFilter.cpp b/storage/ndb/test/ndbapi/testScanFilter.cpp
--- a/storage/ndb/test/ndbapi/testScanFilter.cpp 2008-01-14 12:55:49 +00:00
+++ b/storage/ndb/test/ndbapi/testScanFilter.cpp 2008-02-07 14:59:06 +00:00
@@ -837,7 +837,7 @@ int runScanRandomFilterTest(NDBT_Context
int runMaxScanFilterSize(NDBT_Context* ctx, NDBT_Step* step)
{
- /* This TC uses the ScanFilter methods to build a large
+ /* This testcase uses the ScanFilter methods to build a large
* scanFilter, checking that ScanFilter building fails
* at the expected point, with the correct error message
*/
| Thread |
|---|
| • bk commit into 5.1 tree (frazer:1.2644) | Frazer Clement | 7 Feb |