TupleSchema* AbstractPlanNode::generateTupleSchema(const std::vector<SchemaColumn*>& outputSchema) { int schema_size = static_cast<int>(outputSchema.size()); vector<voltdb::ValueType> columnTypes; vector<int32_t> columnSizes; vector<bool> columnAllowNull(schema_size, true); vector<bool> columnInBytes; for (int i = 0; i < schema_size; i++) { //TODO: SchemaColumn is a sad little class that holds an expression pointer, // a column name that only really comes in handy in one quirky special case, // (see UpdateExecutor::p_init) and a bunch of other stuff that doesn't get used. // Someone should put that class out of our misery. SchemaColumn* col = outputSchema[i]; AbstractExpression * expr = col->getExpression(); columnTypes.push_back(expr->getValueType()); columnSizes.push_back(expr->getValueSize()); columnInBytes.push_back(expr->getInBytes()); } TupleSchema* schema = TupleSchema::createTupleSchema(columnTypes, columnSizes, columnAllowNull, columnInBytes); return schema; }
bool AggregateExecutorBase::p_init(AbstractPlanNode*, TempTableLimits* limits) { AggregatePlanNode* node = dynamic_cast<AggregatePlanNode*>(m_abstractNode); assert(node); assert(node->getChildren().size() == 1); assert(node->getChildren()[0] != NULL); m_inputExpressions = node->getAggregateInputExpressions(); for (int i = 0; i < m_inputExpressions.size(); i++) { VOLT_DEBUG("\nAGG INPUT EXPRESSION: %s\n", m_inputExpressions[i] ? m_inputExpressions[i]->debug().c_str() : "null"); } /* * Find the difference between the set of aggregate output columns * (output columns resulting from an aggregate) and output columns. * Columns that are not the result of aggregates are being passed * through from the input table. Do this extra work here rather then * serialize yet more data. */ std::vector<bool> outputColumnsResultingFromAggregates(node->getOutputSchema().size(), false); std::vector<int> aggregateOutputColumns = node->getAggregateOutputColumns(); BOOST_FOREACH(int aOC, aggregateOutputColumns) { outputColumnsResultingFromAggregates[aOC] = true; } /* * Now collect the indices in the output table of the pass * through columns. */ for (int ii = 0; ii < outputColumnsResultingFromAggregates.size(); ii++) { if (outputColumnsResultingFromAggregates[ii] == false) { m_passThroughColumns.push_back(ii); } } setTempOutputTable(limits); m_aggTypes = node->getAggregates(); m_distinctAggs = node->getDistinctAggregates(); m_groupByExpressions = node->getGroupByExpressions(); node->collectOutputExpressions(m_outputColumnExpressions); m_aggregateOutputColumns = node->getAggregateOutputColumns(); m_prePredicate = node->getPrePredicate(); m_postPredicate = node->getPostPredicate(); std::vector<ValueType> groupByColumnTypes; std::vector<int32_t> groupByColumnSizes; std::vector<bool> groupByColumnAllowNull; for (int ii = 0; ii < m_groupByExpressions.size(); ii++) { AbstractExpression* expr = m_groupByExpressions[ii]; groupByColumnTypes.push_back(expr->getValueType()); groupByColumnSizes.push_back(expr->getValueSize()); groupByColumnAllowNull.push_back(true); } m_groupByKeySchema = TupleSchema::createTupleSchema(groupByColumnTypes, groupByColumnSizes, groupByColumnAllowNull, true); return true; }