MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Frazer Clement Date:February 7 2008 2:59pm
Subject:bk commit into 5.1 tree (frazer:1.2644)
View as plain text  
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 Clement7 Feb