Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ target
.devbox
/.envrc
*.credentials
.DS_Store
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ INPUT_PATH="${SCENARIO_DIR}/${INPUT_FILE}"
{{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME}
echo "OK Created namespace: ${NAMESPACE_NAME}"

# List namespaces via list-namespaces command (top-level)
{{ICE_CLI}} --config {{CLI_CONFIG}} list-namespaces > /tmp/basic_ops_list_namespace.txt
if ! grep -q "${NAMESPACE_NAME}" /tmp/basic_ops_list_namespace.txt; then
echo "FAIL: list-namespaces output missing namespace ${NAMESPACE_NAME}"
cat /tmp/basic_ops_list_namespace.txt
exit 1
fi
echo "OK list-namespaces listed ${NAMESPACE_NAME}"

# List namespaces (ice describe) - no output when no tables yet
{{ICE_CLI}} --config {{CLI_CONFIG}} describe
echo "OK Listed namespaces"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ set -e

# Verification script - checks that the test completed successfully
# Exit code 0 = success, non-zero = failure
# Expects run.sh to have written: basic_ops_describe.txt, basic_ops_scan_iris.txt,
# basic_ops_scan_partitioned.txt, basic_ops_scan_sorted.txt, basic_ops_files.txt under /tmp
# Expects run.sh to have written: basic_ops_list_namespace.txt, basic_ops_describe.txt,
# basic_ops_scan_iris.txt, basic_ops_scan_partitioned.txt, basic_ops_scan_sorted.txt,
# basic_ops_files.txt under /tmp

echo "Verifying basic operations test..."

for f in /tmp/basic_ops_describe.txt /tmp/basic_ops_scan_iris.txt /tmp/basic_ops_scan_partitioned.txt /tmp/basic_ops_scan_sorted.txt; do
for f in /tmp/basic_ops_list_namespace.txt /tmp/basic_ops_describe.txt /tmp/basic_ops_scan_iris.txt /tmp/basic_ops_scan_partitioned.txt /tmp/basic_ops_scan_sorted.txt; do
if [ ! -f "$f" ]; then
echo "FAIL Output file not found: $f"
exit 1
Expand Down Expand Up @@ -65,8 +66,14 @@ if ! grep -qE "s3a://test-bucket/warehouse/test_ns/.*/data/.*\.parquet" "$F"; th
echo "FAIL $F does not contain expected datafile path pattern"
exit 1
fi
# Verify list-namespaces output contains the test namespace
if ! grep -q "test_ns" /tmp/basic_ops_list_namespace.txt; then
echo "FAIL basic_ops_list_namespace.txt does not contain expected namespace 'test_ns'"
exit 1
fi

# Cleanup temp files
rm -f /tmp/basic_ops_describe.txt /tmp/basic_ops_scan_iris.txt /tmp/basic_ops_scan_partitioned.txt /tmp/basic_ops_scan_sorted.txt /tmp/basic_ops_files.txt
rm -f /tmp/basic_ops_list_namespace.txt /tmp/basic_ops_describe.txt /tmp/basic_ops_scan_iris.txt /tmp/basic_ops_scan_partitioned.txt /tmp/basic_ops_scan_sorted.txt /tmp/basic_ops_files.txt

echo "OK Verification passed"
exit 0
Expand Down
23 changes: 23 additions & 0 deletions ice/src/main/java/com/altinity/ice/cli/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.altinity.ice.cli.internal.cmd.Files;
import com.altinity.ice.cli.internal.cmd.Insert;
import com.altinity.ice.cli.internal.cmd.InsertWatch;
import com.altinity.ice.cli.internal.cmd.ListNamespaces;
import com.altinity.ice.cli.internal.cmd.ListPartitions;
import com.altinity.ice.cli.internal.cmd.Scan;
import com.altinity.ice.cli.internal.config.Config;
Expand Down Expand Up @@ -708,6 +709,28 @@ void deleteNamespace(
}
}

@CommandLine.Command(name = "list-namespaces", description = "List namespaces.")
void listNamespaces(
@CommandLine.Parameters(
arity = "0..1",
paramLabel = "<parent>",
description =
"Parent namespace to list children of (e.g. parent_ns). Omit for top-level.")
String parent,
@CommandLine.Option(
names = {"--json"},
description = "Output JSON instead of YAML")
boolean json)
throws IOException {
try (RESTCatalog catalog = loadCatalog()) {
Namespace namespace =
(parent == null || parent.isEmpty())
? Namespace.empty()
: Namespace.of(parent.split("[.]"));
ListNamespaces.run(catalog, namespace, json);
}
}

@CommandLine.Command(name = "delete", description = "Delete data from catalog.")
void delete(
@CommandLine.Parameters(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2025 Altinity Inc and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
package com.altinity.ice.cli.internal.cmd;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.rest.RESTCatalog;

public final class ListNamespaces {

private ListNamespaces() {}

public static void run(RESTCatalog catalog, Namespace parent, boolean json) throws IOException {
List<Namespace> namespaces = catalog.listNamespaces(parent);
List<String> names =
namespaces.stream().map(Namespace::toString).sorted().collect(Collectors.toList());
var result = new Result(names);
output(result, json);
}

private static void output(Result result, boolean json) throws IOException {
ObjectMapper mapper =
json
? new ObjectMapper()
: new ObjectMapper(new YAMLFactory().enable(YAMLGenerator.Feature.MINIMIZE_QUOTES));
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
System.out.println(mapper.writeValueAsString(result));
}

@JsonInclude(JsonInclude.Include.NON_NULL)
record Result(List<String> namespaces) {}
}
Loading