Skip to content
Open
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
17 changes: 9 additions & 8 deletions java/lance-jni/src/blocking_dataset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ impl BlockingDataset {
}

// Set up namespace commit handler if namespace and table_id are provided
if let (Some(ns), Some(tid)) = (namespace, table_id) {
let external_store = LanceNamespaceExternalManifestStore::new(ns, tid);
if let (Some(namespace_client), Some(tid)) = (namespace, table_id) {
let external_store = LanceNamespaceExternalManifestStore::new(namespace_client, tid);
let commit_handler: Arc<dyn CommitHandler> = Arc::new(ExternalManifestCommitHandler {
external_manifest_store: Arc::new(external_store),
});
Expand Down Expand Up @@ -1252,20 +1252,21 @@ pub(crate) fn extract_namespace_info(
return Ok(None);
}

let namespace: Arc<dyn LanceNamespace> = if is_directory_namespace(env, namespace_obj)? {
let namespace_client: Arc<dyn LanceNamespace> = if is_directory_namespace(env, namespace_obj)? {
let native_handle = get_native_namespace_handle(env, namespace_obj)?;
let ns = unsafe { &*(native_handle as *const BlockingDirectoryNamespace) };
ns.inner.clone()
let dir_namespace_client =
unsafe { &*(native_handle as *const BlockingDirectoryNamespace) };
dir_namespace_client.inner.clone()
} else if is_rest_namespace(env, namespace_obj)? {
let native_handle = get_native_namespace_handle(env, namespace_obj)?;
let ns = unsafe { &*(native_handle as *const BlockingRestNamespace) };
ns.inner.clone()
let rest_namespace_client = unsafe { &*(native_handle as *const BlockingRestNamespace) };
rest_namespace_client.inner.clone()
} else {
create_java_lance_namespace(env, namespace_obj)?
};

let table_id = env.get_strings(table_id_obj)?;
Ok(Some((namespace, table_id)))
Ok(Some((namespace_client, table_id)))
}

#[unsafe(no_mangle)]
Expand Down
222 changes: 117 additions & 105 deletions java/lance-jni/src/namespace.rs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions java/lance-jni/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1455,7 +1455,7 @@ fn inner_commit_to_uri<'local>(

let namespace_info = extract_namespace_info(env, &namespace_obj, &table_id_obj)?;
let (open_namespace, open_table_id) = match &namespace_info {
Some((ns, tid)) => (Some(ns.clone()), Some(tid.clone())),
Some((namespace_client, tid)) => (Some(namespace_client.clone()), Some(tid.clone())),
None => (None, None),
};

Expand Down Expand Up @@ -1505,8 +1505,8 @@ fn inner_commit_to_uri<'local>(
}

// Set namespace commit handler if provided
if let Some((ns, tid)) = namespace_info {
let external_store = LanceNamespaceExternalManifestStore::new(ns, tid);
if let Some((namespace_client, tid)) = namespace_info {
let external_store = LanceNamespaceExternalManifestStore::new(namespace_client, tid);
let commit_handler: Arc<dyn CommitHandler> = Arc::new(ExternalManifestCommitHandler {
external_manifest_store: Arc::new(external_store),
});
Expand Down
26 changes: 23 additions & 3 deletions java/src/main/java/org/lance/CommitBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public class CommitBuilder {

private Map<String, String> writeParams;
private StorageOptionsProvider storageOptionsProvider;
private LanceNamespace namespace;
private LanceNamespace namespaceClient;
private List<String> tableId;
private boolean enableV2ManifestPaths = true;
private boolean detached = false;
Expand Down Expand Up @@ -117,26 +117,46 @@ public CommitBuilder writeParams(Map<String, String> writeParams) {
*
* @param provider the storage options provider
* @return this builder instance
* @deprecated This method is deprecated and will be removed in version 5.0.0. When using
* namespace and tableId, the storage options provider is created automatically from the
* namespace. Use writeParams for static or initial storage options.
*/
@Deprecated
public CommitBuilder storageOptionsProvider(StorageOptionsProvider provider) {
this.storageOptionsProvider = provider;
return this;
}

/**
* Set the namespace client for managed versioning during URI-based commits.
*
* @param namespaceClient the LanceNamespace client instance
* @return this builder instance
*/
public CommitBuilder namespaceClient(LanceNamespace namespaceClient) {
this.namespaceClient = namespaceClient;
return this;
}

/**
* Set the namespace for managed versioning during URI-based commits.
*
* @param namespace the LanceNamespace instance
* @return this builder instance
* @deprecated This method is deprecated and will be removed in version 5.0.0. Use {@link
* #namespaceClient(LanceNamespace)} instead.
*/
@Deprecated
public CommitBuilder namespace(LanceNamespace namespace) {
this.namespace = namespace;
this.namespaceClient = namespace;
return this;
}

/**
* Set the table ID for namespace-based commit handling.
*
* <p>Must be provided together with `namespaceClient`.
*
* @param tableId the table identifier (e.g., ["workspace", "table_name"])
* @return this builder instance
*/
Expand Down Expand Up @@ -262,7 +282,7 @@ public Dataset execute(Transaction transaction) {
detached,
enableV2ManifestPaths,
storageOptionsProvider,
namespace,
namespaceClient,
tableId,
allocator,
writeParams,
Expand Down
27 changes: 14 additions & 13 deletions java/src/main/java/org/lance/Dataset.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ private Dataset() {}
* .execute();
* }</pre>
*
* <p>Example usage with namespace and empty table:
* <p>Example usage with namespaceClient and empty table:
*
* <pre>{@code
* Dataset dataset = Dataset.write()
* .schema(mySchema)
* .namespace(myNamespace)
* .namespaceClient(myNamespaceClient)
* .tableId(Arrays.asList("my_table"))
* .mode(WriteMode.CREATE)
* .execute();
Expand Down Expand Up @@ -239,21 +239,21 @@ private static native Dataset createWithFfiStreamAndProvider(
Optional<StorageOptionsProvider> storageOptionsProvider,
Optional<List<BasePath>> initialBases,
Optional<List<String>> targetBases,
LanceNamespace namespace,
LanceNamespace namespaceClient,
List<String> tableId);

/**
* Creates a dataset with optional namespace support for managed versioning.
*
* <p>When a namespace is provided, the commit handler will use the namespace's
* <p>When a namespaceClient is provided, the commit handler will use the namespace's
* create_table_version method for version tracking.
*
* @param allocator buffer allocator
* @param stream arrow stream
* @param path dataset uri
* @param params write parameters
* @param storageOptionsProvider optional provider for dynamic storage options/credentials
* @param namespace optional namespace implementation for managed versioning (can be null)
* @param namespaceClient optional namespace implementation for managed versioning (can be null)
* @param tableId optional table identifier within the namespace (can be null)
* @return Dataset
*/
Expand All @@ -263,7 +263,7 @@ static Dataset create(
String path,
WriteParams params,
StorageOptionsProvider storageOptionsProvider,
LanceNamespace namespace,
LanceNamespace namespaceClient,
List<String> tableId) {
Preconditions.checkNotNull(allocator);
Preconditions.checkNotNull(stream);
Expand All @@ -284,7 +284,7 @@ static Dataset create(
Optional.ofNullable(storageOptionsProvider),
params.getInitialBases(),
params.getTargetBases(),
namespace,
namespaceClient,
tableId);
dataset.allocator = allocator;
return dataset;
Expand Down Expand Up @@ -367,7 +367,8 @@ static Dataset open(
*
* @param path file path
* @param options the open options
* @param namespace the LanceNamespace to use for managed versioning (null if not using namespace)
* @param namespaceClient the LanceNamespace to use for managed versioning (null if not using
* namespace)
* @param tableId table identifier (null if not using namespace)
* @return Dataset
*/
Expand All @@ -377,7 +378,7 @@ static Dataset open(
String path,
ReadOptions options,
Session session,
LanceNamespace namespace,
LanceNamespace namespaceClient,
List<String> tableId) {
Preconditions.checkNotNull(path);
Preconditions.checkNotNull(allocator);
Expand All @@ -400,7 +401,7 @@ static Dataset open(
options.getSerializedManifest(),
options.getStorageOptionsProvider(),
sessionHandle,
namespace,
namespaceClient,
tableId);
dataset.allocator = allocator;
dataset.selfManagedAllocator = selfManagedAllocator;
Expand All @@ -423,7 +424,7 @@ private static native Dataset openNative(
Optional<ByteBuffer> serializedManifest,
Optional<StorageOptionsProvider> storageOptionsProvider,
long sessionHandle,
LanceNamespace namespace,
LanceNamespace namespaceClient,
List<String> tableId);

/**
Expand All @@ -440,11 +441,11 @@ private static native Dataset openNative(
* .build();
* }</pre>
*
* <p>Example usage with namespace:
* <p>Example usage with namespaceClient:
*
* <pre>{@code
* Dataset dataset = Dataset.open()
* .namespace(myNamespace)
* .namespaceClient(myNamespaceClient)
* .tableId(Arrays.asList("my_table"))
* .build();
* }</pre>
Expand Down
62 changes: 41 additions & 21 deletions java/src/main/java/org/lance/OpenDatasetBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class OpenDatasetBuilder {
private BufferAllocator allocator;
private boolean selfManagedAllocator = false;
private String uri;
private LanceNamespace namespace;
private LanceNamespace namespaceClient;
private List<String> tableId;
private ReadOptions options = new ReadOptions.Builder().build();
private Session session;
Expand Down Expand Up @@ -89,6 +89,20 @@ public OpenDatasetBuilder uri(String uri) {
return this;
}

/**
* Sets the namespace client.
*
* <p>Must be used together with tableId(). Either uri() or namespaceClient()+tableId() must be
* specified, but not both.
*
* @param namespaceClient The namespace implementation to fetch table info from
* @return this builder instance
*/
public OpenDatasetBuilder namespaceClient(LanceNamespace namespaceClient) {
this.namespaceClient = namespaceClient;
return this;
}

/**
* Sets the namespace.
*
Expand All @@ -97,9 +111,12 @@ public OpenDatasetBuilder uri(String uri) {
*
* @param namespace The namespace implementation to fetch table info from
* @return this builder instance
* @deprecated This method is deprecated and will be removed in version 5.0.0. Use {@link
* #namespaceClient(LanceNamespace)} instead.
*/
@Deprecated
public OpenDatasetBuilder namespace(LanceNamespace namespace) {
this.namespace = namespace;
this.namespaceClient = namespace;
return this;
}

Expand Down Expand Up @@ -156,25 +173,26 @@ public OpenDatasetBuilder session(Session session) {
* @throws IllegalArgumentException if required parameters are missing or invalid
*/
public Dataset build() {
// Validate that exactly one of uri or namespace+tableId is provided
// Validate that exactly one of uri or namespaceClient+tableId is provided
boolean hasUri = uri != null;
boolean hasNamespace = namespace != null && tableId != null;
boolean hasNamespaceClient = namespaceClient != null && tableId != null;

if (hasUri && hasNamespace) {
if (hasUri && hasNamespaceClient) {
throw new IllegalArgumentException(
"Cannot specify both uri and namespace+tableId. Use one or the other.");
"Cannot specify both uri and namespaceClient+tableId. Use one or the other.");
}
if (!hasUri && !hasNamespace) {
if (namespace != null) {
if (!hasUri && !hasNamespaceClient) {
if (namespaceClient != null) {
throw new IllegalArgumentException(
"namespace is set but tableId is missing. Both namespace and tableId must be"
+ " provided together.");
"namespaceClient is set but tableId is missing. Both namespaceClient and tableId must"
+ " be provided together.");
} else if (tableId != null) {
throw new IllegalArgumentException(
"tableId is set but namespace is missing. Both namespace and tableId must be"
+ " provided together.");
"tableId is set but namespaceClient is missing. Both namespaceClient and tableId must"
+ " be provided together.");
} else {
throw new IllegalArgumentException("Either uri or namespace+tableId must be provided.");
throw new IllegalArgumentException(
"Either uri or namespaceClient+tableId must be provided.");
}
}

Expand All @@ -187,22 +205,22 @@ public Dataset build() {
}

// Handle namespace-based opening
if (hasNamespace) {
return buildFromNamespace();
if (hasNamespaceClient) {
return buildFromNamespaceClient();
}

// Handle URI-based opening
return Dataset.open(allocator, selfManagedAllocator, uri, options, session);
}

private Dataset buildFromNamespace() {
private Dataset buildFromNamespaceClient() {
// Call describe_table to get location and storage options
DescribeTableRequest request = new DescribeTableRequest();
request.setId(tableId);
// Only set version if present
options.getVersion().ifPresent(v -> request.setVersion(Long.valueOf(v)));

DescribeTableResponse response = namespace.describeTable(request);
DescribeTableResponse response = namespaceClient.describeTable(request);

String location = response.getLocation();
if (location == null || location.isEmpty()) {
Expand All @@ -219,9 +237,11 @@ private Dataset buildFromNamespace() {
.setIndexCacheSizeBytes(options.getIndexCacheSizeBytes())
.setMetadataCacheSizeBytes(options.getMetadataCacheSizeBytes());

if (namespaceStorageOptions != null && !namespaceStorageOptions.isEmpty()) {
// null = namespace doesn't vend credentials (don't create provider)
// empty {} or non-empty = namespace vends credentials (create provider)
if (namespaceStorageOptions != null) {
LanceNamespaceStorageOptionsProvider storageOptionsProvider =
new LanceNamespaceStorageOptionsProvider(namespace, tableId);
new LanceNamespaceStorageOptionsProvider(namespaceClient, tableId);
optionsBuilder.setStorageOptionsProvider(storageOptionsProvider);
}

Expand All @@ -235,15 +255,15 @@ private Dataset buildFromNamespace() {
}
optionsBuilder.setStorageOptions(storageOptions);

// If managed_versioning is true, pass namespace for commit handler setup
// If managed_versioning is true, pass namespaceClient for commit handler setup
if (Boolean.TRUE.equals(managedVersioning)) {
return Dataset.open(
allocator,
selfManagedAllocator,
location,
optionsBuilder.build(),
session,
namespace,
namespaceClient,
tableId);
}

Expand Down
5 changes: 5 additions & 0 deletions java/src/main/java/org/lance/ReadOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,12 @@ public Builder setSerializedManifest(ByteBuffer serializedManifest) {
*
* @param storageOptionsProvider the storage options provider implementation
* @return this builder
* @deprecated This method is deprecated and will be removed in version 5.0.0. When using
* namespace and tableId via {@link OpenDatasetBuilder}, the storage options provider is
* created automatically from the namespace. Use {@link #setStorageOptions(Map)} for static
* or initial storage options.
*/
@Deprecated
public Builder setStorageOptionsProvider(StorageOptionsProvider storageOptionsProvider) {
this.storageOptionsProvider = Optional.of(storageOptionsProvider);
return this;
Expand Down
Loading
Loading