List:Commits« Previous MessageNext Message »
From:knielsen Date:May 29 2007 11:47am
Subject:bk commit into 5.1 tree (knielsen:1.2509)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of knielsen. When knielsen 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, 2007-05-29 13:46:57+02:00, knielsen@ymer.(none) +10 -0
  WL#2223: NdbRecord.
  NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

  storage/ndb/include/Makefile.am@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +2 -1
    NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

  storage/ndb/include/kernel/Interpreter.hpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +6 -0
    Add missing implementation.

  storage/ndb/include/ndbapi/NdbInterpretedCode.hpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +165 -0
    New BitKeeper file ``storage/ndb/include/ndbapi/NdbInterpretedCode.hpp''

  storage/ndb/include/ndbapi/NdbInterpretedCode.hpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +0 -0

  storage/ndb/include/ndbapi/NdbOperation.hpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +3 -0
    NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

  storage/ndb/include/ndbapi/NdbTransaction.hpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +9 -2
    NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

  storage/ndb/src/ndbapi/Makefile.am@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +2 -1
    NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

  storage/ndb/src/ndbapi/NdbInterpretedCode.cpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +286 -0
    New BitKeeper file ``storage/ndb/src/ndbapi/NdbInterpretedCode.cpp''

  storage/ndb/src/ndbapi/NdbInterpretedCode.cpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +0 -0

  storage/ndb/src/ndbapi/NdbOperation.cpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +1 -0
    NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

  storage/ndb/src/ndbapi/NdbOperationExec.cpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +41 -1
    NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

  storage/ndb/src/ndbapi/NdbTransaction.cpp@stripped, 2007-05-29 13:46:54+02:00, knielsen@ymer.(none) +18 -3
    NdbRecord interpreted update, preliminary version for Nokia conflict resolution.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	knielsen
# Host:	ymer.(none)
# Root:	/usr/local/mysql/mysql-5.1-telco-ndbrecord
--- New file ---
+++ storage/ndb/include/ndbapi/NdbInterpretedCode.hpp	07/05/29 13:46:54
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef NdbInterpretedCode_H
#define NdbInterpretedCode_H

#include <ndb_global.h>
#include <ndb_types.h>
#include "NdbDictionary.hpp"

class NdbTableImpl;
class NdbColumnImpl;


#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/*
  @brief Stand-alone interpreted programs, for use with NdbRecord

  @details This class is used to prepare an NDB interpreted program for use
  in operations created using NdbRecord.

  The caller supplies the memory buffer to be used for the operations. If
  this is too small, an error will be returned when attempting to add
  instructions. The caller must deallocate the buffer if necessary after
  the InterpretedCode object is destroyed.

  Methods have minimal error checks, for efficiency.

  Note that this is currently considered an internal interface, and subject
  to change without notice.

  ToDo: We should add placeholders to this, so that one can use a single
  InterpretedCode object to create many operations from different embedded
  constants. Once we do this, we could add more error checks, as the cost
  would then not be paid for each operation creation.

*/
class NdbInterpretedCode
{
private:
  friend class NdbOperation;

  static const Uint32 MaxReg= 8;
  Uint32 *m_buffer;
  const Uint32 m_buffer_length;               // In words
  const Uint32 m_number_of_labels;
  /* Number of words used for instructions. */
  Uint32 m_instructions_length;
  /*
    Number of words left in buffer.
    This can be smaller than m_buffer_length-m_instructions_length, as
    the end of the buffer is used to store jump and label addresses for
    back-patching jumps.
  */
  Uint32 m_available_length;
  Uint32 m_number_of_jumps;
  enum Flags {
    /*
      We will set m_got_error if an error occurs, so that we can
      refuse to create an operation from InterpretedCode that the user
      forgot to do error checks on.
    */
    GotError= 0x1,
    /* Set if reading disk column. */
    UsesDisk= 0x2
  };
  Uint32 m_flags;

