void AbstractTable::copyRowFrom(const c_atable_ptr_t& source, const size_t src_row, const size_t dst_row, const bool copy_values, const bool use_memcpy) { if (copy_values) { for (size_t column = 0; column < source->columnCount(); column++) { copyValueFrom(source, column, src_row, column, dst_row); } } else { // Copy single values for (size_t column = 0; column < source->columnCount(); column++) { setValueId(column, dst_row, source->getValueId(column, src_row)); } } }
bool AbstractTable::contentEquals(const c_atable_ptr_t& other) const { if (size() != other->size()) { return false; } if (columnCount() != other->columnCount()) { return false; } for (size_t column = 0; column < columnCount(); column++) { auto md = metadataAt(column); auto md2 = other->metadataAt(column); if (!types::isCompatible(md.getType(),md2.getType())) { return false; } if (md.getName() != md2.getName()) { return false; } for (size_t row = 0; row < size(); row++) { bool valueEqual = false; switch (md.getType()) { case IntegerType: case IntegerTypeDelta: case IntegerTypeDeltaConcurrent: case IntegerNoDictType: valueEqual = getValue<hyrise_int_t>(column, row) == other->getValue<hyrise_int_t>(column, row); break; case FloatType: case FloatTypeDelta: case FloatTypeDeltaConcurrent: valueEqual = getValue<hyrise_float_t>(column, row) == other->getValue<hyrise_float_t>(column, row); break; case StringType: case StringTypeDelta: case StringTypeDeltaConcurrent: valueEqual = getValue<std::string>(column, row).compare(other->getValue<std::string>(column, row)) == 0; break; default: break; } if (!valueEqual) { return false; } } } return true; }
void PrettyPrinter::printDiff(const c_atable_ptr_t& input, const TableDiff& diff, std::ostream& outStream, const std::string tableName, const size_t& limit, const size_t& start) { ftprinter::FTPrinter tp(tableName, outStream); tp.addColumn("#rowid", 6); const size_t columns = input->columnCount(); for (size_t column_index = 0; column_index < columns; ++column_index) { // Auto adjusting widths means iterating over the table twice, but we use it for // debugging purposes only, anyways, so we'll go with beauty of output here auto name = input->nameOfColumn(column_index); size_t width = std::accumulate(RangeIter(0), RangeIter(input->size()), // minimum width is 4 name.size() > 4 ? name.size() : 4, [&](size_t max, const size_t & row)->size_t { size_t sz = generateValue(input, column_index, row).size(); return sz > max ? sz : max; }); ftprinter::PrintFormat format = ftprinter::format::basic; if (diff.fields[column_index] == TableDiff::FieldWrong) format = ftprinter::format::red; else if (diff.fields[column_index] == TableDiff::FieldWrongType) format = ftprinter::format::magenta; tp.addColumn(name, width, format); } outStream << std::endl; if (limit < (size_t) - 1) { outStream << "(showing first " << limit << " rows)" << std::endl; } auto iWrong = diff.wrongRows.begin(); auto iFalsePos = diff.falsePositionRows.begin(); while (iWrong != diff.wrongRows.end() && *iWrong < start) iWrong++; while (iFalsePos != diff.falsePositionRows.end() && (*iFalsePos).first < start) iFalsePos++; if (tableName.size() > 0) tp.printTableName(); tp.printHeader(); for (size_t row = start; row < input->size() && row < limit; ++row) { tp << row; if (iWrong != diff.wrongRows.end() && *iWrong == row) { tp << ftprinter::format::red; iWrong++; } if (iFalsePos != diff.falsePositionRows.end() && (*iFalsePos).first == row) { tp << ftprinter::format::yellow; iFalsePos++; } for (field_t column = 0; column < columns; ++column) { tp << generateValue(input, column, row); } } tp.printFooter(); };