bool OrderByExecutor::p_execute(const NValueArray ¶ms) { 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; }
bool OrderByExecutor::p_execute(const NValueArray ¶ms) { 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; }