Search in sources :

Example 1 with AlreadyExistsException

use of org.apache.iceberg.exceptions.AlreadyExistsException in project presto by prestodb.

the class IcebergHadoopMetadata method beginCreateTable.

@Override
public ConnectorOutputTableHandle beginCreateTable(ConnectorSession session, ConnectorTableMetadata tableMetadata, Optional<ConnectorNewTableLayout> layout) {
    SchemaTableName schemaTableName = tableMetadata.getTable();
    String schemaName = schemaTableName.getSchemaName();
    String tableName = schemaTableName.getTableName();
    Schema schema = toIcebergSchema(tableMetadata.getColumns());
    PartitionSpec partitionSpec = parsePartitionFields(schema, getPartitioning(tableMetadata.getProperties()));
    ImmutableMap.Builder<String, String> propertiesBuilder = ImmutableMap.builder();
    FileFormat fileFormat = getFileFormat(tableMetadata.getProperties());
    propertiesBuilder.put(DEFAULT_FILE_FORMAT, fileFormat.toString());
    if (tableMetadata.getComment().isPresent()) {
        propertiesBuilder.put(TABLE_COMMENT, tableMetadata.getComment().get());
    }
    String formatVersion = getFormatVersion(tableMetadata.getProperties());
    if (formatVersion != null) {
        propertiesBuilder.put(FORMAT_VERSION, formatVersion);
    }
    try {
        transaction = resourceFactory.getCatalog(session).newCreateTableTransaction(toIcebergTableIdentifier(schemaTableName), schema, partitionSpec, propertiesBuilder.build());
    } catch (AlreadyExistsException e) {
        throw new TableAlreadyExistsException(schemaTableName);
    }
    Table icebergTable = transaction.table();
    return new IcebergWritableTableHandle(schemaName, tableName, SchemaParser.toJson(icebergTable.schema()), PartitionSpecParser.toJson(icebergTable.spec()), getColumns(icebergTable.schema(), typeManager), icebergTable.location(), fileFormat, icebergTable.properties());
}
Also used : TableAlreadyExistsException(com.facebook.presto.hive.TableAlreadyExistsException) SystemTable(com.facebook.presto.spi.SystemTable) IcebergUtil.getHadoopIcebergTable(com.facebook.presto.iceberg.IcebergUtil.getHadoopIcebergTable) Table(org.apache.iceberg.Table) AlreadyExistsException(org.apache.iceberg.exceptions.AlreadyExistsException) TableAlreadyExistsException(com.facebook.presto.hive.TableAlreadyExistsException) Schema(org.apache.iceberg.Schema) FileFormat(org.apache.iceberg.FileFormat) IcebergTableProperties.getFileFormat(com.facebook.presto.iceberg.IcebergTableProperties.getFileFormat) SchemaTableName(com.facebook.presto.spi.SchemaTableName) PartitionSpec(org.apache.iceberg.PartitionSpec) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap)

Example 2 with AlreadyExistsException

use of org.apache.iceberg.exceptions.AlreadyExistsException in project hive by apache.

the class HiveTableOperations method doCommit.

