Beispiel #1
0
bool UpdateExecutor::p_init(AbstractPlanNode* abstract_node,
                            TempTableLimits* limits)
{
    VOLT_TRACE("init Update Executor");

    m_node = dynamic_cast<UpdatePlanNode*>(abstract_node);
    assert(m_node);
    assert(m_node->getInputTableCount() == 1);
    // input table should be temptable
    m_inputTable = dynamic_cast<TempTable*>(m_node->getInputTable());
    assert(m_inputTable);

    // target table should be persistenttable
    PersistentTable*targetTable = dynamic_cast<PersistentTable*>(m_node->getTargetTable());
    assert(targetTable);

    setDMLCountOutputTable(limits);

    AbstractPlanNode *child = m_node->getChildren()[0];
    ProjectionPlanNode *proj_node = NULL;
    if (NULL == child) {
        VOLT_ERROR("Attempted to initialize update executor with NULL child");
        return false;
    }

    PlanNodeType pnt = child->getPlanNodeType();
    if (pnt == PLAN_NODE_TYPE_PROJECTION) {
        proj_node = dynamic_cast<ProjectionPlanNode*>(child);
    } else if (pnt == PLAN_NODE_TYPE_SEQSCAN ||
            pnt == PLAN_NODE_TYPE_INDEXSCAN) {
        proj_node = dynamic_cast<ProjectionPlanNode*>(child->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
        assert(NULL != proj_node);
    }

    vector<string> output_column_names = proj_node->getOutputColumnNames();
    const vector<string> &targettable_column_names = targetTable->getColumnNames();

    /*
     * The first output column is the tuple address expression and it isn't part of our output so we skip
     * it when generating the map from input columns to the target table columns.
     */
    for (int ii = 1; ii < output_column_names.size(); ii++) {
        for (int jj=0; jj < targettable_column_names.size(); ++jj) {
            if (targettable_column_names[jj].compare(output_column_names[ii]) == 0) {
                m_inputTargetMap.push_back(pair<int,int>(ii, jj));
                break;
            }
        }
    }

    assert(m_inputTargetMap.size() == (output_column_names.size() - 1));
    m_inputTargetMapSize = (int)m_inputTargetMap.size();
    m_inputTuple = TableTuple(m_inputTable->schema());

    // for target table related info.
    m_partitionColumn = targetTable->partitionColumn();

    return true;
}
Beispiel #2
0
bool UpdateExecutor::p_init(AbstractPlanNode *abstract_node, const catalog::Database* catalog_db, int* tempTableMemoryInBytes) {
    VOLT_TRACE("init Update Executor");

    UpdatePlanNode* node = dynamic_cast<UpdatePlanNode*>(abstract_node);
    assert(node);
    assert(node->getTargetTable());
    assert(node->getInputTables().size() == 1);
    m_inputTable = dynamic_cast<TempTable*>(node->getInputTables()[0]); //input table should be temptable
    assert(m_inputTable);
    m_targetTable = dynamic_cast<PersistentTable*>(node->getTargetTable()); //target table should be persistenttable
    assert(m_targetTable);
    assert(node->getTargetTable());

    // Our output is just our input table (regardless if plan is single-sited or not)
    node->setOutputTable(node->getInputTables()[0]);

    // record if a full index update is needed, or if these checks can be skipped
    m_updatesIndexes = node->doesUpdateIndexes();

    AbstractPlanNode *child = node->getChildren()[0];
    ProjectionPlanNode *proj_node = NULL;
    if (NULL == child) {
        VOLT_ERROR("Attempted to initialize update executor with NULL child");
        return false;
    }

    PlanNodeType pnt = child->getPlanNodeType();
    if (pnt == PLAN_NODE_TYPE_PROJECTION) {
        proj_node = dynamic_cast<ProjectionPlanNode*>(child);
    } else if (pnt == PLAN_NODE_TYPE_SEQSCAN ||
            pnt == PLAN_NODE_TYPE_INDEXSCAN) {
        proj_node = dynamic_cast<ProjectionPlanNode*>(child->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
        assert(NULL != proj_node);
    }

    std::vector<std::string> output_column_names = proj_node->getOutputColumnNames();

    std::string targetTableName = node->getTargetTableName();
    catalog::Table *targetTable = NULL;
    catalog::CatalogMap<catalog::Table> tables = catalog_db->tables();
    for ( catalog::CatalogMap<catalog::Table>::field_map_iter i = tables.begin(); i != tables.end(); i++) {
        catalog::Table *table = (*i).second;
        if (table->name().compare(targetTableName) == 0) {
            targetTable = table;
            break;
        }
    }
    assert(targetTable != NULL);

    catalog::CatalogMap<catalog::Column> columns = targetTable->columns();

    /*
     * The first output column is the tuple address expression and it isn't part of our output so we skip
     * it when generating the map from input columns to the target table columns.
     */
    for (int ii = 1; ii < output_column_names.size(); ii++) {
        std::string outputColumnName = output_column_names[ii];
        catalog::Column *column = columns.get(outputColumnName);
        assert (column != NULL);
        m_inputTargetMap.push_back(std::pair<int, int>( ii, column->index()));
    }
    m_inputTargetMapSize = (int)m_inputTargetMap.size();

    m_inputTuple = TableTuple(m_inputTable->schema());
    m_targetTuple = TableTuple(m_targetTable->schema());

    m_partitionColumn = m_targetTable->partitionColumn();
    m_partitionColumnIsString = false;
    if (m_partitionColumn != -1) {
        if (m_targetTable->schema()->columnType(m_partitionColumn) == voltdb::VALUE_TYPE_VARCHAR) {
            m_partitionColumnIsString = true;
        }
    }

    return true;
}
bool UpdateExecutor::p_init(AbstractPlanNode* abstract_node,
                            TempTableLimits* limits)
{
    VOLT_TRACE("init Update Executor");

    m_node = dynamic_cast<UpdatePlanNode*>(abstract_node);
    assert(m_node);
    assert(m_node->getTargetTable());
    assert(m_node->getInputTables().size() == 1);
    m_inputTable = dynamic_cast<TempTable*>(m_node->getInputTables()[0]); //input table should be temptable
    assert(m_inputTable);
    m_targetTable = dynamic_cast<PersistentTable*>(m_node->getTargetTable()); //target table should be persistenttable
    assert(m_targetTable);
    assert(m_node->getTargetTable());

    setDMLCountOutputTable(limits);

    AbstractPlanNode *child = m_node->getChildren()[0];
    ProjectionPlanNode *proj_node = NULL;
    if (NULL == child) {
        VOLT_ERROR("Attempted to initialize update executor with NULL child");
        return false;
    }

    PlanNodeType pnt = child->getPlanNodeType();
    if (pnt == PLAN_NODE_TYPE_PROJECTION) {
        proj_node = dynamic_cast<ProjectionPlanNode*>(child);
    } else if (pnt == PLAN_NODE_TYPE_SEQSCAN ||
            pnt == PLAN_NODE_TYPE_INDEXSCAN) {
        proj_node = dynamic_cast<ProjectionPlanNode*>(child->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
        assert(NULL != proj_node);
    }

    vector<string> output_column_names = proj_node->getOutputColumnNames();
    const vector<string> &targettable_column_names = m_targetTable->getColumnNames();

    /*
     * The first output column is the tuple address expression and it isn't part of our output so we skip
     * it when generating the map from input columns to the target table columns.
     */
    for (int ii = 1; ii < output_column_names.size(); ii++) {
        for (int jj=0; jj < targettable_column_names.size(); ++jj) {
            if (targettable_column_names[jj].compare(output_column_names[ii]) == 0) {
                m_inputTargetMap.push_back(pair<int,int>(ii, jj));
                break;
            }
        }
    }

    assert(m_inputTargetMap.size() == (output_column_names.size() - 1));
    m_inputTargetMapSize = (int)m_inputTargetMap.size();
    m_inputTuple = TableTuple(m_inputTable->schema());
    m_targetTuple = TableTuple(m_targetTable->schema());

    m_partitionColumn = m_targetTable->partitionColumn();
    m_partitionColumnIsString = false;
    if (m_partitionColumn != -1) {
        if (m_targetTable->schema()->columnType(m_partitionColumn) == VALUE_TYPE_VARCHAR) {
            m_partitionColumnIsString = true;
        }
    }

    // determine which indices are updated by this executor
    // iterate through all target table indices and see if they contain
    //  tables mutated by this executor
    std::vector<TableIndex*> allIndexes = m_targetTable->allIndexes();
    BOOST_FOREACH(TableIndex *index, allIndexes) {
        bool indexKeyUpdated = false;
        BOOST_FOREACH(int colIndex, index->getColumnIndices()) {
            std::pair<int, int> updateColInfo; // needs to be here because of macro failure
            BOOST_FOREACH(updateColInfo, m_inputTargetMap) {
                if (updateColInfo.second == colIndex) {
                    indexKeyUpdated = true;
                    break;
                }
            }
            if (indexKeyUpdated) break;
        }
        if (indexKeyUpdated) {
            m_indexesToUpdate.push_back(index);
        }
    }