501 lines
13 KiB
C++
501 lines
13 KiB
C++
/*
|
|
Copyright (c) 2004, 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 NDB_QUERY_TREE_HPP
|
|
#define NDB_QUERY_TREE_HPP
|
|
|
|
#include <ndb_global.h>
|
|
#include <ndb_types.h>
|
|
|
|
#define JAM_FILE_ID 129
|
|
|
|
|
|
struct QueryNode // Effectively used as a base class for QN_xxxNode
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 tableId; // 16-bit
|
|
Uint32 tableVersion;
|
|
|
|
enum OpType
|
|
{
|
|
QN_LOOKUP = 0x1,
|
|
QN_SCAN_FRAG_v1 = 0x2, //deprecated
|
|
QN_SCAN_INDEX_v1 = 0x3, //deprecated
|
|
QN_SCAN_FRAG = 0x4, //Replaces both SCAN_*_v1's above
|
|
QN_END = 0
|
|
};
|
|
|
|
static Uint32 getOpType(Uint32 op_len) { return op_len & 0xFFFF;}
|
|
static Uint32 getLength(Uint32 op_len) { return op_len >> 16;}
|
|
|
|
static const QueryNode* nextQueryNode(const QueryNode* node)
|
|
{
|
|
const Uint32 len = QueryNode::getLength(node->len);
|
|
return (const QueryNode*)((Uint32*)node + len);
|
|
}
|
|
|
|
static void setOpLen(Uint32 &d, Uint32 o, Uint32 l) { d = (l << 16) | o;}
|
|
|
|
// If possible we should change the above static methods to non-static:
|
|
//Uint32 getOpType() const { return len & 0xFFFF;}
|
|
//Uint32 getLength() const { return len >> 16;}
|
|
//void setOpLen(Uint32 o, Uint32 l) { len = (l << 16) | o;}
|
|
};
|
|
|
|
struct QueryNodeParameters // Effectively used as a base class for QN_xxxParameters
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 resultData; // Api connect ptr
|
|
|
|
enum OpType
|
|
{
|
|
QN_LOOKUP = 0x1,
|
|
QN_SCAN_FRAG_v1 = 0x2, //deprecated
|
|
QN_SCAN_INDEX_v1 = 0x3, //deprecated
|
|
QN_SCAN_FRAG = 0x4, //Replaces both SCAN_*_v1's above
|
|
QN_END = 0
|
|
};
|
|
|
|
static Uint32 getOpType(Uint32 op_len) { return op_len & 0xFFFF;}
|
|
static Uint32 getLength(Uint32 op_len) { return op_len >> 16;}
|
|
|
|
static void setOpLen(Uint32 &d, Uint32 o, Uint32 l) { d = (l << 16) | o;}
|
|
|
|
// If possible we should change the above static methods to non-static:
|
|
//Uint32 getOpType() const { return len & 0xFFFF;}
|
|
//Uint32 getLength() const { return len >> 16;}
|
|
//void setOpLen(Uint32 o, Uint32 l) { len = (l << 16) | o;}
|
|
};
|
|
|
|
struct DABits
|
|
{
|
|
/**
|
|
* List of requestInfo bits shared for QN_LookupNode,
|
|
* QN_ScanFragNode & QN_ScanIndexNode
|
|
*/
|
|
enum NodeInfoBits
|
|
{
|
|
NI_HAS_PARENT = 0x01,
|
|
|
|
NI_KEY_LINKED = 0x02, // Does keyinfo contain linked values
|
|
NI_KEY_PARAMS = 0x04, // Does keyinfo contain parameters
|
|
NI_KEY_CONSTS = 0x08, // Does keyinfo contain const values
|
|
|
|
NI_LINKED_ATTR = 0x10, // List of attributes to be used by children
|
|
|
|
NI_ATTR_INTERPRET = 0x20, // Is attr-info a interpreted program
|
|
NI_ATTR_PARAMS = 0x40, // Does attrinfo contain parameters
|
|
NI_ATTR_LINKED = 0x80, // Does attrinfo contain linked values
|
|
|
|
/**
|
|
* Iff this flag is set, then this operation has a child operation with a
|
|
* linked value that refes to a disk column of this operation. For example
|
|
* SELECT * FROM t1, t2 WHERE t1.disk_att = t2.primary_key;
|
|
*/
|
|
NI_LINKED_DISK = 0x100,
|
|
|
|
/**
|
|
* If REPEAT_SCAN_RESULT is set, multiple star-joined (or bushy, or X)
|
|
* scan results are handled by repeating the other scans result
|
|
* when we advance to the next batch chunk for the current 'active'
|
|
* result set.
|
|
* This removes the requirement for the API client to being able
|
|
* buffer an (possible huge) amount of scan result relating to
|
|
* the same parent scan.
|
|
*/
|
|
NI_REPEAT_SCAN_RESULT = 0x200,
|
|
|
|
/**
|
|
* If INNER_JOIN is set, we need only to return rows if there
|
|
* is a (equality-) match on both tables.
|
|
* For non-matches the parent tuple will eventually be removed from the
|
|
* result set. This implies that other join-siblings of this parent
|
|
* tuple also will effectively be eliminated. Thus, producing further
|
|
* results having this tuple as a parent could be skipped.
|
|
*
|
|
* In Sql terms this is an INNER JOIN. Not setting an INNER_JOIN
|
|
* is similar to 'LEFT OUTER JOIN' result being produced.
|
|
*/
|
|
NI_INNER_JOIN = 0x400,
|
|
|
|
NI_END = 0
|
|
};
|
|
|
|
/**
|
|
* List of requestInfo bits shared for QN_LookupParameters,
|
|
* QN_ScanFragParameters & QN_ScanIndexParameters
|
|
*/
|
|
enum ParamInfoBits
|
|
{
|
|
PI_ATTR_LIST = 0x1, // "user" projection list
|
|
|
|
/**
|
|
* These 2 must match their resp. QueryNode-definitions
|
|
*/
|
|
PI_ATTR_PARAMS = 0x2, // attr-info parameters (NI_ATTR_PARAMS)
|
|
PI_KEY_PARAMS = 0x4, // key-info parameters (NI_KEY_PARAMS)
|
|
|
|
/**
|
|
* The parameter object contains a program that will be interpreted
|
|
* before reading the attributes (i.e. a scan filter).
|
|
* NOTE: Can/should not be used if QueryNode contains interpreted program
|
|
*/
|
|
PI_ATTR_INTERPRET = 0x8,
|
|
|
|
/**
|
|
* Iff this flag is set, then the user projection for this operation
|
|
* contains at least one disk column.
|
|
*/
|
|
PI_DISK_ATTR = 0x10,
|
|
PI_END = 0
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
* This node describes a pk-lookup
|
|
*/
|
|
struct QN_LookupNode // Is a QueryNode subclass
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 tableId; // 16-bit
|
|
Uint32 tableVersion;
|
|
STATIC_CONST ( NodeSize = 4 );
|
|
|
|
/**
|
|
* See DABits::NodeInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
|
|
enum LookupBits
|
|
{
|
|
/**
|
|
* This is lookup on index table,
|
|
*/
|
|
L_UNIQUE_INDEX = 0x10000,
|
|
|
|
L_END = 0
|
|
};
|
|
|
|
//Uint32 getLength() const { return len >> 16;}
|
|
//void setOpLen(Uint32 o, Uint32 l) { len = (l << 16) | o;}
|
|
};
|
|
|
|
/**
|
|
* This struct describes parameters that are associated with
|
|
* a QN_LookupNode
|
|
*/
|
|
struct QN_LookupParameters // Is a QueryNodeParameters subclass
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 resultData; // Api connect ptr
|
|
STATIC_CONST ( NodeSize = 3 );
|
|
|
|
/**
|
|
* See DABits::ParamInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
};
|
|
|
|
/**
|
|
* This node describes a table/index-fragment scan, Deprecated
|
|
*/
|
|
struct QN_ScanFragNode_v1 // Is a QueryNode subclass
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 tableId; // 16-bit
|
|
Uint32 tableVersion;
|
|
STATIC_CONST ( NodeSize = 4 );
|
|
|
|
/**
|
|
* See DABits::NodeInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
};
|
|
|
|
/**
|
|
* This struct describes parameters that are associated with
|
|
* a QN_ScanFragNode. Deprecated, was used for QN_SCAN_FRAG_v1
|
|
*/
|
|
struct QN_ScanFragParameters_v1 // Is a QueryNodeParameters subclass
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 resultData; // Api connect ptr
|
|
STATIC_CONST ( NodeSize = 3 );
|
|
|
|
/**
|
|
* See DABits::ParamInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
};
|
|
|
|
/**
|
|
* This node describes a IndexScan, Deprecated
|
|
*/
|
|
struct QN_ScanIndexNode_v1
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 tableId; // 16-bit
|
|
Uint32 tableVersion;
|
|
STATIC_CONST( NodeSize = 4 );
|
|
|
|
enum ScanIndexBits
|
|
{
|
|
/**
|
|
* If doing equality search that can be pruned
|
|
* a pattern that creates the key to hash with is stored before
|
|
* the DA optional part
|
|
*/
|
|
SI_PRUNE_PATTERN = 0x10000,
|
|
|
|
// Do pattern contain parameters
|
|
SI_PRUNE_PARAMS = 0x20000,
|
|
|
|
// Is prune pattern dependant on parent key (or only on parameters / constants)
|
|
SI_PRUNE_LINKED = 0x40000,
|
|
|
|
// Should it be parallel scan (can also be set as in parameters)
|
|
SI_PARALLEL = 0x80000,
|
|
|
|
SI_END = 0
|
|
};
|
|
|
|
/**
|
|
* See DABits::NodeInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
};
|
|
|
|
/**
|
|
* This struct describes parameters that are associated with
|
|
* a QN_ScanIndexNode. Deprecated, was used with QN_SCAN_INDEX_v1
|
|
*/
|
|
struct QN_ScanIndexParameters_v1
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 batchSize; // (bytes << 11) | (rows)
|
|
Uint32 resultData; // Api connect ptr
|
|
STATIC_CONST ( NodeSize = 4 );
|
|
// Number of bits for representing row count in 'batchSize'.
|
|
STATIC_CONST ( BatchRowBits = 11 );
|
|
|
|
enum ScanIndexParamBits
|
|
{
|
|
/**
|
|
* Do arguments contain parameters for prune-pattern
|
|
*/
|
|
SIP_PRUNE_PARAMS = 0x10000,
|
|
|
|
/**
|
|
* Should it scan index in parallel
|
|
* This is needed for "multi-cursor" semantics
|
|
* with (partial) ordering
|
|
*/
|
|
SIP_PARALLEL = 0x20000,
|
|
|
|
SIP_END = 0
|
|
};
|
|
|
|
/**
|
|
* See DABits::ParamInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
};
|
|
|
|
|
|
/**
|
|
* This node describes a Fragment scan (QN_SCAN_FRAG)
|
|
*/
|
|
struct QN_ScanFragNode // Note: Same layout as old QN_ScanIndexNode_v1
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 tableId; // 16-bit
|
|
Uint32 tableVersion;
|
|
STATIC_CONST( NodeSize = 4 );
|
|
|
|
enum ScanFragBits // Note: Same enum as old ScanIndexBits_v1
|
|
{
|
|
/**
|
|
* If doing equality search that can be pruned
|
|
* a pattern that creates the key to hash with is stored before
|
|
* the DA optional part
|
|
*/
|
|
SF_PRUNE_PATTERN = 0x10000,
|
|
|
|
// Do pattern contain parameters
|
|
SF_PRUNE_PARAMS = 0x20000,
|
|
|
|
// Is prune pattern dependant on parent key (or only on parameters / constants)
|
|
SF_PRUNE_LINKED = 0x40000,
|
|
|
|
// Should it be parallel scan (can also be set as in parameters)
|
|
SF_PARALLEL = 0x80000,
|
|
|
|
SF_END = 0
|
|
};
|
|
|
|
/**
|
|
* See DABits::NodeInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
};
|
|
|
|
/**
|
|
* This struct describes parameters that are associated with
|
|
* the new QN_ScanFragNode. (QN_SCAN_FRAG)
|
|
*/
|
|
struct QN_ScanFragParameters
|
|
{
|
|
Uint32 len;
|
|
Uint32 requestInfo;
|
|
Uint32 resultData; // Api connect ptr
|
|
Uint32 batch_size_rows;
|
|
Uint32 batch_size_bytes;
|
|
|
|
Uint32 unused0; // Future
|
|
Uint32 unused1;
|
|
Uint32 unused2;
|
|
|
|
STATIC_CONST ( NodeSize = 8 );
|
|
|
|
enum ScanFragParamBits
|
|
{
|
|
/**
|
|
* Do arguments contain parameters for prune-pattern
|
|
*/
|
|
SFP_PRUNE_PARAMS = 0x10000,
|
|
|
|
/**
|
|
* Should it scan fragments in parallel
|
|
* This is needed for "multi-cursor" semantics
|
|
* with (partial) ordering
|
|
*/
|
|
SFP_PARALLEL = 0x20000,
|
|
|
|
/**
|
|
* Should it produce result rows strictly in
|
|
* the order defined by the ordered index being used.
|
|
* (Also require SFP_PARALLEL)
|
|
*/
|
|
SFP_SORTED_ORDER = 0x40000,
|
|
|
|
SFP_END = 0
|
|
};
|
|
|
|
/**
|
|
* See DABits::ParamInfoBits
|
|
*/
|
|
Uint32 optional[1];
|
|
};
|
|
|
|
|
|
/**
|
|
* This is the definition of a QueryTree
|
|
*/
|
|
struct QueryTree
|
|
{
|
|
Uint32 cnt_len; // Length in words describing full tree + #nodes
|
|
Uint32 nodes[1]; // The nodes
|
|
|
|
static Uint32 getNodeCnt(Uint32 cnt_len) { return cnt_len & 0xFFFF;}
|
|
static Uint32 getLength(Uint32 cnt_len) { return cnt_len >> 16;}
|
|
static void setCntLen(Uint32 &d, Uint32 c, Uint32 l) { d=(l << 16) | c;}
|
|
};
|
|
|
|
/**
|
|
* This is description of *one* entry in a QueryPattern
|
|
* (used by various QueryNodes)
|
|
*/
|
|
struct QueryPattern
|
|
{
|
|
Uint32 m_info;
|
|
enum
|
|
{
|
|
P_DATA = 0x1, // Raw data of len-words (constants)
|
|
P_COL = 0x2, // Get column value from RowRef
|
|
P_UNQ_PK = 0x3, // NDB$PK column from a unique index
|
|
P_PARAM = 0x4, // User specified parameter value
|
|
P_PARENT = 0x5, // Move up in tree
|
|
P_PARAM_HEADER = 0x6, // User specified param val including AttributeHeader
|
|
P_ATTRINFO = 0x7,// Get column including header from RowRef
|
|
P_END = 0
|
|
};
|
|
|
|
static Uint32 getType(const Uint32 info) { return info >> 16;}
|
|
|
|
/**
|
|
* If type == DATA, get len here
|
|
*/
|
|
static Uint32 getLength(Uint32 info) { return info & 0xFFFF;}
|
|
static Uint32 data(Uint32 length)
|
|
{
|
|
assert(length <= 0xFFFF);
|
|
return (P_DATA << 16) | length;
|
|
}
|
|
|
|
/**
|
|
* If type == COL, get col-no here (index in row)
|
|
*/
|
|
static Uint32 getColNo(Uint32 info) { return info & 0xFFFF;}
|
|
static Uint32 col(Uint32 no) { return (P_COL << 16) | no; }
|
|
|
|
/**
|
|
* If type == P_UNQ_PK, get PK value from composite NDB$PK col.
|
|
*/
|
|
static Uint32 colPk(Uint32 no) { return (P_UNQ_PK << 16) | no; }
|
|
|
|
/**
|
|
* If type == PARAM, get param-no here (index in param list)
|
|
*/
|
|
static Uint32 getParamNo(Uint32 info) { return info & 0xFFFF;}
|
|
static Uint32 param(Uint32 no) { return (P_PARAM << 16) | no; }
|
|
|
|
static Uint32 paramHeader(Uint32 no) { return (P_PARAM_HEADER << 16) | no; }
|
|
|
|
/**
|
|
* get col including header
|
|
*/
|
|
static Uint32 attrInfo(Uint32 no) { return (P_ATTRINFO << 16) | no;}
|
|
|
|
/**
|
|
* Move to grand-parent no
|
|
* (0 == imediate parent)
|
|
*/
|
|
static Uint32 parent(Uint32 no) { return (P_PARENT << 16) | no;}
|
|
};
|
|
|
|
|
|
#undef JAM_FILE_ID
|
|
|
|
#endif
|