/* Copyright (c) 2003, 2010, 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NdbOperation_H #define NdbOperation_H #include #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 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 not 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.
* 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. * @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 occured. * * @return method number where the error occured. */ #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 { /* * 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 }; /* 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(); 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, bool useRec); 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); int doSend(int ProcessorId, Uint32 lastFlag); 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 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); /****************************************************************************** * 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 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 }; 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 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; 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 #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 != 0xABCDEF01){ #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.theFirstRecAttr; } /****************************************************************************** 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); } #endif // doxygen #endif