bool ProjectionExecutor::p_execute(const NValueArray ¶ms) { #ifndef NDEBUG ProjectionPlanNode* node = dynamic_cast<ProjectionPlanNode*>(m_abstractNode); #endif assert (node); assert (!node->isInline()); // inline projection's execute() should not be // called assert (output_table == dynamic_cast<TempTable*>(node->getOutputTable())); assert (output_table); Table* input_table = m_abstractNode->getInputTable(); assert (input_table); VOLT_TRACE("INPUT TABLE: %s\n", input_table->debug().c_str()); // // Since we have the input params, we need to call substitute to change any // nodes in our expression tree to be ready for the projection operations in // execute // assert (m_columnCount == (int)node->getOutputColumnNames().size()); if (all_tuple_array == NULL && all_param_array == NULL) { for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { assert(expression_array[ctr]); VOLT_TRACE("predicate[%d]: %s", ctr, expression_array[ctr]->debug(true).c_str()); } } // // Now loop through all the tuples and push them through our output // expression This will generate new tuple values that we will insert into // our output table // TableIterator iterator = input_table->iteratorDeletingAsWeGo(); assert (tuple.sizeInValues() == input_table->columnCount()); while (iterator.next(tuple)) { // // Project (or replace) values from input tuple // TableTuple &temp_tuple = output_table->tempTuple(); if (all_tuple_array != NULL) { VOLT_TRACE("sweet, all tuples"); for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { temp_tuple.setNValue(ctr, tuple.getNValue(all_tuple_array[ctr])); } } else if (all_param_array != NULL) { VOLT_TRACE("sweet, all params"); for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { temp_tuple.setNValue(ctr, params[all_param_array[ctr]]); } } else { for (int ctr = m_columnCount - 1; ctr >= 0; --ctr) { temp_tuple.setNValue(ctr, expression_array[ctr]->eval(&tuple, NULL)); } } output_table->insertTupleNonVirtual(temp_tuple); VOLT_TRACE("OUTPUT TABLE: %s\n", output_table->debug().c_str()); } cleanupInputTempTable(input_table); return (true); }
/* * This function is called straight from AbstractExecutor::execute, * which is called from executeExecutors, which is called from the * VoltDBEngine::executePlanFragments. So, this is really the start * of execution for this executor. * * The executor will already have been initialized by p_init. */ bool WindowFunctionExecutor::p_execute(const NValueArray& params) { VOLT_TRACE("windowFunctionExecutor::p_execute(start)\n"); // Input table Table * input_table = m_abstractNode->getInputTable(); assert(input_table); VOLT_TRACE("WindowFunctionExecutor: input table\n%s", input_table->debug().c_str()); m_inputSchema = input_table->schema(); assert(m_inputSchema); /* * Do this after setting the m_inputSchema. */ initWorkingTupleStorage(); TableWindow tableWindow(input_table); ProgressMonitorProxy pmp(m_engine->getExecutorContext(), this); m_pmp = &pmp; m_aggregateRow = new (m_memoryPool, m_aggTypes.size()) WindowAggregateRow(m_inputSchema, m_memoryPool); initAggInstances(); VOLT_TRACE("Beginning: %s", tableWindow.debug().c_str()); TableTuple nextTuple(m_inputSchema); /* * Force a call p_execute_finish when this is all over. */ EnsureCleanupOnExit finishCleanup(this); for (EdgeType etype = START_OF_INPUT, nextEtype = INVALID_EDGE_TYPE; etype != END_OF_INPUT; etype = nextEtype) { // Reset the aggregates if this is the // start of a partition group. The start of // input is a special form of this. if (etype == START_OF_INPUT || etype == START_OF_PARTITION_GROUP) { m_aggregateRow->resetAggs(); } // Find the next edge. This will // give the aggs a crack at each row // if they want it. nextEtype = findNextEdge(etype, tableWindow); // Let the aggs know the results // of the lookahead. lookaheadNextGroupForAggs(tableWindow); // Advance to the end of the current group. for (int idx = 0; idx < tableWindow.m_orderByGroupSize; idx += 1) { VOLT_TRACE("MiddleEdge: Window = %s", m_tableWindow->debug().c_str()); tableWindow.m_middleEdge.next(nextTuple); m_pmp->countdownProgress(); m_aggregateRow->recordPassThroughTuple(nextTuple); insertOutputTuple(); } endGroupForAggs(tableWindow, etype); VOLT_TRACE("FirstEdge: %s", m_tableWindow->debug().c_str()); } VOLT_TRACE("WindowFunctionExecutor: finalizing.."); cleanupInputTempTable(input_table); VOLT_TRACE("WindowFunctionExecutor::p_execute(end)\n"); return true; }