bool DeleteExecutor::p_init(AbstractPlanNode *abstract_node, const catalog::Database* catalog_db, int* tempTableMemoryInBytes) { VOLT_TRACE("init Delete Executor"); DeletePlanNode* node = dynamic_cast<DeletePlanNode*>(abstract_node); assert(node); assert(node->getTargetTable()); m_targetTable = dynamic_cast<PersistentTable*>(node->getTargetTable()); //target table should be persistenttable assert(m_targetTable); m_truncate = node->getTruncate(); if (m_truncate) { assert(node->getInputTables().size() == 0); // TODO : we can't use target table here because // it will report that "0 tuples deleted" as it's already truncated as of Result node.. node->setOutputTable(TableFactory::getCopiedTempTable(m_targetTable->databaseId(), "result_table", m_targetTable, tempTableMemoryInBytes)); return true; } assert(node->getInputTables().size() == 1); m_inputTable = dynamic_cast<TempTable*>(node->getInputTables()[0]); //input table should be temptable assert(m_inputTable); // Our output is just our input table (regardless if plan is single-sited or not) node->setOutputTable(node->getInputTables()[0]); m_inputTuple = TableTuple(m_inputTable->schema()); m_targetTuple = TableTuple(m_targetTable->schema()); return true; }
MaterializedViewMetadata::MaterializedViewMetadata( PersistentTable *srcTable, PersistentTable *destTable, catalog::MaterializedViewInfo *metadata) : m_target(destTable), m_filterPredicate(NULL) { // 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(); m_searchKey = TableTuple(m_index->getKeySchema()); m_searchKeyBackingStore = new char[m_index->getKeySchema()->tupleLength() + 1]; memset(m_searchKeyBackingStore, 0, m_index->getKeySchema()->tupleLength() + 1); m_searchKey.move(m_searchKeyBackingStore); m_existingTuple = TableTuple(m_target->schema()); m_updatedTuple = TableTuple(m_target->schema()); m_updatedTupleBackingStore = new char[m_target->schema()->tupleLength() + 1]; memset(m_updatedTupleBackingStore, 0, m_target->schema()->tupleLength() + 1); m_updatedTuple.move(m_updatedTupleBackingStore); m_emptyTuple = TableTuple(m_target->schema()); m_emptyTupleBackingStore = new char[m_target->schema()->tupleLength() + 1]; memset(m_emptyTupleBackingStore, 0, m_target->schema()->tupleLength() + 1); m_emptyTuple.move(m_emptyTupleBackingStore); }
TableTuple ArrayUniqueIndex::nextValueAtKey() { if (match_i_ == -1) return TableTuple(); if (!(entries_[match_i_])) return TableTuple(); TableTuple retval(m_tupleSchema); retval.move(entries_[match_i_]); match_i_ = -1; return retval; }
void Table::initializeWithColumns(TupleSchema *schema, const std::string* columnNames, bool ownsTupleSchema) { // copy the tuple schema if (m_ownsTupleSchema) { TupleSchema::freeTupleSchema(m_schema); } m_ownsTupleSchema = ownsTupleSchema; m_schema = schema; m_columnCount = schema->columnCount(); #ifdef MEMCHECK m_tuplesPerBlock = 1; #else m_tuplesPerBlock = m_tableAllocationTargetSize / (m_schema->tupleLength() + TUPLE_HEADER_SIZE); #endif // initialize column names delete[] m_columnNames; m_columnNames = new std::string[m_columnCount]; for (int i = 0; i < m_columnCount; ++i) m_columnNames[i] = columnNames[i]; // initialize the temp tuple char *m_tempTupleMemory = m_tempTuple.m_data; delete[] reinterpret_cast<char*>(m_tempTupleMemory); m_tempTupleMemory = new char[m_schema->tupleLength() + TUPLE_HEADER_SIZE]; m_tempTuple = TableTuple(m_tempTupleMemory, m_schema); ::memset(m_tempTupleMemory, 0, m_tempTuple.tupleLength()); m_tempTuple.setDeletedFalse(); // set the data to be empty m_tupleCount = 0; m_usedTuples = 0; #ifdef MEMCHECK_NOFREELIST m_deletedTupleCount = 0; #else m_holeFreeTuples.clear();//Why clear it. Shouldn't it be empty? Won't this leak? #endif m_tupleLength = m_schema->tupleLength() + TUPLE_HEADER_SIZE; if (m_tuplesPerBlock < 1) { m_tuplesPerBlock = 1; m_tableAllocationSize = m_tupleLength; } else { m_tableAllocationSize = m_tableAllocationTargetSize; } // note that any allocated memory in m_data is left alone // as is m_allocatedTuples m_tmpTarget1 = TableTuple(m_schema); m_tmpTarget2 = TableTuple(m_schema); onSetColumns(); // for more initialization }
void Table::initializeWithColumns(TupleSchema *schema, const std::vector<string> &columnNames, bool ownsTupleSchema, int32_t compactionThreshold) { // copy the tuple schema if (m_ownsTupleSchema) { TupleSchema::freeTupleSchema(m_schema); } m_ownsTupleSchema = ownsTupleSchema; m_schema = schema; m_columnCount = schema->columnCount(); m_tupleLength = m_schema->tupleLength() + TUPLE_HEADER_SIZE; #ifdef MEMCHECK m_tuplesPerBlock = 1; m_tableAllocationSize = m_tupleLength; #else m_tuplesPerBlock = m_tableAllocationTargetSize / m_tupleLength; #ifdef USE_MMAP if (m_tuplesPerBlock < 1) { m_tuplesPerBlock = 1; m_tableAllocationSize = nexthigher(m_tupleLength); } else { m_tableAllocationSize = nexthigher(m_tableAllocationTargetSize); } #else if (m_tuplesPerBlock < 1) { m_tuplesPerBlock = 1; m_tableAllocationSize = m_tupleLength; } else { m_tableAllocationSize = m_tableAllocationTargetSize; } #endif #endif // initialize column names m_columnNames.resize(m_columnCount); for (int i = 0; i < m_columnCount; ++i) m_columnNames[i] = columnNames[i]; m_allowNulls.resize(m_columnCount); for (int i = m_columnCount - 1; i >= 0; --i) { TupleSchema::ColumnInfo const* columnInfo = m_schema->getColumnInfo(i); m_allowNulls[i] = columnInfo->allowNull; } // initialize the temp tuple m_tempTupleMemory.reset(new char[m_schema->tupleLength() + TUPLE_HEADER_SIZE]); m_tempTuple = TableTuple(m_tempTupleMemory.get(), m_schema); ::memset(m_tempTupleMemory.get(), 0, m_tempTuple.tupleLength()); // default value of hidden dr timestamp is null if (m_schema->hiddenColumnCount() > 0) { m_tempTuple.setHiddenNValue(0, NValue::getNullValue(VALUE_TYPE_BIGINT)); } m_tempTuple.setActiveTrue(); // set the data to be empty m_tupleCount = 0; m_compactionThreshold = compactionThreshold; }
bool ElasticIndexTupleRangeIterator::next(TableTuple &tuple) { if (m_iter == m_end) { return false; } tuple = TableTuple(m_iter++->getTupleAddress(), &m_schema); return true; }
void MaterializedViewMetadata::allocateBackedTuples() { m_searchKey = TableTuple(m_index->getKeySchema()); m_searchKeyBackingStore = new char[m_index->getKeySchema()->tupleLength() + 1]; memset(m_searchKeyBackingStore, 0, m_index->getKeySchema()->tupleLength() + 1); m_searchKey.move(m_searchKeyBackingStore); m_existingTuple = TableTuple(m_target->schema()); m_updatedTuple = TableTuple(m_target->schema()); m_updatedTupleBackingStore = new char[m_target->schema()->tupleLength() + 1]; memset(m_updatedTupleBackingStore, 0, m_target->schema()->tupleLength() + 1); m_updatedTuple.move(m_updatedTupleBackingStore); m_emptyTuple = TableTuple(m_target->schema()); m_emptyTupleBackingStore = new char[m_target->schema()->tupleLength() + 1]; memset(m_emptyTupleBackingStore, 0, m_target->schema()->tupleLength() + 1); m_emptyTuple.move(m_emptyTupleBackingStore); }
bool ProjectionExecutor::p_init(AbstractPlanNode *abstractNode, TempTableLimits* limits) { VOLT_TRACE("init Projection Executor"); assert(limits); ProjectionPlanNode* node = dynamic_cast<ProjectionPlanNode*>(abstractNode); assert(node); // // Construct the output table // TupleSchema* schema = node->generateTupleSchema(true); m_columnCount = static_cast<int>(node->getOutputSchema().size()); std::string* column_names = new std::string[m_columnCount]; for (int ctr = 0; ctr < m_columnCount; ctr++) { column_names[ctr] = node->getOutputSchema()[ctr]->getColumnName(); } node->setOutputTable(TableFactory::getTempTable(node->databaseId(), "temp", schema, column_names, limits)); delete[] column_names; // initialize local variables all_tuple_array_ptr = ExpressionUtil::convertIfAllTupleValues(node->getOutputColumnExpressions()); all_tuple_array = all_tuple_array_ptr.get(); all_param_array_ptr = ExpressionUtil::convertIfAllParameterValues(node->getOutputColumnExpressions()); all_param_array = all_param_array_ptr.get(); needs_substitute_ptr = boost::shared_array<bool>(new bool[m_columnCount]); needs_substitute = needs_substitute_ptr.get(); typedef AbstractExpression* ExpRawPtr; expression_array_ptr = boost::shared_array<ExpRawPtr>(new ExpRawPtr[m_columnCount]); expression_array = expression_array_ptr.get(); for (int ctr = 0; ctr < m_columnCount; ctr++) { assert (node->getOutputColumnExpressions()[ctr] != NULL); expression_array_ptr[ctr] = node->getOutputColumnExpressions()[ctr]; needs_substitute_ptr[ctr] = node->getOutputColumnExpressions()[ctr]->hasParameter(); } output_table = dynamic_cast<TempTable*>(node->getOutputTable()); //output table should be temptable if (!node->isInline()) { input_table = node->getInputTables()[0]; tuple = TableTuple(input_table->schema()); } return true; }
bool ProjectionExecutor::p_init(AbstractPlanNode *abstractNode, TempTableLimits* limits) { VOLT_TRACE("init Projection Executor"); assert(limits); ProjectionPlanNode* node = dynamic_cast<ProjectionPlanNode*>(abstractNode); assert(node); // Create output table based on output schema from the plan setTempOutputTable(limits); m_columnCount = static_cast<int>(node->getOutputSchema().size()); // initialize local variables all_tuple_array_ptr = ExpressionUtil::convertIfAllTupleValues(node->getOutputColumnExpressions()); all_tuple_array = all_tuple_array_ptr.get(); all_param_array_ptr = ExpressionUtil::convertIfAllParameterValues(node->getOutputColumnExpressions()); all_param_array = all_param_array_ptr.get(); needs_substitute_ptr = boost::shared_array<bool>(new bool[m_columnCount]); needs_substitute = needs_substitute_ptr.get(); typedef AbstractExpression* ExpRawPtr; expression_array_ptr = boost::shared_array<ExpRawPtr>(new ExpRawPtr[m_columnCount]); expression_array = expression_array_ptr.get(); for (int ctr = 0; ctr < m_columnCount; ctr++) { assert (node->getOutputColumnExpressions()[ctr] != NULL); VOLT_TRACE("OutputColumnExpressions [%d]: %s", ctr, node->getOutputColumnExpressions()[ctr]->debug(true).c_str()); expression_array_ptr[ctr] = node->getOutputColumnExpressions()[ctr]; needs_substitute_ptr[ctr] = node->getOutputColumnExpressions()[ctr]->hasParameter(); } output_table = dynamic_cast<TempTable*>(node->getOutputTable()); //output table should be temptable if (!node->isInline()) { Table* input_table = node->getInputTable(); tuple = TableTuple(input_table->schema()); } return true; }
bool DeleteExecutor::p_init(AbstractPlanNode *abstract_node, const ExecutorVector& executorVector) { VOLT_TRACE("init Delete Executor"); m_node = dynamic_cast<DeletePlanNode*>(abstract_node); assert(m_node); assert(m_node->getTargetTable()); setDMLCountOutputTable(executorVector.limits()); m_truncate = m_node->getTruncate(); if (m_truncate) { assert(m_node->getInputTableCount() == 0); return true; } assert(m_node->getInputTableCount() == 1); m_inputTable = dynamic_cast<AbstractTempTable*>(m_node->getInputTable()); //input table should be temptable assert(m_inputTable); m_inputTuple = TableTuple(m_inputTable->schema()); return true; }
bool InsertExecutor::p_execute_init_internal(const TupleSchema *inputSchema, AbstractTempTable *newOutputTable, TableTuple &temp_tuple) { assert(m_node == dynamic_cast<InsertPlanNode*>(m_abstractNode)); assert(m_node); assert(inputSchema); assert(m_node->isInline() || (m_inputTable == dynamic_cast<AbstractTempTable*>(m_node->getInputTable()))); assert(m_node->isInline() || m_inputTable); // Target table can be StreamedTable or PersistentTable and must not be NULL // Update target table reference from table delegate m_targetTable = m_node->getTargetTable(); assert(m_targetTable); assert((m_targetTable == dynamic_cast<PersistentTable*>(m_targetTable)) || (m_targetTable == dynamic_cast<StreamedTable*>(m_targetTable))); m_persistentTable = m_isStreamed ? NULL : static_cast<PersistentTable*>(m_targetTable); assert((!m_persistentTable && !m_replicatedTableOperation) || m_replicatedTableOperation == m_persistentTable->isCatalogTableReplicated()); m_upsertTuple = TableTuple(m_targetTable->schema()); VOLT_TRACE("INPUT TABLE: %s\n", m_node->isInline() ? "INLINE" : m_inputTable->debug().c_str()); // count the number of successful inserts m_modifiedTuples = 0; m_tmpOutputTable = newOutputTable; assert(m_tmpOutputTable); m_count_tuple = m_tmpOutputTable->tempTuple(); // For export tables with no partition column, // if the data is from a replicated source, // only insert into one partition (the one for hash(0)). // Other partitions can just return a 0 modified tuple count. // OTOH, if the data is coming from a (sub)query with // partitioned tables, perform the insert on every partition. if (m_partitionColumn == -1 && m_isStreamed && m_multiPartition && !m_sourceIsPartitioned && !m_engine->isLocalSite(ValueFactory::getBigIntValue(0L))) { m_count_tuple.setNValue(0, ValueFactory::getBigIntValue(0L)); // put the tuple into the output table m_tmpOutputTable->insertTuple(m_count_tuple); return false; } m_templateTuple = m_templateTupleStorage.tuple(); std::vector<int>::iterator it; for (it = m_nowFields.begin(); it != m_nowFields.end(); ++it) { m_templateTuple.setNValue(*it, NValue::callConstant<FUNC_CURRENT_TIMESTAMP>()); } VOLT_DEBUG("Initializing insert executor to insert into %s table %s", static_cast<PersistentTable*>(m_targetTable)->isCatalogTableReplicated() ? "replicated" : "partitioned", m_targetTable->name().c_str()); VOLT_DEBUG("This is a %s insert on partition with id %d", m_node->isInline() ? "inline" : (m_node->getChildren()[0]->getPlanNodeType() == PLAN_NODE_TYPE_MATERIALIZE ? "single-row" : "multi-row"), m_engine->getPartitionId()); VOLT_DEBUG("Offset of partition column is %d", m_partitionColumn); // // Return a tuple whose schema we can use as an // input. // m_tempPool = ExecutorContext::getTempStringPool(); char *storage = static_cast<char *>(m_tempPool->allocateZeroes(inputSchema->tupleLength() + TUPLE_HEADER_SIZE)); temp_tuple = TableTuple(storage, inputSchema); return true; }
int64_t TupleTrackerManager::getPrimaryKey(std::string tableName, uint32_t tupleId){ Table* table = voltDBEngine->getTable(tableName); TableTuple tuple = TableTuple(table->schema()); tuple.move(table->dataPtrForTuple(tupleId)); TableIndex *m_index = table->primaryKeyIndex(); std::vector<int> column_indices_vector = m_index->getColumnIndices(); std::vector<int>::iterator it = column_indices_vector.begin(); NValue colValue; int i = 0; while (it != column_indices_vector.end()) // this is for non composite key { colValue = tuple.getNValue(*it); it++; i++; } return colValue.castAsBigIntAndGetValue(); //return i; //return colValue.isNull(); /* it = std::find(column_indices_vector.begin(), column_indices_vector.end(), tupleId); return (int) std:: distance(column_indices_vector.begin(), it); TableTuple outputTuple = ... // tuple for your output table TableTuple inputTuple = ... // tuple from your tracking table TableTuple origTuple = ... // tuple from the original PersistantTable foreach (inputTuple in tracking table) { // (1) Get offset from inputTuple and move the origTuple to that location origTuple.move(table->dataPtrForTuple(tupleId)); // (2) Now iterate over the pkey column offsets and copy the values into the inputTuple int col_idx = 0; for (pkey_offset in m_index->getColumnIndices()) { NValue colValue = origTuple.getNValue(pkey_offset); outputTuple.setNValue(col_idx, colValue); col_idx++; } // (3) Insert outputTuple into output table } int colCount = (int)column_indices_vector.size(); if (colCount < tupleId) return -1; return column_indices_vector[tupleId]; //*/ }
bool UpdateExecutor::p_init(AbstractPlanNode *abstract_node, const catalog::Database* catalog_db, int* tempTableMemoryInBytes) { VOLT_TRACE("init Update Executor"); UpdatePlanNode* node = dynamic_cast<UpdatePlanNode*>(abstract_node); assert(node); assert(node->getTargetTable()); assert(node->getInputTables().size() == 1); m_inputTable = dynamic_cast<TempTable*>(node->getInputTables()[0]); //input table should be temptable assert(m_inputTable); m_targetTable = dynamic_cast<PersistentTable*>(node->getTargetTable()); //target table should be persistenttable assert(m_targetTable); assert(node->getTargetTable()); // Our output is just our input table (regardless if plan is single-sited or not) node->setOutputTable(node->getInputTables()[0]); // record if a full index update is needed, or if these checks can be skipped m_updatesIndexes = node->doesUpdateIndexes(); AbstractPlanNode *child = node->getChildren()[0]; ProjectionPlanNode *proj_node = NULL; if (NULL == child) { VOLT_ERROR("Attempted to initialize update executor with NULL child"); return false; } PlanNodeType pnt = child->getPlanNodeType(); if (pnt == PLAN_NODE_TYPE_PROJECTION) { proj_node = dynamic_cast<ProjectionPlanNode*>(child); } else if (pnt == PLAN_NODE_TYPE_SEQSCAN || pnt == PLAN_NODE_TYPE_INDEXSCAN) { proj_node = dynamic_cast<ProjectionPlanNode*>(child->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION)); assert(NULL != proj_node); } std::vector<std::string> output_column_names = proj_node->getOutputColumnNames(); std::string targetTableName = node->getTargetTableName(); catalog::Table *targetTable = NULL; catalog::CatalogMap<catalog::Table> tables = catalog_db->tables(); for ( catalog::CatalogMap<catalog::Table>::field_map_iter i = tables.begin(); i != tables.end(); i++) { catalog::Table *table = (*i).second; if (table->name().compare(targetTableName) == 0) { targetTable = table; break; } } assert(targetTable != NULL); catalog::CatalogMap<catalog::Column> columns = targetTable->columns(); /* * The first output column is the tuple address expression and it isn't part of our output so we skip * it when generating the map from input columns to the target table columns. */ for (int ii = 1; ii < output_column_names.size(); ii++) { std::string outputColumnName = output_column_names[ii]; catalog::Column *column = columns.get(outputColumnName); assert (column != NULL); m_inputTargetMap.push_back(std::pair<int, int>( ii, column->index())); } m_inputTargetMapSize = (int)m_inputTargetMap.size(); m_inputTuple = TableTuple(m_inputTable->schema()); m_targetTuple = TableTuple(m_targetTable->schema()); m_partitionColumn = m_targetTable->partitionColumn(); m_partitionColumnIsString = false; if (m_partitionColumn != -1) { if (m_targetTable->schema()->columnType(m_partitionColumn) == voltdb::VALUE_TYPE_VARCHAR) { m_partitionColumnIsString = true; } } return true; }