Documentation Home
MySQL NDB Cluster API Developer Guide
Download this Manual

2.3.24 The NdbScanOperation Class

This section provides information about the NdbScanOperation class.

NdbScanOperation Class Overview

Parent class

NdbOperation

Child classes

NdbIndexScanOperation

Description

The NdbScanOperation class represents a scanning operation used in a transaction. This class inherits from NdbOperation.

Methods

The following table lists the public methods of this class and the purpose or use of each method:

Table 2.61 NdbScanOperation class methods and descriptions

Name Description
close() Closes the scan
deleteCurrentTuple() Deletes the current tuple
lockCurrentTuple() Locks the current tuple
nextResult() Gets the next tuple
getNdbTransaction() Gets the NdbTransaction object for this scan
getPruned() Used to find out whether this scan is pruned to a single partition
readTuples() Reads tuples
restart() Restarts the scan
updateCurrentTuple() Updates the current tuple

This class has no public constructor. To create an instance of NdbScanOperation, it is necessary to use the NdbTransaction::getNdbScanOperation() method.

Types

This class defines two public types, which are listed here:

For more information about the use of NdbScanOperation, see Section 1.4.2.3.3, “Scan Operations”, and Section 1.4.2.3.4, “Using Scans to Update or Delete Rows”.

NdbScanOperation::close()

Description

Calling this method closes a scan. Rows returned by this scan are no longer available after the scan has been closed using this method.

See Scans with exclusive locks, for information about multiple threads attempting to perform the same scan with an exclusive lock and how this can affect closing the scans.

Signature
void close
    (
      bool forceSend = false,
      bool releaseOp = false
    )
Parameters