  int error()
  {
    m_flags|= GotError;
    return -1;
  }

  int add1(Uint32 x1)
  {
    if (unlikely(m_available_length < 1))
      return error();
    Uint32 current = m_instructions_length;
    m_buffer[current    ] = x1;
    m_instructions_length = current + 1;
    m_available_length--;
    return 0;
  }

  int add2(Uint32 x1, Uint32 x2)
  {
    if (unlikely(m_available_length < 2))
      return error();
    Uint32 current = m_instructions_length;
    m_buffer[current    ] = x1;
    m_buffer[current + 1] = x2;
    m_instructions_length = current + 2;
    m_available_length -= 2;
    return 0;
  }

  int add3(Uint32 x1, Uint32 x2, Uint32 x3)
  {
    if (unlikely(m_available_length < 3))
      return error();
    Uint32 current = m_instructions_length;
    m_buffer[current    ] = x1;
    m_buffer[current + 1] = x2;
    m_buffer[current + 2] = x3;
    m_instructions_length = current + 3;
    m_available_length -= 3;
    return 0;
  }

  int add_branch(Uint32 instruction, Uint32 Label);
  int read_attr_impl(const NdbColumnImpl *c, Uint32 RegDest);
  int write_attr_impl(const NdbColumnImpl *c, Uint32 RegSource);
public:
  NdbInterpretedCode(Uint32 *buffer, Uint32 buffer_word_size,
                     Uint32 num_labels);
  int def_label(int tLabelNo);
  int add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest);
  int sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest);
  int load_const_u32(Uint32 RegDest, Uint32 Constant);
  int load_const_u64(Uint32 RegDest, Uint64 Constant);
  int load_const_null(Uint32 RegDest);
  int read_attr(const NdbDictionary::Table *table, Uint32 attrId,
                Uint32 RegDest);
  int read_attr(const NdbDictionary::Column *column, Uint32 RegDest);
  int write_attr(const NdbDictionary::Table *table, Uint32 attrId,
                 Uint32 RegSource);
  int write_attr(const NdbDictionary::Column *column, Uint32 RegSource);


  int branch_ge(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label);
  int branch_gt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label);
  int branch_le(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label);
  int branch_lt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label);
  int branch_eq(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label);
  int branch_ne(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label);
  int branch_ne_null(Uint32 RegLvalue, Uint32 Label);
  int branch_eq_null(Uint32 RegLvalue, Uint32 Label);
  int branch_label(Uint32 Label);
  int interpret_exit_ok();
  int interpret_exit_nok(Uint32 ErrorCode);
  int interpret_exit_nok();
  int interpret_exit_last_row();
  /*
    This must be called after all instructions have been defined, but
    before using the NdbInterpretedCode object, to resolve label adresses
    for all jumps.
  */
  int backpatch();
};
#endif

#endif

--- New file ---
+++ storage/ndb/src/ndbapi/NdbInterpretedCode.cpp	07/05/29 13:46:54
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include "NdbInterpretedCode.hpp"
#include "Interpreter.hpp"
#include "NdbDictionaryImpl.hpp"


int NdbInterpretedCode::add_branch(Uint32 instruction, Uint32 Label)
{
  /* NOTE: subroutines not supported yet. */
  /* Store the jump location for backpatching. */
  if (m_available_length < 2 ||
      m_instructions_length > 0xffff ||
      Label > 0xffff)
    return error();
  m_number_of_jumps++;
  m_available_length--;
  Uint32 pos= m_buffer_length - (m_number_of_labels + m_number_of_jumps);
  m_buffer[pos]= m_instructions_length | (Label << 16);
  return add1(instruction);
}

