std::string TableTuple::debug(const std::string& tableName, bool skipNonInline) const { assert(m_schema); assert(m_data); std::ostringstream buffer; if (tableName.empty()) { buffer << "TableTuple(no table) ->"; } else { buffer << "TableTuple(" << tableName << ") ->"; } if (isActive() == false) { buffer << " <DELETED> "; } for (int ctr = 0; ctr < m_schema->columnCount(); ctr++) { buffer << "("; const TupleSchema::ColumnInfo *colInfo = m_schema->getColumnInfo(ctr); if (isVariableLengthType(colInfo->getVoltType()) && !colInfo->inlined && skipNonInline) { StringRef* sr = *reinterpret_cast<StringRef**>(getWritableDataPtr(colInfo)); buffer << "<non-inlined value @" << static_cast<void*>(sr) << ">"; } else { buffer << getNValue(ctr).debug(); } buffer << ")"; } if (m_schema->hiddenColumnCount() > 0) { buffer << " hidden->"; for (int ctr = 0; ctr < m_schema->hiddenColumnCount(); ctr++) { buffer << "("; const TupleSchema::ColumnInfo* colInfo = m_schema->getHiddenColumnInfo(ctr); if (isVariableLengthType(colInfo->getVoltType()) && !colInfo->inlined && skipNonInline) { StringRef* sr = *reinterpret_cast<StringRef**>(getWritableDataPtr(colInfo)); buffer << "<non-inlined value @" << static_cast<void*>(sr) << ">"; } else { buffer << getHiddenNValue(ctr).debug(); } buffer << ")"; } } buffer << " @" << static_cast<const void*>(address()); return buffer.str(); }
void TupleSchema::setColumnMetaData(uint16_t index, ValueType type, const int32_t length, bool allowNull, uint16_t &uninlinedObjectColumnIndex, bool inBytes) { assert(length <= COLUMN_MAX_VALUE_LENGTH); uint32_t offset = 0; // set the type ColumnInfo *columnInfo = getColumnInfoPrivate(index); columnInfo->type = static_cast<char>(type); columnInfo->allowNull = (char)(allowNull ? 1 : 0); columnInfo->length = length; columnInfo->inBytes = inBytes; if (isVariableLengthType(type)) { if (length == 0) { throwFatalLogicErrorStreamed("Zero length for object type " << valueToString((ValueType)type)); } if (isInlineable(type, length, inBytes)) { columnInfo->inlined = true; // If the length was specified in characters, convert to bytes. int32_t factor = (type == VALUE_TYPE_VARCHAR && !inBytes) ? MAX_BYTES_PER_UTF8_CHARACTER : 1; // inlined variable length columns have a size prefix (1 byte) offset = static_cast<uint32_t>(SHORT_OBJECT_LENGTHLENGTH + (length * factor)); } else { columnInfo->inlined = false; // Set the length to the size of a String pointer since it won't be inlined. offset = static_cast<uint32_t>(NValue::getTupleStorageSize(type)); setUninlinedObjectColumnInfoIndex(uninlinedObjectColumnIndex++, index); } } else { // All values are inlined if they aren't strings. columnInfo->inlined = true; // don't trust the planner since it can be avoided offset = static_cast<uint32_t>(NValue::getTupleStorageSize(type)); } // make the column offsets right for all columns past this one int oldsize = columnLengthPrivate(index); ColumnInfo *nextColumnInfo = NULL; for (int i = index + 1; i <= totalColumnCount(); i++) { nextColumnInfo = getColumnInfoPrivate(i); nextColumnInfo->offset = static_cast<uint32_t>(nextColumnInfo->offset + offset - oldsize); } assert(index == 0 ? columnInfo->offset == 0 : true); }
size_t TupleSchema::getMaxSerializedTupleSize(bool includeHiddenColumns) const { size_t bytes = sizeof(int32_t); // placeholder for tuple length int serializeColumnCount = m_columnCount; if (includeHiddenColumns) { serializeColumnCount += m_hiddenColumnCount; } for (int i = 0;i < serializeColumnCount; ++i) { const TupleSchema::ColumnInfo* columnInfo = getColumnInfoPrivate(i); int32_t factor = (columnInfo->type == VALUE_TYPE_VARCHAR && !columnInfo->inBytes) ? MAX_BYTES_PER_UTF8_CHARACTER : 1; if (isVariableLengthType((ValueType)columnInfo->type)) { bytes += sizeof(int32_t); // value length placeholder for variable length columns } bytes += columnInfo->length * factor; } return bytes; }
virtual void advance(const NValue& val) { if (val.isNull()) { return; } // Cannot (yet?) handle variable length types. This should be // enforced by the front end, so we don't actually expect this // error. // // FLOATs are not handled due to the possibility of different // bit patterns representing the same value (positive/negative // zero, and [de-]normalized numbers). This is also enforced // in the front end. assert((! isVariableLengthType(ValuePeeker::peekValueType(val))) && ValuePeeker::peekValueType(val) != VALUE_TYPE_POINT && ValuePeeker::peekValueType(val) != VALUE_TYPE_DOUBLE); int32_t valLength = 0; const char* data = ValuePeeker::peekPointerToDataBytes(val, &valLength); assert(valLength != 0); m_hyperLogLog.add(data, static_cast<uint32_t>(valLength)); }