void MaterializedViewMetadata::processTupleUpdate(TableTuple &oldTuple, TableTuple &newTuple) { // this approach is far from optimal, but should be technically correct processTupleDelete(oldTuple); processTupleInsert(newTuple); }
MaterializedViewMetadata::MaterializedViewMetadata( PersistentTable *srcTable, PersistentTable *destTable, catalog::MaterializedViewInfo *metadata) : m_target(destTable), m_filterPredicate(NULL) { // DEBUG_STREAM_HERE("New mat view on source table " << srcTable->name() << " @" << srcTable << " view table " << m_target->name() << " @" << m_target); // best not to have to worry about the destination table disappearing out from under the source table that feeds it. m_target->incrementRefcount(); srcTable->addMaterializedView(this); // try to load the predicate from the catalog view parsePredicate(metadata); // set up the group by columns from the catalog info m_groupByColumnCount = metadata->groupbycols().size(); m_groupByColumns = new int32_t[m_groupByColumnCount]; std::map<std::string, catalog::ColumnRef*>::const_iterator colRefIterator; for (colRefIterator = metadata->groupbycols().begin(); colRefIterator != metadata->groupbycols().end(); colRefIterator++) { int32_t grouping_order_offset = colRefIterator->second->index(); m_groupByColumns[grouping_order_offset] = colRefIterator->second->column()->index(); } // set up the mapping from input col to output col m_outputColumnCount = metadata->dest()->columns().size(); m_outputColumnSrcTableIndexes = new int32_t[m_outputColumnCount]; m_outputColumnAggTypes = new ExpressionType[m_outputColumnCount]; std::map<std::string, catalog::Column*>::const_iterator colIterator; // iterate the source table for (colIterator = metadata->dest()->columns().begin(); colIterator != metadata->dest()->columns().end(); colIterator++) { const catalog::Column *destCol = colIterator->second; int destIndex = destCol->index(); const catalog::Column *srcCol = destCol->matviewsource(); if (srcCol) { m_outputColumnSrcTableIndexes[destIndex] = srcCol->index(); m_outputColumnAggTypes[destIndex] = static_cast<ExpressionType>(destCol->aggregatetype()); } else { m_outputColumnSrcTableIndexes[destIndex] = -1; m_outputColumnAggTypes[destIndex] = EXPRESSION_TYPE_INVALID; } } m_index = m_target->primaryKeyIndex(); // When updateTupleWithSpecificIndexes needs to be called, // the context is lost that identifies which base table columns potentially changed. // So the minimal set of indexes that MIGHT need to be updated must include // any that are not solely based on primary key components. // Until the DDL compiler does this analysis and marks the indexes accordingly, // include all target table indexes except the actual primary key index on the group by columns. const std::vector<TableIndex*>& targetIndexes = m_target->allIndexes(); BOOST_FOREACH(TableIndex *index, targetIndexes) { if (index != m_index) { m_updatableIndexList.push_back(index); } } allocateBackedTuples(); // Catch up on pre-existing source tuples UNLESS target tuples have already been migrated in. if (( ! srcTable->isPersistentTableEmpty()) && m_target->isPersistentTableEmpty()) { TableTuple scannedTuple(srcTable->schema()); TableIterator &iterator = srcTable->iterator(); while (iterator.next(scannedTuple)) { processTupleInsert(scannedTuple, false); } } }