NdbInterpretedCode::NdbInterpretedCode(Uint32 *buffer, Uint32 buffer_word_size,
                                       Uint32 num_labels) :
  m_buffer(buffer),
  m_buffer_length(buffer_word_size),
  m_number_of_labels(num_labels),
  m_instructions_length(0),
  m_available_length(m_buffer_length),
  m_number_of_jumps(0),
  m_flags(0)
{
  Uint32 i;
  /*
    At the end of the buffer we store the address of all labels as they are
    defined, so that we can back-patch forward jumps later.
    If the supplied buffer is too small, we cannot fail in the constructor,
    but all attempts to add instructions will fail due to full buffer.
  */
  for (i = 0; i < num_labels && i < buffer_word_size; i++)
  {
    buffer[buffer_word_size - (i + 1)] = ~(Uint32)0;
    m_available_length--;
  }
}

int
NdbInterpretedCode::def_label(int tLabelNo)
{
  if (tLabelNo < 0 ||
      (Uint32)tLabelNo >= m_number_of_labels)
    return error();
  Uint32 pos= m_buffer_length - (tLabelNo + 1);
  /* Check label not already defined. */
  if (m_buffer[pos] != ~(Uint32)0)
    return error();
  m_buffer[pos]= m_instructions_length;
  return 0;
}

int
NdbInterpretedCode::add_reg(Uint32 RegSource1, Uint32 RegSource2,
                            Uint32 RegDest)
{
  return add1(Interpreter::Add(RegDest % MaxReg, RegSource1 % MaxReg,
                               RegSource2 % MaxReg));
}

int
NdbInterpretedCode::sub_reg(Uint32 RegSource1, Uint32 RegSource2,
                            Uint32 RegDest)
{
  return add1(Interpreter::Sub(RegDest % MaxReg, RegSource1 % MaxReg,
                               RegSource2 % MaxReg));
}

int
NdbInterpretedCode::load_const_u32(Uint32 RegDest, Uint32 Constant)
{
  return add2(Interpreter::LoadConst32(RegDest % MaxReg), Constant);
}

int
NdbInterpretedCode::load_const_u64(Uint32 RegDest, Uint64 Constant)
{
  const Uint32* p= (const Uint32 *)(&Constant);
  return add3(Interpreter::LoadConst64(RegDest % MaxReg), p[0], p[1]);
}

int
NdbInterpretedCode::load_const_null(Uint32 RegDest)
{
  return add1(Interpreter::LoadNull(RegDest % MaxReg));
}

int
NdbInterpretedCode::read_attr_impl(const NdbColumnImpl *c, Uint32 RegDest)
{
  if (c->m_storageType == NDB_STORAGETYPE_DISK)
    m_flags|= UsesDisk;
  return add1(Interpreter::Read(c->m_attrId, RegDest % MaxReg));
}

int
NdbInterpretedCode::read_attr(const NdbDictionary::Table *table,
                              Uint32 attrId, Uint32 RegDest)
{
  const NdbTableImpl *t= & NdbTableImpl::getImpl(*table);
  const NdbColumnImpl *c= t->getColumn(attrId);
  if (unlikely(c == NULL))
    return error();
  return read_attr_impl(c, RegDest);
}

int
NdbInterpretedCode::read_attr(const NdbDictionary::Column *column,
                              Uint32 RegDest)
{
  return read_attr_impl(&NdbColumnImpl::getImpl(*column), RegDest);
}

int
NdbInterpretedCode::write_attr_impl(const NdbColumnImpl *c, Uint32 RegSource)
{
  if (c->m_storageType == NDB_STORAGETYPE_DISK)
    m_flags|= UsesDisk;
  return add1(Interpreter::Write(c->m_attrId, RegSource % MaxReg));
}

int
NdbInterpretedCode::write_attr(const NdbDictionary::Table *table,
                               Uint32 attrId, Uint32 RegSource)
{
  const NdbTableImpl *t= & NdbTableImpl::getImpl(*table);
  const NdbColumnImpl *c= t->getColumn(attrId);
  if (unlikely(c == NULL))
    return error();
  return write_attr_impl(c, RegSource);
}

