bool UnionExecutor::p_init(AbstractPlanNode* abstract_node, TempTableLimits* limits) { VOLT_TRACE("init Union Executor"); UnionPlanNode* node = dynamic_cast<UnionPlanNode*>(abstract_node); assert(node); // // First check to make sure they have the same number of columns // assert(node->getInputTables().size() > 0); for (int table_ctr = 1, table_cnt = (int)node->getInputTables().size(); table_ctr < table_cnt; table_ctr++) { if (node->getInputTables()[0]->columnCount() != node->getInputTables()[table_ctr]->columnCount()) { VOLT_ERROR("Table '%s' has %d columns, but table '%s' has %d" " columns", node->getInputTables()[0]->name().c_str(), node->getInputTables()[0]->columnCount(), node->getInputTables()[table_ctr]->name().c_str(), node->getInputTables()[table_ctr]->columnCount()); return false; } } // // Then check that they have the same types // The two loops here are broken out so that we don't have to keep grabbing the same column for input_table[0] // // get the first table const TupleSchema *table0Schema = node->getInputTables()[0]->schema(); // iterate over all columns in the first table for (int col_ctr = 0, col_cnt = table0Schema->columnCount(); col_ctr < col_cnt; col_ctr++) { // get the type for the current column ValueType type0 = table0Schema->columnType(col_ctr); // iterate through all the other tables, comparing one column at a time for (int table_ctr = 1, table_cnt = (int)node->getInputTables().size(); table_ctr < table_cnt; table_ctr++) { // get another table const TupleSchema *table1Schema = node->getInputTables()[table_ctr]->schema(); ValueType type1 = table1Schema->columnType(col_ctr); if (type0 != type1) { // TODO: DEBUG VOLT_ERROR("Table '%s' has value type '%s' for column '%d'," " table '%s' has value type '%s' for column '%d'", node->getInputTables()[0]->name().c_str(), getTypeName(type0).c_str(), col_ctr, node->getInputTables()[table_ctr]->name().c_str(), getTypeName(type1).c_str(), col_ctr); return false; } } } // // Create our output table that will hold all the tuples that we are appending into. // Since we're are assuming that all of the tables have the same number of columns with // the same format. Therefore, we will just grab the first table in the list // node->setOutputTable(TableFactory::getCopiedTempTable(node->databaseId(), node->getInputTables()[0]->name(), node->getInputTables()[0], limits)); m_setOperator = detail::SetOperator::getSetOperator(node); return true; }
bool UnionExecutor::p_init(AbstractPlanNode* abstract_node, const ExecutorVector& executorVector) { VOLT_TRACE("init Union Executor"); assert(! executorVector.isLargeQuery()); UnionPlanNode* node = dynamic_cast<UnionPlanNode*>(abstract_node); assert(node); // // First check to make sure they have the same number of columns // assert(node->getInputTableCount() > 0); Table* input_table_0 = node->getInputTable(0); const TupleSchema *table_0_schema = input_table_0->schema(); for (int table_ctr = 1, table_cnt = (int)node->getInputTableCount(); table_ctr < table_cnt; ++table_ctr) { Table* input_table_n = node->getInputTable(table_ctr); if (input_table_0->columnCount() != input_table_n->columnCount()) { VOLT_ERROR("Table '%s' has %d columns, but table '%s' has %d" " columns", input_table_0->name().c_str(), input_table_0->columnCount(), input_table_n->name().c_str(), input_table_n->columnCount()); return false; } // // Then check that they have the same types // // iterate over all columns in the first table for (int col_ctr = 0, col_cnt = table_0_schema->columnCount(); col_ctr < col_cnt; col_ctr++) { // get the type for the current column ValueType type_0 = table_0_schema->columnType(col_ctr); const TupleSchema *table_n_schema = input_table_n->schema(); ValueType type_n = table_n_schema->columnType(col_ctr); if (type_0 != type_n) { VOLT_ERROR("Table '%s' has value type '%s' for column '%d'," " table '%s' has value type '%s' for column '%d'", input_table_0->name().c_str(), getTypeName(type_0).c_str(), col_ctr, input_table_n->name().c_str(), getTypeName(type_n).c_str(), col_ctr); return false; } } } // // Create our output table that will hold all the tuples that we are appending into. // Since we're are assuming that all of the tables have the same number of columns with // the same format. Therefore, we will just grab the first table in the list // node->setOutputTable(TableFactory::buildCopiedTempTable(node->getInputTable(0)->name(), node->getInputTable(0), executorVector)); m_setOperator.reset(detail::SetOperator::getSetOperator(node)); return true; }