blob: 8c017e198ac412dea97f4db938a980ed329d0c20 [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
#ifndef EXP_TUPLE_DESC_H
#define EXP_TUPLE_DESC_H
/* -*-C++-*-
*****************************************************************************
*
* File: <file>
* Description:
*
* Created: 5/30/96
* Language: C++
*
*
*
*
*****************************************************************************
*/
#include "ExpAlignedFormat.h"
// Forward external references
class Attributes;
class ex_clause;
// -----------------------------------------------------------------------
// Classes defined in this file
// -----------------------------------------------------------------------
class ExpTupleDesc;
// ---------------------------------------------------------------------
// Template instantiation to produce a 64-bit pointer emulator class
// for ExTupleDesc
// ---------------------------------------------------------------------
typedef NAVersionedObjectPtrTempl<ExpTupleDesc> ExpTupleDescPtr;
typedef NAVersionedObjectPtrArrayTempl<ExpTupleDescPtr> ExpTupleDescPtrPtr;
typedef NAVersionedObjectPtrTempl<Attributes> AttributesPtr;
typedef NAVersionedObjectPtrArrayTempl<AttributesPtr> AttributesPtrPtr;
#define NEG_BIT_MASK 0x0080 //the first bit in a byte - used for finding
//out whether the negative bit in a number
//is flipped
// Size of each VOA array entry for SQLMX_FORMAT.
// The SQLMX_ALIGNED_FORMAT has its own constant in ExpAlignedFormat.h
static const UInt32 ExpVoaSize = sizeof(Int32);
static const UInt32 ExpOffsetMax = UINT_MAX;
////////////////////////////////////////////////////////////////////
//
// class ExpTupleDesc
//
////////////////////////////////////////////////////////////////////
class ExpTupleDesc : public NAVersionedObject
{
public:
//
// Format of data in tuple:
//
// PACKED_FORMAT: records stored in tables created on SQL/MP.
// Fields stored without any alignment.
// If nullable field, null indicator bytes are
// stored just before the actual data.
// Null indicator length = 2.
// If variable length field, the varchar length
// bytes are stored just before the actual varchar data.
// Varchar indicator length = 2.
// Varchars are NOT stored in exploded format.
//
// SQLMX_KEY_FORMAT:
// Fields aligned like PACKED_FORMAT plus (no VOA)
// varchars are blank padded to max len. Used to
// build key buffers for SQL/MX and SQL/MP tables.
//
// SQLARK_EXPLODED_FORMAT:
// All fields aligned on their appropriate byte boundary.
// Int16 aligned on 2 byte, Int32 on 4 byte and Int64
// on 8-byte boundary.
// If nullable field, null indicator bytes are
// stored just before the actual data.
// Null indicator length = 2.
// If variable length field, the varchar length
// bytes are stored just before the actual varchar data.
// Varchar indicator length = 2 or 4.
// Varchars stored in exploded format(blankpadded
// to max len).
//
// SQLMX_FORMAT:
// Records stored in tables created within SQL/MX.
// Fields are stored as follows (without any alignment):
// all fixed fields stored first, then all variable
// length fields.
// There is an additional VariableOffsetArray that is
// stored on disk. This array is the # of variable
// length fields + 1 (for the first fixed field). Each
// VOA entry is 4 bytes.
//
// SQLMX_ALIGNED_FORMAT:
// Records are padded if needed to 4 byte boundaries.
// Fixed fields are re-arranged and grouped based on their
// alignment boundaries.
// Added fixed length columns follow the original fixed
// fields and are in the logical order they were added.
// Null bitmap at the beginning of record to record
// null column values.
// For more details see exp/ExpAlignedFormat.h
//
enum TupleDataFormat
{ UNINITIALIZED_FORMAT,
OBSOLETE_SIMULATOR_FORMAT,
PACKED_FORMAT, SQLMX_KEY_FORMAT,
SQLARK_EXPLODED_FORMAT,
SQLMX_FORMAT,
SQLMX_ALIGNED_FORMAT
};
enum TupleDescConstants
{
// Size of each VOA (variable offset array) entry for SQLMX_FORMAT records
// data. This includes the first fixed field offset (i.e., VOA[0])
EXP_VOA_SIZE = sizeof(UInt32)
,NULL_INDICATOR_LENGTH = sizeof(Int16)
,VC_ACTUAL_LENGTH = sizeof(UInt16) // varchar actual length
,SQLMX_VC_ACTUAL_LENGTH = sizeof(UInt32) // SQLMX_FORMAT varchar data len
,KEY_NULL_INDICATOR_LENGTH = sizeof(Int16) // Key null indicator length
};
// Format of tuple descriptor.
// LONG_FORMAT: Contains information about the tuple and each attribute
// that it contains.
// 'this' class is followed by an array of size numAttrs_.
// The array is followed by numAttrs_ Attributes. Each array
// entry points to the corresponding Attribute. The array
// is needed because the size of all Attributes may not be
// the same. See file exp_attrs.h for details on Attributes
// class.
//
// SHORT_FORMAT: Only contains 'this' class.
//
enum TupleDescFormat
{ SHORT_FORMAT, LONG_FORMAT
};
private:
enum flagsType
{
PACKED = 0x0001,
VAR_FIELD_PRESENT = 0x0002,
ADDED_COLUMN = 0x0004,
TDM_FLOAT_PRESENT = 0x0008,
KEY_SHIFT = 0x0010, // key fields may be shifted
// thus pCode can not be relied on
ADDED_FIXED_PRESENT = 0x0020
};
// Optional array of numAttrs_ Attributes pointers.
// Each entry points to the corresponding Attributes structure.
AttributesPtrPtr attrs_; // 00-07
// number of attributes/fields/columns/entries in this tuple
UInt32 numAttrs_; // 08-11
// total length of the generated tuple descriptor. Includes
// sizeof(this) + size of Attributes array + size of all
// Attributes.
UInt32 tupleDescLength_; // 12-15
// total max length of data in this tuple
UInt32 tupleDataLength_; // 16-19
Int16 /*TupleDataFormat*/ tupleDataFormat_; // 20-21
Int16 /*TupleDescFormat*/ tupleDescFormat_; // 22-23
UInt32 flags_; // 24-27
// ---------------------------------------------------------------------
// Fillers for potential future extensions without changing class size.
// When a new member is added, size of this filler should be reduced so
// that the size of the object remains the same (and is modulo 8).
// ---------------------------------------------------------------------
char fillers_[4]; // 28-31
Int16 packed()
{
return (Int16)(flags_ & PACKED);
}
public:
ExpTupleDesc(UInt32 num_attrs,
Attributes ** attrs,
UInt32 tupleDataLength,
TupleDataFormat tdataF,
TupleDescFormat tdescF,
Space * space);
ExpTupleDesc(UInt32 num_attrs,
AttributesPtr * attrs,
UInt32 tupleDataLength,
TupleDataFormat tdataF,
TupleDescFormat tdescF);
ExpTupleDesc();
~ExpTupleDesc();
UInt32 numAttrs(){return numAttrs_;}
/* Attributes** */ AttributesPtr * attrs(){return attrs_;}
Attributes * getAttr(UInt32 attr_num) {return attrs_[attr_num];}
virtual Long pack(void *);
virtual Int32 unpack(void *, void * reallocator);
////////////////////////////////////////////////////////
// Computes offsets of all attributes in the attrs array.
// start_offset could be passed in optionally indicating
// offsets computation to start there.
////////////////////////////////////////////////////////
static Int16 computeOffsets(UInt32 num_attr,
Attributes ** attrs,
TupleDataFormat tf,
UInt32 & datalen,
UInt32 startOffset = 0,
UInt32 * rtnFlags = NULL,
TupleDataFormat * outTf = NULL,
ExpHdrInfo * hdrInfo = NULL,
UInt32 * headerSizePtr = NULL,
UInt32 * VarSizePtr = NULL);
////////////////////////////////////////////////////////
// Computes offsets of a single attribute.
// start_offset could be passed in optionally indicating
// offsets computation to start there.
////////////////////////////////////////////////////////
static Int16 computeOffsets(Attributes * attr,
TupleDataFormat tf,
UInt32 & datalen,
UInt32 startOffset = 0);
////////////////////////////////////////////////////////
// Class method that centralizes SQLARK_EXPLODED_FORMAT tuple
// format offset calculations. Returns aligned column offset.
////////////////////////////////////////////////////////
static UInt32 sqlarkExplodedOffsets(
UInt32 offset,
UInt32 length,
Int16 dataType,
NABoolean isNullable,
UInt32 * nullIndicatorOffset = NULL,
UInt32 * vcIndicatorOffset = NULL,
UInt32 vcIndicatorSize = ExpTupleDesc::VC_ACTUAL_LENGTH);
Int16 operator==(ExpTupleDesc * td);
// assigns the atp and atp_index value to all attributes
void assignAtpAndIndex(Int16 atp, Int16 atp_index);
UInt32 tupleDescLength() {return tupleDescLength_;}
UInt32 tupleDataLength() {return tupleDataLength_;}
void setAddedField()
{ flags_ |= ADDED_COLUMN; }
Int16 addedFieldPresent()
{ return (Int16)(flags_ & ADDED_COLUMN); }
void setAddedFixed()
{ flags_ |= ADDED_FIXED_PRESENT; }
Int16 addedFixedPresent()
{ return (Int16)(flags_ & ADDED_FIXED_PRESENT); }
NABoolean variableFieldPresent()
{ return( (flags_ & (UInt32)VAR_FIELD_PRESENT) != 0 ); }
NABoolean tandemFloatPresent()
{ return( (flags_ & (UInt32)TDM_FLOAT_PRESENT) != 0 ); }
// Check if key fields may be shifted due to an added column or not.
NABoolean isKeyShifted()
{ return( (flags_ & KEY_SHIFT) > 0 ); }
void setFlags(UInt32 newFlags) { flags_ = newFlags; }
Int16 tupleFormat() { return tupleDataFormat_; };
const char *tupleFormatStr() {
switch(tupleDataFormat_) {
case UNINITIALIZED_FORMAT:
return "Uninitialized";
case OBSOLETE_SIMULATOR_FORMAT:
return "Simulator";
case PACKED_FORMAT:
return "Packed";
case SQLMX_KEY_FORMAT:
return "Key";
case SQLARK_EXPLODED_FORMAT:
return "Exploded";
case SQLMX_FORMAT:
return "SqlMX";
case SQLMX_ALIGNED_FORMAT:
return "Aligned";
default:
return "Unknown";
}
}
NABoolean isSQLMXTable()
{ return tupleDataFormat_ == (Int16) ExpTupleDesc::SQLMX_FORMAT; }
NABoolean isSQLMXAlignedTable()
{ return tupleDataFormat_ == (Int16)ExpTupleDesc::SQLMX_ALIGNED_FORMAT; }
NABoolean isSQLPackedTable()
{ return tupleDataFormat_ == (Int16) ExpTupleDesc::PACKED_FORMAT; }
// computeFirstFixedOffset
// Called at compile time to compute the offset to the first fixed
// field.
// For SQLMX_FORMAT set it to the minimum that it can be - right
// after VOA[0].
// For SQLMX_ALIGNED_FORMAT see notes in ExpAlignedFormat.h
static UInt32 computeFirstFixedOffset(Int32 ffAlignSize,
UInt32 startOffset,
UInt32 voaIdxOffset,
TupleDataFormat tdf,
UInt32 nullableFieldCount,
ExpHdrInfo * hdrInfo,
UInt32 & headerSize,
UInt32 & bitmapOffset)
{
if ( tdf == ExpTupleDesc::SQLMX_ALIGNED_FORMAT )
{
return ExpAlignedFormat::computeFirstFixedOffset( ffAlignSize,
startOffset,
voaIdxOffset,
nullableFieldCount,
hdrInfo,
headerSize,
bitmapOffset );
}
else
{
headerSize = ExpVoaSize; // First fixed field offset
if (hdrInfo != NULL)
{
hdrInfo->setValues(headerSize); // first fixed field offset area
}
return voaIdxOffset + headerSize;
}
}
static UInt32 read4( char *tempPtr )
{
// use 'unsigned char *' so that the value is not sign extended.
UChar *dataPtr = (UChar *)tempPtr;
#ifdef NA_BIG_ENDIAN
return (dataPtr[0] << 24) |
(dataPtr[1] << 16) |
(dataPtr[2] << 8) |
(dataPtr[3]);
#else
return (dataPtr[3] << 24) |
(dataPtr[2] << 16) |
(dataPtr[1] << 8) |
(dataPtr[0]);
#endif
}
static UInt32 read2( char *tempPtr )
{
// use 'unsigned char *' so that the value is not sign extended.
UChar *dataPtr = (UChar *)tempPtr;
#ifdef NA_BIG_ENDIAN
return (unsigned short )((dataPtr[0] << 8) | dataPtr[1]);
#else
return (unsigned short )((dataPtr[1] << 8) | dataPtr[0]);
#endif
}
static void write4( char *dataPtr,
UInt32 value )
{
#ifdef NA_BIG_ENDIAN
dataPtr[0] = (char)(value >> 24);
dataPtr[1] = (char)(value >> 16);
dataPtr[2] = (char)(value >> 8);
dataPtr[3] = (char)value;
#else
dataPtr[3] = (char)(value >> 24);
dataPtr[2] = (char)(value >> 16);
dataPtr[1] = (char)(value >> 8);
dataPtr[0] = (char)value;
#endif
}
static void write2( char *dataPtr,
unsigned short value )
{
#ifdef NA_BIG_ENDIAN
dataPtr[0] = (char)(value >> 8);
dataPtr[1] = (char)value;
#else
dataPtr[1] = (char)(value >> 8);
dataPtr[0] = (char)value;
#endif
}
// If filler bytes are needed to extend a record to a 4-byte multiple
// then the bytes are stored specific to each data format.
UInt32 getNumberFillerBytes( char * dataPtr )
{
if ( isSQLMXAlignedTable() )
return ((ExpAlignedFormat *)dataPtr)->getNumberFillerBytes();
else
return 0; // no filler bytes
}
// If there were filler bytes added to the row length, subtract them out
// and return the true length of the data.
UInt32 getActualDataLength( char * dataPtr,
UInt32 dataLen )
{
if ( isSQLMXAlignedTable() )
return( dataLen - ((ExpAlignedFormat *)dataPtr)->getNumberFillerBytes());
else
return dataLen; // no filler bytes
}
//
// Get the size of each header and voa entry dependent on the table row
// format.
static UInt32 getVoaSize( TupleDataFormat tdf )
{
return (( tdf == SQLMX_ALIGNED_FORMAT )
? ExpAlignedFormat::OFFSET_SIZE : ExpVoaSize );
}
UInt32 getVoaSize()
{
return getVoaSize( (TupleDataFormat)tupleDataFormat_ );
}
UInt32 adjustDataLength( char * dataPtr,
UInt32 currLength )
{
if ( isSQLMXAlignedTable() )
return ExpAlignedFormat::adjustDataLength( dataPtr,
currLength,
ExpAlignedFormat::ALIGNMENT );
else
// no resizing needed since fields are packed
return currLength;
}
// Determine which disk format we are working with and return the first
// field offset based on the disk format.
static UInt32 getFirstFixedOffset( char * dataPtr,
TupleDataFormat tdf )
{
if ( tdf == ExpTupleDesc::SQLMX_ALIGNED_FORMAT )
return ( ExpAlignedFormat::getFirstFixedOffset( dataPtr ) );
else
return ( *(UInt32 *)dataPtr );
}
// Set the first fixed field's offset.
static void setFirstFixedOffset( char * dataPtr,
UInt32 firstFixedOffset,
TupleDataFormat tdf )
{
if ( tdf == ExpTupleDesc::SQLMX_ALIGNED_FORMAT )
ExpAlignedFormat::setFirstFixedOffset( dataPtr, firstFixedOffset );
else
*((UInt32 *)dataPtr) = firstFixedOffset;
}
// Determine which disk format we are working with and return the first
// field offset based on the disk format.
UInt32 getFirstVariableOffset( char * dataPtr,
UInt32 firstFixedOffset )
{
UInt32 offset = 0;
if ( variableFieldPresent() )
{
if ( isSQLMXAlignedTable() )
{
offset = ExpAlignedFormat::getFirstVariableOffset( dataPtr,
firstFixedOffset
);
}
else
{
// One would think this could not happen if variableFieldPresent() were
// true, but that is not the case when there are added columns in the
// table and the data row is a "short" row where no variable length
// columns exist.
if ( firstFixedOffset == ExpVoaSize ) // fixed fields only
offset = 0;
else // variable fields present
offset = *(UInt32 *)(dataPtr + ExpVoaSize);
}
}
return offset;
}
static char getNullChar()
{ return (char)'\377'; }
static char getZeroChar()
{ return (char)'\0'; }
// Determine the data format we are working with and set the appropriate
// null indicator correctly.
// This assumes we are pointing to the null indicator bytes for MX format
// or the bitmap itself for MX Aligned format.
static void setNullValue( char * dataPtr,
Int16 nullBitIndex,
TupleDataFormat tdf )
{
if ( tdf == ExpTupleDesc::SQLMX_ALIGNED_FORMAT )
{
ExpAlignedFormat::setNullBit( dataPtr, nullBitIndex );
}
else
{
dataPtr[0] = '\377';
dataPtr[1] = '\377';
}
}
//
// Set the null indicator.
static void setNullValue( char * dataPtr,
Int16 nullBitIndex )
{
if ( nullBitIndex >= 0 )
{
ExpAlignedFormat::setNullBit( dataPtr, nullBitIndex );
}
else
{
dataPtr[0] = '\377';
dataPtr[1] = '\377';
}
}
// Determine the data format we are working with and set the appropriate
// null indicator correctly.
static void clearNullValue( char * dataPtr,
Int16 nullBitIndex,
TupleDataFormat tdf )
{
if ( tdf == ExpTupleDesc::SQLMX_ALIGNED_FORMAT )
{
ExpAlignedFormat::clearNullBit( dataPtr, nullBitIndex );
}
else
{
dataPtr[0] = '\0';
dataPtr[1] = '\0';
}
}
// Determine the data format we are working with and set the appropriate
// null indicator correctly.
static void clearNullValue( char * dataPtr,
Int16 nullBitIndex )
{
if ( nullBitIndex >= 0 )
{
ExpAlignedFormat::clearNullBit( dataPtr, nullBitIndex );
}
else
{
dataPtr[0] = '\0';
dataPtr[1] = '\0';
}
}
// Based on the data format, determine if the value is NULL or not.
static NABoolean isNullValue( char * nullDataPtr,
Int16 nullBitIdx,
TupleDataFormat tdf )
{
if ( tdf == ExpTupleDesc::SQLMX_ALIGNED_FORMAT )
{
return ( ExpAlignedFormat::isNullValue( nullDataPtr, nullBitIdx ) );
}
else
{
// NSK and NT have different byte orderings.
return ((nullDataPtr)[1] & NEG_BIT_MASK); // sign bit is flipped
}
}
// Null bit index is set to [0,n] for aligned format,
// and all other formats it is initialized to -1.
static NABoolean isNullValue( char * nullDataPtr,
Int16 nullBitIdx )
{
if ( nullBitIdx >= 0 )
{
return ( ExpAlignedFormat::isNullValue( nullDataPtr, nullBitIdx ) );
}
else
{
return ((nullDataPtr)[0] & NEG_BIT_MASK);
}
}
//
// Method to determine if a variable field offset is valid or not.
// If not valid then the offset must be read from the VOA entry.
static
NABoolean isValidVariableOffset(UInt32 offset)
{ return (offset != ExpOffsetMax); }
static void setVoaValue( char * dataPtr,
UInt32 voaEntryOffset,
UInt32 voaEntryValue,
TupleDataFormat tdf)
{
if (voaEntryOffset != ExpOffsetMax)
{
if ( tdf == SQLMX_ALIGNED_FORMAT )
{
((ExpAlignedFormat *)dataPtr)->setVoaOffset(voaEntryOffset,
voaEntryValue);
}
else if ( tdf == SQLMX_FORMAT )
{
str_cpy_all(dataPtr + voaEntryOffset,(char *)&voaEntryValue,ExpVoaSize);
}
else
{
// should never be here
assert( 0 );
}
}
}
// Set a variable length field's offset value in it's VOA entry.
// The size of the voa entry is the same as the size of the variable
// length fields "length" bytes.
static void setVoaValue( char * dataPtr,
UInt32 voaEntryOffset,
UInt32 voaEntryValue,
Int16 vcIndLen)
{
if (voaEntryOffset != ExpOffsetMax)
{
if ( vcIndLen == sizeof(Int16) )
{
((ExpAlignedFormat *)dataPtr)->setVoaOffset(voaEntryOffset,
voaEntryValue);
}
else if ( vcIndLen == sizeof(Int32) )
{
str_cpy_all(dataPtr + voaEntryOffset,(char *)&voaEntryValue,ExpVoaSize);
}
else
{
// should never be here
assert( 0 );
}
}
}
void setVoaValue( char * dataPtr,
UInt32 voaEntryOffset,
UInt32 voaEntryValue )
{
ExpTupleDesc::setVoaValue( dataPtr,
voaEntryOffset,
voaEntryValue,
getTupleDataFormat() );
}
// Get the offset value out of the VOA entry based on tuple data format.
static UInt32 getVoaOffset( char * dataPtr,
UInt32 voaEntryOffset,
TupleDataFormat tdf )
{
UInt32 offset = 0;
if (voaEntryOffset != ExpOffsetMax)
{
if ( SQLMX_ALIGNED_FORMAT == tdf )
{
offset = ((ExpAlignedFormat *)dataPtr)->getVoaEntry( voaEntryOffset );
}
else
{
offset = *(UInt32 *)(dataPtr + voaEntryOffset);
}
}
return offset;
}
static
UInt32 getVoaOffset( char *dataPtr,
UInt32 voaEntryOffset,
Int32 voaSize )
{
UInt32 offset = 0;
if (voaSize == ExpVoaSize) // non-aligned format
{
offset = *(UInt32 *)(dataPtr + voaEntryOffset);
}
else
{
offset = (UInt32)((ExpAlignedFormat *)dataPtr)->getVoaEntry( voaEntryOffset );
}
return offset;
}
UInt32 getVoaOffset( char * dataPtr,
UInt32 voaEntryOffset )
{
return ExpTupleDesc::getVoaOffset( dataPtr,
voaEntryOffset,
getTupleDataFormat() );
}
// Return the offset to the start of the variable field,
// i.e., at the start of the vcIndLen.
// If the offset is -1, it must read the offset from the voa entry
static
UInt32 getVarOffset( char * dataPtr,
UInt32 offset,
UInt32 voaEntryOffset,
UInt32 vcIndLen,
UInt32 nullIndLen
)
{
UInt32 varLenIndOffset;
if (offset == ExpOffsetMax)
{
// indirect varchar
varLenIndOffset = getVoaOffset( dataPtr, voaEntryOffset, vcIndLen )
+ nullIndLen;
}
else
{
// offset is valid, go back vcIndLen bytes
varLenIndOffset = offset - vcIndLen;
}
return varLenIndOffset;
}
// Compute the target varchar offset.
// For tgt in disk format, compute offset based on loop variable.
// Update the VOA entry.
static
Int32 getTgtVarOffset( char *dataPtr,
Int32 offset,
Int32 voaEntryOffset,
UInt32 vcIndLen,
UInt32 nullIndLen,
Int32 &varOffset,
UInt32 len)
{
char *tgt = dataPtr;
Int32 tgtOffset = offset;
if (voaEntryOffset > 0) // disk format
{
if ( tgtOffset >= 0 ) // If tgtOffset is valid ... use it.
{
tgtOffset -= vcIndLen;
if ( voaEntryOffset >= 0 ) // if first varchar, setup loop variable?
varOffset = tgtOffset - nullIndLen;
}
else // indirect varchar, get offset from loop variable.
tgtOffset = varOffset + nullIndLen; // skip over the null indicator len
setVoaValue(tgt, voaEntryOffset, varOffset, (UInt32)vcIndLen);
varOffset += len + nullIndLen + vcIndLen;
}
else
{
tgtOffset -= vcIndLen;
}
return tgtOffset;
}
static
UInt32 getVarLength( char * dataPtr,
Int32 vcIndLen )
{
UInt32 varLen = 0;
if (vcIndLen == sizeof(Int16))
varLen = read2(dataPtr);
else
varLen = read4(dataPtr);
return varLen;
}
static void setVarLength( char * dataPtr,
UInt32 varLength,
Int32 vcIndLen )
{
if (vcIndLen == sizeof(Int16))
write2(dataPtr, (UInt16)varLength);
else
write4(dataPtr, varLength);
}
// Return the number of bytes used to store the length for variable fields
static Int32 getVarLenBytes( TupleDataFormat tdf )
{
return( tdf == SQLMX_FORMAT
? ExpTupleDesc::SQLMX_VC_ACTUAL_LENGTH
: ( tdf == SQLMX_ALIGNED_FORMAT
? (Int32) ExpAlignedFormat::VARIABLE_LEN_SIZE
: (Int32) ExpTupleDesc::VC_ACTUAL_LENGTH ) );
}
// Return the number of bytes used to store the null indicator based on
// the tuple data format.
static Int32 getNullIndBytes(TupleDataFormat tdf)
{
return( tdf == SQLMX_ALIGNED_FORMAT
? (Int32) ExpAlignedFormat::NULL_IND_SIZE
: (Int32) ExpTupleDesc::NULL_INDICATOR_LENGTH );
}
static
UInt32 getVarLength( char * dataPtr, TupleDataFormat tdf )
{
if (tdf == ExpTupleDesc::SQLMX_ALIGNED_FORMAT ||
tdf == ExpTupleDesc::SQLARK_EXPLODED_FORMAT)
return getVarLength(dataPtr, sizeof(Int16));
else
return getVarLength(dataPtr, sizeof(Int32));
}
TupleDataFormat getTupleDataFormat()
{ return (TupleDataFormat)tupleDataFormat_; }
static NABoolean isDiskFormat(TupleDataFormat tdf )
{
return ( ((tdf == SQLMX_ALIGNED_FORMAT) || (tdf == SQLMX_FORMAT))
? TRUE : FALSE );
}
static NABoolean isAlignedFormat(TupleDataFormat tdf)
{ return ( SQLMX_ALIGNED_FORMAT == tdf ); }
static NABoolean isHeaderClauseNeeded( TupleDataFormat tdf )
{
return ( tdf == SQLMX_ALIGNED_FORMAT );
}
void display(const char* title = NULL);
// ---------------------------------------------------------------------
// Redefinition of methods inherited from NAVersionedObject.
// ---------------------------------------------------------------------
virtual unsigned char getClassVersionID()
{
return 1;
}
virtual void populateImageVersionIDArray()
{
setImageVersionID(0,getClassVersionID());
}
virtual Int16 getClassSize() { return (Int16)sizeof(*this); }
// ---------------------------------------------------------------------
};
#endif