This method takes the two parameters listed here:

  • forceSend defaults to false; call close() with this parameter set to true in order to force transactions to be sent.

  • releaseOp also defaults to false; set this to true in order to release the operation.

    Prior to NDB 7.3.8, the buffer allocated by an NdbScanOperation for receiving the scanned rows was not released until the NdbTransaction owning the scan operation was closed (Bug #75128, Bug #20166585). In these and subsequent versions of NDB Cluster, the buffer is released whenever the cursor navigating the result set is closed using the close() method, regardless of the value of the releaseOp argument.

Return value

None.

NdbScanOperation::deleteCurrentTuple()

Description

This method is used to delete the current tuple.

Signature
const NdbOperation* deleteCurrentTuple
    (
      NdbTransaction* takeOverTrans,
      const NdbRecord* record,
      char* row = 0,
      const unsigned char* mask = 0,
      const NdbOperation::OperationOptions* opts = 0,
      Uint32 sizeOfOpts = 0
    )

For more information, see Section 2.3.22, “The NdbRecord Interface”.

Parameters

When used with the NdbRecord interface, this method takes the parameters listed here:

  • The transaction (takeOverTrans) that should perform the lock; when using NdbRecord with scans, this parameter is not optional.

  • The NdbRecord referenced by the scan. This record value is required, even if no records are being read.

  • The row from which to read. Set this to NULL if no read is to occur.

  • The mask pointer is optional. If it is present, then only columns for which the corresponding bit in the mask is set are retrieved by the scan.

  • OperationOptions (opts) can be used to provide more finely-grained control of operation definitions. An OperationOptions structure is passed with flags indicating which operation definition options are present. Not all operation types support all operation options; the options supported for each type of operation are shown in the following table:

    Table 2.62 Operation types for the NdbRecord OperationOptions

    Operation type (Method) OperationOptions Flags Supported
    readTuple() OO_ABORTOPTION, OO_GETVALUE, OO_PARTITION_ID, OO_INTERPRETED
    insertTuple() OO_ABORTOPTION, OO_SETVALUE, OO_PARTITION_ID, OO_ANYVALUE
    updateTuple() OO_ABORTOPTION, OO_SETVALUE, OO_PARTITION_ID, OO_INTERPRETED, OO_ANYVALUE
    writeTuple() OO_ABORTOPTION, OO_SETVALUE, OO_PARTITION_ID, OO_ANYVALUE
    deleteTuple() OO_ABORTOPTION, OO_GETVALUE, OO_PARTITION_ID, OO_INTERPRETED, OO_ANYVALUE

  • The optional sizeOfOptions parameter is used to preserve backward compatibility of this interface with previous definitions of the OperationOptions structure. If an unusual size is detected by the interface implementation, it can use this to determine how to interpret the passed OperationOptions structure. To enable this functionality, the caller should pass sizeof(NdbOperation::OperationOptions) for the value of this argument.

  • If options are specified, their length (sizeOfOpts) must be specified as well.

Return value

Returns 0 on success, or -1 on failure.

NdbScanOperation::getNdbTransaction()

Description

Gets the NdbTransaction object for this scan.

Signature
NdbTransaction* getNdbTransaction
    (
      void
    ) const
Parameters

None.

Return value

A pointer to an NdbTransaction object.

NdbScanOperation::getPruned()

Description

This method is used to determine whether or not a given scan operation has been pruned to a single partition. For scans defined using NdbRecord, this method can be called before or after the scan is executed. For scans not defined using NdbRecord, getPruned() is valid only after the scan has been executed.

Signature
bool getPruned
    (
      void
    ) const
Parameters

None.

Return value

Returns true, if the scan is pruned to a single table partition.

NdbScanOperation::lockCurrentTuple()

Description

This method locks the current tuple.

Signature

This method can be called with an optional single parameter, in either of the two ways shown here:

NdbOperation* lockCurrentTuple
    (
      void
    )

NdbOperation* lockCurrentTuple
    (
      NdbTransaction* lockTrans
    )

The following signature is also supported for this method, when using NdbRecord:

NdbOperation *lockCurrentTuple
    (
      NdbTransaction* takeOverTrans,
      const NdbRecord* record,
      char* row = 0,
      const unsigned char* mask = 0
    )

This method also supports specifying one or more OperationOptions (also when using NdbRecord):

NdbOperation *lockCurrentTuple
    (
      NdbTransaction* takeOverTrans,
      const NdbRecord* record,
      char* row = 0,
      const unsigned char* mask = 0,
      const NdbOperation::OperationOptions* opts = 0,
      Uint32 sizeOfOptions = 0
    )
Parameters (without NdbRecord)

This method takes a single, optional parameter—the transaction that should perform the lock. If this is omitted, the transaction is the current one.

Parameters (using NdbRecord)

When using the NdbRecord interface, this method takes these parameters, as described in the following list:

  • The transaction (takeOverTrans) that should perform the lock; when using NdbRecord with scans, this parameter is not optional.

  • The NdbRecord referenced by the scan. This is required, even if no records are being read.

  • The row from which to read. Set this to NULL if no read is to occur.

  • The mask pointer is optional. If it is present, then only columns for which the corresponding bit in the mask is set are retrieved by the scan.

  • The opts argument can take on any of the following OperationOptions values: OO_ABORTOPTION, OO_GETVALUE, and OO_ANYVALUE.

  • If options are specified, their length (sizeOfOptions) must be specified as well.

Calling an NdbRecord scan lock takeover on an NdbRecAttr-style scan is not valid, nor is calling an NdbRecAttr-style scan lock takeover on an NdbRecord-style scan.

Return value

This method returns a pointer to an NdbOperation object, or NULL.

NdbScanOperation::nextResult()

Description

This method is used to fetch the next tuple in a scan transaction. Following each call to nextResult(), the buffers and NdbRecAttr objects defined in NdbOperation::getValue() are updated with values from the scanned tuple.

When nextResult() is executed following end-of-file, NDB returns error code 4210 (Ndb sent more info than length specified) and the extra transaction object is freed by returning it to the idle list for the right TC node.

Signatures

This method can be invoked in one of two ways. The first of these is shown here:

int nextResult
    (
      bool fetchAllowed = true,
      bool forceSend = false
    )

It is also possible to use this method as shown here:

int nextResult
    (
      const char*& outRow,
      bool fetchAllowed = true,
      bool forceSend = false
    )
Parameters (2-parameter version)

This method takes the following two parameters:

  • Normally, the NDB API contacts the NDB kernel for more tuples whenever it is necessary; setting fetchAllowed to false keeps this from happening.

    Disabling fetchAllowed by setting it to false forces NDB to process any records it already has in its caches. When there are no more cached records it returns 2. You must then call nextResult() with fetchAllowed equal to true in order to contact NDB for more records.

    While nextResult(false) returns 0, you should transfer the record to another transaction using execute(NdbTransaction::NoCommit). When nextResult(false) returns 2, you should normally execute and commit the other transaction. This causes any locks to be transferred to the other transaction, updates or deletes to be made, and then, the locks to be released. Following this, you can call nextResult(true) to have more records fetched and cached in the NDB API.

    Note

    If you do not transfer the records to another transaction, the locks on those records will be released the next time that the NDB Kernel is contacted for more records.

    Disabling fetchAllowed can be useful when you want to update or delete all of the records obtained in a given transaction, as doing so saves time and speeds up updates or deletes of scanned records.

  • forceSend defaults to false, and can normally be omitted. However, setting this parameter to true means that transactions are sent immediately. See Section 1.4.4, “The Adaptive Send Algorithm”, for more information.

Parameters (3-parameter version)

This method can also be called with the following three parameters:

  • Calling nextResult() sets a pointer to the next row in outRow (if returning 0). This pointer is valid (only) until the next call to nextResult() when fetchAllowed is true. The NdbRecord object defining the row format must be specified beforehand using NdbTransaction::scanTable() (or NdbTransaction::scanIndex().

  • When false, fetchAllowed forces NDB to process any records it already has in its caches. See the description for this parameter in the previous Parameters subsection for more details.

  • Setting forceSend to true means that transactions are sent immediately, as described in the previous Parameters subsection, as well as in Section 1.4.4, “The Adaptive Send Algorithm”.

Return value

This method returns one of the following 4 integer values, interpreted as shown in the following list:

  • -1: Indicates that an error has occurred.

  • 0: Another tuple has been received.

  • 1: There are no more tuples to scan.

  • 2: There are no more cached records (invoke nextResult(true) to fetch more records).

Example

See Section 2.5.4, “NDB API Basic Scanning Example”.

NdbScanOperation::readTuples()

Description

This method is used to perform a scan.

Signature
virtual int readTuples
    (
      LockMode mode = LM_Read,
      Uint32   flags = 0,
      Uint32   parallel = 0,
      Uint32   batch = 0
    )
Parameters

This method takes the four parameters listed here:

  • The lock mode; this is a LockMode value.

    Scans with exclusive locks.  When scanning with an exclusive lock, extra care must be taken due to the fact that, if two threads perform this scan simultaneously over the same range, then there is a significant probability of causing a deadlock. The likelihood of a deadlock is increased if the scan is also ordered (that is, using SF_OrderBy or SF_Descending).

    The NdbScanOperation::close() method is also affected by this deadlock, since all outstanding requests are serviced before the scan is actually closed.

  • One or more ScanFlag values. Multiple values are OR'ed together

  • The number of fragments to scan in parallel; use 0 to require that the maximum possible number be used.

  • The batch parameter specifies how many records will be returned to the client from the server by the next NdbScanOperation::nextResult(true) method call. Use 0 to specify the maximum automatically.

Return value

Returns 0 on success, -1 on failure.

NdbScanOperation::restart()

Description

Use this method to restart a scan without changing any of its getValue() calls or search conditions.

Signature
int restart
    (
      bool forceSend = false
    )
Parameters

Call this method with forceSend set to true in order to force the transaction to be sent.

Return value

0 on success; -1 on failure.

NdbScanOperation::ScanFlag

This section provides information about the ScanFlag data type.

Description

Values of this type are the scan flags used with the readTuples() method. More than one may be used, in which case, they are OR'ed together as the second argument to that method. See NdbScanOperation::readTuples(), for more information.

Enumeration values

Possible values are shown, along with descriptions, in the following table:

Table 2.63 NdbScanOperation::ScanFlag values and descriptions

Value Description
SF_TupScan Scan in TUP order (that is, in the order of the rows in memory). Applies to table scans only.
SF_DiskScan Scan in disk order (order of rows on disk). Applies to table scans only.
SF_OrderBy

Ordered index scan (ascending); rows returned from an index scan are sorted, and ordered on the index key. Scans in either ascending or descending order are affected by this flag, which causes the API to perform a merge-sort among the ordered scans of each fragment to obtain a single sorted result set.

Notes:

  • Ordered indexes are distributed, with one ordered index for each fragment of a table.

  • Range scans are often parallel across all index fragments. Occasionally, they can be pruned to one index fragment.

  • Each index fragment range scan can return results in either ascending or descending order. Ascending is the default; to choose descending order, set the SF_Descending flag.

  • When multiple index fragments are scanned in parallel, the results are sent back to NDB where they can optionally be merge-sorted before being returned to the user. This merge sorting is controlled using the SF_OrderBy and SF_OrderByFull flags.

  • If SF_OrderBy or SF_OrderByFull is not used, the results from each index fragment are in order (either ascending or descending), but results from different fragments may be interleaved.

  • When using SF_OrderBy or SF_OrderByFull, some extra constraints are imposed internally; these are listed here:

    1. If the range scan is not pruned to one index fragment then all index fragments must be scanned in parallel. (Unordered scans can be executed with less than full parallelism.)

    2. Results from every index fragment must be available before returning any rows, to ensure a correct merge sort. This serialises the scrolling of the scan, potentially resulting in lower row throughput.

    3. Unordered scans can return rows to the API client before all index fragments have returned any batches, and can overlap next-batch requests with row processing.

SF_OrderByFull This is the same as SF_OrderBy, except that all key columns are added automatically to the read bitmask.
SF_Descending Causes an ordered index scan to be performed in descending order.
SF_ReadRangeNo For index scans, when this flag is set, NdbIndexScanOperation::get_range_no() can be called to read back the range_no defined in NdbIndexScanOperation::setBound(). In addition, when this flag is set, and SF_OrderBy or SF_OrderByFull is also set, results from ranges are returned in their entirety before any results are returned from subsequent ranges.
SF_MultiRange Indicates that this scan is part of a multirange scan; each range is scanned separately.
SF_KeyInfo Requests KeyInfo to be sent back to the caller. This enables the option to take over the row lock taken by the scan, using lockCurrentTuple(), by making sure that the kernel sends back the information needed to identify the row and the lock. This flag is enabled by default for scans using LM_Exclusive, but must be explicitly specified to enable the taking over of LM_Read locks. (See the LockMode documentation for more information.)

NdbScanOperation::ScanOptions

This section provides information about the ScanOptions data structure.

Parent class

NdbScanOperation

Description

This data structure is used to pass options to the NdbRecord-based scanTable() and scanIndex() methods of the NdbTransaction class. Each option type is marked as present by setting the corresponding bit in the optionsPresent field. Only the option types marked in the optionsPresent field need have sensible data.

All data is copied out of the ScanOptions structure (and any subtended structures) at operation definition time. If no options are required, then NULL may be passed as the ScanOptions pointer.

Members

The elements making up this structure are shown in the following table:

Table 2.64 NdbScanOperation::ScanOptions attributes, with types and descriptions

Name Type Description
optionsPresent Uint64 Which options are present.
[...] Type:
  • SO_SCANFLAGS: 0x01

  • SO_PARALLEL: 0x02

  • SO_BATCH: 0x04

  • SO_GETVALUE: 0x08

  • SO_PARTITION_ID: 0x10

  • SO_INTERPRETED: 0x20

  • SO_CUSTOMDATA: 0x40

  • SO_PARTINFO: 0x80

Type of options.
scan_flags Uint32 Flags controlling scan behavior; see NdbScanOperation::ScanFlag, for more information.
parallel Uint32 Scan parallelism; 0 (the default) sets maximum parallelism.
batch Uint32 Batch size for transfers from data nodes to API nodes; 0 (the default) enables this to be selected automatically.
extraGetValues GetValueSpec Extra values to be read for each row matching the sdcan criteria.
numExtraGetValues Uint32 Number of extra values to be read.
partitionId Uint32 Limit the scan to the partition having this ID; alternatively, you can supply an PartitionSpec here. For index scans, partitioning information can be supplied for each range.
interpretedCode NdbInterpretedCode Interpeted code to execute as part of the scan.
customData void* Data pointer to associate with this scan operation.
partitionInfo PartitionSpec Partition information for bounding this scan.
sizeOfPartInfo Uint32 Size of the bounding partition information.

For more information, see Section 2.3.22, “The NdbRecord Interface”.

NdbScanOperation::updateCurrentTuple()

Description

This method is used to update the current tuple.

Signature

Originally, this method could be called with a single. optional parameter, in either of the ways shown here:

NdbOperation* updateCurrentTuple
    (
      void
    )


NdbOperation* updateCurrentTuple
    (
      NdbTransaction* updateTrans
    )

It is also possible to employ this method, when using NdbRecord with scans, as shown here:

NdbOperation* updateCurrentTuple
    (
      NdbTransaction*      takeOverTrans,
      const NdbRecord*     record,
      const char*          row,
      const unsigned char* mask = 0
    )

See Section 2.3.22, “The NdbRecord Interface”, for more information.

Parameters (original)

This method takes a single, optional parameter—the transaction that should perform the lock. If this is omitted, the transaction is the current one.

Parameters (using NdbRecord)

When using the NdbRecord interface, this method takes the following parameters, as described in the following list:

  • The takeover transaction (takeOverTrans).

  • The record (NdbRecord object) referencing the column used for the scan.

  • The row to read from. If no attributes are to be read, set this equal to NULL.

  • The mask pointer is optional. If it is present, then only columns for which the corresponding bit in the mask is set are retrieved by the scan.

Return value

This method returns an NdbOperation object or NULL.