Table *TableCatalogDelegate::constructTableFromCatalog(catalog::Database &catalogDatabase, catalog::Table &catalogTable) { // Create a persistent table for this table in our catalog int32_t table_id = catalogTable.relativeIndex(); // get an array of table column names const int numColumns = static_cast<int>(catalogTable.columns().size()); map<string, catalog::Column*>::const_iterator col_iterator; vector<string> columnNames(numColumns); for (col_iterator = catalogTable.columns().begin(); col_iterator != catalogTable.columns().end(); col_iterator++) { const catalog::Column *catalog_column = col_iterator->second; columnNames[catalog_column->index()] = catalog_column->name(); } // get the schema for the table TupleSchema *schema = createTupleSchema(catalogTable); // Indexes map<string, TableIndexScheme> index_map; map<string, catalog::Index*>::const_iterator idx_iterator; for (idx_iterator = catalogTable.indexes().begin(); idx_iterator != catalogTable.indexes().end(); idx_iterator++) { catalog::Index *catalog_index = idx_iterator->second; TableIndexScheme index_scheme; if (getIndexScheme(catalogTable, *catalog_index, schema, &index_scheme)) { index_map[catalog_index->name()] = index_scheme; } } // Constraints string pkey_index_id; map<string, catalog::Constraint*>::const_iterator constraint_iterator; for (constraint_iterator = catalogTable.constraints().begin(); constraint_iterator != catalogTable.constraints().end(); constraint_iterator++) { catalog::Constraint *catalog_constraint = constraint_iterator->second; // Constraint Type ConstraintType type = (ConstraintType)catalog_constraint->type(); switch (type) { case CONSTRAINT_TYPE_PRIMARY_KEY: // Make sure we have an index to use if (catalog_constraint->index() == NULL) { VOLT_ERROR("The '%s' constraint '%s' on table '%s' does" " not specify an index", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str(), catalogTable.name().c_str()); return NULL; } // Make sure they didn't declare more than one primary key index else if (pkey_index_id.size() > 0) { VOLT_ERROR("Trying to declare a primary key on table '%s'" "using index '%s' but '%s' was already set as" " the primary key", catalogTable.name().c_str(), catalog_constraint->index()->name().c_str(), pkey_index_id.c_str()); return NULL; } pkey_index_id = catalog_constraint->index()->name(); break; case CONSTRAINT_TYPE_UNIQUE: // Make sure we have an index to use // TODO: In the future I would like bring back my Constraint // object so that we can keep track of everything that a // table has... if (catalog_constraint->index() == NULL) { VOLT_ERROR("The '%s' constraint '%s' on table '%s' does" " not specify an index", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str(), catalogTable.name().c_str()); return NULL; } break; // Unsupported case CONSTRAINT_TYPE_CHECK: case CONSTRAINT_TYPE_FOREIGN_KEY: case CONSTRAINT_TYPE_MAIN: VOLT_WARN("Unsupported type '%s' for constraint '%s'", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str()); break; // Unknown default: VOLT_ERROR("Invalid constraint type '%s' for '%s'", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str()); return NULL; } } // Build the index array vector<TableIndexScheme> indexes; TableIndexScheme pkey_index_scheme; map<string, TableIndexScheme>::const_iterator index_iterator; for (index_iterator = index_map.begin(); index_iterator != index_map.end(); index_iterator++) { // Exclude the primary key if (index_iterator->first.compare(pkey_index_id) == 0) { pkey_index_scheme = index_iterator->second; // Just add it to the list } else { indexes.push_back(index_iterator->second); } } // partition column: const catalog::Column* partitionColumn = catalogTable.partitioncolumn(); int partitionColumnIndex = -1; if (partitionColumn != NULL) { partitionColumnIndex = partitionColumn->index(); } bool exportEnabled = isExportEnabledForTable(catalogDatabase, table_id); bool tableIsExportOnly = isTableExportOnly(catalogDatabase, table_id); const string& tableName = catalogTable.name(); int32_t databaseId = catalogDatabase.relativeIndex(); Table *table = TableFactory::getPersistentTable(databaseId, tableName, schema, columnNames, partitionColumnIndex, exportEnabled, tableIsExportOnly); // add a pkey index if one exists if (pkey_index_id.size() != 0) { TableIndex *pkeyIndex = TableIndexFactory::getInstance(pkey_index_scheme); assert(pkeyIndex); table->addIndex(pkeyIndex); table->setPrimaryKeyIndex(pkeyIndex); } // add other indexes BOOST_FOREACH(TableIndexScheme &scheme, indexes) { TableIndex *index = TableIndexFactory::getInstance(scheme); assert(index); table->addIndex(index); }
Table *TableCatalogDelegate::constructTableFromCatalog(catalog::Database const &catalogDatabase, catalog::Table const &catalogTable) { // Create a persistent table for this table in our catalog int32_t table_id = catalogTable.relativeIndex(); // get an array of table column names const int numColumns = static_cast<int>(catalogTable.columns().size()); map<string, catalog::Column*>::const_iterator col_iterator; vector<string> columnNames(numColumns); for (col_iterator = catalogTable.columns().begin(); col_iterator != catalogTable.columns().end(); col_iterator++) { const catalog::Column *catalog_column = col_iterator->second; columnNames[catalog_column->index()] = catalog_column->name(); } // get the schema for the table TupleSchema *schema = createTupleSchema(catalogDatabase, catalogTable); // Indexes map<string, TableIndexScheme> index_map; map<string, catalog::Index*>::const_iterator idx_iterator; for (idx_iterator = catalogTable.indexes().begin(); idx_iterator != catalogTable.indexes().end(); idx_iterator++) { catalog::Index *catalog_index = idx_iterator->second; TableIndexScheme index_scheme; if (getIndexScheme(catalogTable, *catalog_index, schema, &index_scheme)) { index_map[catalog_index->name()] = index_scheme; } } // Constraints string pkey_index_id; map<string, catalog::Constraint*>::const_iterator constraint_iterator; for (constraint_iterator = catalogTable.constraints().begin(); constraint_iterator != catalogTable.constraints().end(); constraint_iterator++) { catalog::Constraint *catalog_constraint = constraint_iterator->second; // Constraint Type ConstraintType type = (ConstraintType)catalog_constraint->type(); switch (type) { case CONSTRAINT_TYPE_PRIMARY_KEY: // Make sure we have an index to use if (catalog_constraint->index() == NULL) { VOLT_ERROR("The '%s' constraint '%s' on table '%s' does" " not specify an index", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str(), catalogTable.name().c_str()); return NULL; } // Make sure they didn't declare more than one primary key index else if (pkey_index_id.size() > 0) { VOLT_ERROR("Trying to declare a primary key on table '%s'" "using index '%s' but '%s' was already set as" " the primary key", catalogTable.name().c_str(), catalog_constraint->index()->name().c_str(), pkey_index_id.c_str()); return NULL; } pkey_index_id = catalog_constraint->index()->name(); break; case CONSTRAINT_TYPE_UNIQUE: // Make sure we have an index to use // TODO: In the future I would like bring back my Constraint // object so that we can keep track of everything that a // table has... if (catalog_constraint->index() == NULL) { VOLT_ERROR("The '%s' constraint '%s' on table '%s' does" " not specify an index", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str(), catalogTable.name().c_str()); return NULL; } break; // Unsupported case CONSTRAINT_TYPE_CHECK: case CONSTRAINT_TYPE_FOREIGN_KEY: case CONSTRAINT_TYPE_MAIN: VOLT_WARN("Unsupported type '%s' for constraint '%s'", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str()); break; // Unknown default: VOLT_ERROR("Invalid constraint type '%s' for '%s'", constraintutil::getTypeName(type).c_str(), catalog_constraint->name().c_str()); return NULL; } } // Build the index array // Please note the index array should follow the order of primary key first, // all unique indices afterwards, and all the non-unique indices at the end. deque<TableIndexScheme> indexes; TableIndexScheme pkey_index_scheme; map<string, TableIndexScheme>::const_iterator index_iterator; for (index_iterator = index_map.begin(); index_iterator != index_map.end(); index_iterator++) { // Exclude the primary key if (index_iterator->second.name.compare(pkey_index_id) == 0) { pkey_index_scheme = index_iterator->second; // Just add it to the list } else { if (index_iterator->second.unique) { indexes.push_front(index_iterator->second); } else { indexes.push_back(index_iterator->second); } } } // partition column: const catalog::Column* partitionColumn = catalogTable.partitioncolumn(); int partitionColumnIndex = -1; if (partitionColumn != NULL) { partitionColumnIndex = partitionColumn->index(); } bool exportEnabled = isExportEnabledForTable(catalogDatabase, table_id); bool tableIsExportOnly = isTableExportOnly(catalogDatabase, table_id); bool drEnabled = catalogTable.isDRed(); m_materialized = isTableMaterialized(catalogTable); const string& tableName = catalogTable.name(); int32_t databaseId = catalogDatabase.relativeIndex(); SHA1_CTX shaCTX; SHA1Init(&shaCTX); SHA1Update(&shaCTX, reinterpret_cast<const uint8_t *>(catalogTable.signature().c_str()), (uint32_t )::strlen(catalogTable.signature().c_str())); SHA1Final(reinterpret_cast<unsigned char *>(m_signatureHash), &shaCTX); // Persistent table will use default size (2MB) if tableAllocationTargetSize is zero. int tableAllocationTargetSize = 0; if (m_materialized) { catalog::MaterializedViewInfo *mvInfo = catalogTable.materializer()->views().get(catalogTable.name()); if (mvInfo->groupbycols().size() == 0) { // ENG-8490: If the materialized view came with no group by, set table block size to 64KB // to achieve better space efficiency. // FYI: maximum column count = 1024, largest fixed length data type is short varchars (64 bytes) tableAllocationTargetSize = 1024 * 64; } } Table *table = TableFactory::getPersistentTable(databaseId, tableName, schema, columnNames, m_signatureHash, m_materialized, partitionColumnIndex, exportEnabled, tableIsExportOnly, tableAllocationTargetSize, catalogTable.tuplelimit(), m_compactionThreshold, drEnabled); // add a pkey index if one exists if (pkey_index_id.size() != 0) { TableIndex *pkeyIndex = TableIndexFactory::getInstance(pkey_index_scheme); assert(pkeyIndex); table->addIndex(pkeyIndex); table->setPrimaryKeyIndex(pkeyIndex); } // add other indexes BOOST_FOREACH(TableIndexScheme &scheme, indexes) { TableIndex *index = TableIndexFactory::getInstance(scheme); assert(index); table->addIndex(index); }