//Shouldn't this functionality go into table.h? void ExecutionEngineTest::compareTables(Table *first, Table *second) { ASSERT_TRUE(first->columnCount() == second->columnCount()); ASSERT_TRUE(first->indexCount() == second->indexCount()); ASSERT_TRUE(first->activeTupleCount() == second->activeTupleCount()); ASSERT_TRUE(first->databaseId() == second->databaseId()); ASSERT_TRUE(first->name() == second->name()); ASSERT_TRUE(first->tableType() == second->tableType()); vector<TableIndex*> firstAllIndexes = first->allIndexes(); vector<TableIndex*> secondAllIndexes = second->allIndexes(); ASSERT_TRUE(firstAllIndexes.size() == secondAllIndexes.size()); for (size_t ii = 0; ii < firstAllIndexes.size(); ii++) { ASSERT_TRUE(firstAllIndexes[ii]->equals(secondAllIndexes[ii])); } const TupleSchema *firstSchema = first->schema(); const TupleSchema *secondSchema = second->schema(); ASSERT_TRUE(firstSchema->equals(secondSchema)); TableIterator firstTI = first->iterator(); TableIterator secondTI = second->iterator(); TableTuple firstTuple(firstSchema); TableTuple secondTuple(secondSchema); while(firstTI.next(firstTuple)) { ASSERT_TRUE(secondTI.next(secondTuple)); ASSERT_TRUE(firstTuple.equals(secondTuple)); } }
TEST_F(FilterTest, SimpleFilter) { // WHERE id = 20 // ComparisonExpression equal(EXPRESSION_TYPE_COMPARE_EQUAL, // TupleValueExpression::getInstance(0), // ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(20))); TupleValueExpression *tup_val_exp = new TupleValueExpression(0, std::string("tablename"), std::string("colname")); ConstantValueExpression *const_val_exp = new ConstantValueExpression(ValueFactory::getBigIntValue(20)); ComparisonExpression<CmpEq> *equal = new ComparisonExpression<CmpEq>(EXPRESSION_TYPE_COMPARE_EQUAL, tup_val_exp, const_val_exp); // ::printf("\nFilter:%s\n", equal->debug().c_str()); int count = 0; TableIterator iter = table->iterator(); TableTuple match(table->schema()); while (iter.next(match)) { if (equal->eval(&match, NULL).isTrue()) { //::printf(" match:%s", match->debug(table).c_str()); ++count; } } ASSERT_EQ(1, count); // delete the root to destroy the full tree. delete equal; }
void visit(const PredTable* table) { Assert(isTheoryOpen()); if (not table->finite()) { std::clog << "Requested to print infinite table, did not do this.\n"; } TableIterator kt = table->begin(); if (table->arity() > 0) { output() << "{ "; if (not kt.isAtEnd()) { bool beginlist = true; for (; not kt.isAtEnd(); ++kt) { CHECKTERMINATION; if (not beginlist) { output() << "; "; } beginlist = false; ElementTuple tuple = *kt; bool begintuple = true; for (auto lt = tuple.cbegin(); lt != tuple.cend(); ++lt) { if (not begintuple) { output() << ','; } begintuple = false; output() << print(*lt); } } } output() << " }"; } else if (not kt.isAtEnd()) { output() << "{()}"; } else { output() << "{}"; } }
TEST_F(TableTest, TupleInsert) { // // All of the values have already been inserted, we just // need to make sure that the data makes sense // TableIterator iterator = this->table->iterator(); TableTuple tuple(table->schema()); while (iterator.next(tuple)) { //printf("%s\n", tuple->debug(this->table).c_str()); // // Make sure it is not deleted // EXPECT_EQ(true, tuple.isActive()); } // // Make sure that if we insert one tuple, we only get one tuple // TableTuple &temp_tuple = this->table->tempTuple(); ASSERT_EQ(true, tableutil::setRandomTupleValues(this->table, &temp_tuple)); this->table->deleteAllTuples(true); ASSERT_EQ(0, this->table->activeTupleCount()); ASSERT_EQ(true, this->table->insertTuple(temp_tuple)); ASSERT_EQ(1, this->table->activeTupleCount()); // // Then check to make sure that it has the same value and type // iterator = this->table->iterator(); ASSERT_EQ(true, iterator.next(tuple)); for (int col_ctr = 0, col_cnt = NUM_OF_COLUMNS; col_ctr < col_cnt; col_ctr++) { EXPECT_EQ(COLUMN_TYPES[col_ctr], tuple.getType(col_ctr)); EXPECT_TRUE(temp_tuple.getNValue(col_ctr).op_equals(tuple.getNValue(col_ctr)).isTrue()); } }
bool UnionSetOperator::processTuplesDo() { // Set to keep candidate tuples. TupleSet tuples; // // For each input table, grab their TableIterator and then append all of its tuples // to our ouput table. Only distinct tuples are retained. // for (size_t ctr = 0, cnt = m_input_tables.size(); ctr < cnt; ctr++) { Table* input_table = m_input_tables[ctr]; assert(input_table); TableIterator iterator = input_table->iterator(); TableTuple tuple(input_table->schema()); while (iterator.next(tuple)) { if (m_is_all || needToInsert(tuple, tuples)) { // we got tuple to insert if (!m_output_table->insertTuple(tuple)) { VOLT_ERROR("Failed to insert tuple from input table '%s' into" " output table '%s'", input_table->name().c_str(), m_output_table->name().c_str()); return false; } } } } return true; }
TEST_F(FilterTest, FunctionAbs2Filter) { // WHERE abs(0 - id) = 20 // ComparisonExpression equal(EXPRESSION_TYPE_COMPARE_EQUAL, // 0 - TupleValueExpression::getInstance(0), // UnaryFunctionExpression(EXPRESSION_TYPE_FUNCTION_ABS, // ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(20)))); ConstantValueExpression *zero_val_exp = new ConstantValueExpression(ValueFactory::getBigIntValue(0)); TupleValueExpression *tup_val_exp = new TupleValueExpression(0, 0); AbstractExpression* minus_exp = new OperatorExpression<OpMinus>(EXPRESSION_TYPE_OPERATOR_MINUS, zero_val_exp, tup_val_exp); std::vector<AbstractExpression*>* argument = new std::vector<AbstractExpression*>(); argument->push_back(minus_exp); AbstractExpression* abs_exp = ExpressionUtil::functionFactory(FUNC_ABS, argument); ConstantValueExpression *const_val_exp = new ConstantValueExpression(ValueFactory::getBigIntValue(20)); ComparisonExpression<CmpEq> *equal = new ComparisonExpression<CmpEq>(EXPRESSION_TYPE_COMPARE_EQUAL, abs_exp, const_val_exp); // ::printf("\nFilter:%s\n", equal->debug().c_str()); int count = 0; TableIterator iter = table->iterator(); TableTuple match(table->schema()); while (iter.next(match)) { if (equal->eval(&match, NULL).isTrue()) { // ::printf(" match:%s\n", match.debug(std::string("tablename")).c_str()); ++count; } } ASSERT_EQ(1, count); // delete the root to destroy the full tree. delete equal; }
bool InsertExecutor::p_execute(const NValueArray ¶ms) { // // See p_execute_init above. If we are inserting a // replicated table into an export table with no partition column, // we only insert on one site. For all other sites we just // do nothing. // TableTuple inputTuple; const TupleSchema *inputSchema = m_inputTable->schema(); if (p_execute_init(inputSchema, m_tmpOutputTable, inputTuple)) { p_execute_finish(); return true; } // // An insert is quite simple really. We just loop through our m_inputTable // and insert any tuple that we find into our targetTable. It doesn't get any easier than that! // TableIterator iterator = m_inputTable->iterator(); while (iterator.next(inputTuple)) { p_execute_tuple(inputTuple); } p_execute_finish(); return true; }
void Table::serializeTo(SerializeOutput &serialOutput) { // The table is serialized as: // [(int) total size] // [(int) header size] [num columns] [column types] [column names] // [(int) num tuples] [tuple data] /* NOTE: VoltDBEngine uses a binary template to create tables of single integers. It's called m_templateSingleLongTable and if you are seeing a serialization bug in tables of single integers, make sure that's correct. */ // a placeholder for the total table size std::size_t pos = serialOutput.position(); serialOutput.writeInt(-1); serializeColumnHeaderTo(serialOutput); // active tuple counts serialOutput.writeInt(static_cast<int32_t>(m_tupleCount)); int64_t written_count = 0; TableIterator titer = iterator(); TableTuple tuple(m_schema); while (titer.next(tuple)) { tuple.serializeTo(serialOutput); ++written_count; } assert(written_count == m_tupleCount); // length prefix is non-inclusive int32_t sz = static_cast<int32_t>(serialOutput.position() - pos - sizeof(int32_t)); assert(sz > 0); serialOutput.writeIntAt(pos, sz); }
bool DistinctExecutor::p_execute(const NValueArray ¶ms) { DistinctPlanNode* node = dynamic_cast<DistinctPlanNode*>(m_abstractNode); assert(node); Table* output_table = node->getOutputTable(); assert(output_table); Table* input_table = node->getInputTables()[0]; assert(input_table); TableIterator iterator = input_table->iterator(); TableTuple tuple(input_table->schema()); std::set<NValue, NValue::ltNValue> found_values; while (iterator.next(tuple)) { // // Check whether this value already exists in our list // NValue tuple_value = node->getDistinctExpression()->eval(&tuple, NULL); if (found_values.find(tuple_value) == found_values.end()) { found_values.insert(tuple_value); if (!output_table->insertTuple(tuple)) { VOLT_ERROR("Failed to insert tuple from input table '%s' into" " output table '%s'", input_table->name().c_str(), output_table->name().c_str()); return false; } } } return true; }
TEST_F(TableTest, BigTest) { vector<NValue> cachedStringValues;//To free at the end of the test TableTuple *temp_tuple = &warehouseTempTable->tempTuple(); temp_tuple->setNValue(0, ValueFactory::getTinyIntValue(static_cast<int8_t>(3))); cachedStringValues.push_back(ValueFactory::getStringValue("EZ Street WHouse")); temp_tuple->setNValue(1, cachedStringValues.back()); cachedStringValues.push_back(ValueFactory::getStringValue("Headquarters")); temp_tuple->setNValue(2, cachedStringValues.back()); cachedStringValues.push_back(ValueFactory::getStringValue("77 Mass. Ave.")); temp_tuple->setNValue(3, cachedStringValues.back()); cachedStringValues.push_back(ValueFactory::getStringValue("Cambridge")); temp_tuple->setNValue(4, cachedStringValues.back()); cachedStringValues.push_back(ValueFactory::getStringValue("AZ")); temp_tuple->setNValue(5, cachedStringValues.back()); cachedStringValues.push_back(ValueFactory::getStringValue("12938")); temp_tuple->setNValue(6, cachedStringValues.back()); temp_tuple->setNValue(7, ValueFactory::getDoubleValue(static_cast<double>(.1234))); temp_tuple->setNValue(8, ValueFactory::getDoubleValue(static_cast<double>(15241.45))); warehouseTempTable->insertTupleNonVirtual(*temp_tuple); TableTuple warehouseTuple = TableTuple(warehouseTempTable->schema()); TableIterator warehouseIterator = warehouseTempTable->iterator(); while (warehouseIterator.next(warehouseTuple)) { if (!warehouseTable->insertTuple(warehouseTuple)) { cout << "Failed to insert tuple from input table '" << warehouseTempTable->name() << "' into target table '" << warehouseTable->name() << "'" << endl; } } warehouseTempTable->deleteAllTuplesNonVirtual(true); }
FOPropTableDomain* FOPropTableDomainFactory::exists(FOPropTableDomain* domain, const varset& sv) const { vector<bool> keepcol; vector<Variable*> newvars; vector<SortTable*> newunivcols; for (unsigned int n = 0; n < domain->vars().size(); ++n) { Variable* v = domain->vars()[n]; if (sv.find(v) == sv.cend()) { keepcol.push_back(true); newvars.push_back(v); newunivcols.push_back(domain->table()->universe().tables()[n]); } else { keepcol.push_back(false); } } if (not domain->table()->approxFinite()) { clog << "Probably entering an infinite loop when trying to project a possibly infinite table...\n"; } PredTable* npt = new PredTable(new EnumeratedInternalPredTable(), Universe(newunivcols)); for (TableIterator it = domain->table()->begin(); not it.isAtEnd(); ++it) { const ElementTuple& tuple = *it; ElementTuple newtuple; for (size_t n = 0; n < tuple.size(); ++n) { if (keepcol[n]) { newtuple.push_back(tuple[n]); } } npt->add(newtuple); } return new FOPropTableDomain(npt, newvars); }
bool ProjectionExecutor::p_execute(const NValueArray ¶ms) { #ifndef NDEBUG ProjectionPlanNode* node = dynamic_cast<ProjectionPlanNode*>(m_abstractNode); #endif assert (node); assert (!node->isInline()); // inline projection's execute() should not be // called assert (m_outputTable == dynamic_cast<AbstractTempTable*>(node->getOutputTable())); assert (m_outputTable); Table* input_table = m_abstractNode->getInputTable(); assert (input_table); VOLT_TRACE("INPUT TABLE: %s\n", input_table->debug().c_str()); assert (m_columnCount == (int)node->getOutputColumnNames().size()); if (m_allTupleArray == NULL && m_allParamArray == NULL) { for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { assert(expression_array[ctr]); VOLT_TRACE("predicate[%d]: %s", ctr, expression_array[ctr]->debug(true).c_str()); } } // // Now loop through all the tuples and push them through our output // expression This will generate new tuple values that we will insert into // our output table // TableIterator iterator = input_table->iteratorDeletingAsWeGo(); assert (m_tuple.columnCount() == input_table->columnCount()); while (iterator.next(m_tuple)) { // // Project (or replace) values from input tuple // TableTuple &temp_tuple = m_outputTable->tempTuple(); if (m_allTupleArray != NULL) { VOLT_TRACE("sweet, all tuples"); for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { temp_tuple.setNValue(ctr, m_tuple.getNValue(m_allTupleArray[ctr])); } } else if (m_allParamArray != NULL) { VOLT_TRACE("sweet, all params"); for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { temp_tuple.setNValue(ctr, params[m_allParamArray[ctr]]); } } else { for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { temp_tuple.setNValue(ctr, expression_array[ctr]->eval(&m_tuple, NULL)); } } m_outputTable->insertTempTuple(temp_tuple); VOLT_TRACE("OUTPUT TABLE: %s\n", m_outputTable->debug().c_str()); } return true; }
TEST_F(FilterTest, ComplexFilter) { // WHERE val1=1 AND val2=2 AND val3=3 AND val4=4 // shared_ptr<AbstractExpression> equal1 // = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(1), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(1))); // shared_ptr<AbstractExpression> equal2 // = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(2), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(2))); // shared_ptr<AbstractExpression> equal3 // = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(3), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(3))); // shared_ptr<AbstractExpression> equal4 // = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(4), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(4))); // // shared_ptr<AbstractExpression> predicate3 // = ConjunctionExpression::getInstance(EXPRESSION_TYPE_CONJUNCTION_AND, equal3, equal4); // shared_ptr<AbstractExpression> predicate2 // = ConjunctionExpression::getInstance(EXPRESSION_TYPE_CONJUNCTION_AND, equal2, predicate3); // // ConjunctionExpression predicate(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, predicate2); AbstractExpression *equal1 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL, new TupleValueExpression(1, std::string("tablename"), std::string("colname")), constantValueFactory(ValueFactory::getBigIntValue(1))); AbstractExpression *equal2 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL, new TupleValueExpression(2, std::string("tablename"), std::string("colname")), constantValueFactory(ValueFactory::getBigIntValue(2))); AbstractExpression *equal3 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL, new TupleValueExpression(3, std::string("tablename"), std::string("colname")), constantValueFactory(ValueFactory::getBigIntValue(3))); AbstractExpression *equal4 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL, new TupleValueExpression(4, std::string("tablename"), std::string("colname")), constantValueFactory(ValueFactory::getBigIntValue(4))); AbstractExpression *predicate3 = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal3, equal4); AbstractExpression *predicate2 = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal2, predicate3); AbstractExpression *predicate = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, predicate2); // ::printf("\nFilter:%s\n", predicate->debug().c_str()); int count = 0; TableIterator iter = table->iterator(); TableTuple match(table->schema()); while (iter.next(match)) { if (predicate->eval(&match, NULL).isTrue()) { //::printf(" match:%s\n", match->debug(table).c_str()); ++count; } } ASSERT_EQ(5, count); delete predicate; }
TEST_F(TableSerializeTest, NullStrings) { std::string *columnNames = new std::string[1]; std::vector<voltdb::ValueType> columnTypes(1, voltdb::VALUE_TYPE_VARCHAR); std::vector<int32_t> columnSizes(1, 20); std::vector<bool> columnAllowNull(1, false); voltdb::TupleSchema *schema = voltdb::TupleSchema::createTupleSchema(columnTypes, columnSizes, columnAllowNull, true); columnNames[0] = ""; table_->deleteAllTuples(true); delete table_; table_ = TableFactory::getTempTable(this->database_id, "temp_table", schema, columnNames, NULL); TableTuple& tuple = table_->tempTuple(); tuple.setNValue(0, ValueFactory::getNullStringValue()); table_->insertTuple(tuple); // Serialize the table CopySerializeOutput serialize_out; table_->serializeTo(serialize_out); // Deserialize the table: verify that it matches the existing table ReferenceSerializeInput serialize_in(serialize_out.data() + sizeof(int32_t), serialize_out.size() - sizeof(int32_t)); TempTableLimits limits; schema = TupleSchema::createTupleSchema(table_->schema()); Table* deserialized = TableFactory::getTempTable(this->database_id, "foo", schema, columnNames, &limits); deserialized->loadTuplesFrom(serialize_in, NULL); EXPECT_EQ(1, deserialized->activeTupleCount()); EXPECT_EQ(1, table_->activeTupleCount()); EXPECT_EQ(1, deserialized->columnCount()); EXPECT_EQ(1, table_->columnCount()); EXPECT_EQ("", table_->columnName(0)); EXPECT_EQ("", deserialized->columnName(0)); EXPECT_EQ(VALUE_TYPE_VARCHAR, table_->schema()->columnType(0)); EXPECT_EQ(VALUE_TYPE_VARCHAR, deserialized->schema()->columnType(0)); EXPECT_EQ(true, table_->schema()->columnIsInlined(0)); TableIterator iter = deserialized->iterator(); TableTuple t(deserialized->schema()); int count = 0; while (iter.next(t)) { EXPECT_EQ(VALUE_TYPE_VARCHAR, tuple.getType(0)); EXPECT_EQ(VALUE_TYPE_VARCHAR, t.getType(0)); EXPECT_TRUE(tuple.getNValue(0).isNull()); EXPECT_TRUE(t.getNValue(0).isNull()); EXPECT_TRUE(ValueFactory::getNullStringValue().op_equals(tuple.getNValue(0)).isTrue()); EXPECT_TRUE(ValueFactory::getNullStringValue().op_equals(t.getNValue(0)).isTrue()); count += 1; } EXPECT_EQ(1, count); delete deserialized; // clean up delete[] columnNames; }
static int countMatches(AbstractExpression* predicate) { int count = 0; TableIterator iter = m_table_static->iterator(); TableTuple match(m_table_static->schema()); while (iter.next(match)) { if (predicate->eval(&match, NULL).isTrue()) { //::printf(" match:%s\n", match->debug(table).c_str()); ++count; } } return count; }
void ExceptIntersectSetOperator::collectTuples(Table& input_table, TupleMap& tuple_map) { TableIterator iterator = input_table.iterator(); TableTuple tuple(input_table.schema()); while (iterator.next(tuple)) { TupleMap::iterator mapIt = tuple_map.find(tuple); if (mapIt == tuple_map.end()) { tuple_map.insert(std::make_pair(tuple, 1)); } else if (m_is_all) { ++mapIt->second; } } }
static Table* copyTable(const std::string &name, Table* template_table, char *signature) { Table* t = TableFactory::getPersistentTable(0, name, TupleSchema::createTupleSchema(template_table->schema()), template_table->getColumnNames(), signature); TableTuple tuple(template_table->schema()); TableIterator iterator = template_table->iterator(); while (iterator.next(tuple)) { t->insertTuple(tuple); } return t; }
void Table::serializeToWithoutTotalSize(SerializeOutput &serialOutput) { serializeColumnHeaderTo(serialOutput); // active tuple counts serialOutput.writeInt(static_cast<int32_t>(m_tupleCount)); int64_t written_count = 0; TableIterator titer = iterator(); TableTuple tuple(m_schema); while (titer.next(tuple)) { tuple.serializeTo(serialOutput); ++written_count; } assert(written_count == m_tupleCount); }
TEST_F(TableTest, ValueTypes) { // // Make sure that our table has the right types and that when // we pull out values from a tuple that it has the right type too // TableIterator iterator = this->table->iterator(); TableTuple tuple(table->schema()); while (iterator.next(tuple)) { for (int ctr = 0; ctr < NUM_OF_COLUMNS; ctr++) { EXPECT_EQ(COLUMN_TYPES[ctr], this->table->schema()->columnType(ctr)); EXPECT_EQ(COLUMN_TYPES[ctr], tuple.getType(ctr)); } } }
TEST_F(TableTupleTest, VolatileTempTuplePersistent) { UniqueEngine engine = UniqueEngineBuilder().build(); // A schema with // - one fixed-length column // - one inlined variable-length column // - one non-inlined variable-length column TupleSchema *schema = Tools::buildSchema(VALUE_TYPE_BIGINT, std::make_pair(VALUE_TYPE_VARCHAR, 12), std::make_pair(VALUE_TYPE_VARCHAR, 256)); std::vector<std::string> columnNames{"id", "inlined", "noninlined"}; char signature[20]; std::unique_ptr<Table> table{TableFactory::getPersistentTable(0, "perstbl", schema, columnNames, signature)}; TableTuple tuple = table->tempTuple(); Tools::setTupleValues(&tuple, int64_t(0), "foo", "foo bar"); ASSERT_TRUE(tuple.inlinedDataIsVolatile()); ASSERT_FALSE(tuple.nonInlinedDataIsVolatile()); NValue nv = tuple.getNValue(0); ASSERT_FALSE(nv.getVolatile()); nv = tuple.getNValue(1); ASSERT_TRUE(nv.getVolatile()); nv = tuple.getNValue(2); ASSERT_FALSE(nv.getVolatile()); table->insertTuple(tuple); TableIterator it = table->iterator(); TableTuple iterTuple{schema}; while (it.next(iterTuple)) { // Regular, TupleBlock-backed tuples are never volatile. ASSERT_FALSE(iterTuple.inlinedDataIsVolatile()); ASSERT_FALSE(iterTuple.nonInlinedDataIsVolatile()); nv = iterTuple.getNValue(0); ASSERT_FALSE(nv.getVolatile()); nv = iterTuple.getNValue(1); ASSERT_FALSE(nv.getVolatile()); nv = iterTuple.getNValue(2); ASSERT_FALSE(nv.getVolatile()); } }
bool LimitExecutor::p_execute(const NValueArray ¶ms) { // cout << "Limit" << endl; LimitPlanNode* node = dynamic_cast<LimitPlanNode*>(m_abstractNode); assert(node); Table* output_table = node->getOutputTable(); assert(output_table); Table* input_table = node->getInputTable(); assert(input_table); // // Grab the iterator for our input table, and loop through until // we have copy enough tuples for the limit specified by the node // TableTuple tuple(input_table->schema()); TableIterator iterator = input_table->iteratorDeletingAsWeGo(); int tuple_ctr = 0; int tuples_skipped = 0; int limit = -1; int offset = -1; node->getLimitAndOffsetByReference(params, limit, offset); while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple)) { // TODO: need a way to skip / iterate N items. if (tuples_skipped < offset) { tuples_skipped++; continue; } tuple_ctr++; if (!output_table->insertTuple(tuple)) { VOLT_ERROR("Failed to insert tuple from input table '%s' into" " output table '%s'", input_table->name().c_str(), output_table->name().c_str()); return false; } } cleanupInputTempTable(input_table); return true; }
TEST_F(TableTest, ValueTypes) { // // Make sure that our table has the right types and that when // we pull out values from a tuple that it has the right type too // TableIterator iterator = m_table->iterator(); TableTuple tuple(m_table->schema()); while (iterator.next(tuple)) { for (int ctr = 0; ctr < NUM_OF_COLUMNS; ctr++) { EXPECT_EQ(COLUMN_TYPES[ctr], m_table->schema()->columnType(ctr)); const TupleSchema::ColumnInfo *columnInfo = tuple.getSchema()->getColumnInfo(ctr); EXPECT_EQ(COLUMN_TYPES[ctr], columnInfo->getVoltType()); } } }
void validateResults(AbstractExecutor::TupleComparer comp, std::vector<TableTuple>& srcTuples, int limit = -1, int offset = 0) { std::size_t size = (limit == -1) ? srcTuples.size() : limit; ASSERT_EQ(size, m_tempDstTable->activeTupleCount()); // Sort the source std::sort(srcTuples.begin(), srcTuples.end(), comp); int i = 0; TableIterator iterator = m_tempDstTable->iterator(); TableTuple tuple(m_tempDstTable->schema()); while(iterator.next(tuple)) { ASSERT_TRUE(srcTuples[offset + i++].getNValue(0).op_equals(tuple.getNValue(0)).isTrue()); } // Clean-up m_tempDstTable->deleteAllTuplesNonVirtual(true); }
bool Table::serializeToWithoutTotalSize(SerializeOutput &serialize_io) { if (!serializeColumnHeaderTo(serialize_io)) return false; // active tuple counts serialize_io.writeInt(static_cast<int32_t>(m_tupleCount)); int64_t written_count = 0; TableIterator titer = iterator(); TableTuple tuple(m_schema); while (titer.next(tuple)) { tuple.serializeTo(serialize_io); ++written_count; } assert(written_count == m_tupleCount); return true; }
void clear() { doRemoveEntries(); TableIterator bucketPos = m_buckets.begin(); while (bucketPos != m_buckets.end()) { bucketPos->clear(); ++bucketPos; } m_eraseCount = 0; assert(0 == m_size); assert(m_entries.empty()); }
/* * Warn: Iterate all tuples to get accurate size, don't use it on * performance critical path if table is large. */ size_t Table::getAccurateSizeToSerialize() { // column header size size_t bytes = getColumnHeaderSizeToSerialize(); // tuples bytes += sizeof(int32_t); // tuple count int64_t written_count = 0; TableIterator titer = iterator(); TableTuple tuple(m_schema); while (titer.next(tuple)) { bytes += tuple.serializationSize(); // tuple size ++written_count; } assert(written_count == m_tupleCount); return bytes; }
TEST_F(FilterTest, SubstituteFilter) { // WHERE id <= 20 AND val4=$1 // shared_ptr<AbstractExpression> equal1 // = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO, TupleValueExpression::getInstance(0), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(20))); // // shared_ptr<AbstractExpression> equal2 // = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(4), ParameterValueExpression::getInstance(0)); // // ConjunctionExpression predicate(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, equal2); AbstractExpression *tv1 = new TupleValueExpression(0, std::string("tablename"), std::string("colname")); AbstractExpression *cv1 = constantValueFactory(ValueFactory::getBigIntValue(20)); AbstractExpression *equal1 = comparisonFactory(EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO, tv1, cv1); AbstractExpression *tv2 = new TupleValueExpression(4, std::string("tablename"), std::string("colname")); AbstractExpression *pv2 = parameterValueFactory(0); AbstractExpression *equal2 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL, tv2, pv2); AbstractExpression *predicate = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, equal2); // ::printf("\nFilter:%s\n", predicate->debug().c_str()); for (int64_t implantedValue = 1; implantedValue < 5; ++implantedValue) { NValueArray params(1); params[0] = ValueFactory::getBigIntValue(implantedValue); predicate->substitute(params); // ::printf("\nSubstituted Filter:%s\n", predicate->debug().c_str()); // ::printf("\tLEFT: %s\n", predicate->getLeft()->debug().c_str()); // ::printf("\tRIGHT: %s\n", predicate->getRight()->debug().c_str()); int count = 0; TableIterator iter = table->iterator(); TableTuple match(table->schema()); while (iter.next(match)) { if (predicate->eval(&match, NULL).isTrue()) { ++count; } } ASSERT_EQ(3, count); } delete predicate; }
std::string Table::debug(const std::string &spacer) const { VOLT_DEBUG("tabledebug start"); std::ostringstream buffer; std::string infoSpacer = spacer + " |"; buffer << infoSpacer << tableType() << "(" << name() << "):\n"; buffer << infoSpacer << "\tAllocated Tuples: " << allocatedTupleCount() << "\n"; buffer << infoSpacer << "\tNumber of Columns: " << columnCount() << "\n"; // // Columns // buffer << infoSpacer << "===========================================================\n"; buffer << infoSpacer << "\tCOLUMNS\n"; buffer << infoSpacer << m_schema->debug(); //buffer << infoSpacer << " - TupleSchema needs a \"debug\" method. Add one for output here.\n"; #ifdef VOLT_TRACE_ENABLED // // Tuples // if (tableType().compare("LargeTempTable") != 0) { buffer << infoSpacer << "===========================================================\n"; buffer << infoSpacer << "\tDATA\n"; TableIterator iter = const_cast<Table*>(this)->iterator(); TableTuple tuple(m_schema); if (this->activeTupleCount() == 0) { buffer << infoSpacer << "\t<NONE>\n"; } else { std::string lastTuple = ""; while (iter.next(tuple)) { if (tuple.isActive()) { buffer << infoSpacer << "\t" << tuple.debug(this->name().c_str()) << "\n"; } } } buffer << infoSpacer << "===========================================================\n"; } #endif std::string ret(buffer.str()); VOLT_DEBUG("tabledebug end"); return ret; }
TEST_F(TableTupleFilterTest, tableTupleFilterTest) { static const int MARKER = 33; TempTable* table = getTempTable(); TableTupleFilter tableFilter; tableFilter.init(table); int tuplePerBlock = table->getTuplesPerBlock(); // make sure table spans more than one block ASSERT_TRUE(NUM_OF_TUPLES / tuplePerBlock > 1); TableTuple tuple = table->tempTuple(); TableIterator iterator = table->iterator(); // iterator over and mark every 5th tuple int counter = 0; std::multiset<int64_t> control_values; while(iterator.next(tuple)) { if (++counter % 5 == 0) { NValue nvalue = tuple.getNValue(1); int64_t value = ValuePeeker::peekBigInt(nvalue); control_values.insert(value); tableFilter.updateTuple(tuple, MARKER); } } TableTupleFilter_iter<MARKER> endItr = tableFilter.end<MARKER>(); for (TableTupleFilter_iter<MARKER> itr = tableFilter.begin<MARKER>(); itr != endItr; ++itr) { uint64_t tupleAddr = tableFilter.getTupleAddress(*itr); tuple.move((char *)tupleAddr); ASSERT_TRUE(tuple.isActive()); NValue nvalue = tuple.getNValue(1); int64_t value = ValuePeeker::peekBigInt(nvalue); ASSERT_FALSE(control_values.empty()); auto it = control_values.find(value); ASSERT_NE(it, control_values.end()); control_values.erase(it); } ASSERT_TRUE(control_values.empty()); }
bool LimitExecutor::p_execute(const NValueArray ¶ms) { LimitPlanNode* node = dynamic_cast<LimitPlanNode*>(m_abstractNode); assert(node); Table* output_table = node->getOutputTable(); assert(output_table); Table* input_table = node->getInputTables()[0]; assert(input_table); // // Grab the iterator for our input table, and loop through until // we have copy enough tuples for the limit specified by the node // TableTuple tuple(input_table->schema()); TableIterator iterator = input_table->iterator(); int tuple_ctr = 0; int limit = 0, offset = 0; bool start = (node->getOffset() == 0); node->getLimitAndOffsetByReference(params, limit, offset); while (iterator.next(tuple) && (tuple_ctr < limit)) { // TODO: need a way to skip / iterate N items. if (start) { if (!output_table->insertTuple(tuple)) { VOLT_ERROR("Failed to insert tuple from input table '%s' into" " output table '%s'", input_table->name().c_str(), output_table->name().c_str()); return false; } tuple_ctr++; } else { start = (iterator.getLocation() >= offset); } } return true; }