int
NdbInterpretedCode::write_attr(const NdbDictionary::Column *column,
                               Uint32 RegSource)
{
  return write_attr_impl(&NdbColumnImpl::getImpl(*column), RegSource);
}

int
NdbInterpretedCode::branch_ge(Uint32 RegLvalue, Uint32 RegRvalue,
                              Uint32 Label)
{
  Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_GE_REG_REG,
                                     RegLvalue, RegRvalue);
  return add_branch(instr, Label);
}

int
NdbInterpretedCode::branch_gt(Uint32 RegLvalue, Uint32 RegRvalue,
                              Uint32 Label)
{
  Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_GT_REG_REG,
                                     RegLvalue, RegRvalue);
  return add_branch(instr, Label);
}

int
NdbInterpretedCode::branch_le(Uint32 RegLvalue, Uint32 RegRvalue,
                              Uint32 Label)
{
  Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_LE_REG_REG,
                                     RegLvalue, RegRvalue);
  return add_branch(instr, Label);
}

int
NdbInterpretedCode::branch_lt(Uint32 RegLvalue, Uint32 RegRvalue,
                              Uint32 Label)
{
  Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_LT_REG_REG,
                                     RegLvalue, RegRvalue);
  return add_branch(instr, Label);
}

int
NdbInterpretedCode::branch_eq(Uint32 RegLvalue, Uint32 RegRvalue,
                              Uint32 Label)
{
  Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_EQ_REG_REG,
                                     RegLvalue, RegRvalue);
  return add_branch(instr, Label);
}

int
NdbInterpretedCode::branch_ne(Uint32 RegLvalue, Uint32 RegRvalue,
                              Uint32 Label)
{
  Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_NE_REG_REG,
                                     RegLvalue, RegRvalue);
  return add_branch(instr, Label);
}

int
NdbInterpretedCode::branch_ne_null(Uint32 RegLvalue, Uint32 Label)
{
  return add_branch
    (((RegLvalue % MaxReg) << 6) | Interpreter::BRANCH_REG_NE_NULL, Label);
}

int
NdbInterpretedCode::branch_eq_null(Uint32 RegLvalue, Uint32 Label)
{
  return add_branch
    (((RegLvalue % MaxReg) << 6) | Interpreter::BRANCH_REG_EQ_NULL, Label);
}

int
NdbInterpretedCode::branch_label(Uint32 Label)
{
  return add_branch(Interpreter::BRANCH, Label);
}

int
NdbInterpretedCode::interpret_exit_ok()
{
  return add1(Interpreter::EXIT_OK);
}

int
NdbInterpretedCode::interpret_exit_nok(Uint32 ErrorCode)
{
  return add1((ErrorCode << 16) | Interpreter::EXIT_REFUSE);
}

int
NdbInterpretedCode::interpret_exit_nok()
{
  return add1((899 << 16) | Interpreter::EXIT_REFUSE);
}

int
NdbInterpretedCode::interpret_exit_last_row()
{
  return add1(Interpreter::EXIT_OK_LAST);
}

int
NdbInterpretedCode::backpatch()
{
  Uint32 i;
  Uint32 jumplist_end = m_buffer_length - m_number_of_labels;
  Uint32 jumplist_start = jumplist_end - m_number_of_jumps;

  for (i = jumplist_start; i < jumplist_end; i++)
  {
    Uint32 value = m_buffer[i];
    Uint32 instruction_address = value & 0xffff;
    Uint32 label_idx = value >> 16;
    assert(label_idx < m_number_of_labels);
    assert(instruction_address < m_instructions_length);
    Uint32 label_address = m_buffer[m_buffer_length - (label_idx + 1)];
    /* Check for jump to undefined label. */
    if (label_address == ~(Uint32)0)
      return error();
    /* Check if backwards or forwards jump. */
    if (label_address < instruction_address)
      m_buffer[instruction_address] |=
        (((instruction_address - label_address) << 16) | ((Uint32)1 << 31));
    else
      m_buffer[instruction_address] |=
        ((label_address - instruction_address) << 16);
  }
  return 0;
}


