/** * 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); }
bool DeleteExecutor::p_init(AbstractPlanNode *abstract_node, const ExecutorVector& executorVector) { VOLT_TRACE("init Delete Executor"); m_node = dynamic_cast<DeletePlanNode*>(abstract_node); assert(m_node); assert(m_node->getTargetTable()); setDMLCountOutputTable(executorVector.limits()); m_truncate = m_node->getTruncate(); if (m_truncate) { assert(m_node->getInputTableCount() == 0); return true; } assert(m_node->getInputTableCount() == 1); m_inputTable = dynamic_cast<AbstractTempTable*>(m_node->getInputTable()); //input table should be temptable assert(m_inputTable); m_inputTuple = TableTuple(m_inputTable->schema()); return true; }
bool InsertExecutor::p_init(AbstractPlanNode* abstractNode, const ExecutorVector& executorVector) { VOLT_TRACE("init Insert Executor"); m_node = dynamic_cast<InsertPlanNode*>(abstractNode); assert(m_node); assert(m_node->getTargetTable()); assert(m_node->getInputTableCount() == (m_node->isInline() ? 0 : 1)); Table* targetTable = m_node->getTargetTable(); m_isUpsert = m_node->isUpsert(); // // The insert node's input schema is fixed. But // if this is an inline node we don't set it here. // We let the parent node set it in p_execute_init. // // Also, we don't want to set the input table for inline // insert nodes. // if ( ! m_node->isInline()) { setDMLCountOutputTable(executorVector.limits()); m_inputTable = dynamic_cast<AbstractTempTable*>(m_node->getInputTable()); //input table should be temptable assert(m_inputTable); } else { m_inputTable = NULL; } // Target table can be StreamedTable or PersistentTable and must not be NULL PersistentTable *persistentTarget = dynamic_cast<PersistentTable*>(targetTable); m_partitionColumn = -1; StreamedTable *streamTarget = dynamic_cast<StreamedTable*>(targetTable); m_hasStreamView = false; if (streamTarget != NULL) { m_isStreamed = true; //See if we have any views. m_hasStreamView = streamTarget->hasViews(); m_partitionColumn = streamTarget->partitionColumn(); } if (m_isUpsert) { VOLT_TRACE("init Upsert Executor actually"); assert( ! m_node->isInline() ); if (m_isStreamed) { VOLT_ERROR("UPSERT is not supported for Stream table %s", targetTable->name().c_str()); } // look up the tuple whether it exists already if (persistentTarget->primaryKeyIndex() == NULL) { VOLT_ERROR("No primary keys were found in our target table '%s'", targetTable->name().c_str()); } } if (persistentTarget) { m_partitionColumn = persistentTarget->partitionColumn(); m_replicatedTableOperation = persistentTarget->isCatalogTableReplicated(); } m_multiPartition = m_node->isMultiPartition(); m_sourceIsPartitioned = m_node->sourceIsPartitioned(); // allocate memory for template tuple, set defaults for all columns m_templateTupleStorage.init(targetTable->schema()); TableTuple tuple = m_templateTupleStorage.tuple(); std::set<int> fieldsExplicitlySet(m_node->getFieldMap().begin(), m_node->getFieldMap().end()); // These default values are used for an INSERT including the INSERT sub-case of an UPSERT. // The defaults are purposely ignored in favor of existing column values // for the UPDATE subcase of an UPSERT. m_node->initTupleWithDefaultValues(m_engine, &m_memoryPool, fieldsExplicitlySet, tuple, m_nowFields); m_hasPurgeFragment = persistentTarget ? persistentTarget->hasPurgeFragment() : false; 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; }