| /********************************************************************** |
| // @@@ 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 |