1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00
2025-02-21 20:02:38 +04:00

893 lines
24 KiB
C++

/* Copyright (C) 2014 InfiniDB, Inc.
Copyright (C) 2016-2021 MariaDB Corporation
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 Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/*
* $Id: primitivemsg.h 9655 2013-06-25 23:08:13Z xlou $
*/
/** @file */
#pragma once
#include <sys/types.h>
#include "blocksize.h"
#include "calpontsystemcatalog.h"
#include "joblisttypes.h"
#include <columnwidth.h>
#include <vector>
#pragma pack(push, 1)
// from blocksize.h
const int32_t DATA_BLOCK_SIZE = BLOCK_SIZE;
const int8_t COMPARE_NIL = 0x00; // means c = NULL predicate
const int8_t COMPARE_LT = 0x01;
const int8_t COMPARE_EQ = 0x02;
const int8_t COMPARE_LE = (COMPARE_LT | COMPARE_EQ); // 0x03
const int8_t COMPARE_GT = 0x04;
const int8_t COMPARE_NE = (COMPARE_LT | COMPARE_GT); // 0x05
const int8_t COMPARE_GE = (COMPARE_GT | COMPARE_EQ); // 0x06
const int8_t COMPARE_NULLEQ = 0x07; // means c IS NULL(see column.cpp for details)
const int8_t COMPARE_NOT = 0x08;
const int8_t COMPARE_NLT = (COMPARE_LT | COMPARE_NOT); // 0x09
const int8_t COMPARE_NLE = (COMPARE_LE | COMPARE_NOT); // 0x0b
const int8_t COMPARE_NGT = (COMPARE_GT | COMPARE_NOT); // 0x0c
const int8_t COMPARE_NGE = (COMPARE_GE | COMPARE_NOT); // 0x0e
const int8_t COMPARE_LIKE = 0x10;
const int8_t COMPARE_NLIKE = (COMPARE_LIKE | COMPARE_NOT); // 0x18
namespace primitives
{
using RIDType = uint16_t;
using NVALSType = uint16_t;
using utils::ConstString;
class StringComparator : public datatypes::Charset
{
public:
explicit StringComparator(const Charset& cs) : Charset(cs)
{
}
bool op(int* error, uint8_t COP, const ConstString& str1, const ConstString& str2) const
{
if (COP & COMPARE_LIKE)
return like(COP & COMPARE_NOT, str1, str2);
if (COP == COMPARE_NULLEQ)
return str1.isNull() ==
str2.isNull(); // XXX: TODO: I do not know the logic here, so it is temporary solution.
int cmp = strnncollsp(str1, str2);
switch (COP)
{
case COMPARE_NIL: return false;
case COMPARE_LT: return cmp < 0;
case COMPARE_EQ: return cmp == 0;
case COMPARE_LE: return cmp <= 0;
case COMPARE_GT: return cmp > 0;
case COMPARE_NE: return cmp != 0;
case COMPARE_GE: return cmp >= 0;
default: *error |= 1; return false;
}
}
};
} // namespace primitives
// BOP (Binary Operation) values
// used to tell if the operations are all be true or
// any to be true.
#define BOP_NONE 0
#define BOP_AND 1
#define BOP_OR 2
#define BOP_XOR 3
// OT (Output Type) values
// 1 = RID, 2 = Token, 3 = Both
#define OT_RID 1
#define OT_TOKEN 2
#define OT_BOTH 3 // both = RID & TOKEN
#define OT_DATAVALUE 4
#define OT_INPUTARG OT_RID // reuse OT_RID's flag in dictionary primitives. Specifies that
// the filter argument that matched should be part of the result set.
// (only makes sense when BOP = OR).
#define OT_AGGREGATE 8 // specifies that aggregate data should be generated
// Packet Header Types
enum PACKETTYPE
{
NULL1 = 0,
NULL2 = 0X0F,
DATA = 1,
CMD = 2,
FLOW = 3,
CONFIG = 9
};
enum TYPEFLOWCOMMAND
{
ACK = 1,
NACK = 2
};
// Define the ISM Commands
#define PRIM_LOCALBASE 10
#define PRIM_COLBASE 50
#define PRIM_INDEXBASE 100
#define PRIM_CACHEBASE 190
#define PRIM_DICTBASE 200
#define PRIM_DELIVERBASE 250
// 8 bits only!
enum ISMPACKETCOMMAND
{
// max of 50-10=40 commands
LOCAL_JOIN_BY_RID = PRIM_LOCALBASE + 0,
LOCAL_OR_BY_RID = PRIM_LOCALBASE + 1,
ARITHMETIC_FUNCTION = PRIM_LOCALBASE + 2,
FUNCTION_CALL = PRIM_LOCALBASE + 3,
FUNCTION_CALL_VECTOR = PRIM_LOCALBASE + 4,
LOCAL_COMPARE_BY_VALUE = PRIM_LOCALBASE + 5,
LOCAL_JOIN_BY_VALUE = PRIM_LOCALBASE + 6,
BATCH_PRIMITIVE_CREATE = PRIM_LOCALBASE + 7,
BATCH_PRIMITIVE_RUN = PRIM_LOCALBASE + 8,
BATCH_PRIMITIVE_DESTROY = PRIM_LOCALBASE + 9,
BATCH_PRIMITIVE_ADD_JOINER = PRIM_LOCALBASE + 10,
BATCH_PRIMITIVE_END_JOINER = PRIM_LOCALBASE + 11,
BATCH_PRIMITIVE_ACK = PRIM_LOCALBASE + 12,
BATCH_PRIMITIVE_ABORT = PRIM_LOCALBASE + 13,
// max of 100-50=50 commands
COL_RESULTS = PRIM_COLBASE + 0,
COL_AGG_RESULTS = PRIM_COLBASE + 1,
COL_BY_SCAN = PRIM_COLBASE + 2,
COL_BY_RID = PRIM_COLBASE + 3,
COL_AGG_BY_SCAN = PRIM_COLBASE + 4,
COL_AGG_BY_RID = PRIM_COLBASE + 5,
COL_JOIN_BY_SCAN = PRIM_COLBASE + 6,
COL_FILTER_BY_TOKEN = PRIM_COLBASE + 7,
COL_FILTER_BY_RID_VAL = PRIM_COLBASE + 8,
COL_BY_SCAN_RANGE = PRIM_COLBASE + 9,
COL_LOOPBACK = PRIM_COLBASE + 10,
// max of 190-100=90 commands
INDEX_RESULTS = PRIM_INDEXBASE + 0, // Obsolete ?
INDEX_SCAN_RESULTS = PRIM_INDEXBASE + 1, // p_IdxScan results
INDEX_WALK_RESULTS = PRIM_INDEXBASE + 2, // p_IdxWalk results
INDEX_LIST_RESULTS = PRIM_INDEXBASE + 3, // p_IdxList results
INDEX_LIST_AGGREGATE_RESULTS = PRIM_INDEXBASE + 4, // p_IdxListAggregate results
INDEX_SCAN_AGGREGATE_RESULTS = PRIM_INDEXBASE + 5, // p_IdxScanAggregate results
INDEX_BY_SCAN = PRIM_INDEXBASE + 6, // p_IdxScan
INDEX_BY_COMPARE = PRIM_INDEXBASE + 7, // Obsolete ?
INDEX_WALK = PRIM_INDEXBASE + 8, // p_IdxWalk
INDEX_LIST = PRIM_INDEXBASE + 9, // p_IdxList
INDEX_LIST_AGGREGATE = PRIM_INDEXBASE + 10, // p_IdxListAggregate
INDEX_SCAN_AGGREGATE = PRIM_INDEXBASE + 11, // p_IdxScanAggregate
// max of 200-190=10 commands
CACHE_OP_RESULTS = PRIM_CACHEBASE + 0, // Response msg
CACHE_FLUSH = PRIM_CACHEBASE + 1, // Flush the entire block cache
CACHE_CLEAN_VSS = PRIM_CACHEBASE + 2, // Clean out indicated VSS entries
CACHE_DROP_FDS = PRIM_CACHEBASE + 3, // Drop the whole file descriptor cache
FLUSH_ALL_VERSION = PRIM_CACHEBASE + 4, // Drop all versions of specified LBIDs
CACHE_FLUSH_BY_OID = PRIM_CACHEBASE + 5, // Drop all versions of all LBIDs for the given OIDs
CACHE_FLUSH_PARTITION = PRIM_CACHEBASE + 6, // Drop a partition
CACHE_PURGE_FDS = PRIM_CACHEBASE + 7, // Purge the file descriptor cache for the modified files
// max of 250-200=50 commands
DICT_RESULTS = PRIM_DICTBASE + 0,
DICT_TOKEN_BY_INDEX_COMPARE = PRIM_DICTBASE + 1,
DICT_TOKEN_BY_SCAN_COMPARE = PRIM_DICTBASE + 2,
DICT_SIGNATURE = PRIM_DICTBASE + 3,
DICT_AGGREGATE = PRIM_DICTBASE + 4,
DICT_AGGREGATE_RESULTS = PRIM_DICTBASE + 5,
DICT_SCAN_COMPARE_RESULTS = PRIM_DICTBASE + 6,
DICT_SIGNATURE_RANGE = PRIM_DICTBASE + 7,
DICT_CREATE_EQUALITY_FILTER = PRIM_DICTBASE + 8,
DICT_DESTROY_EQUALITY_FILTER = PRIM_DICTBASE + 9,
// max of 256-250=6 commands
DELIVER_TOKEN_RESULTS = PRIM_DELIVERBASE + 0,
DELIVER_RID_RESULTS = PRIM_DELIVERBASE + 1
};
#undef PRIM_LOCALBASE
#undef PRIM_COLBASE
#undef PRIM_INDEXBASE
#undef PRIM_DICTBASE
#undef PRIM_DELIVERBASE
/* Flags for BPP messages */
const uint16_t NEED_STR_VALUES = 0x01; // 1;
const uint16_t GOT_ABS_RIDS = 0x02; // 2;
const uint16_t GOT_VALUES = 0x04; // 4;
const uint16_t LBID_TRACE = 0x08; // 8;
const uint16_t HAS_JOINER = 0x10; // 16;
const uint16_t SEND_RIDS_AT_DELIVERY = 0x20; // 32;
const uint16_t HAS_ROWGROUP = 0x40; // 64;
const uint16_t JOIN_ROWGROUP_DATA = 0x80; // 128
const uint16_t HAS_WIDE_COLUMNS = 0x100; // 256;
// TODO: put this in a namespace to stop global ns pollution
enum PrimFlags
{
PF_LBID_TRACE = 0x01, /*!< Enable LBID tracing in PrimProc */
PF_PM_PROF = 0x02, /*!< Enable LBID tracing in PrimProc */
};
enum BPSOutputType
{
BPS_ELEMENT_TYPE,
STRING_ELEMENT_TYPE,
TABLE_BAND,
TUPLE,
ROW_GROUP
};
// Constant Message Header structures
// Packet Header for VBEU & CachEU
#if 0
struct VBCPacketHeader
{
// unsigned char Type:4;
// unsigned char SubType:4;
// unsigned int Size:16;
// unsigned int Dest:16;
unsigned int Source: 16;
unsigned char CmdAddr: 8;
};
#endif
// Packet Header for ISM SubBlock EU
// Changing this structure one !MUST! align ColResultHeader
struct ISMPacketHeader
{
ISMPacketHeader() : Interleave(0), Flags(0), Command(0), Size(0), Type(0), MsgCount(0), Status(0)
{
}
uint32_t Interleave;
uint16_t Flags;
uint8_t Command;
// !!! This attribute is used to store a sum which arg type is potentially uint64_t.
// As of 23.02.10 uint32_t here is always enough for the purpose of this attribute though.
uint16_t Size;
unsigned Type : 4;
unsigned MsgCount : 4;
uint16_t Status;
};
// Primitive request/response structure Header
//@Bug 2744 changed all variables to 32 bit, and took out StatementID
// Changing this structure one !MUST! align ColResultHeader
struct PrimitiveHeader
{
uint32_t SessionID; // Front end Session Identifier
uint32_t TransactionID; // Front end Transaction Identifier
uint32_t VerID; // DB Version ID used for this Session/Statement
uint32_t StepID; // Internal Primitive Sequence number
uint32_t UniqueID; // Unique ID for DEC and BPP
uint32_t Priority; // Priority level of the user
};
#if 0
struct AckNackHeader
{
int VerID: 16;
};
struct DiskResultsHeader
{
uint64_t LBID;
uint64_t VerID;
uint64_t ArbIndex;
uint64_t ISM;
uint64_t Status;
uint8_t data[DATA_BLOCK_SIZE];
};
#endif
// COL_LOOPBACK
struct ColLoopback
{
PrimitiveHeader Hdr; // 64 bit header
};
struct ColRequestHeaderDataType : public datatypes::Charset
{
int32_t CompType;
uint16_t DataSize;
uint8_t DataType; // enum ColDataType defined in calpont system catalog header file
ColRequestHeaderDataType() : Charset(my_charset_bin), CompType(0), DataSize(0), DataType(0)
{
}
explicit ColRequestHeaderDataType(const execplan::CalpontSystemCatalog::ColType& rhs)
: Charset(rhs.charsetNumber)
, CompType(rhs.compressionType)
, DataSize(rhs.colWidth)
, DataType(rhs.colDataType)
{
}
};
// COL_BY_SCAN
// Tied to ColByScanRangeRequestHeader and NewColRequestHeader. Check other headers if modifying.
struct ColByScanRequestHeader
{
PrimitiveHeader Hdr; // 64 bit header
uint64_t LBID;
ColRequestHeaderDataType colType;
uint8_t OutputType; // 1 = RID, 2 = Token, 3 = Both
uint8_t BOP; // 0 = N/A, 1 = AND, 2 = OR
uint16_t RidFlags; // a bitmap indicating the rid ranges in the result MSB => row 7680-8191
uint16_t NOPS;
uint16_t NVALS;
uint8_t sort;
ColByScanRequestHeader() : LBID(0), OutputType(0), BOP(0), RidFlags(0), NOPS(0), NVALS(0), sort(0)
{
memset(&Hdr, 0, sizeof(Hdr));
}
};
// COL_BY_SCAN_RANGE
// Tied to ColByScanRequestHeader and NewColRequestHeader. Check other headers if modifying.
struct ColByScanRangeRequestHeader
{
PrimitiveHeader Hdr; // 64 bit header
uint64_t LBID; // starting LBID
ColRequestHeaderDataType colType;
uint8_t OutputType; // 1 = RID, 2 = Token, 3 = Both
uint8_t BOP; // 0 = N/A, 1 = AND, 2 = OR
uint16_t RidFlags; // a bitmap indicating the rid ranges in the result MSB => row 7680-8191
uint16_t NOPS;
uint16_t NVALS;
uint8_t sort;
uint16_t Count; // Number of LBID's
ColByScanRangeRequestHeader()
: LBID(0), OutputType(0), BOP(0), RidFlags(0), NOPS(0), NVALS(0), sort(0), Count(0)
{
memset(&Hdr, 0, sizeof(Hdr));
}
};
// COL_BY_RID
struct ColByRIDRequestHeader
{
PrimitiveHeader Hdr; // 64 bit header
uint64_t LBID;
ColRequestHeaderDataType colType;
uint8_t OutputType; // 1 = RID, 2 = Token, 3 = Both
uint8_t BOP; // 0 = N/A, 1 = AND, 2 = OR
uint8_t InputFlags; // 1 = interpret each NOP & RID as a pair
uint16_t NOPS;
uint16_t NVALS;
uint8_t sort;
ColByRIDRequestHeader(); // QQ? Not used?
};
// COL_AGG_BY_SCAN
struct ColAggByScanRequestHeader
{
PrimitiveHeader Hdr; // 64 bit header
uint64_t LBID;
uint16_t DataSize;
uint8_t DataType; // enum ColDataType defined in calpont system catalog header file
uint8_t OutputType; // 1 = RID, 2 = Token, 3 = Both
uint8_t BOP; // 0 = N/A, 1 = AND, 2 = OR
uint8_t ExtraNotUsed;
uint16_t NOPS;
uint16_t NVALS;
};
// COL_AGG_BY_RID
struct ColAggByRIDRequestHeader
{
PrimitiveHeader Hdr; // 64 bit header
uint64_t LBID;
ColRequestHeaderDataType colType;
uint8_t OutputType; // 1 = RID, 2 = Token, 3 = Both
uint8_t BOP; // 0 = N/A, 1 = AND, 2 = OR
uint8_t ExtraNotUsed;
uint16_t NOPS;
uint16_t NVALS;
ColAggByRIDRequestHeader(); // Not used?
};
// Loopback Results
struct LoopbackResultHeader
{
PrimitiveHeader Hdr;
};
// Column Results
// Column Aggregate results
struct ColAggResultHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
uint64_t MIN; // Minimum value in this block (signed)
uint64_t MAX; // Maximum value in this block (signed)
uint64_t SUM; // Sum of values in this block (unsigned)
uint32_t SUMOverflow; // Overflow of sum (unsigned)
uint16_t NVALS; // Number of values in this block
uint16_t Pad1;
};
// INDEX_BY_SCAN
struct IndexByScanRequestHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
uint32_t State;
uint8_t Flags;
uint8_t DataSize;
uint8_t DataType; // enum ColDataType defined in calpont system catalog header file
uint8_t ExtraNotUsed;
uint16_t NVALS;
};
// INDEX_BY_COMPARE
struct IndexByCompareRequestHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
uint32_t State;
uint8_t Flags;
uint8_t DataSize;
uint8_t DataType; // enum ColDataType defined in calpont system catalog header file
uint8_t ExtraNotUsed;
uint16_t NVALS;
};
struct IndexResultHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
uint32_t State;
uint16_t NVALS;
uint16_t Pad;
};
// p_IdxWalk
// this is used as input & output to the software p_IdxWalk processor. Ideally
// there would only be one copy of the ISM and packet headers per returned result.
#ifdef __cplusplus
struct IndexWalkHeader
{
ISMPacketHeader ism;
PrimitiveHeader Hdr;
uint64_t SearchString[2];
const std::vector<uint64_t>* SearchStrings; // used only if NVALS > 2
uint8_t SSlen; // width of the search argument in BITS
uint8_t Shift; // initialize to zero when first sending to primitive
uint8_t BOP;
uint8_t COP1;
uint8_t COP2;
uint8_t State; // right now this is only 1 or 0, specifying entire subtrees
uint16_t NVALS;
uint64_t LBID : 36;
uint8_t SubBlock : 5;
uint8_t SBEntry : 5;
};
#endif
// p_IdxList
struct IndexListHeader
{
ISMPacketHeader ism;
PrimitiveHeader Hdr;
uint64_t LBID;
uint16_t NVALS;
uint16_t Pad1;
uint32_t Pad2;
// As the input parameter, what follows is IndexListParam[NVALS]
// As the output parameter, what follows is IndexListResult[NVALS]
};
// p_IdxList parameter
struct IndexListParam
{
uint64_t type : 3; // 0 - header, 4 - subblock, 5 - block
uint64_t spare : 15;
uint64_t fbo : 36;
uint64_t sbid : 5;
uint64_t entry : 5;
// int64_t listValue;
};
struct IndexListEntry
{
uint64_t type : 3;
uint64_t spare : 5;
uint64_t ridCt : 10;
uint64_t value : 46;
};
struct IndexListResult
{
IndexListEntry entry;
int64_t listValue;
};
enum IndexListType
{
LIST_SIZE = 0,
EMPTY_LIST_PTR = 1,
EMPTY_PTR = 2,
RID = 3,
LLP_SUBBLK = 4,
LLP_BLK = 5,
PARENT = 6,
NOT_IN_USE = 7
};
// DICT_TOKEN_BY_INDEX_COMPARE
struct DictTokenByIndexRequestHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
uint16_t NVALS;
uint16_t Pad1;
uint32_t Pad2;
};
// DICT_TOKEN_BY_SCAN_COMPARE
struct DataValue
{
uint8_t isnull;
uint16_t len;
char data[];
};
struct NonNullDataValue
{
uint16_t len;
char data[];
};
struct PrimToken
{
uint64_t LBID;
uint16_t offset; // measured in bytes
uint16_t len; // # of bytes
};
// Masks for the flags member of TokenByScanRequestHeader
#define HAS_EQ_FILTER 0x1
#define IS_SYSCAT 0x2
struct TokenByScanRequestHeader
{
ISMPacketHeader ism;
PrimitiveHeader Hdr;
uint64_t LBID;
int32_t CompType;
uint8_t COP1;
uint8_t COP2;
uint8_t BOP;
uint8_t OutputType;
uint16_t NVALS;
uint16_t flags;
uint32_t Pad2;
uint16_t Count;
uint32_t charsetNumber;
}; // what follows is NVALS DataValues.
// compatibility with Ron's stuff.
typedef TokenByScanRequestHeader DictTokenByScanRequestHeader;
struct TokenByScanResultHeader
{
ISMPacketHeader ism;
PrimitiveHeader Hdr;
uint32_t NBYTES;
uint16_t NVALS;
uint16_t Pad1;
uint32_t CacheIO; // I/O count from buffer cache
uint32_t PhysicalIO; // Physical I/O count from disk
}; // what follows is NVALS Tokens or DataValues.
// DICT_SIGNATURE
struct DictSignatureRequestHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
int32_t CompType;
uint16_t NVALS;
uint16_t Pad1;
uint32_t Pad2;
};
// Tied to DictSignatureRequestHeader, note if modifying either.
struct DictSignatureRangeRequestHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
int32_t CompType;
uint16_t NVALS;
uint16_t Pad1;
uint32_t Pad2;
uint16_t Count;
};
// DICT_AGGREGATE
struct DictAggregateRequestHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
int32_t CompType;
uint16_t NVALS;
uint16_t Pad1;
uint32_t Pad2;
};
struct DictResultHeader
{
PrimitiveHeader Hdr;
uint64_t LBID;
uint16_t NVALS;
uint16_t Pad1;
uint32_t Pad2;
};
struct AggregateSignatureRequestHeader
{
ISMPacketHeader ism;
PrimitiveHeader hdr;
uint16_t NVALS;
PrimToken tokens[];
};
struct AggregateSignatureResultHeader
{
ISMPacketHeader ism;
PrimitiveHeader hdr;
uint16_t Count;
// these implicitly follow the header
// DataValue min;
// DataValue max;
};
/* An array of these structures defines a filter applied by p_Col. The length
* of the val field should be the width of the column the filter will be applied
* to, ex: 4 bytes long for a 32-bit column.
*/
struct ColArgs
{
uint8_t COP;
uint8_t rf; // rounding flag: indicates if val is truncated or saturated
// for further evaluation of an equal condiction
int8_t val[];
};
// const for rf
const uint8_t ROUND_POS = 0x01; // actual value larger/longer than the stored value
const uint8_t ROUND_NEG = 0x80; // actual value less than the stored value
// Tied to ColByScanRequestHeader and ColByScanRangeRequestHeader. Check other headers if modifying.
struct /*alignas(utils::MAXCOLUMNWIDTH)*/ NewColRequestHeader
{
ISMPacketHeader ism;
PrimitiveHeader hdr;
uint64_t LBID;
ColRequestHeaderDataType colType;
uint8_t OutputType; // OT_DATAVALUE, OT_RID, or OT_BOTH
uint8_t BOP;
// uint8_t InputFlags; // 1 = interpret each NOP & RID as a pair (deprecated)
uint16_t RidFlags; // a bitmap indicating the rid ranges in the result MSB => row 7680-8191
uint16_t NOPS;
uint16_t NVALS;
uint8_t sort; // 1 to sort
bool hasAuxCol;
// this follows the header
// ColArgs ArgList[NOPS] (where the val field is DataSize bytes long)
// uint16_t Rids[NVALS] (each rid is relative to the given block)
// QQ: The below constructor is never used.
// This struct is used in a cast only, in a hackish way.
NewColRequestHeader();
inline uint16_t* getRIDArrayPtr(const int width) const
{
return (NVALS > 0) ? reinterpret_cast<uint16_t*>((uint8_t*)this + sizeof(NewColRequestHeader) +
(NOPS * getFilterSize(width)))
: nullptr;
}
// WIP change to unsigned if needed
inline int getFilterSize(const int width) const
{
return sizeof(uint8_t) + sizeof(uint8_t) + width;
}
inline uint8_t* getFilterStringPtr()
{
return reinterpret_cast<uint8_t*>(this) + sizeof(NewColRequestHeader);
}
inline void sortRIDArrayIfNeeded(const int width)
{
// NVALS means number of RIDs in the context of the f().
if (NVALS > 0)
{
uint16_t* ridArray = getRIDArrayPtr(width);
if (sort == 1)
std::sort(ridArray, ridArray + NVALS);
}
}
};
struct NewColAggRequestHeader
{
ISMPacketHeader ism;
PrimitiveHeader hdr;
uint64_t LBID;
ColRequestHeaderDataType colType;
uint8_t OutputType;
uint8_t BOP;
uint8_t ExtraNotUsed;
uint16_t NOPS;
uint16_t NVALS;
// this follows the header
// ColArgs ArgList[NOPS] (where the val field is DataSize bytes long)
// uint16_t Rids[NVALS] (each rid is relative to the given block)
NewColAggRequestHeader(); // QQ: not used
};
// The size of the structure !MUST! be aligned by the max(sizeof(DataType)) supported by MCS.
struct ColResultHeader
{
PrimitiveHeader hdr;
int128_t Min; // Minimum value in this block for signed data types
int128_t Max; // Maximum value in this block for signed data types
ISMPacketHeader ism;
uint64_t LBID;
uint16_t RidFlags;
primitives::NVALSType NVALS;
uint16_t ValidMinMax; // 1 if Min/Max are valid, otherwise 0
uint32_t OutputType;
uint32_t CacheIO; // I/O count from buffer cache
uint32_t PhysicalIO; // Physical I/O count from disk
char padding[34];
// if OutputType was OT_DATAVALUE, what follows is DataType[NVALS]
// if OutputType was OT_RID, what follows is uint16_t Rids[NVALS]
// if OutputType was OT_BOTH, what follows is uint16_t Rids[NVALS] DataType[NVALS]
};
namespace primitives
{
constexpr static uint32_t ColResultHeaderFirstValueOffset =
sizeof(ColResultHeader) + sizeof(RIDType) * BLOCK_SIZE;
constexpr static uint32_t RID2FirstValueOffset = sizeof(RIDType) * BLOCK_SIZE;
template <typename T>
inline T* getValuesArrayPosition(uint8_t* out, const NVALSType offset)
{
return reinterpret_cast<T*>(out + offset * sizeof(T));
}
inline primitives::RIDType* getRIDArrayPosition(uint8_t* out, const NVALSType offset)
{
return getValuesArrayPosition<RIDType>(out, offset);
}
inline uint8_t* getFirstValueArrayPosition(ColResultHeader* outMsg)
{
return reinterpret_cast<uint8_t*>(outMsg) + ColResultHeaderFirstValueOffset;
}
inline uint8_t* getFirstRIDArrayPosition(ColResultHeader* outMsg)
{
return reinterpret_cast<uint8_t*>(&outMsg[1]);
}
} // namespace primitives
/* additional types to support p_dictionary */
struct DictFilterElement
{
uint8_t COP;
uint16_t len; // this is the length of data, not the size of the entire entry
uint8_t data[];
};
struct DictInput
{
ISMPacketHeader ism;
PrimitiveHeader hdr;
uint64_t LBID;
uint8_t BOP;
uint8_t InputFlags; // 1 -> 64-bit RID, 64-bit token pairs (old p_GetSignature behavior),
// 0-> new behavior
uint8_t OutputType;
uint16_t NOPS;
uint16_t NVALS;
PrimToken tokens[]; // NVALS of these.
// DictFilterElement[NOPS] filter;
};
struct DictAggregate
{
uint16_t Count;
// DataValue min;
// DataValue max;
};
struct DictOutput
{
ISMPacketHeader ism;
PrimitiveHeader hdr;
uint64_t LBID;
uint16_t NVALS;
uint16_t Pad;
uint32_t NBYTES;
uint32_t CacheIO; // I/O count from buffer cache
uint32_t PhysicalIO; // Physical I/O count from disk
// What follows this header depends on OutputType.
// for each NVAL, what follows is ...
// if OutputType | OT_RID & InputFlags==1, the 64-bit RID associated with the input token
// if OutputType | OT_TOKEN, a PrimToken
// if OutputType | OT_DATAVALUE, a DataValue containing the string in the dict block
// if OutputType | OT_INPUT, a DataValue containing the first filter string...
// ... that matched (only makes sense when BOP is OR).
// DictAggregate agg; (if OutputType | OT_AGGREGATE)
}; // same as TokenByScanResultHeader at the moment
struct OldGetSigParams
{
uint64_t rid;
uint16_t offsetIndex;
};
struct LbidAtVer
{
uint64_t LBID;
uint32_t Ver;
};
#pragma pack(pop)