1910 lines
60 KiB
C++
1910 lines
60 KiB
C++
/*
|
|
Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License, version 2.0,
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is also distributed with certain software (including
|
|
but not limited to OpenSSL) that is licensed under separate terms,
|
|
as designated in a particular file or component or in included license
|
|
documentation. The authors of MySQL hereby grant you an additional
|
|
permission to link the program and your derivative works with the
|
|
separately licensed software that they have included with MySQL.
|
|
|
|
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, version 2.0, 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#ifndef NdbOperation_H
|
|
#define NdbOperation_H
|
|
|
|
#include <ndb_types.h>
|
|
#include "ndbapi_limits.h"
|
|
#include "NdbError.hpp"
|
|
#include "NdbReceiver.hpp"
|
|
#include "NdbDictionary.hpp"
|
|
#include "Ndb.hpp"
|
|
|
|
class Ndb;
|
|
class NdbApiSignal;
|
|
class NdbRecAttr;
|
|
class NdbOperation;
|
|
class NdbTransaction;
|
|
class NdbColumnImpl;
|
|
class NdbBlob;
|
|
class TcKeyReq;
|
|
class NdbRecord;
|
|
class NdbInterpretedCode;
|
|
struct GenericSectionPtr;
|
|
class NdbLockHandle;
|
|
|
|
/**
|
|
* @class NdbOperation
|
|
* @brief Class of operations for use in transactions.
|
|
*/
|
|
class NdbOperation
|
|
{
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
friend class Ndb;
|
|
friend class NdbImpl;
|
|
friend class NdbTransaction;
|
|
friend class NdbScanOperation;
|
|
friend class NdbScanReceiver;
|
|
friend class NdbScanFilter;
|
|
friend class NdbScanFilterImpl;
|
|
friend class NdbReceiver;
|
|
friend class NdbBlob;
|
|
#endif
|
|
|
|
public:
|
|
/**
|
|
* @name Define Standard Operation Type
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Different access types (supported by sub-classes of NdbOperation)
|
|
*/
|
|
|
|
enum Type {
|
|
PrimaryKeyAccess ///< Read, insert, update, or delete using pk
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
= 0 // NdbOperation
|
|
#endif
|
|
,UniqueIndexAccess ///< Read, update, or delete using unique index
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
= 1 // NdbIndexOperation
|
|
#endif
|
|
,TableScan ///< Full table scan
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
= 2 // NdbScanOperation
|
|
#endif
|
|
,OrderedIndexScan ///< Ordered index scan
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
= 3 // NdbIndexScanOperation
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* Lock when performing read
|
|
*/
|
|
|
|
enum LockMode {
|
|
LM_Read ///< Read with shared lock
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
= 0
|
|
#endif
|
|
,LM_Exclusive ///< Read with exclusive lock
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
= 1
|
|
#endif
|
|
,LM_CommittedRead ///< Ignore locks, read last committed value
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
= 2,
|
|
LM_Dirty = 2,
|
|
#endif
|
|
LM_SimpleRead = 3 ///< Read with shared lock, but release lock directly
|
|
};
|
|
|
|
/**
|
|
* How should transaction be handled if operation fails.
|
|
*
|
|
* If AO_IgnoreError, a failure in one operation will not abort the
|
|
* transaction, and NdbTransaction::execute() will return 0 (success). Use
|
|
* NdbOperation::getNdbError() to check for errors from individual
|
|
* operations.
|
|
*
|
|
* If AbortOnError, a failure in one operation will abort the transaction
|
|
* and cause NdbTransaction::execute() to return -1.
|
|
*
|
|
* Abort option can be set on execute(), or in the individual operation.
|
|
* Setting AO_IgnoreError or AbortOnError in execute() overrides the settings
|
|
* on individual operations. Setting DefaultAbortOption in execute() (the
|
|
* default) causes individual operation settings to be used.
|
|
*
|
|
* For READ, default is AO_IgnoreError
|
|
* DML, default is AbortOnError
|
|
* CommittedRead does _only_ support AO_IgnoreError
|
|
*/
|
|
enum AbortOption {
|
|
DefaultAbortOption = -1,///< Use default as specified by op-type
|
|
AbortOnError = 0, ///< Abort transaction on failed operation
|
|
AO_IgnoreError = 2 ///< Transaction continues on failed operation
|
|
};
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type insertTuple.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* adds a new tuple to the table.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int insertTuple();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type updateTuple.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* updates a tuple in the table.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int updateTuple();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type writeTuple.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* writes a tuple to the table.
|
|
* If the tuple exists, it updates it, otherwise an insert takes place.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int writeTuple();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type deleteTuple.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* delete a tuple.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int deleteTuple();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type readTuple.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* reads a tuple.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int readTuple(LockMode);
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type readTuple.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* reads a tuple.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int readTuple();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type
|
|
* readTupleExclusive.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* read a tuple using an exclusive lock.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int readTupleExclusive();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type
|
|
* simpleRead.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* reads an existing tuple (using shared read lock),
|
|
* but releases lock immediately after read.
|
|
*
|
|
* @note Using this operation twice in the same transaction
|
|
* may produce different results (e.g. if there is another
|
|
* transaction which updates the value between the
|
|
* simple reads).
|
|
*
|
|
* Note that simpleRead can read the value from any database node while
|
|
* standard read always read the value on the database node which is
|
|
* primary for the record.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int simpleRead();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type committedRead.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* read latest committed value of the record.
|
|
*
|
|
* This means that if another transaction is updating the
|
|
* record, then the current transaction will not wait.
|
|
* It will instead use the latest committed value of the
|
|
* record.
|
|
* dirtyRead is a deprecated name for committedRead
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
* @deprecated
|
|
*/
|
|
virtual int dirtyRead();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type committedRead.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* read latest committed value of the record.
|
|
*
|
|
* This means that if another transaction is updating the
|
|
* record, then the current transaction will not wait.
|
|
* It will instead use the latest committed value of the
|
|
* record.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int committedRead();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type dirtyUpdate.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* updates without two-phase commit.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int dirtyUpdate();
|
|
|
|
/**
|
|
* Define the NdbOperation to be a standard operation of type dirtyWrite.
|
|
* When calling NdbTransaction::execute, this operation
|
|
* writes without two-phase commit.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int dirtyWrite();
|
|
#endif
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
/** @} *********************************************************************/
|
|
/**
|
|
* @name Define Interpreted Program Operation Type
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Update a tuple using an interpreted program.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int interpretedUpdateTuple();
|
|
|
|
/**
|
|
* Delete a tuple using an interpreted program.
|
|
*
|
|
* @return 0 if successful otherwise -1.
|
|
*/
|
|
virtual int interpretedDeleteTuple();
|
|
#endif
|
|
|
|
/** @} *********************************************************************/
|
|
|
|
/**
|
|
* @name Specify Search Conditions
|
|
* @{
|
|
*/
|
|
/**
|
|
* Define a search condition with equality.
|
|
* The condition is true if the attribute has the given value.
|
|
* To set search conditions on multiple attributes,
|
|
* use several equals (then all of them must be satisfied for the
|
|
* tuple to be selected).
|
|
*
|
|
* @note For insertTuple() it is also allowed to define the
|
|
* search key by using setValue().
|
|
*
|
|
* @note There are 10 versions of equal() with
|
|
* slightly different parameters.
|
|
*
|
|
* @note If attribute has fixed size, value must include all bytes.
|
|
* In particular a Char must be native-blank padded.
|
|
* If attribute has variable size, value must start with
|
|
* 1 or 2 little-endian length bytes (2 if Long*).
|
|
*
|
|
* @param anAttrName Attribute name
|
|
* @param aValue Attribute value.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
|
int equal(const char* anAttrName, const char* aValue, Uint32 len);
|
|
#endif
|
|
int equal(const char* anAttrName, const char* aValue);
|
|
int equal(const char* anAttrName, Int32 aValue);
|
|
int equal(const char* anAttrName, Uint32 aValue);
|
|
int equal(const char* anAttrName, Int64 aValue);
|
|
int equal(const char* anAttrName, Uint64 aValue);
|
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
|
int equal(Uint32 anAttrId, const char* aValue, Uint32 len);
|
|
#endif
|
|
int equal(Uint32 anAttrId, const char* aValue);
|
|
int equal(Uint32 anAttrId, Int32 aValue);
|
|
int equal(Uint32 anAttrId, Uint32 aValue);
|
|
int equal(Uint32 anAttrId, Int64 aValue);
|
|
int equal(Uint32 anAttrId, Uint64 aValue);
|
|
|
|
/** @} *********************************************************************/
|
|
/**
|
|
* @name Specify Attribute Actions for Operations
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Defines a retrieval operation of an attribute value.
|
|
* The NDB API allocate memory for the NdbRecAttr object that
|
|
* will hold the returned attribute value.
|
|
*
|
|
* @note Note that it is the applications responsibility
|
|
* to allocate enough memory for aValue (if non-NULL).
|
|
* The buffer aValue supplied by the application must be
|
|
* aligned appropriately. The buffer is used directly
|
|
* (avoiding a copy penalty) only if it is aligned on a
|
|
* 4-byte boundary and the attribute size in bytes
|
|
* (i.e. NdbRecAttr::attrSize times NdbRecAttr::arraySize is
|
|
* a multiple of 4).
|
|
*
|
|
* @note There are two versions of NdbOperation::getValue with
|
|
* slightly different parameters.
|
|
*
|
|
* @note This method does not fetch the attribute value from
|
|
* the database! The NdbRecAttr object returned by this method
|
|
* is <em>not</em> readable/printable before the
|
|
* transaction has been executed with NdbTransaction::execute.
|
|
*
|
|
* @param anAttrName Attribute name
|
|
* @param aValue If this is non-NULL, then the attribute value
|
|
* will be returned in this parameter.<br>
|
|
* If NULL, then the attribute value will only
|
|
* be stored in the returned NdbRecAttr object.
|
|
* @return An NdbRecAttr object to hold the value of
|
|
* the attribute, or a NULL pointer
|
|
* (indicating error).
|
|
*/
|
|
NdbRecAttr* getValue(const char* anAttrName, char* aValue = 0);
|
|
NdbRecAttr* getValue(Uint32 anAttrId, char* aValue = 0);
|
|
NdbRecAttr* getValue(const NdbDictionary::Column*, char* val = 0);
|
|
|
|
/**
|
|
* Define an attribute to set or update in query.
|
|
*
|
|
* To set a NULL value, use the following construct:
|
|
* @code
|
|
* setValue("ATTR_NAME", (char*)NULL);
|
|
* @endcode
|
|
*
|
|
* There are a number of NdbOperation::setValue methods that
|
|
* take a certain type as input
|
|
* (pass by value rather than passing a pointer).
|
|
* As the interface is currently implemented it is the responsibility
|
|
* of the application programmer to use the correct types.
|
|
*
|
|
* The NDB API will however check that the application sends
|
|
* a correct length to the interface as given in the length parameter.
|
|
* The passing of char* as the value can contain any type or
|
|
* any type of array.
|
|
* If length is not provided or set to zero,
|
|
* then the API will assume that the pointer
|
|
* is correct and not bother with checking it.
|
|
*
|
|
* @note For insertTuple() the NDB API will automatically detect that
|
|
* it is supposed to use equal() instead.
|
|
*
|
|
* @note For insertTuple() it is not necessary to use
|
|
* setValue() on key attributes before other attributes.
|
|
*
|
|
* @note There are 14 versions of NdbOperation::setValue with
|
|
* slightly different parameters.
|
|
*
|
|
* @note See note under equal() about value format and length.
|
|
*
|
|
* @param anAttrName Name (or Id) of attribute.
|
|
* @param aValue Attribute value to set.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
|
int setValue(const char* anAttrName, const char* aValue, Uint32 len);
|
|
#endif
|
|
int setValue(const char* anAttrName, const char* aValue);
|
|
int setValue(const char* anAttrName, Int32 aValue);
|
|
int setValue(const char* anAttrName, Uint32 aValue);
|
|
int setValue(const char* anAttrName, Int64 aValue);
|
|
int setValue(const char* anAttrName, Uint64 aValue);
|
|
int setValue(const char* anAttrName, float aValue);
|
|
int setValue(const char* anAttrName, double aValue);
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
int setAnyValue(Uint32 aValue);
|
|
int setOptimize(Uint32 options);
|
|
#endif
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
|
int setValue(Uint32 anAttrId, const char* aValue, Uint32 len);
|
|
#endif
|
|
int setValue(Uint32 anAttrId, const char* aValue);
|
|
int setValue(Uint32 anAttrId, Int32 aValue);
|
|
int setValue(Uint32 anAttrId, Uint32 aValue);
|
|
int setValue(Uint32 anAttrId, Int64 aValue);
|
|
int setValue(Uint32 anAttrId, Uint64 aValue);
|
|
int setValue(Uint32 anAttrId, float aValue);
|
|
int setValue(Uint32 anAttrId, double aValue);
|
|
|
|
/**
|
|
* This method replaces getValue/setValue for blobs. It creates
|
|
* a blob handle NdbBlob. A second call with same argument returns
|
|
* the previously created handle. The handle is linked to the
|
|
* operation and is maintained automatically.
|
|
*
|
|
* See NdbBlob for details.
|
|
*
|
|
* For NdbRecord operation, this method can be used to fetch the blob
|
|
* handle for an NdbRecord operation that references the blob, but extra
|
|
* blob columns can not be added with this call (it will return 0).
|
|
*
|
|
* For reading with NdbRecord, the NdbRecord entry for each blob must
|
|
* reserve space in the row for sizeof(NdbBlob *). The blob handle
|
|
* will be stored there, providing an alternative way of obtaining the
|
|
* blob handle.
|
|
*/
|
|
virtual NdbBlob* getBlobHandle(const char* anAttrName);
|
|
virtual NdbBlob* getBlobHandle(Uint32 anAttrId);
|
|
virtual NdbBlob* getBlobHandle(const char* anAttrName) const;
|
|
virtual NdbBlob* getBlobHandle(Uint32 anAttrId) const;
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
/** @} *********************************************************************/
|
|
/**
|
|
* @name Specify Interpreted Program Instructions
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Interpreted program instruction: Add a value to an attribute.
|
|
*
|
|
* @note Destroys the contents of registers 6 and 7.
|
|
* (The instruction uses these registers for its operation.)
|
|
*
|
|
* @note There are four versions of NdbOperation::incValue with
|
|
* slightly different parameters.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param anAttrName Attribute name.
|
|
* @param aValue Value to add.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int incValue(const char* anAttrName, Uint32 aValue);
|
|
int incValue(const char* anAttrName, Uint64 aValue);
|
|
int incValue(Uint32 anAttrId, Uint32 aValue);
|
|
int incValue(Uint32 anAttrId, Uint64 aValue);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Subtract a value from an attribute in an interpreted operation.
|
|
*
|
|
* @note Destroys the contents of registers 6 and 7.
|
|
* (The instruction uses these registers for its operation.)
|
|
*
|
|
* @note There are four versions of NdbOperation::subValue with
|
|
* slightly different parameters.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param anAttrName Attribute name.
|
|
* @param aValue Value to subtract.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int subValue(const char* anAttrName, Uint32 aValue);
|
|
int subValue(const char* anAttrName, Uint64 aValue);
|
|
int subValue(Uint32 anAttrId, Uint32 aValue);
|
|
int subValue(Uint32 anAttrId, Uint64 aValue);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Define a jump label in an interpreted operation.
|
|
*
|
|
* @note The labels are automatically numbered starting with 0.
|
|
* The parameter used by NdbOperation::def_label should
|
|
* match the automatic numbering to make it easier to
|
|
* debug the interpreted program.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param labelNumber Label number.
|
|
* @return Label number, -1 if unsuccessful.
|
|
*/
|
|
int def_label(int labelNumber);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Add two registers into a third.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param RegSource1 First register.
|
|
* @param RegSource2 Second register.
|
|
* @param RegDest Destination register where the result will be stored.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Substract RegSource2 from RegSource1 and put the result in RegDest.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param RegSource1 First register.
|
|
* @param RegSource2 Second register.
|
|
* @param RegDest Destination register where the result will be stored.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Load a constant into a register.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param RegDest Destination register.
|
|
* @param Constant Value to load.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int load_const_u32(Uint32 RegDest, Uint32 Constant);
|
|
int load_const_u64(Uint32 RegDest, Uint64 Constant);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Load NULL value into a register.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param RegDest Destination register.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int load_const_null(Uint32 RegDest);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Read an attribute into a register.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param anAttrName Attribute name.
|
|
* @param RegDest Destination register.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int read_attr(const char* anAttrName, Uint32 RegDest);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Write an attribute from a register.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param anAttrName Attribute name.
|
|
* @param RegSource Source register.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int write_attr(const char* anAttrName, Uint32 RegSource);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Read an attribute into a register.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param anAttrId the attribute id.
|
|
* @param RegDest the destination register.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int read_attr(Uint32 anAttrId, Uint32 RegDest);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Write an attribute from a register.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param anAttrId the attribute id.
|
|
* @param RegSource the source register.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int write_attr(Uint32 anAttrId, Uint32 RegSource);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Define a search condition. Last two letters in the function name
|
|
* describes the search condition.
|
|
* The condition compares RegR with RegL and therefore appears
|
|
* to be reversed.
|
|
*
|
|
* - ge RegR >= RegL
|
|
* - gt RegR > RegL
|
|
* - le RegR <= RegL
|
|
* - lt RegR < RegL
|
|
* - eq RegR = RegL
|
|
* - ne RegR <> RegL
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param RegLvalue left value.
|
|
* @param RegRvalue right value.
|
|
* @param Label the label to jump to.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
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);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Jump to Label if RegLvalue is not NULL.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param RegLvalue the value to check.
|
|
* @param Label the label to jump to.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int branch_ne_null(Uint32 RegLvalue, Uint32 Label);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Jump to Label if RegLvalue is equal to NULL.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param RegLvalue Value to check.
|
|
* @param Label Label to jump to.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int branch_eq_null(Uint32 RegLvalue, Uint32 Label);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Jump to Label.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param Label Label to jump to.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int branch_label(Uint32 Label);
|
|
|
|
/**
|
|
* Interpreted program instruction: branch after memcmp
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param ColId Column to check
|
|
* @param Label Label to jump to
|
|
* @return -1 if unsuccessful
|
|
*/
|
|
int branch_col_eq_null(Uint32 ColId, Uint32 Label);
|
|
int branch_col_ne_null(Uint32 ColId, Uint32 Label);
|
|
|
|
/**
|
|
* Interpreted program instruction: branch after memcmp
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param ColId column to check
|
|
* @param val search value
|
|
* @param len length of search value
|
|
* @param nopad force non-padded comparison for a Char column
|
|
* @param Label label to jump to
|
|
* @return -1 if unsuccessful
|
|
*/
|
|
int branch_col_eq(Uint32 ColId, const void * val, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_ne(Uint32 ColId, const void * val, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_lt(Uint32 ColId, const void * val, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_le(Uint32 ColId, const void * val, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_gt(Uint32 ColId, const void * val, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_ge(Uint32 ColId, const void * val, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
/**
|
|
* LIKE/NOTLIKE wildcard comparisons
|
|
* These instructions support SQL-style % and _ wildcards for
|
|
* (VAR)CHAR/BINARY columns only
|
|
*
|
|
* The argument is always plain char format, even if the field
|
|
* is varchar
|
|
* (changed in 5.0.22).
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*/
|
|
int branch_col_like(Uint32 ColId, const void *, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_notlike(Uint32 ColId, const void *, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
|
|
/**
|
|
* Bitwise logical comparisons
|
|
*
|
|
* These comparison types are only supported for the Bitfield
|
|
* type
|
|
* They can be used to test for bit patterns in bitfield columns
|
|
* The value passed is a bitmask which is bitwise-ANDed with the
|
|
* column data.
|
|
* Bitfields are passed in/out of NdbApi as 32-bit words with
|
|
* bits set from lsb to msb.
|
|
* The platform's endianness controls which byte contains the ls
|
|
* bits.
|
|
* x86= first(0th) byte. Sparc/PPC= last (3rd byte)
|
|
*
|
|
* To set bit n of a bitmask to 1 from a Uint32* mask :
|
|
* mask[n >> 5] |= (1 << (n & 31))
|
|
*
|
|
* The branch can be taken in 4 cases :
|
|
* - Column data AND Mask == Mask (all masked bits are set in data)
|
|
* - Column data AND Mask != Mask (not all masked bits are set in data)
|
|
* - Column data AND Mask == 0 (No masked bits are set in data)
|
|
* - Column data AND Mask != 0 (Some masked bits are set in data)
|
|
*
|
|
*/
|
|
int branch_col_and_mask_eq_mask(Uint32 ColId, const void *, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_and_mask_ne_mask(Uint32 ColId, const void *, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_and_mask_eq_zero(Uint32 ColId, const void *, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
int branch_col_and_mask_ne_zero(Uint32 ColId, const void *, Uint32 len,
|
|
bool nopad, Uint32 Label);
|
|
|
|
/**
|
|
* Interpreted program instruction: Exit with Ok
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int interpret_exit_ok();
|
|
|
|
/**
|
|
* Interpreted program instruction: Exit with Not Ok
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @note A method also exists without the error parameter.
|
|
*
|
|
* @param ErrorCode An error code given by the application programmer.
|
|
* If not supplied, defaults to 899. Applications should
|
|
* use error code 626 or any code in the [6000-6999]
|
|
* range. Error code 899 is supported for backwards
|
|
* compatibility, but 626 is recommmended instead. For
|
|
* other codes, the behavior is undefined and may change
|
|
* at any time without prior notice.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int interpret_exit_nok(Uint32 ErrorCode);
|
|
int interpret_exit_nok();
|
|
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
*
|
|
* abort the whole transaction.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int interpret_exit_last_row();
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Define a subroutine in an interpreted operation.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param SubroutineNumber the subroutine number.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int def_subroutine(int SubroutineNumber);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* Call a subroutine.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @param Subroutine the subroutine to call.
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int call_sub(Uint32 Subroutine);
|
|
|
|
/**
|
|
* Interpreted program instruction:
|
|
* End a subroutine.
|
|
*
|
|
* @note For Scans and NdbRecord operations, use the
|
|
* NdbInterpretedCode interface.
|
|
*
|
|
* @return -1 if unsuccessful.
|
|
*/
|
|
int ret_sub();
|
|
#endif
|
|
|
|
/** @} *********************************************************************/
|
|
|
|
/**
|
|
* @name Error Handling
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Get the latest error code.
|
|
*
|
|
* @return error code.
|
|
*/
|
|
const NdbError & getNdbError() const;
|
|
|
|
/**
|
|
* Get the method number where the error occurred.
|
|
*
|
|
* @return method number where the error occurred.
|
|
*/
|
|
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
|
int getNdbErrorLine();
|
|
#endif
|
|
int getNdbErrorLine() const;
|
|
|
|
/**
|
|
* Get table name of this operation.
|
|
* Not supported for NdbRecord operation.
|
|
*/
|
|
const char* getTableName() const;
|
|
|
|
/**
|
|
* Get table object for this operation
|
|
* Not supported for NdbRecord operation.
|
|
*/
|
|
const NdbDictionary::Table * getTable() const;
|
|
|
|
/**
|
|
* Get the type of access for this operation
|
|
*/
|
|
Type getType() const;
|
|
|
|
/** @} *********************************************************************/
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
/**
|
|
* Type of operation
|
|
*/
|
|
enum OperationType {
|
|
ReadRequest = 0, ///< Read operation
|
|
UpdateRequest = 1, ///< Update Operation
|
|
InsertRequest = 2, ///< Insert Operation
|
|
DeleteRequest = 3, ///< Delete Operation
|
|
WriteRequest = 4, ///< Write Operation
|
|
ReadExclusive = 5, ///< Read exclusive
|
|
RefreshRequest = 6, ///<
|
|
UnlockRequest = 7, ///< Unlock operation
|
|
OpenScanRequest, ///< Scan Operation
|
|
OpenRangeScanRequest, ///< Range scan operation
|
|
NotDefined2, ///< Internal for debugging
|
|
NotDefined ///< Internal for debugging
|
|
};
|
|
#endif
|
|
|
|
/**
|
|
* Return lock mode for operation
|
|
*/
|
|
LockMode getLockMode() const { return theLockMode; }
|
|
|
|
/**
|
|
* Get/set abort option
|
|
*/
|
|
AbortOption getAbortOption() const;
|
|
int setAbortOption(AbortOption);
|
|
|
|
/**
|
|
* Get NdbTransaction object pointer for this operation
|
|
*/
|
|
virtual NdbTransaction* getNdbTransaction() const;
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
|
|
/**
|
|
* Set/get partition key
|
|
*/
|
|
void setPartitionId(Uint32 id);
|
|
Uint32 getPartitionId() const;
|
|
#endif
|
|
|
|
/* Specification of an extra value to get
|
|
* as part of an NdbRecord operation.
|
|
* Inputs :
|
|
* To specify an extra value to read, the
|
|
* caller must provide a column, and a
|
|
* (optionally NULL) appStorage pointer.
|
|
* Outputs :
|
|
* After the operation is defined, the
|
|
* recAttr member will contain a pointer
|
|
* to the NdbRecAttr object for receiving
|
|
* the data.
|
|
*
|
|
* appStorage pointer
|
|
* If the appStorage pointer is null, then
|
|
* the received value will be stored in
|
|
* memory managed by the NdbRecAttr object.
|
|
*
|
|
* If the appStorage pointer is non-null then
|
|
* the received value will be stored at the
|
|
* location pointed to (and will still be
|
|
* accessable via the NdbRecAttr object).
|
|
* It is the caller's responsibility to
|
|
* ensure that :
|
|
* - appStorage points to sufficient space
|
|
* to store any returned data.
|
|
* - Memory pointed to by appStorage is not
|
|
* reused/freed until after the execute()
|
|
* call returns.
|
|
*
|
|
* Limitation : Blob reads cannot be specified
|
|
* using GetValueSpec.
|
|
*/
|
|
struct GetValueSpec
|
|
{
|
|
const NdbDictionary::Column *column;
|
|
void *appStorage;
|
|
NdbRecAttr *recAttr;
|
|
};
|
|
|
|
/* Specification of an extra value to set
|
|
* as part of an NdbRecord operation.
|
|
* The value ptr must point to the value
|
|
* to set, or NULL if the attribute is to
|
|
* be set to NULL.
|
|
* The pointed to value is copied when the
|
|
* operation is defined and need not remain
|
|
* in place until execution time.
|
|
*
|
|
* Limitation : Blobs cannot be set using
|
|
* SetValueSpec.
|
|
*/
|
|
struct SetValueSpec
|
|
{
|
|
const NdbDictionary::Column *column;
|
|
const void * value;
|
|
};
|
|
|
|
/*
|
|
* OperationOptions
|
|
* These are options passed to the NdbRecord primary key and scan
|
|
* takeover operation methods defined in the NdbTransaction and
|
|
* NdbScanOperation classes.
|
|
*
|
|
* Each option type is marked as present by setting the corresponding
|
|
* bit in the optionsPresent field. Only the option types marked in the
|
|
* optionsPresent structure need have sensible data.
|
|
* All data is copied out of the OperationOptions structure (and any
|
|
* subtended structures) at operation definition time.
|
|
* If no options are required, then NULL may be passed as the
|
|
* OperationOptions pointer.
|
|
*
|
|
* Most methods take a supplementary sizeOfOptions parameter. This
|
|
* is optional, and is intended to allow the interface implementation
|
|
* to remain backwards compatible with older un-recompiled clients
|
|
* that may pass an older (smaller) version of the OperationOptions
|
|
* structure. This effect is achieved by passing
|
|
* sizeof(OperationOptions) into this parameter.
|
|
*/
|
|
struct OperationOptions
|
|
{
|
|
/*
|
|
Size of the OperationOptions structure.
|
|
*/
|
|
static inline Uint32 size()
|
|
{
|
|
return sizeof(OperationOptions);
|
|
}
|
|
|
|
/*
|
|
* Which options are present. See below for option details
|
|
*/
|
|
Uint64 optionsPresent;
|
|
enum Flags { OO_ABORTOPTION = 0x01,
|
|
OO_GETVALUE = 0x02,
|
|
OO_SETVALUE = 0x04,
|
|
OO_PARTITION_ID = 0x08,
|
|
OO_INTERPRETED = 0x10,
|
|
OO_ANYVALUE = 0x20,
|
|
OO_CUSTOMDATA = 0x40,
|
|
OO_LOCKHANDLE = 0x80,
|
|
OO_QUEUABLE = 0x100,
|
|
OO_NOT_QUEUABLE = 0x200,
|
|
OO_DEFERRED_CONSTAINTS = 0x400,
|
|
OO_DISABLE_FK = 0x800,
|
|
OO_NOWAIT = 0x1000
|
|
};
|
|
|
|
/* An operation-specific abort option.
|
|
* Only necessary if the default abortoption behaviour
|
|
* is not satisfactory
|
|
*/
|
|
AbortOption abortOption;
|
|
|
|
/* Extra column values to be read */
|
|
GetValueSpec *extraGetValues;
|
|
Uint32 numExtraGetValues;
|
|
|
|
/* Extra column values to be set */
|
|
const SetValueSpec *extraSetValues;
|
|
Uint32 numExtraSetValues;
|
|
|
|
/* Specific partition to execute this operation on */
|
|
Uint32 partitionId;
|
|
|
|
/* Interpreted code to be executed in this operation
|
|
* Only supported for update operations currently
|
|
*/
|
|
const NdbInterpretedCode *interpretedCode;
|
|
|
|
/* anyValue to be used for this operation */
|
|
Uint32 anyValue;
|
|
|
|
/* customData ptr for this operation */
|
|
void * customData;
|
|
};
|
|
|
|
/* getLockHandle
|
|
* Returns a pointer to this operation's LockHandle.
|
|
* For NdbRecord, the lock handle must first be requested using
|
|
* the OO_LOCKHANDLE operation option.
|
|
* For non-NdbRecord operations, this call can be used alone.
|
|
* The returned LockHandle cannot be used until the operation
|
|
* has been executed.
|
|
*/
|
|
const NdbLockHandle* getLockHandle() const;
|
|
const NdbLockHandle* getLockHandle();
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
// XXX until NdbRecord is used in ndb_restore
|
|
void set_disable_fk() { m_flags |= OF_DISABLE_FK; }
|
|
|
|
/* Set nowait option on locking read */
|
|
int setNoWait();
|
|
#endif
|
|
|
|
protected:
|
|
/******************************************************************************
|
|
* These are the methods used to create and delete the NdbOperation objects.
|
|
*****************************************************************************/
|
|
|
|
bool needReply();
|
|
/******************************************************************************
|
|
* These methods are service routines used by the other NDB API classes.
|
|
*****************************************************************************/
|
|
//--------------------------------------------------------------
|
|
// Initialise after allocating operation to a transaction
|
|
//--------------------------------------------------------------
|
|
int init(const class NdbTableImpl*, NdbTransaction* aCon);
|
|
void initInterpreter();
|
|
|
|
NdbOperation(Ndb* aNdb, Type aType = PrimaryKeyAccess);
|
|
virtual ~NdbOperation();
|
|
void next(NdbOperation*); // Set next pointer
|
|
NdbOperation* next(); // Get next pointer
|
|
|
|
public:
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
const NdbOperation* next() const;
|
|
const NdbRecAttr* getFirstRecAttr() const;
|
|
|
|
void* getCustomData() const { return m_customData; }
|
|
void setCustomData(void* p) { m_customData = p; }
|
|
protected:
|
|
void* m_customData;
|
|
#endif
|
|
protected:
|
|
|
|
/*
|
|
Methods that define the operation (readTuple(), getValue(), etc). can be
|
|
called in any order, but not all are valid.
|
|
|
|
To keep track of things, we store a 'current state of definitin operation'
|
|
in member 'theStatus', with possible values given here.
|
|
*/
|
|
enum OperationStatus
|
|
{
|
|
/*
|
|
Init: Initial state after getting NdbOperation.
|
|
At this point, the type of operation must be set (insertTuple(),
|
|
readTuple(), etc.).
|
|
|
|
*/
|
|
Init,
|
|
/*
|
|
OperationDefined: State in which the primary key search condition is
|
|
defined with equal().
|
|
*/
|
|
OperationDefined,
|
|
/*
|
|
TupleKeyDefined: All parts of the primary key have been specified with
|
|
equal().
|
|
*/
|
|
TupleKeyDefined,
|
|
/*
|
|
GetValue: The state in which the attributes to read are defined with
|
|
calls to getValue(). For interpreted operations, these are the initial
|
|
reads, before the interpreted program.
|
|
*/
|
|
GetValue,
|
|
/*
|
|
SetValue: The state in which attributes to update are defined with
|
|
calls to setValue().
|
|
*/
|
|
SetValue,
|
|
/*
|
|
ExecInterpretedValue: The state in which the interpreted program is
|
|
defined.
|
|
*/
|
|
ExecInterpretedValue,
|
|
/*
|
|
SetValueInterpreted: Updates after interpreted program.
|
|
*/
|
|
SetValueInterpreted,
|
|
/*
|
|
FinalGetValue: Attributes to read after interpreted program.
|
|
*/
|
|
FinalGetValue,
|
|
/*
|
|
SubroutineExec: In the middle of a subroutine definition being defined.
|
|
*/
|
|
SubroutineExec,
|
|
/*
|
|
SubroutineEnd: A subroutine has been fully defined, but a new subroutine
|
|
definition may still be defined after.
|
|
*/
|
|
SubroutineEnd,
|
|
/*
|
|
WaitResponse: Operation has been sent to kernel, waiting for reply.
|
|
*/
|
|
WaitResponse,
|
|
/*
|
|
Finished: The TCKEY{REF,CONF} signal for this operation has been
|
|
received.
|
|
*/
|
|
Finished,
|
|
/*
|
|
NdbRecord: For operations using NdbRecord. Built in a single call (like
|
|
NdbTransaction::readTuple(), and no state transitions possible before
|
|
execute().
|
|
*/
|
|
UseNdbRecord
|
|
};
|
|
|
|
OperationStatus Status(); // Read the status information
|
|
|
|
void Status(OperationStatus); // Set the status information
|
|
|
|
void NdbCon(NdbTransaction*); // Set reference to connection
|
|
// object.
|
|
|
|
virtual void release(); // Release all operations
|
|
// connected to
|
|
// the operations object.
|
|
void postExecuteRelease(); // Release resources
|
|
// no longer needed after
|
|
// exceute
|
|
void setStartIndicator();
|
|
|
|
/* Utility method to 'add' operation options to an NdbOperation
|
|
*
|
|
* @return 0 for success. NDBAPI to set error otherwise.
|
|
*/
|
|
static int handleOperationOptions (const OperationType type,
|
|
const OperationOptions *opts,
|
|
const Uint32 sizeOfOptions,
|
|
NdbOperation *op);
|
|
|
|
/******************************************************************************
|
|
* The methods below is the execution part of the NdbOperation
|
|
* class. This is where the NDB signals are sent and received. The
|
|
* operation can send TC[KEY/INDX]REQ, [INDX]ATTRINFO.
|
|
* It can receive TC[KEY/INDX]CONF, TC[KEY/INDX]REF, [INDX]ATTRINFO.
|
|
* When an operation is received in its fulness or a refuse message
|
|
* was sent, then the connection object is told about this situation.
|
|
*****************************************************************************/
|
|
|
|
int doSendKeyReq(int processorId,
|
|
GenericSectionPtr* secs,
|
|
Uint32 numSecs,
|
|
bool lastFlag);
|
|
int doSend(int ProcessorId, Uint32 lastFlag);
|
|
void setRequestInfoTCKEYREQ(bool lastFlag, bool longSignal);
|
|
virtual int prepareSend(Uint32 TC_ConnectPtr,
|
|
Uint64 TransactionId,
|
|
AbortOption);
|
|
virtual void setLastFlag(NdbApiSignal* signal, Uint32 lastFlag);
|
|
|
|
int prepareSendInterpreted(); // Help routine to prepare*
|
|
|
|
int initInterpretedInfo(const NdbInterpretedCode *code,
|
|
Uint32*& interpretedInfo,
|
|
Uint32* stackSpace,
|
|
Uint32 stackSpaceEntries,
|
|
Uint32*& dynamicSpace);
|
|
|
|
void freeInterpretedInfo(Uint32*& dynamicSpace);
|
|
|
|
|
|
/* Method for adding signals for an interpreted program
|
|
* to the signal train
|
|
*/
|
|
int buildInterpretedProgramSignals(Uint32 aTC_ConnectPtr,
|
|
Uint64 aTransId,
|
|
Uint32 **attrInfoPtr,
|
|
Uint32 *remain,
|
|
const NdbInterpretedCode *code,
|
|
Uint32 *interpretedWorkspace,
|
|
bool mainProgram,
|
|
Uint32 &wordsWritten);
|
|
|
|
// Method which prepares signals at operation definition time.
|
|
int buildSignalsNdbRecord(Uint32 aTC_ConnectPtr, Uint64 aTransId,
|
|
const Uint32 * read_mask);
|
|
|
|
// Method which does final preparations at execute time.
|
|
int prepareSendNdbRecord(AbortOption ao);
|
|
|
|
/* Helper routines for buildSignalsNdbRecord(). */
|
|
Uint32 fillTcKeyReqHdr(TcKeyReq *tcKeyReq,
|
|
Uint32 connectPtr,
|
|
Uint64 transId);
|
|
int allocKeyInfo();
|
|
int allocAttrInfo();
|
|
int insertKEYINFO_NdbRecord(const char *value,
|
|
Uint32 byteSize);
|
|
int insertATTRINFOHdr_NdbRecord(Uint32 attrId,
|
|
Uint32 attrLen);
|
|
int insertATTRINFOData_NdbRecord(const char *value,
|
|
Uint32 size);
|
|
|
|
int receiveTCKEYREF(const NdbApiSignal*);
|
|
|
|
int checkMagicNumber(bool b = true); // Verify correct object
|
|
static Uint32 getMagicNumber() { return (Uint32)0xABCDEF01; }
|
|
|
|
int checkState_TransId(const NdbApiSignal* aSignal);
|
|
|
|
/******************************************************************************
|
|
* These are support methods only used locally in this class.
|
|
******************************************************************************/
|
|
|
|
virtual int equal_impl(const NdbColumnImpl*,const char* aValue);
|
|
virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char* aValue = 0);
|
|
NdbRecAttr* getValue_NdbRecord(const NdbColumnImpl* tAttrInfo, char* aValue);
|
|
int setValue(const NdbColumnImpl* anAttrObject, const char* aValue);
|
|
NdbBlob* getBlobHandle(NdbTransaction* aCon, const NdbColumnImpl* anAttrObject);
|
|
NdbBlob* getBlobHandle(NdbTransaction* aCon, const NdbColumnImpl* anAttrObject) const;
|
|
int incValue(const NdbColumnImpl* anAttrObject, Uint32 aValue);
|
|
int incValue(const NdbColumnImpl* anAttrObject, Uint64 aValue);
|
|
int subValue(const NdbColumnImpl* anAttrObject, Uint32 aValue);
|
|
int subValue(const NdbColumnImpl* anAttrObject, Uint64 aValue);
|
|
int read_attr(const NdbColumnImpl* anAttrObject, Uint32 RegDest);
|
|
int write_attr(const NdbColumnImpl* anAttrObject, Uint32 RegSource);
|
|
int branch_reg_reg(Uint32 type, Uint32, Uint32, Uint32);
|
|
int branch_col(Uint32 type, Uint32, const void *, Uint32, Uint32 Label);
|
|
int branch_col_null(Uint32 type, Uint32 col, Uint32 Label);
|
|
NdbBlob *linkInBlobHandle(NdbTransaction *aCon,
|
|
const NdbColumnImpl *column,
|
|
NdbBlob * & lastPtr);
|
|
int getBlobHandlesNdbRecord(NdbTransaction* aCon, const Uint32 * mask);
|
|
int getBlobHandlesNdbRecordDelete(NdbTransaction* aCon,
|
|
bool checkReadSet, const Uint32 * mask);
|
|
|
|
// Handle ATTRINFO signals
|
|
int insertATTRINFO(Uint32 aData);
|
|
int insertATTRINFOloop(const Uint32* aDataPtr, Uint32 aLength);
|
|
|
|
int insertKEYINFO(const char* aValue,
|
|
Uint32 aStartPosition,
|
|
Uint32 aKeyLenInByte);
|
|
void reorderKEYINFO();
|
|
|
|
virtual void setErrorCode(int aErrorCode) const;
|
|
virtual void setErrorCodeAbort(int aErrorCode) const;
|
|
|
|
bool isNdbRecordOperation();
|
|
int incCheck(const NdbColumnImpl* anAttrObject);
|
|
int initial_interpreterCheck();
|
|
int intermediate_interpreterCheck();
|
|
int read_attrCheck(const NdbColumnImpl* anAttrObject);
|
|
int write_attrCheck(const NdbColumnImpl* anAttrObject);
|
|
int labelCheck();
|
|
int insertCall(Uint32 aCall);
|
|
int insertBranch(Uint32 aBranch);
|
|
|
|
Uint32 ptr2int() { return theReceiver.getId(); }
|
|
Uint32 ptr2int() const { return theReceiver.getId(); }
|
|
|
|
// get table or index key from prepared signals
|
|
int getKeyFromTCREQ(Uint32* data, Uint32 & size);
|
|
|
|
int getLockHandleImpl();
|
|
int prepareGetLockHandle();
|
|
int prepareGetLockHandleNdbRecord();
|
|
|
|
virtual void setReadLockMode(LockMode lockMode);
|
|
void setReadCommittedBase();
|
|
Uint32 getReadCommittedBase();
|
|
|
|
/******************************************************************************
|
|
* These are the private variables that are defined in the operation objects.
|
|
*****************************************************************************/
|
|
|
|
Type m_type;
|
|
|
|
NdbReceiver theReceiver;
|
|
|
|
NdbError theError; // Errorcode
|
|
int theErrorLine; // Error line
|
|
|
|
Ndb* theNdb; // Point back to the Ndb object.
|
|
NdbTransaction* theNdbCon; // Point back to the connection object.
|
|
NdbOperation* theNext; // Next pointer to operation.
|
|
|
|
union {
|
|
NdbApiSignal* theTCREQ; // The TC[KEY/INDX]REQ signal object
|
|
NdbApiSignal* theSCAN_TABREQ;
|
|
NdbApiSignal* theRequest;
|
|
};
|
|
|
|
NdbApiSignal* theFirstATTRINFO; // The first ATTRINFO signal object
|
|
NdbApiSignal* theCurrentATTRINFO; // The current ATTRINFO signal object
|
|
Uint32 theTotalCurrAI_Len; // The total number of attribute info
|
|
// words currently defined
|
|
Uint32 theAI_LenInCurrAI; // The number of words defined in the
|
|
// current ATTRINFO signal
|
|
NdbApiSignal* theLastKEYINFO; // The first KEYINFO signal object
|
|
|
|
class NdbLabel* theFirstLabel;
|
|
class NdbLabel* theLastLabel;
|
|
class NdbBranch* theFirstBranch;
|
|
class NdbBranch* theLastBranch;
|
|
class NdbCall* theFirstCall;
|
|
class NdbCall* theLastCall;
|
|
class NdbSubroutine* theFirstSubroutine;
|
|
class NdbSubroutine* theLastSubroutine;
|
|
Uint32 theNoOfLabels;
|
|
Uint32 theNoOfSubroutines;
|
|
|
|
Uint32* theKEYINFOptr; // Pointer to where to write KEYINFO
|
|
Uint32 keyInfoRemain; // KeyInfo space in current signal
|
|
Uint32* theATTRINFOptr; // Pointer to where to write ATTRINFO
|
|
Uint32 attrInfoRemain; // AttrInfo space in current signal
|
|
|
|
/*
|
|
The table object for the table to read or modify (for index operations,
|
|
it is the table being indexed.)
|
|
*/
|
|
const class NdbTableImpl* m_currentTable;
|
|
|
|
/*
|
|
The table object for the index used to access the table. For primary key
|
|
lookups, it is equal to m_currentTable.
|
|
*/
|
|
const class NdbTableImpl* m_accessTable;
|
|
|
|
// Set to TRUE when a tuple key attribute has been defined.
|
|
Uint32 theTupleKeyDefined[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY][3];
|
|
|
|
Uint32 theTotalNrOfKeyWordInSignal; // The total number of
|
|
// keyword in signal.
|
|
|
|
Uint32 theTupKeyLen; // Length of the tuple key in words
|
|
// left until done
|
|
Uint8 theNoOfTupKeyLeft; // The number of tuple key attributes
|
|
OperationType theOperationType; // Read Request, Update Req......
|
|
|
|
LockMode theLockMode; // Can be set to WRITE if read operation
|
|
OperationStatus theStatus; // The status of the operation.
|
|
|
|
Uint32 theMagicNumber; // Magic number to verify that object
|
|
// is correct
|
|
Uint32 theScanInfo; // Scan info bits (take over flag etc)
|
|
Uint32 theDistributionKey; // Distribution Key size if used
|
|
|
|
Uint32 theSubroutineSize; // Size of subroutines for interpretation
|
|
Uint32 theInitialReadSize; // Size of initial reads for interpretation
|
|
Uint32 theInterpretedSize; // Size of interpretation
|
|
Uint32 theFinalUpdateSize; // Size of final updates for interpretation
|
|
Uint32 theFinalReadSize; // Size of final reads for interpretation
|
|
|
|
Uint8 theStartIndicator; // Indicator of whether start operation
|
|
Uint8 theCommitIndicator; // Indicator of whether commit operation
|
|
Uint8 theSimpleIndicator; // Indicator of whether simple operation
|
|
Uint8 theDirtyIndicator; // Indicator of whether dirty operation
|
|
/**
|
|
* Indicates that the base operation is ReadCommitted although it has
|
|
* been upgraded to use locking read.
|
|
*/
|
|
Uint8 theReadCommittedBaseIndicator;
|
|
Uint8 theInterpretIndicator; // Indicator of whether interpreted operation
|
|
// Note that scan operations always have this
|
|
// set true
|
|
Int8 theDistrKeyIndicator_; // Indicates whether distr. key is used
|
|
|
|
enum OP_FLAGS {
|
|
OF_NO_DISK = 0x1,
|
|
|
|
/*
|
|
For NdbRecord, this flag indicates that we need to send the Event-attached
|
|
word set by setAnyValue().
|
|
*/
|
|
OF_USE_ANY_VALUE = 0x2,
|
|
OF_QUEUEABLE = 0x4,
|
|
OF_DEFERRED_CONSTRAINTS = 0x8,
|
|
OF_DISABLE_FK = 0x10,
|
|
OF_NOWAIT = 0x20
|
|
};
|
|
Uint8 m_flags;
|
|
|
|
Uint8 _unused1;
|
|
|
|
Uint16 m_tcReqGSN;
|
|
Uint16 m_keyInfoGSN;
|
|
Uint16 m_attrInfoGSN;
|
|
|
|
/*
|
|
Members for NdbRecord operations.
|
|
ToDo: We might overlap these (with anonymous unions) with members used
|
|
for NdbRecAttr access (theKEYINFOptr etc), to save a bit of memory. Not
|
|
sure if it is worth the loss of code clarity though.
|
|
*/
|
|
|
|
/*
|
|
NdbRecord describing the placement of Primary key in row.
|
|
As a special case, we set this to NULL for scan lock take-over operations,
|
|
in which case the m_key_row points to keyinfo obtained from the KEYINFO20
|
|
signal.
|
|
*/
|
|
const NdbRecord *m_key_record;
|
|
/* Row containing the primary key to operate on, or KEYINFO20 data. */
|
|
const char *m_key_row;
|
|
/* Size in words of keyinfo in m_key_row. */
|
|
Uint32 m_keyinfo_length;
|
|
/*
|
|
NdbRecord describing attributes to update (or read for scans).
|
|
We also use m_attribute_record!=NULL to indicate that the operation is
|
|
using the NdbRecord interface (as opposed to NdbRecAttr).
|
|
*/
|
|
const NdbRecord *m_attribute_record;
|
|
/* Row containing the update values. */
|
|
const char *m_attribute_row;
|
|
/*
|
|
Bitmask to disable selected columns.
|
|
Do not use clas Bitmask/BitmaskPOD here, to avoid having to
|
|
#include <Bitmask.hpp> in application code.
|
|
*/
|
|
Uint32 m_unused_read_mask[(128+31)>>5];
|
|
/* Interpreted program for NdbRecord operations. */
|
|
const NdbInterpretedCode *m_interpreted_code;
|
|
|
|
/* Ptr to supplied SetValueSpec for NdbRecord */
|
|
const SetValueSpec *m_extraSetValues;
|
|
Uint32 m_numExtraSetValues;
|
|
|
|
Uint32 m_any_value; // Valid if m_use_any_value!=0
|
|
|
|
// Blobs in this operation
|
|
NdbBlob* theBlobList;
|
|
|
|
// ONLY for blob V2 implementation (not virtual, only PK ops)
|
|
NdbRecAttr*
|
|
getVarValue(const NdbColumnImpl*, char* aBareValue, Uint16* aLenLoc);
|
|
int
|
|
setVarValue(const NdbColumnImpl*, const char* aBareValue, const Uint16& aLen);
|
|
|
|
/*
|
|
* Abort option per operation, used by blobs.
|
|
* See also comments on enum AbortOption.
|
|
*/
|
|
Int8 m_abortOption;
|
|
|
|
/*
|
|
* For blob impl, option to not propagate error to trans level.
|
|
* Could be AO_IgnoreError variant if we want it public.
|
|
* Ignored unless AO_IgnoreError is also set.
|
|
*/
|
|
Int8 m_noErrorPropagation;
|
|
|
|
friend struct Ndb_free_list_t<NdbOperation>;
|
|
|
|
Uint32 repack_read(Uint32 len);
|
|
|
|
NdbLockHandle* theLockHandle;
|
|
|
|
bool m_blob_lock_upgraded; /* Did Blob code upgrade LM_CommittedRead
|
|
* to LM_Read?
|
|
*/
|
|
|
|
private:
|
|
NdbOperation(const NdbOperation&); // Not impl.
|
|
NdbOperation&operator=(const NdbOperation&);
|
|
};
|
|
|
|
#ifdef NDB_NO_DROPPED_SIGNAL
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
|
|
|
inline
|
|
int
|
|
NdbOperation::checkMagicNumber(bool b)
|
|
{
|
|
#ifndef NDB_NO_DROPPED_SIGNAL
|
|
(void)b; // unused param in this context
|
|
#endif
|
|
if (theMagicNumber != getMagicNumber()){
|
|
#ifdef NDB_NO_DROPPED_SIGNAL
|
|
if(b) abort();
|
|
#endif
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline
|
|
void
|
|
NdbOperation::setStartIndicator()
|
|
{
|
|
theStartIndicator = 1;
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::getNdbErrorLine()
|
|
{
|
|
// delegate to overloaded const function for same semantics
|
|
const NdbOperation * const cthis = this;
|
|
return cthis->NdbOperation::getNdbErrorLine();
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::getNdbErrorLine() const
|
|
{
|
|
return theErrorLine;
|
|
}
|
|
|
|
/******************************************************************************
|
|
void next(NdbOperation* aNdbOperation);
|
|
|
|
Parameters: aNdbOperation: Pointers to the NdbOperation object.
|
|
Remark: Set the next variable of the operation object.
|
|
******************************************************************************/
|
|
inline
|
|
void
|
|
NdbOperation::next(NdbOperation* aNdbOperation)
|
|
{
|
|
theNext = aNdbOperation;
|
|
}
|
|
|
|
/******************************************************************************
|
|
NdbOperation* next();
|
|
|
|
Return Value: Return next pointer to NdbOperation object.
|
|
Remark: Get the next variable of the operation object.
|
|
******************************************************************************/
|
|
inline
|
|
NdbOperation*
|
|
NdbOperation::next()
|
|
{
|
|
return theNext;
|
|
}
|
|
|
|
inline
|
|
const NdbOperation*
|
|
NdbOperation::next() const
|
|
{
|
|
return theNext;
|
|
}
|
|
|
|
inline
|
|
const NdbRecAttr*
|
|
NdbOperation::getFirstRecAttr() const
|
|
{
|
|
return theReceiver.m_firstRecAttr;
|
|
}
|
|
|
|
/******************************************************************************
|
|
Type getType()
|
|
|
|
Return Value Return the Type.
|
|
Remark: Gets type of access.
|
|
******************************************************************************/
|
|
inline
|
|
NdbOperation::Type
|
|
NdbOperation::getType() const
|
|
{
|
|
return m_type;
|
|
}
|
|
|
|
/******************************************************************************
|
|
OperationStatus Status();
|
|
|
|
Return Value Return the OperationStatus.
|
|
Parameters: aStatus: The status.
|
|
Remark: Sets Operation status.
|
|
******************************************************************************/
|
|
inline
|
|
NdbOperation::OperationStatus
|
|
NdbOperation::Status()
|
|
{
|
|
return theStatus;
|
|
}
|
|
|
|
/******************************************************************************
|
|
void Status(OperationStatus aStatus);
|
|
|
|
Parameters: aStatus: The status.
|
|
Remark: Sets Operation
|
|
status.
|
|
******************************************************************************/
|
|
inline
|
|
void
|
|
NdbOperation::Status( OperationStatus aStatus )
|
|
{
|
|
theStatus = aStatus;
|
|
}
|
|
|
|
/******************************************************************************
|
|
void NdbCon(NdbTransaction* aNdbCon);
|
|
|
|
Parameters: aNdbCon: Pointers to NdbTransaction object.
|
|
Remark: Set the reference to the connection in the operation object.
|
|
******************************************************************************/
|
|
inline
|
|
void
|
|
NdbOperation::NdbCon(NdbTransaction* aNdbCon)
|
|
{
|
|
theNdbCon = aNdbCon;
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(const char* anAttrName, const char* aValue,
|
|
Uint32 len)
|
|
{
|
|
(void)len; // unused
|
|
return equal(anAttrName, aValue);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(const char* anAttrName, Int32 aPar)
|
|
{
|
|
return equal(anAttrName, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(const char* anAttrName, Uint32 aPar)
|
|
{
|
|
return equal(anAttrName, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(const char* anAttrName, Int64 aPar)
|
|
{
|
|
return equal(anAttrName, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(const char* anAttrName, Uint64 aPar)
|
|
{
|
|
return equal(anAttrName, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(Uint32 anAttrId, const char* aValue,
|
|
Uint32 len)
|
|
{
|
|
(void)len; // unused
|
|
return equal(anAttrId, aValue);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(Uint32 anAttrId, Int32 aPar)
|
|
{
|
|
return equal(anAttrId, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(Uint32 anAttrId, Uint32 aPar)
|
|
{
|
|
return equal(anAttrId, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(Uint32 anAttrId, Int64 aPar)
|
|
{
|
|
return equal(anAttrId, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::equal(Uint32 anAttrId, Uint64 aPar)
|
|
{
|
|
return equal(anAttrId, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(const char* anAttrName, const char* aValue,
|
|
Uint32 len)
|
|
{
|
|
(void)len; // unused
|
|
return setValue(anAttrName, aValue);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(const char* anAttrName, Int32 aPar)
|
|
{
|
|
return setValue(anAttrName, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(const char* anAttrName, Uint32 aPar)
|
|
{
|
|
return setValue(anAttrName, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(const char* anAttrName, Int64 aPar)
|
|
{
|
|
return setValue(anAttrName, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(const char* anAttrName, Uint64 aPar)
|
|
{
|
|
return setValue(anAttrName, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(const char* anAttrName, float aPar)
|
|
{
|
|
return setValue(anAttrName, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(const char* anAttrName, double aPar)
|
|
{
|
|
return setValue(anAttrName, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(Uint32 anAttrId, const char* aValue,
|
|
Uint32 len)
|
|
{
|
|
(void)len; // unused
|
|
return setValue(anAttrId, aValue);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(Uint32 anAttrId, Int32 aPar)
|
|
{
|
|
return setValue(anAttrId, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(Uint32 anAttrId, Uint32 aPar)
|
|
{
|
|
return setValue(anAttrId, (const char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(Uint32 anAttrId, Int64 aPar)
|
|
{
|
|
return setValue(anAttrId, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(Uint32 anAttrId, Uint64 aPar)
|
|
{
|
|
return setValue(anAttrId, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(Uint32 anAttrId, float aPar)
|
|
{
|
|
return setValue(anAttrId, (char*)&aPar, (Uint32)4);
|
|
}
|
|
|
|
inline
|
|
int
|
|
NdbOperation::setValue(Uint32 anAttrId, double aPar)
|
|
{
|
|
return setValue(anAttrId, (const char*)&aPar, (Uint32)8);
|
|
}
|
|
|
|
inline
|
|
void
|
|
NdbOperation::setReadCommittedBase()
|
|
{
|
|
theReadCommittedBaseIndicator = 1;
|
|
}
|
|
|
|
inline
|
|
Uint32
|
|
NdbOperation::getReadCommittedBase()
|
|
{
|
|
return theReadCommittedBaseIndicator;
|
|
}
|
|
#endif // doxygen
|
|
|
|
#endif
|