diff --git a/tools/java-iceberg-cli/src/main/java/iceberg_cli/IcebergConnector.java b/tools/java-iceberg-cli/src/main/java/iceberg_cli/IcebergConnector.java index 165a3b1..0574be9 100644 --- a/tools/java-iceberg-cli/src/main/java/iceberg_cli/IcebergConnector.java +++ b/tools/java-iceberg-cli/src/main/java/iceberg_cli/IcebergConnector.java @@ -51,6 +51,7 @@ import org.apache.iceberg.TableScan; import org.apache.iceberg.Transaction; import org.apache.iceberg.UpdateSchema; +import org.apache.iceberg.UpdateProperties; import org.apache.iceberg.aws.s3.S3FileIO; import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; @@ -194,6 +195,18 @@ public boolean createTable(Schema schema, PartitionSpec spec, boolean overwrite) * { * "drop":["c1","c2"] * } + * + * The property changes are expected in the following format: + * SETTING key/value property + * { + * "set_property":[ + * {"key":"p1","value":"v1"} + * ] + * } + * REMOVING property key + * { + * "remove_property":["p1","p2"] + * } * * * There are more ALTER operations that can be performed according to the documentation, @@ -205,6 +218,10 @@ public boolean alterTable(String newSchema) throws Exception { final int OP_ADD = 1; final int OP_DROP = 2; final int OP_RENAME = 4; + final int OP_SET_PROP = 8; + final int OP_RM_PROP = 16; + final int UPDATE_SCHEMA = OP_ADD | OP_DROP | OP_RENAME; + final int UPDATE_PROP = OP_SET_PROP | OP_RM_PROP; loadTable(); UpdateSchema updateSchema = iceberg_table.updateSchema(); JSONObject schemaSpecs = new JSONObject(newSchema); @@ -265,20 +282,62 @@ public boolean alterTable(String newSchema) throws Exception { // no columns to rename, move on } - // have we altered anything? - if (op == OP_NONE) { - System.out.println("Unrecognized ALTER operation."); - return false; + // check for updates to table properties + UpdateProperties updateProperties = iceberg_table.updateProperties(); + try { + JSONArray setProps = schemaSpecs.getJSONArray("set_property"); + for (int i = 0; i < setProps.length(); i++) { + try { + JSONObject jo = setProps.getJSONObject(i); + String key = jo.getString("key"); + String value = jo.getString("value"); + updateProperties.set(key, value); + op |= OP_SET_PROP; + } catch (JSONException e) { + System.out.println("Invalid key/value property."); + return false; + } + } + } catch (JSONException e) { + // no properties to set, move on } + try { + JSONArray rmProps = schemaSpecs.getJSONArray("remove_property"); + for (int i = 0; i < rmProps.length(); i++) { + try { + String key = rmProps.getString(i); + updateProperties.remove(key); + op |= OP_RM_PROP; + } catch (JSONException e) { + System.out.println("Invalid property key."); + return false; + } + } + } catch (JSONException e) { + // no properties to remove, move on + } + // confirm DROP wasn't bundled with any other ALTERs if ((op & OP_DROP) == OP_DROP && op != OP_DROP) { System.out.println("Cannot perform DROP along with other ALTER operations."); return false; } + // have we altered anything? + if (op == OP_NONE) { + System.out.println("Unrecognized ALTER operation."); + return false; + } + // all good - commit changes - updateSchema.commit(); + if ((op & UPDATE_SCHEMA) != 0) { + updateSchema.commit(); + } + if ((op & UPDATE_PROP) != 0) { + updateProperties.commit(); + } + return true; } diff --git a/tools/java-iceberg-cli/src/main/java/iceberg_cli/cli/Parser.java b/tools/java-iceberg-cli/src/main/java/iceberg_cli/cli/Parser.java index 477c6f9..4ba9026 100644 --- a/tools/java-iceberg-cli/src/main/java/iceberg_cli/cli/Parser.java +++ b/tools/java-iceberg-cli/src/main/java/iceberg_cli/cli/Parser.java @@ -90,7 +90,7 @@ private void initializeCommands() { Command alter = new Command("alter", "Alter a table"); alter.addOption("--help", "Show this help message and exit"); alter.addArgument("identifier", "Table or namespace identifier", true); - create.addArgument("schema", "Alter a table using this schema"); + alter.addArgument("schema", "Alter a table using this schema"); m_commands.put("alter", alter); Command drop = new Command("drop", "Drop a table or a namespace");