in metacat-connector-polaris/src/main/java/com/netflix/metacat/connector/polaris/PolarisConnectorTableService.java [236:335]
public void update(final ConnectorRequestContext requestContext, final TableInfo tableInfo) {
final QualifiedName name = tableInfo.getName();
final Config conf = connectorContext.getConfig();
final String lastModifiedBy = PolarisUtils.getUserOrDefault(requestContext);
final boolean isView = HiveTableUtil.isCommonView(tableInfo);
if (isView) {
commonViewHandler.update(tableInfo);
} else {
icebergTableHandler.update(tableInfo);
}
try {
final Map<String, String> newTableMetadata = tableInfo.getMetadata();
if (MapUtils.isEmpty(newTableMetadata)) {
log.warn("No parameters defined for iceberg table %s, no data update needed", name);
return;
}
final String prevLoc = newTableMetadata.get(DirectSqlTable.PARAM_PREVIOUS_METADATA_LOCATION);
final String newLoc = newTableMetadata.get(DirectSqlTable.PARAM_METADATA_LOCATION);
if (StringUtils.isBlank(prevLoc)) {
log.info("Provided previous {} empty for {} with new {}, treating as no location update needed.",
prevLoc, name, newLoc);
return;
}
if (StringUtils.isBlank(newLoc)) {
final String message = String.format(
"Invalid metadata for %s. Provided previous %s or new %s location is empty.",
name, prevLoc, newLoc);
log.error(message);
throw new InvalidMetaException(name, message, null);
}
if (conf.isIcebergPreviousMetadataLocationCheckEnabled()
&& !icebergTableHandler.doesMetadataLocationExist(name, prevLoc)) {
final String message = String.format(
"Provided previous metadata location: %s for table: %s does not exist.",
name, prevLoc);
log.error(message);
throw new InvalidMetaException(name, message, null);
}
boolean updated = false;
if (isView) {
final Map<String, String> newTableParams = polarisTableMapper.filterMetadata(newTableMetadata);
final Map<String, String> existingTableParams = polarisStoreService
.getTable(name.getDatabaseName(), name.getTableName())
.orElseThrow(() -> new TableNotFoundException(name))
.getParams();
// optimistically attempt to update metadata location and/or params
updated = polarisStoreService.updateTableMetadataLocationAndParams(
name.getDatabaseName(), name.getTableName(), prevLoc, newLoc,
existingTableParams, newTableParams, lastModifiedBy);
} else {
// optimistically attempt to update metadata location
updated = polarisStoreService.updateTableMetadataLocation(
name.getDatabaseName(), name.getTableName(), prevLoc, newLoc, lastModifiedBy
);
}
// if succeeded then done, else try to figure out why and throw corresponding exception
if (updated) {
requestContext.setIgnoreErrorsAfterUpdate(true);
log.warn("Success servicing Iceberg commit request for table: {}, "
+ "previousLocation: {}, newLocation: {}",
tableInfo.getName(), prevLoc, newLoc);
return;
}
final PolarisTableEntity table = polarisStoreService
.getTable(name.getDatabaseName(), name.getTableName())
.orElseThrow(() -> new TableNotFoundException(name));
final String existingLoc = table.getMetadataLocation();
log.warn("Error servicing Iceberg commit request for tableId: {}, "
+ "previousLocation: {}, existingLocation: {}, newLocation: {}",
table.getTblId(), prevLoc, existingLoc, newLoc);
if (StringUtils.isBlank(existingLoc)) {
final String message = String.format(
"Invalid metadata location for %s existing location is empty.", name);
log.error(message);
throw new TablePreconditionFailedException(name, message, existingLoc, prevLoc);
}
if (StringUtils.equalsIgnoreCase(existingLoc, newLoc)) {
log.warn("Existing metadata location is the same as new. Existing: {}, New: {}",
existingLoc, newLoc);
return;
}
if (!Objects.equals(existingLoc, prevLoc)) {
final String message = String.format(
"Invalid metadata location for %s expected: %s, provided: %s", name, existingLoc, prevLoc);
log.error(message);
throw new TablePreconditionFailedException(name, message, existingLoc, prevLoc);
}
} catch (TableNotFoundException | InvalidMetaException | TablePreconditionFailedException exception) {
throw exception;
} catch (DataIntegrityViolationException exception) {
throw new InvalidMetaException(name, exception);
} catch (Exception exception) {
final String msg = String.format("Failed updating polaris table %s", tableInfo.getName());
log.error(msg, exception);
throw new ConnectorException(msg, exception);
}
}