--- 1.5/storage/ndb/include/kernel/Interpreter.hpp	2007-05-29 13:47:04 +02:00
+++ 1.6/storage/ndb/include/kernel/Interpreter.hpp	2007-05-29 13:47:04 +02:00
@@ -153,6 +153,12 @@ Interpreter::Write(Uint32 AttrId, Uint32
 
 inline
 Uint32
+Interpreter::LoadNull(Uint32 Register){
+  return (Register << 6) + LOAD_CONST_NULL;
+}
+
+inline
+Uint32
 Interpreter::LoadConst16(Uint32 Register, Uint32 Value){
   return (Value << 16) + (Register << 6) + LOAD_CONST16;
 }

--- 1.65/storage/ndb/include/ndbapi/NdbTransaction.hpp	2007-05-29 13:47:04 +02:00
+++ 1.66/storage/ndb/include/ndbapi/NdbTransaction.hpp	2007-05-29 13:47:04 +02:00
@@ -30,6 +30,7 @@ class NdbIndexOperation;
 class NdbApiSignal;
 class Ndb;
 class NdbBlob;
+class NdbInterpretedCode;
 
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 // to be documented later
@@ -590,7 +591,10 @@ public:
                             const unsigned char *mask= 0);
   NdbOperation *updateTuple(const NdbRecord *key_rec, const char *key_row,
                             const NdbRecord *attr_rec, const char *attr_row,
-                            const unsigned char *mask= 0);
+                            const unsigned char *mask= 0,
+                            const Uint32 *setPartitionId = 0,
+                            const void *getSetValue = 0,
+                            const NdbInterpretedCode *interpreted_code = 0);
   NdbOperation *writeTuple(const NdbRecord *key_rec, const char *key_row,
                            const NdbRecord *attr_rec, const char *attr_row,
                            const unsigned char *mask= 0);
@@ -814,7 +818,10 @@ private:						
                               const char *key_row,
                               const NdbRecord *attribute_record,
                               const char *attribute_row,
-                              const unsigned char *mask);
+                              const unsigned char *mask,
+                              const Uint32 *setPartitionId = 0,
+                              const void *getSetValue = 0,
+                              const NdbInterpretedCode *interpreted_code = 0);
 
   void		handleExecuteCompletion();
   

--- 1.52/storage/ndb/include/ndbapi/NdbOperation.hpp	2007-05-29 13:47:04 +02:00
+++ 1.53/storage/ndb/include/ndbapi/NdbOperation.hpp	2007-05-29 13:47:04 +02:00
@@ -32,6 +32,7 @@ class NdbColumnImpl;
 class NdbBlob;
 class TcKeyReq;
 class NdbRecord;
+class NdbInterpretedCode;
 
 /**
  * @class NdbOperation
@@ -1183,6 +1184,8 @@ protected:
     #include <Bitmask.hpp> in application code.
   */
   Uint32 m_read_mask[(NDB_MAX_ATTRIBUTES_IN_TABLE+31)>>5];
+  /* Interpreted program for NdbRecord operations. */
+  const NdbInterpretedCode *m_interpreted_code;
 
   Uint32 m_any_value;                           // Valid if m_use_any_value!=0
 

