Esempio n. 1
0
bool
OrderByExecutor::p_init(AbstractPlanNode* abstract_node,
                        TempTableLimits* limits)
{
    VOLT_TRACE("init OrderBy Executor");

    OrderByPlanNode* node = dynamic_cast<OrderByPlanNode*>(abstract_node);
    assert(node);

    if (!node->isInline()) {
        assert(node->getInputTableCount() == 1);

        assert(node->getChildren()[0] != NULL);

        //
        // Our output table should look exactly like our input table
        //
        node->
            setOutputTable(TableFactory::
                       getCopiedTempTable(node->databaseId(),
                                          node->getInputTable()->name(),
                                          node->getInputTable(),
                                          limits));
        // pickup an inlined limit, if one exists
        limit_node =
            dynamic_cast<LimitPlanNode*>(node->
                                     getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));
    } else {
        assert(node->getChildren().empty());
        assert(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT) == NULL);
    }

#if defined(VOLT_LOG_LEVEL)
#if VOLT_LOG_LEVEL<=VOLT_LEVEL_TRACE
    const std::vector<AbstractExpression*>& sortExprs = node->getSortExpressions();
    for (int i = 0; i < sortExprs.size(); ++i) {
        VOLT_TRACE("Sort key[%d]:\n%s", i, sortExprs[i]->debug(true).c_str());
    }
#endif
#endif

    return true;
}
Esempio n. 2
0
bool
OrderByExecutor::p_execute(const NValueArray &params)
{
    OrderByPlanNode* node = dynamic_cast<OrderByPlanNode*>(m_abstractNode);
    assert(node);
    TempTable* output_table = dynamic_cast<TempTable*>(node->getOutputTable());
    assert(output_table);
    Table* input_table = node->getInputTables()[0];
    assert(input_table);

    //
    // OPTIMIZATION: NESTED LIMIT
    // How nice! We can also cut off our scanning with a nested limit!
    //
    int limit = -1;
    int offset = -1;
    if (limit_node != NULL)
    {
        limit_node->getLimitAndOffsetByReference(params, limit, offset);
    }

    VOLT_TRACE("Running OrderBy '%s'", m_abstractNode->debug().c_str());
    VOLT_TRACE("Input Table:\n '%s'", input_table->debug().c_str());
    TableIterator iterator = input_table->iterator();
    TableTuple tuple(input_table->schema());
    vector<TableTuple> xs;
    ProgressMonitorProxy pmp(m_engine, this);
    while (iterator.next(tuple))
    {
        pmp.countdownProgress();
        assert(tuple.isActive());
        xs.push_back(tuple);
    }
    VOLT_TRACE("\n***** Input Table PreSort:\n '%s'",
               input_table->debug().c_str());
    sort(xs.begin(), xs.end(), TupleComparer(node->getSortExpressions(),
                                             node->getSortDirections()));

    int tuple_ctr = 0;
    int tuple_skipped = 0;
    for (vector<TableTuple>::iterator it = xs.begin(); it != xs.end(); it++)
    {
        //
        // Check if has gone past the offset
        //
        if (tuple_skipped < offset) {
            tuple_skipped++;
            continue;
        }

        VOLT_TRACE("\n***** Input Table PostSort:\n '%s'",
                   input_table->debug().c_str());
        output_table->insertTupleNonVirtual(*it);
        pmp.countdownProgress();
        //
        // Check whether we have gone past our limit
        //
        if (limit >= 0 && ++tuple_ctr >= limit) {
            break;
        }
    }
    VOLT_TRACE("Result of OrderBy:\n '%s'", output_table->debug().c_str());

    return true;
}
Esempio n. 3
0
bool
OrderByExecutor::p_execute(const NValueArray &params)
{
    OrderByPlanNode* node = dynamic_cast<OrderByPlanNode*>(m_abstractNode);
    assert(node);
    Table* output_table = node->getOutputTable();
    assert(output_table);
    Table* input_table = node->getInputTables()[0];
    assert(input_table);

    //
    // OPTIMIZATION: NESTED LIMIT
    // How nice! We can also cut off our scanning with a nested limit!
    //
    int limit = -1;
    int offset = -1;
    if (limit_node != NULL)
    {
        limit_node->getLimitAndOffsetByReference(params, limit, offset);
    }

    // substitute parameters in the order by expressions
    for (int i = 0; i < node->getSortExpressions().size(); i++) {
        node->getSortExpressions()[i]->substitute(params);
    }

    VOLT_TRACE("Running OrderBy '%s'", m_abstractNode->debug().c_str());
    VOLT_TRACE("Input Table:\n '%s'", input_table->debug().c_str());
    TableIterator iterator = input_table->iterator();
    TableTuple tuple(input_table->schema());
    vector<TableTuple> xs;
    while (iterator.next(tuple))
    {
        m_engine->noteTuplesProcessedForProgressMonitoring(1);
        assert(tuple.isActive());
        xs.push_back(tuple);
    }
    VOLT_TRACE("\n***** Input Table PreSort:\n '%s'",
               input_table->debug().c_str());
    sort(xs.begin(), xs.end(), TupleComparer(node->getSortExpressions(),
                                             node->getSortDirections()));

    int tuple_ctr = 0;
    int tuple_skipped = 0;
    for (vector<TableTuple>::iterator it = xs.begin(); it != xs.end(); it++)
    {
        //
        // Check if has gone past the offset
        //
        if (tuple_skipped < offset) {
            tuple_skipped++;
            continue;
        }

        VOLT_TRACE("\n***** Input Table PostSort:\n '%s'",
                   input_table->debug().c_str());
        if (!output_table->insertTuple(*it))
        {
            VOLT_ERROR("Failed to insert order-by tuple from input table '%s'"
                       " into output table '%s'",
                       input_table->name().c_str(),
                       output_table->name().c_str());
            return false;
        }
        //
        // Check whether we have gone past our limit
        //
        if (limit >= 0 && ++tuple_ctr >= limit) {
            break;
        }
    }
    VOLT_TRACE("Result of OrderBy:\n '%s'", output_table->debug().c_str());

    return true;
}