/** * Set up a multi-column temp output table for those executors that require one. * Called from p_init. */ void AbstractExecutor::setTempOutputTable(const ExecutorVector& executorVector, const string tempTableName) { TupleSchema* schema = m_abstractNode->generateTupleSchema(); int column_count = schema->columnCount(); std::vector<std::string> column_names(column_count); assert(column_count >= 1); const std::vector<SchemaColumn*>& outputSchema = m_abstractNode->getOutputSchema(); for (int ctr = 0; ctr < column_count; ctr++) { column_names[ctr] = outputSchema[ctr]->getColumnName(); } if (executorVector.isLargeQuery()) { m_tmpOutputTable = TableFactory::buildLargeTempTable(tempTableName, schema, column_names); } else { m_tmpOutputTable = TableFactory::buildTempTable(tempTableName, schema, column_names, executorVector.limits()); } m_abstractNode->setOutputTable(m_tmpOutputTable); }
// helper to make a schema, a tuple and calculate EL size size_t TableTupleExportTest::maxElSize(std::vector<uint16_t> &keep_offsets, bool useNullStrings) { TableTuple *tt; TupleSchema *ts; char buf[1024]; // tuple data ts = TupleSchema::createTupleSchema(m_schema, keep_offsets); tt = new TableTuple(buf, ts); // if the tuple includes strings, add some content // assuming all Export tuples were allocated for persistent // storage and choosing set* api accordingly here. if (ts->columnCount() > 6) { NValue nv = ValueFactory::getStringValue("ABCDEabcde"); // 10 char if (useNullStrings) { nv.free(); nv.setNull(); } tt->setNValueAllocateForObjectCopies(6, nv, NULL); nv.free(); } if (ts->columnCount() > 7) { NValue nv = ValueFactory::getStringValue("abcdeabcdeabcdeabcde"); // 20 char if (useNullStrings) { nv.free(); nv.setNull(); } tt->setNValueAllocateForObjectCopies(7, nv, NULL); nv.free(); } // The function under test! size_t sz = tt->maxExportSerializationSize(); // and cleanup tt->freeObjectColumns(); delete tt; TupleSchema::freeTupleSchema(ts); return sz; }
TEST_F(TupleSchemaTest, CreateEvictedTupleSchema) { initTable(true); // Create the TupleSchema for our evicted tuple tables // The first columns should be all of the columns of our primary key index TupleSchema *evictedSchema = TupleSchema::createEvictedTupleSchema(); // fprintf(stdout, "\nEVICTED TABLE SCHEMA\n%s\n", evictedSchema->debug().c_str()); ASSERT_EQ(2, evictedSchema->columnCount()); ASSERT_EQ(VALUE_TYPE_SMALLINT, evictedSchema->columnType(0)); ASSERT_EQ(VALUE_TYPE_INTEGER, evictedSchema->columnType(1)); TupleSchema::freeTupleSchema(evictedSchema); }
/** * Set up a multi-column temp output table for those executors that require one. * Called from p_init. */ void AbstractExecutor::setTempOutputTable(TempTableLimits* limits, const string tempTableName) { assert(limits); TupleSchema* schema = m_abstractNode->generateTupleSchema(); int column_count = schema->columnCount(); std::vector<std::string> column_names(column_count); assert(column_count >= 1); const std::vector<SchemaColumn*>& outputSchema = m_abstractNode->getOutputSchema(); for (int ctr = 0; ctr < column_count; ctr++) { column_names[ctr] = outputSchema[ctr]->getColumnName(); } m_tmpOutputTable = TableFactory::getTempTable(m_abstractNode->databaseId(), tempTableName, schema, column_names, limits); m_abstractNode->setOutputTable(m_tmpOutputTable); }
TEST_F(TupleSchemaTest, CreateEvictedTupleSchema) { initTable(true); // Create the TupleSchema for our evicted tuple tables // The first columns should be all of the columns of our primary key index TupleSchema *evictedSchema = TupleSchema::createEvictedTupleSchema(m_primaryKeyIndexSchema); // fprintf(stdout, "\nEVICTED TABLE SCHEMA\n%s\n", evictedSchema->debug().c_str()); ASSERT_EQ(m_numPrimaryKeyCols+1, evictedSchema->columnCount()); for (int i = 0; i < m_numPrimaryKeyCols; i++) { ASSERT_EQ(m_primaryKeyIndexSchema->columnType(i), evictedSchema->columnType(i)); ASSERT_EQ(m_primaryKeyIndexSchema->columnLength(i), evictedSchema->columnLength(i)); ASSERT_EQ(m_primaryKeyIndexSchema->columnAllowNull(i), evictedSchema->columnAllowNull(i)); } // Then there should only be one more column that contains the 16-bit block ids ASSERT_EQ(VALUE_TYPE_SMALLINT, evictedSchema->columnType(m_numPrimaryKeyCols)); ASSERT_FALSE(evictedSchema->columnAllowNull(m_numPrimaryKeyCols)); TupleSchema::freeTupleSchema(evictedSchema); }
// Create a table with the schema described above, where the // caller may have specified a number of extra columns. Also add // two indexes: one integer primary key and one geospatial. static unique_ptr<PersistentTable> createTable(int numExtraCols = 0) { TupleSchema* schema = createTupleSchemaWithExtraCols(numExtraCols); char signature[20]; CatalogId databaseId = 1000; std::vector<std::string> columnNames; for (int i = 0; i < schema->columnCount(); ++i) { std::ostringstream oss; oss << "col_" << i; columnNames.push_back(oss.str()); } auto table = unique_ptr<PersistentTable>( static_cast<PersistentTable*>(TableFactory::getPersistentTable(databaseId, "test_table", schema, columnNames, signature))); table->addIndex(createGeospatialIndex(table->schema())); TableIndex* pkIndex = createPrimaryKeyIndex(table->schema()); table->addIndex(pkIndex); table->setPrimaryKeyIndex(pkIndex); return table; }
// helper to make a schema, a tuple and serialize to a buffer size_t TableTupleExportTest::serElSize(std::vector<uint16_t> &keep_offsets, uint8_t *nullArray, char *dataPtr, bool nulls) { TableTuple *tt; TupleSchema *ts; char buf[1024]; // tuple data ts = TupleSchema::createTupleSchema(m_schema, keep_offsets); tt = new TableTuple(buf, ts); // assuming all Export tuples were allocated for persistent // storage and choosing set* api accordingly here. switch (ts->columnCount()) { // note my sophisticated and clever use of fall through case 8: { NValue nv = ValueFactory::getStringValue("abcdeabcdeabcdeabcde"); // 20 char if (nulls) { nv.free(); nv.setNull(); } tt->setNValueAllocateForObjectCopies(7, nv, NULL); nv.free(); } case 7: { NValue nv = ValueFactory::getStringValue("ABCDEabcde"); // 10 char if (nulls) { nv.free(); nv.setNull(); } tt->setNValueAllocateForObjectCopies(6, nv, NULL); nv.free(); } case 6: { NValue nv = ValueFactory::getDecimalValueFromString("-12.34"); if (nulls) { nv.free(); nv.setNull(); } tt->setNValueAllocateForObjectCopies(5, nv, NULL); nv.free(); } case 5: { NValue nv = ValueFactory::getTimestampValue(9999); if (nulls) nv.setNull(); tt->setNValueAllocateForObjectCopies(4, nv, NULL); nv.free(); } case 4: { NValue nv = ValueFactory::getBigIntValue(1024); if (nulls) nv.setNull(); tt->setNValueAllocateForObjectCopies(3, nv, NULL); nv.free(); } case 3: { NValue nv = ValueFactory::getIntegerValue(512); if (nulls) nv.setNull(); tt->setNValueAllocateForObjectCopies(2, nv, NULL); nv.free(); } case 2: { NValue nv = ValueFactory::getSmallIntValue(256); if (nulls) nv.setNull(); tt->setNValueAllocateForObjectCopies(1, nv, NULL); nv.free(); } case 1: { NValue nv = ValueFactory::getTinyIntValue(120); if (nulls) nv.setNull(); tt->setNValueAllocateForObjectCopies(0, nv, NULL); nv.free(); } break; default: // this is an error in the test fixture. EXPECT_EQ(0,1); break; } // The function under test! ExportSerializeOutput io(dataPtr, 2048); tt->serializeToExport(io, 0, nullArray); // and cleanup tt->freeObjectColumns(); delete tt; TupleSchema::freeTupleSchema(ts); return io.position(); }