@SuppressWarnings("checkstyle:CyclomaticComplexity")
@Override
protected void doCommit(TableMetadata base, TableMetadata metadata) {
    String newMetadataLocation = writeNewMetadata(metadata, currentVersion() + 1);
    boolean hiveEngineEnabled = hiveEngineEnabled(metadata, conf);
    boolean keepHiveStats = conf.getBoolean(KEEP_HIVE_STATS, false);
    CommitStatus commitStatus = CommitStatus.FAILURE;
    boolean updateHiveTable = false;
    Optional<Long> lockId = Optional.empty();
    // getting a process-level lock per table to avoid concurrent commit attempts to the same table from the same
    // JVM process, which would result in unnecessary and costly HMS lock acquisition requests
    ReentrantLock tableLevelMutex = commitLockCache.get(fullName, t -> new ReentrantLock(true));
    tableLevelMutex.lock();
    try {
        lockId = Optional.of(acquireLock());
        // TODO add lock heart beating for cases where default lock timeout is too low.
        Table tbl = loadHmsTable();
        if (tbl != null) {
            // If we try to create the table but the metadata location is already set, then we had a concurrent commit
            if (base == null && tbl.getParameters().get(BaseMetastoreTableOperations.METADATA_LOCATION_PROP) != null) {
                throw new AlreadyExistsException("Table already exists: %s.%s", database, tableName);
            }
            updateHiveTable = true;
            LOG.debug("Committing existing table: {}", fullName);
        } else {
            tbl = newHmsTable();
            LOG.debug("Committing new table: {}", fullName);
        }
        // set to pickup any schema changes
        tbl.setSd(storageDescriptor(metadata, hiveEngineEnabled));
        String metadataLocation = tbl.getParameters().get(METADATA_LOCATION_PROP);
        String baseMetadataLocation = base != null ? base.metadataFileLocation() : null;
        if (!Objects.equals(baseMetadataLocation, metadataLocation)) {
            throw new CommitFailedException("Base metadata location '%s' is not same as the current table metadata location '%s' for %s.%s", baseMetadataLocation, metadataLocation, database, tableName);
        }
        // get Iceberg props that have been removed
        Set<String> removedProps = Collections.emptySet();
        if (base != null) {
            removedProps = base.properties().keySet().stream().filter(key -> !metadata.properties().containsKey(key)).collect(Collectors.toSet());
        }
        Map<String, String> summary = Optional.ofNullable(metadata.currentSnapshot()).map(Snapshot::summary).orElseGet(ImmutableMap::of);
        setHmsTableParameters(newMetadataLocation, tbl, metadata.properties(), removedProps, hiveEngineEnabled, summary);
        if (!keepHiveStats) {
            StatsSetupConst.setBasicStatsState(tbl.getParameters(), StatsSetupConst.FALSE);
            StatsSetupConst.clearColumnStatsState(tbl.getParameters());
        }
        try {
            persistTable(tbl, updateHiveTable);
            commitStatus = CommitStatus.SUCCESS;
        } catch (Throwable persistFailure) {
            LOG.error("Cannot tell if commit to {}.{} succeeded, attempting to reconnect and check.", database, tableName, persistFailure);
            commitStatus = checkCommitStatus(newMetadataLocation, metadata);
            switch(commitStatus) {
                case SUCCESS:
                    break;
                case FAILURE:
                    throw persistFailure;
                case UNKNOWN:
                    throw new CommitStateUnknownException(persistFailure);
            }
        }
    } catch (org.apache.hadoop.hive.metastore.api.AlreadyExistsException e) {
        throw new AlreadyExistsException("Table already exists: %s.%s", database, tableName);
    } catch (TException | UnknownHostException e) {
        if (e.getMessage() != null && e.getMessage().contains("Table/View 'HIVE_LOCKS' does not exist")) {
            throw new RuntimeException("Failed to acquire locks from metastore because 'HIVE_LOCKS' doesn't " + "exist, this probably happened when using embedded metastore or doesn't create a " + "transactional meta table. To fix this, use an alternative metastore", e);
        }
        throw new RuntimeException(String.format("Metastore operation failed for %s.%s", database, tableName), e);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new RuntimeException("Interrupted during commit", e);
    } finally {
        cleanupMetadataAndUnlock(commitStatus, newMetadataLocation, lockId, tableLevelMutex);
    }
}
Also used : ReentrantLock(java.util.concurrent.locks.ReentrantLock) TException(org.apache.thrift.TException) Table(org.apache.hadoop.hive.metastore.api.Table) AlreadyExistsException(org.apache.iceberg.exceptions.AlreadyExistsException) UnknownHostException(java.net.UnknownHostException) CommitStateUnknownException(org.apache.iceberg.exceptions.CommitStateUnknownException) ImmutableMap(org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap) CommitFailedException(org.apache.iceberg.exceptions.CommitFailedException)

Example 3 with AlreadyExistsException

use of org.apache.iceberg.exceptions.AlreadyExistsException in project drill by apache.

the class IcebergMetastore method loadTable.

/**
 * Creates / loads Iceberg table for specific component based on given location
 * and config properties and table schema.
 * Updates table properties for existing Iceberg table only once based on
 * {@link #loadStatusMap} status.
 *
 * @param componentLocationConfig path to component location config
 * @param componentPropertiesConfig path to component properties config
 * @param schema Iceberg table schema
 * @param loadClass Metastore component implementation interface
 * @return Iceberg table instance
 */
private Table loadTable(String componentLocationConfig, String componentPropertiesConfig, IcebergTableSchema schema, Class<?> loadClass) {
    String location = tableLocation(componentLocationConfig);
    Map<String, String> tableProperties = tableProperties(componentPropertiesConfig);
    Table table;
    try {
        table = tables.load(location);
    } catch (NoSuchTableException e) {
        try {
            // creating new Iceberg table, no need to update table properties
            return tables.create(schema.tableSchema(), schema.partitionSpec(), tableProperties, location);
        } catch (AlreadyExistsException ex) {
            table = tables.load(location);
        }
    }
    // updates table properties only during first component table call
    if (loadStatusMap.putIfAbsent(loadClass, Boolean.TRUE) == null) {
        updateTableProperties(table, tableProperties);
    }
    return table;
}
Also used : Table(org.apache.iceberg.Table) AlreadyExistsException(org.apache.iceberg.exceptions.AlreadyExistsException) NoSuchTableException(org.apache.iceberg.exceptions.NoSuchTableException)

Aggregations

AlreadyExistsException (org.apache.iceberg.exceptions.AlreadyExistsException)3 Table (org.apache.iceberg.Table)2 TableAlreadyExistsException (com.facebook.presto.hive.TableAlreadyExistsException)1 IcebergTableProperties.getFileFormat (com.facebook.presto.iceberg.IcebergTableProperties.getFileFormat)1 IcebergUtil.getHadoopIcebergTable (com.facebook.presto.iceberg.IcebergUtil.getHadoopIcebergTable)1 SchemaTableName (com.facebook.presto.spi.SchemaTableName)1 SystemTable (com.facebook.presto.spi.SystemTable)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)1 UnknownHostException (java.net.UnknownHostException)1 ReentrantLock (java.util.concurrent.locks.ReentrantLock)1 Table (org.apache.hadoop.hive.metastore.api.Table)1 FileFormat (org.apache.iceberg.FileFormat)1 PartitionSpec (org.apache.iceberg.PartitionSpec)1 Schema (org.apache.iceberg.Schema)1 CommitFailedException (org.apache.iceberg.exceptions.CommitFailedException)1 CommitStateUnknownException (org.apache.iceberg.exceptions.CommitStateUnknownException)1 NoSuchTableException (org.apache.iceberg.exceptions.NoSuchTableException)1 ImmutableMap (org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap)1 TException (org.apache.thrift.TException)1