--- 1.87/storage/ndb/src/ndbapi/NdbTransaction.cpp	2007-05-29 13:47:04 +02:00
+++ 1.88/storage/ndb/src/ndbapi/NdbTransaction.cpp	2007-05-29 13:47:04 +02:00
@@ -2107,7 +2107,10 @@ NdbTransaction::setupRecordOp(NdbOperati
                               const char *key_row,
                               const NdbRecord *attribute_record,
                               const char *attribute_row,
-                              const unsigned char *mask)
+                              const unsigned char *mask,
+                              const Uint32 *setPartitionId,
+                              const void *getSetValue,
+                              const NdbInterpretedCode *interpreted_code)
 {
   NdbOperation *op;
   /*
@@ -2144,6 +2147,14 @@ NdbTransaction::setupRecordOp(NdbOperati
   op->m_attribute_row= attribute_row;
   attribute_record->copyMask(op->m_read_mask, mask);
 
+  assert(getSetValue == NULL);                  // ToDo
+  if (setPartitionId != NULL)
+  {
+    op->theDistributionKey= *setPartitionId;
+    op->theDistrKeyIndicator_= 1;
+  }
+  op->m_interpreted_code= interpreted_code;
+
   if (unlikely(attribute_record->flags & NdbRecord::RecHasBlob))
   {
     if (op->getBlobHandlesNdbRecord(this) == -1)
@@ -2222,7 +2233,10 @@ NdbTransaction::insertTuple(const NdbRec
 NdbOperation *
 NdbTransaction::updateTuple(const NdbRecord *key_rec, const char *key_row,
                             const NdbRecord *attr_rec, const char *attr_row,
-                            const unsigned char *mask)
+                            const unsigned char *mask,
+                            const Uint32 *setPartitionId,
+                            const void *getSetValue,
+                            const NdbInterpretedCode *interpreted_code)
 {
   /* Check that the NdbRecord specifies the full primary key. */
   if (!(key_rec->flags & NdbRecord::RecIsKeyRecord))
@@ -2233,7 +2247,8 @@ NdbTransaction::updateTuple(const NdbRec
 
   NdbOperation *op= setupRecordOp(NdbOperation::UpdateRequest,
                                   NdbOperation::LM_Exclusive, key_rec, key_row,
-                                  attr_rec, attr_row, mask);
+                                  attr_rec, attr_row, mask, setPartitionId,
+                                  getSetValue, interpreted_code);
   if(!op)
     return op;
 

--- 1.24/storage/ndb/src/ndbapi/NdbOperation.cpp	2007-05-29 13:47:04 +02:00
+++ 1.25/storage/ndb/src/ndbapi/NdbOperation.cpp	2007-05-29 13:47:04 +02:00
@@ -164,6 +164,7 @@ NdbOperation::init(const NdbTableImpl* t
   theBlobList = NULL;
   m_abortOption = -1;
   m_no_disk_flag = 1;
+  m_interpreted_code = NULL;
   m_use_any_value = 0;
 
   tSignal = theNdb->getSignal();

--- 1.39/storage/ndb/src/ndbapi/NdbOperationExec.cpp	2007-05-29 13:47:04 +02:00
+++ 1.40/storage/ndb/src/ndbapi/NdbOperationExec.cpp	2007-05-29 13:47:04 +02:00
@@ -21,6 +21,7 @@
 #include <Ndb.hpp>
 #include <NdbRecAttr.hpp>
 #include "NdbUtil.hpp"
+#include "NdbInterpretedCode.hpp"
 
 #include "Interpreter.hpp"
 #include <AttributeHeader.hpp>
@@ -617,6 +618,8 @@ NdbOperation::prepareSendNdbRecord(Uint3
   Uint32 remain;
   int res;
   Uint32 no_disk_flag;
+  Uint32 interpreted_code_end;
+  Uint32 *update_len_addr;
 
   assert(theStatus==UseNdbRecord);
   /* Not yet support for NdbRecord with interpreted operations. */
@@ -706,6 +709,34 @@ NdbOperation::prepareSendNdbRecord(Uint3
 
   no_disk_flag= m_no_disk_flag;
 
+  /* Handle any interpreted program. */
+  const NdbInterpretedCode *code= m_interpreted_code;
+  if (code)
+  {
+    if (code->m_flags & NdbInterpretedCode::UsesDisk)
+      no_disk_flag = 0;
+    Uint32 sizes[5];
+    sizes[0] = 0;               // Initial read.
+    sizes[1] = code->m_instructions_length;
+    sizes[2] = 0;               // Update size, filled later
+    update_len_addr= attrInfoPtr + 2;
+    sizes[3] = 0;               // Final read size, ToDo
+    sizes[4] = 0;               // Subroutine size, ToDo
+    res = insertATTRINFOData_NdbRecord(aTC_ConnectPtr, aTransId,
+                                       (const char *)sizes,
+                                       sizeof(sizes),
+                                       &attrInfoPtr, &remain);
+    if (res)
+      return res;
+    res = insertATTRINFOData_NdbRecord(aTC_ConnectPtr, aTransId,
+                                       (const char *)(code->m_buffer),
+                                       code->m_instructions_length*4,
+                                       &attrInfoPtr, &remain);
+    if (res)
+      return res;
+    interpreted_code_end= theTotalCurrAI_Len;
+  }
+
   OperationType tOpType= theOperationType;
   if ((tOpType == InsertRequest) || (tOpType == WriteRequest) ||
       (tOpType == UpdateRequest))
@@ -854,6 +885,15 @@ NdbOperation::prepareSendNdbRecord(Uint3
       return res;
   }
 
+  if (code)
+  {
+    /* ToDo: This only handles update currently. */
+    Uint32 update_word_length= theTotalCurrAI_Len - interpreted_code_end;
+    *update_len_addr = update_word_length;
+for (Uint32 i= 0; i < 5; i++) {fprintf(stderr, "%2d %p 0x%08x    %u  %p 0x%08x\n", i, tcKeyReq->attrInfo, tcKeyReq->attrInfo[i], update_word_length, update_len_addr-2, update_len_addr[(int)i - 2]);}
+assert(update_word_length > 0);
+  }
+
   Uint32 signalLength= hdrSize +
     (theTupKeyLen > TcKeyReq::MaxKeyInfo ?
          TcKeyReq::MaxKeyInfo : theTupKeyLen) +
@@ -906,7 +946,7 @@ NdbOperation::fillTcKeyReqHdr(TcKeyReq *
   TcKeyReq::setSimpleFlag(reqInfo, theSimpleIndicator);
   TcKeyReq::setCommitFlag(reqInfo, theCommitIndicator);
   TcKeyReq::setStartFlag(reqInfo, theStartIndicator);
-  TcKeyReq::setInterpretedFlag(reqInfo, theInterpretIndicator);
+  TcKeyReq::setInterpretedFlag(reqInfo, (m_interpreted_code != NULL));
   /* We will setNoDiskFlag() later when we have checked all columns. */
   TcKeyReq::setDirtyFlag(reqInfo, theDirtyIndicator);
   TcKeyReq::setOperationType(reqInfo, theOperationType);

--- 1.20/storage/ndb/src/ndbapi/Makefile.am	2007-05-29 13:47:04 +02:00
+++ 1.21/storage/ndb/src/ndbapi/Makefile.am	2007-05-29 13:47:04 +02:00
@@ -56,7 +56,8 @@ libndbapi_la_SOURCES = \
 	NdbBlob.cpp \
 	NdbIndexStat.cpp \
         SignalSender.cpp \
-        ObjectMap.cpp
+        ObjectMap.cpp \
+	NdbInterpretedCode.cpp
 
 INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
 

--- 1.22/storage/ndb/include/Makefile.am	2007-05-29 13:47:04 +02:00
+++ 1.23/storage/ndb/include/Makefile.am	2007-05-29 13:47:04 +02:00
@@ -41,7 +41,8 @@ ndbapi/NdbScanFilter.hpp \
 ndbapi/NdbScanOperation.hpp \
 ndbapi/NdbIndexScanOperation.hpp \
 ndbapi/NdbIndexStat.hpp \
-ndbapi/ndberror.h
+ndbapi/ndberror.h \
+ndbapi/NdbInterpretedCode.hpp
 
 mgmapiinclude_HEADERS = \
 mgmapi/mgmapi.h \
Thread
bk commit into 5.1 tree (knielsen:1.2509)knielsen29 May