This is an automated email from the ASF dual-hosted git repository.
yzou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new b48cfb654 Add server and client support for the new generic table
`baseLocation` field (#2122)
b48cfb654 is described below
commit b48cfb654cdd867830ca6105f790104503bfb1b1
Author: Yun Zou <[email protected]>
AuthorDate: Fri Jul 18 18:22:03 2025 -0700
Add server and client support for the new generic table `baseLocation`
field (#2122)
---
.../org/apache/polaris/spark/PolarisCatalog.java | 6 +++-
.../apache/polaris/spark/PolarisRESTCatalog.java | 7 ++++-
.../apache/polaris/spark/PolarisSparkCatalog.java | 26 +++++++++++++++++-
.../polaris/spark/utils/PolarisCatalogUtils.java | 8 ++++--
.../polaris/spark/PolarisInMemoryCatalog.java | 7 ++++-
.../polaris/spark/rest/DeserializationTest.java | 28 +++++++++++++------
.../core/entity/table/GenericTableEntity.java | 12 ++++++++
.../core/entity/table/IcebergTableLikeEntity.java | 3 +-
.../polaris/core/entity/table/TableLikeEntity.java | 4 +--
.../quarkus/admin/PolarisAuthzTestBase.java | 3 +-
.../AbstractPolarisGenericTableCatalogTest.java | 32 +++++++++++++---------
...PolarisGenericTableCatalogHandlerAuthzTest.java | 7 +++--
.../catalog/generic/GenericTableCatalog.java | 6 +++-
.../generic/GenericTableCatalogAdapter.java | 1 +
.../generic/GenericTableCatalogHandler.java | 11 ++++++--
.../generic/PolarisGenericTableCatalog.java | 7 ++++-
16 files changed, 128 insertions(+), 40 deletions(-)
diff --git
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisCatalog.java
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisCatalog.java
index 99802d3cb..08116c9e6 100644
---
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisCatalog.java
+++
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisCatalog.java
@@ -32,5 +32,9 @@ public interface PolarisCatalog {
boolean dropGenericTable(TableIdentifier identifier);
GenericTable createGenericTable(
- TableIdentifier identifier, String format, String doc, Map<String,
String> props);
+ TableIdentifier identifier,
+ String format,
+ String baseLocation,
+ String doc,
+ Map<String, String> props);
}
diff --git
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisRESTCatalog.java
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisRESTCatalog.java
index 5dfd1f898..5be0f6952 100644
---
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisRESTCatalog.java
+++
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisRESTCatalog.java
@@ -200,13 +200,18 @@ public class PolarisRESTCatalog implements
PolarisCatalog, Closeable {
@Override
public GenericTable createGenericTable(
- TableIdentifier identifier, String format, String doc, Map<String,
String> props) {
+ TableIdentifier identifier,
+ String format,
+ String baseLocation,
+ String doc,
+ Map<String, String> props) {
Endpoint.check(endpoints, PolarisEndpoints.V1_CREATE_GENERIC_TABLE);
CreateGenericTableRESTRequest request =
new CreateGenericTableRESTRequest(
CreateGenericTableRequest.builder()
.setName(identifier.name())
.setFormat(format)
+ .setBaseLocation(baseLocation)
.setDoc(doc)
.setProperties(props)
.build());
diff --git
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisSparkCatalog.java
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisSparkCatalog.java
index fe0c6e180..964674e54 100644
---
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisSparkCatalog.java
+++
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisSparkCatalog.java
@@ -38,6 +38,8 @@ import org.apache.spark.sql.connector.catalog.TableChange;
import org.apache.spark.sql.connector.expressions.Transform;
import org.apache.spark.sql.types.StructType;
import org.apache.spark.sql.util.CaseInsensitiveStringMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A spark TableCatalog Implementation interacts with Polaris specific APIs
only. The APIs it
@@ -45,6 +47,7 @@ import org.apache.spark.sql.util.CaseInsensitiveStringMap;
* expected to be for non-iceberg tables.
*/
public class PolarisSparkCatalog implements TableCatalog {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(PolarisSparkCatalog.class);
private PolarisCatalog polarisCatalog = null;
private String catalogName = null;
@@ -83,9 +86,30 @@ public class PolarisSparkCatalog implements TableCatalog {
throws TableAlreadyExistsException, NoSuchNamespaceException {
try {
String format = properties.get(PolarisCatalogUtils.TABLE_PROVIDER_KEY);
+
+ String baseLocation;
+ // Extract the base table location from the spark properties.
+ // Spark pass the table base location either with the
+ // TableCatalog.PROP_LOCATION key, or with "path" key if created
+ // with the path option.
+ if (properties.get(TableCatalog.PROP_LOCATION) != null) {
+ baseLocation = properties.get(TableCatalog.PROP_LOCATION);
+ if (properties.get(PolarisCatalogUtils.TABLE_PATH_KEY) != null) {
+ LOGGER.debug(
+ "Both location and path are propagated in the table properties,
location {}, path {}",
+ baseLocation,
+ properties.get(PolarisCatalogUtils.TABLE_PATH_KEY));
+ }
+ } else {
+ baseLocation = properties.get(PolarisCatalogUtils.TABLE_PATH_KEY);
+ }
GenericTable genericTable =
this.polarisCatalog.createGenericTable(
- Spark3Util.identifierToTableIdentifier(identifier), format,
null, properties);
+ Spark3Util.identifierToTableIdentifier(identifier),
+ format,
+ baseLocation,
+ null,
+ properties);
return PolarisCatalogUtils.loadSparkTable(genericTable);
} catch (AlreadyExistsException e) {
throw new TableAlreadyExistsException(identifier);
diff --git
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/utils/PolarisCatalogUtils.java
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/utils/PolarisCatalogUtils.java
index e7cd76bca..df433ec9f 100644
---
a/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/utils/PolarisCatalogUtils.java
+++
b/plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/utils/PolarisCatalogUtils.java
@@ -76,12 +76,16 @@ public class PolarisCatalogUtils {
boolean hasPathClause = properties.get(TABLE_PATH_KEY) != null;
Map<String, String> tableProperties = Maps.newHashMap();
tableProperties.putAll(properties);
- if (!hasPathClause && hasLocationClause) {
+ if (!hasPathClause) {
// DataSourceV2 requires the path property on table loading. However,
spark today
// doesn't create the corresponding path property if the path keyword is
not
// provided by user when location is provided. Here, we duplicate the
location
// property as path to make sure the table can be loaded.
- tableProperties.put(TABLE_PATH_KEY,
properties.get(TableCatalog.PROP_LOCATION));
+ if (genericTable.getBaseLocation() != null &&
!genericTable.getBaseLocation().isEmpty()) {
+ tableProperties.put(TABLE_PATH_KEY, genericTable.getBaseLocation());
+ } else if (hasLocationClause) {
+ tableProperties.put(TABLE_PATH_KEY,
properties.get(TableCatalog.PROP_LOCATION));
+ }
}
return DataSourceV2Utils.getTableFromProvider(
provider, new CaseInsensitiveStringMap(tableProperties),
scala.Option.empty());
diff --git
a/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/PolarisInMemoryCatalog.java
b/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/PolarisInMemoryCatalog.java
index c846659df..2d71d9cb6 100644
---
a/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/PolarisInMemoryCatalog.java
+++
b/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/PolarisInMemoryCatalog.java
@@ -65,7 +65,11 @@ public class PolarisInMemoryCatalog extends InMemoryCatalog
implements PolarisCa
@Override
public GenericTable createGenericTable(
- TableIdentifier identifier, String format, String doc, Map<String,
String> props) {
+ TableIdentifier identifier,
+ String format,
+ String baseLocation,
+ String doc,
+ Map<String, String> props) {
if (!namespaceExists(identifier.namespace())) {
throw new NoSuchNamespaceException(
"Cannot create generic table %s. Namespace does not exist: %s",
@@ -78,6 +82,7 @@ public class PolarisInMemoryCatalog extends InMemoryCatalog
implements PolarisCa
GenericTable.builder()
.setName(identifier.name())
.setFormat(format)
+ .setBaseLocation(baseLocation)
.setProperties(props)
.build());
diff --git
a/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/rest/DeserializationTest.java
b/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/rest/DeserializationTest.java
index d4d4da6ab..0f7d3c99b 100644
---
a/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/rest/DeserializationTest.java
+++
b/plugins/spark/v3.5/spark/src/test/java/org/apache/polaris/spark/rest/DeserializationTest.java
@@ -65,15 +65,19 @@ public class DeserializationTest {
@ParameterizedTest
@MethodSource("genericTableTestCases")
- public void testLoadGenericTableRESTResponse(String doc, Map<String, String>
properties)
+ public void testLoadGenericTableRESTResponse(
+ String baseLocation, String doc, Map<String, String> properties)
throws JsonProcessingException {
- GenericTable table =
+ GenericTable.Builder tableBuilder =
GenericTable.builder()
.setFormat("delta")
.setName("test-table")
.setProperties(properties)
- .setDoc(doc)
- .build();
+ .setDoc(doc);
+ if (baseLocation != null) {
+ tableBuilder.setBaseLocation(baseLocation);
+ }
+ GenericTable table = tableBuilder.build();
LoadGenericTableRESTResponse response = new
LoadGenericTableRESTResponse(table);
String json = mapper.writeValueAsString(response);
LoadGenericTableRESTResponse deserializedResponse =
@@ -82,11 +86,13 @@ public class DeserializationTest {
assertThat(deserializedResponse.getTable().getName()).isEqualTo("test-table");
assertThat(deserializedResponse.getTable().getDoc()).isEqualTo(doc);
assertThat(deserializedResponse.getTable().getProperties().size()).isEqualTo(properties.size());
+
assertThat(deserializedResponse.getTable().getBaseLocation()).isEqualTo(baseLocation);
}
@ParameterizedTest
@MethodSource("genericTableTestCases")
- public void testCreateGenericTableRESTRequest(String doc, Map<String,
String> properties)
+ public void testCreateGenericTableRESTRequest(
+ String baseLocation, String doc, Map<String, String> properties)
throws JsonProcessingException {
CreateGenericTableRESTRequest request =
new CreateGenericTableRESTRequest(
@@ -94,6 +100,7 @@ public class DeserializationTest {
.setName("test-table")
.setFormat("delta")
.setDoc(doc)
+ .setBaseLocation(baseLocation)
.setProperties(properties)
.build());
String json = mapper.writeValueAsString(request);
@@ -103,6 +110,7 @@ public class DeserializationTest {
assertThat(deserializedRequest.getFormat()).isEqualTo("delta");
assertThat(deserializedRequest.getDoc()).isEqualTo(doc);
assertThat(deserializedRequest.getProperties().size()).isEqualTo(properties.size());
+ assertThat(deserializedRequest.getBaseLocation()).isEqualTo(baseLocation);
}
@Test
@@ -150,10 +158,12 @@ public class DeserializationTest {
var doc = "table for testing";
var properties = Maps.newHashMap();
properties.put("location", "s3://path/to/table/");
+ var baseLocation = "s3://path/to/table/";
return Stream.of(
- Arguments.of(doc, properties),
- Arguments.of(null, Maps.newHashMap()),
- Arguments.of(doc, Maps.newHashMap()),
- Arguments.of(null, properties));
+ Arguments.of(null, doc, properties),
+ Arguments.of(baseLocation, doc, properties),
+ Arguments.of(null, null, Maps.newHashMap()),
+ Arguments.of(baseLocation, doc, Maps.newHashMap()),
+ Arguments.of(baseLocation, null, properties));
}
}
diff --git
a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/GenericTableEntity.java
b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/GenericTableEntity.java
index a5eae86fe..5f9250803 100644
---
a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/GenericTableEntity.java
+++
b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/GenericTableEntity.java
@@ -25,6 +25,7 @@ import org.apache.iceberg.rest.RESTUtil;
import org.apache.polaris.core.entity.NamespaceEntity;
import org.apache.polaris.core.entity.PolarisBaseEntity;
import org.apache.polaris.core.entity.PolarisEntity;
+import org.apache.polaris.core.entity.PolarisEntityConstants;
import org.apache.polaris.core.entity.PolarisEntitySubType;
import org.apache.polaris.core.entity.PolarisEntityType;
@@ -58,6 +59,12 @@ public class GenericTableEntity extends TableLikeEntity {
return getInternalPropertiesAsMap().get(GenericTableEntity.DOC_KEY);
}
+ @Override
+ @JsonIgnore
+ public String getBaseLocation() {
+ return
getInternalPropertiesAsMap().get(PolarisEntityConstants.ENTITY_BASE_LOCATION);
+ }
+
public static class Builder
extends PolarisEntity.BaseBuilder<GenericTableEntity,
GenericTableEntity.Builder> {
public Builder(TableIdentifier tableIdentifier, String format) {
@@ -79,6 +86,11 @@ public class GenericTableEntity extends TableLikeEntity {
return this;
}
+ public GenericTableEntity.Builder setBaseLocation(String location) {
+ internalProperties.put(PolarisEntityConstants.ENTITY_BASE_LOCATION,
location);
+ return this;
+ }
+
public GenericTableEntity.Builder setTableIdentifier(TableIdentifier
identifier) {
Namespace namespace = identifier.namespace();
setParentNamespace(namespace);
diff --git
a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java
b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java
index 21e922982..57d15a103 100644
---
a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java
+++
b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/IcebergTableLikeEntity.java
@@ -23,7 +23,6 @@ import java.util.Optional;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.rest.RESTUtil;
-import org.apache.polaris.core.entity.LocationBasedEntity;
import org.apache.polaris.core.entity.NamespaceEntity;
import org.apache.polaris.core.entity.PolarisBaseEntity;
import org.apache.polaris.core.entity.PolarisEntity;
@@ -34,7 +33,7 @@ import org.apache.polaris.core.entity.PolarisEntityType;
* An entity type for {@link TableLikeEntity} instances that conform to
iceberg semantics around
* locations. This includes both Iceberg tables and Iceberg views.
*/
-public class IcebergTableLikeEntity extends TableLikeEntity implements
LocationBasedEntity {
+public class IcebergTableLikeEntity extends TableLikeEntity {
// For applicable types, this key on the "internalProperties" map will
return the location
// of the internalProperties JSON file.
public static final String METADATA_LOCATION_KEY = "metadata-location";
diff --git
a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java
b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java
index 22808d1a7..21ba80f4a 100644
---
a/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java
+++
b/polaris-core/src/main/java/org/apache/polaris/core/entity/table/TableLikeEntity.java
@@ -23,16 +23,16 @@ import jakarta.annotation.Nonnull;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.rest.RESTUtil;
+import org.apache.polaris.core.entity.LocationBasedEntity;
import org.apache.polaris.core.entity.NamespaceEntity;
import org.apache.polaris.core.entity.PolarisBaseEntity;
import org.apache.polaris.core.entity.PolarisEntity;
-import org.apache.polaris.core.entity.PolarisEntityType;
/**
* An entity type for all table-like entities including Iceberg tables,
Iceberg views, and generic
* tables. This entity maps to {@link PolarisEntityType#TABLE_LIKE}
*/
-public abstract class TableLikeEntity extends PolarisEntity {
+public abstract class TableLikeEntity extends PolarisEntity implements
LocationBasedEntity {
public TableLikeEntity(@Nonnull PolarisBaseEntity sourceEntity) {
super(sourceEntity);
diff --git
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java
index 013e2c99e..c86cefe6e 100644
---
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java
+++
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java
@@ -325,7 +325,8 @@ public abstract class PolarisAuthzTestBase {
baseCatalog.buildTable(TABLE_NS1B_1, SCHEMA).create();
baseCatalog.buildTable(TABLE_NS2_1, SCHEMA).create();
- genericTableCatalog.createGenericTable(TABLE_NS1_1_GENERIC, "format",
"doc", Map.of());
+ genericTableCatalog.createGenericTable(
+ TABLE_NS1_1_GENERIC, "format", "file:///tmp/test_table", "doc",
Map.of());
policyCatalog.createPolicy(
POLICY_NS1_1,
diff --git
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java
index ea044fbab..ade4768f4 100644
---
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java
+++
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java
@@ -81,6 +81,9 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullSource;
+import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mockito;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
@@ -277,7 +280,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
Assertions.assertThatCode(
() ->
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "t1"), "test-format", "doc",
Map.of()))
+ TableIdentifier.of("ns", "t1"), "test-format", null,
"doc", Map.of()))
.doesNotThrowAnyException();
}
@@ -286,12 +289,12 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
Namespace namespace = Namespace.of("ns");
icebergCatalog.createNamespace(namespace);
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "t1"), "format1", "doc", Map.of());
+ TableIdentifier.of("ns", "t1"), "format1", null, "doc", Map.of());
Assertions.assertThatCode(
() ->
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "t1"), "format2", "doc",
Map.of()))
+ TableIdentifier.of("ns", "t1"), "format2", null, "doc",
Map.of()))
.hasMessageContaining("already exists");
Assertions.assertThatCode(
@@ -308,7 +311,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
Assertions.assertThatCode(
() ->
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "t1"), "format2", "doc",
Map.of()))
+ TableIdentifier.of("ns", "t1"), "format2", null, "doc",
Map.of()))
.hasMessageContaining("already exists");
Assertions.assertThatCode(
@@ -316,8 +319,10 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
.hasMessageContaining("already exists");
}
- @Test
- public void testGenericTableRoundTrip() {
+ @ParameterizedTest
+ @NullSource
+ @ValueSource(strings = {"", "file://path/to/my/table"})
+ public void testGenericTableRoundTrip(String baseLocation) {
Namespace namespace = Namespace.of("ns");
icebergCatalog.createNamespace(namespace);
@@ -327,7 +332,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
String doc = "round-trip-doc";
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", tableName), format, doc, properties);
+ TableIdentifier.of("ns", tableName), format, baseLocation, doc,
properties);
GenericTableEntity resultEntity =
genericTableCatalog.loadGenericTable(TableIdentifier.of("ns",
tableName));
@@ -335,6 +340,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
Assertions.assertThat(resultEntity.getFormat()).isEqualTo(format);
Assertions.assertThat(resultEntity.getPropertiesAsMap()).isEqualTo(properties);
Assertions.assertThat(resultEntity.getName()).isEqualTo(tableName);
+
Assertions.assertThat(resultEntity.getBaseLocation()).isEqualTo(baseLocation);
}
@Test
@@ -381,7 +387,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
String tableName = "t1";
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", tableName), "format", "doc", Map.of());
+ TableIdentifier.of("ns", tableName), "format", null, "doc", Map.of());
Assertions.assertThatCode(() ->
icebergCatalog.loadTable(TableIdentifier.of("ns", tableName)))
.hasMessageContaining("does not exist: ns.t1");
}
@@ -394,7 +400,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
String tableName = "t1";
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", tableName), "format", "doc", Map.of());
+ TableIdentifier.of("ns", tableName), "format", null, "doc", Map.of());
Assertions.assertThatCode(() ->
icebergCatalog.loadView(TableIdentifier.of("ns", tableName)))
.hasMessageContaining("does not exist: ns.t1");
}
@@ -406,7 +412,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
for (int i = 0; i < 10; i++) {
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "t" + i), "format", "doc", Map.of());
+ TableIdentifier.of("ns", "t" + i), "format", null, "doc", Map.of());
}
List<TableIdentifier> listResult =
genericTableCatalog.listGenericTables(namespace);
@@ -468,7 +474,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
for (int i = 0; i < 10; i++) {
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "g" + i), "format", "doc", Map.of());
+ TableIdentifier.of("ns", "g" + i), "format", null, "doc", Map.of());
}
Assertions.assertThat(genericTableCatalog.listGenericTables(namespace).size()).isEqualTo(10);
@@ -514,7 +520,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
Namespace namespace = Namespace.of("ns");
icebergCatalog.createNamespace(namespace);
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "t1"), "format", "doc", Map.of());
+ TableIdentifier.of("ns", "t1"), "format", null, "doc", Map.of());
Assertions.assertThat(icebergCatalog.dropTable(TableIdentifier.of("ns",
"t1"))).isFalse();
Assertions.assertThat(genericTableCatalog.loadGenericTable(TableIdentifier.of("ns",
"t1")))
@@ -526,7 +532,7 @@ public abstract class
AbstractPolarisGenericTableCatalogTest {
Namespace namespace = Namespace.of("ns");
icebergCatalog.createNamespace(namespace);
genericTableCatalog.createGenericTable(
- TableIdentifier.of("ns", "t1"), "format", "doc", Map.of());
+ TableIdentifier.of("ns", "t1"), "format", null, "doc", Map.of());
Assertions.assertThat(icebergCatalog.dropView(TableIdentifier.of("ns",
"t1"))).isFalse();
Assertions.assertThat(genericTableCatalog.loadGenericTable(TableIdentifier.of("ns",
"t1")))
diff --git
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogHandlerAuthzTest.java
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogHandlerAuthzTest.java
index 6deb37bb3..446e5505b 100644
---
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogHandlerAuthzTest.java
+++
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogHandlerAuthzTest.java
@@ -188,7 +188,7 @@ public class PolarisGenericTableCatalogHandlerAuthzTest
extends PolarisAuthzTest
PolarisPrivilege.CATALOG_MANAGE_CONTENT),
() -> {
newWrapper(Set.of(PRINCIPAL_ROLE1))
- .createGenericTable(newtable, "format", "doc", Map.of());
+ .createGenericTable(newtable, "format", "file:///temp/", "doc",
Map.of());
},
() -> {
newWrapper(Set.of(PRINCIPAL_ROLE2)).dropGenericTable(newtable);
@@ -209,7 +209,8 @@ public class PolarisGenericTableCatalogHandlerAuthzTest
extends PolarisAuthzTest
PolarisPrivilege.TABLE_LIST),
() -> {
newWrapper(Set.of(PRINCIPAL_ROLE1))
- .createGenericTable(TableIdentifier.of(NS2, "newtable"),
"format", "doc", Map.of());
+ .createGenericTable(
+ TableIdentifier.of(NS2, "newtable"), "format", null, "doc",
Map.of());
});
}
@@ -256,7 +257,7 @@ public class PolarisGenericTableCatalogHandlerAuthzTest
extends PolarisAuthzTest
},
() -> {
newWrapper(Set.of(PRINCIPAL_ROLE2))
- .createGenericTable(TABLE_NS1_1_GENERIC, "format", "doc",
Map.of());
+ .createGenericTable(TABLE_NS1_1_GENERIC, "format",
"file:///temp/", "doc", Map.of());
});
}
diff --git
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java
index 197be3645..ff1661290 100644
---
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java
+++
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java
@@ -32,7 +32,11 @@ public interface GenericTableCatalog {
/** Create a generic table with the specified identifier */
GenericTableEntity createGenericTable(
- TableIdentifier tableIdentifier, String format, String doc, Map<String,
String> properties);
+ TableIdentifier tableIdentifier,
+ String format,
+ String baseLocation,
+ String doc,
+ Map<String, String> properties);
/** Retrieve a generic table entity with a given identifier */
GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier);
diff --git
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogAdapter.java
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogAdapter.java
index 0c40960f5..ddc03a291 100644
---
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogAdapter.java
+++
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogAdapter.java
@@ -101,6 +101,7 @@ public class GenericTableCatalogAdapter
handler.createGenericTable(
TableIdentifier.of(decodeNamespace(namespace),
createGenericTableRequest.getName()),
createGenericTableRequest.getFormat(),
+ createGenericTableRequest.getBaseLocation(),
createGenericTableRequest.getDoc(),
reservedProperties.removeReservedProperties(createGenericTableRequest.getProperties()));
diff --git
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogHandler.java
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogHandler.java
index 66a2b81d1..670cddbb0 100644
---
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogHandler.java
+++
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalogHandler.java
@@ -69,16 +69,22 @@ public class GenericTableCatalogHandler extends
CatalogHandler {
}
public LoadGenericTableResponse createGenericTable(
- TableIdentifier identifier, String format, String doc, Map<String,
String> properties) {
+ TableIdentifier identifier,
+ String format,
+ String baseLocation,
+ String doc,
+ Map<String, String> properties) {
PolarisAuthorizableOperation op =
PolarisAuthorizableOperation.CREATE_TABLE_DIRECT;
authorizeCreateTableLikeUnderNamespaceOperationOrThrow(op, identifier);
GenericTableEntity createdEntity =
- this.genericTableCatalog.createGenericTable(identifier, format, doc,
properties);
+ this.genericTableCatalog.createGenericTable(
+ identifier, format, baseLocation, doc, properties);
GenericTable createdTable =
GenericTable.builder()
.setName(createdEntity.getName())
.setFormat(createdEntity.getFormat())
+ .setBaseLocation(createdEntity.getBaseLocation())
.setDoc(createdEntity.getDoc())
.setProperties(createdEntity.getPropertiesAsMap())
.build();
@@ -102,6 +108,7 @@ public class GenericTableCatalogHandler extends
CatalogHandler {
GenericTable.builder()
.setName(loadedEntity.getName())
.setFormat(loadedEntity.getFormat())
+ .setBaseLocation(loadedEntity.getBaseLocation())
.setDoc(loadedEntity.getDoc())
.setProperties(loadedEntity.getPropertiesAsMap())
.build();
diff --git
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
index 2b884e787..a198c6cb3 100644
---
a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
+++
b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java
@@ -75,7 +75,11 @@ public class PolarisGenericTableCatalog implements
GenericTableCatalog {
@Override
public GenericTableEntity createGenericTable(
- TableIdentifier tableIdentifier, String format, String doc, Map<String,
String> properties) {
+ TableIdentifier tableIdentifier,
+ String format,
+ String baseLocation,
+ String doc,
+ Map<String, String> properties) {
PolarisResolvedPathWrapper resolvedParent =
resolvedEntityView.getResolvedPath(tableIdentifier.namespace());
if (resolvedParent == null) {
@@ -105,6 +109,7 @@ public class PolarisGenericTableCatalog implements
GenericTableCatalog {
.getId())
.setProperties(properties)
.setDoc(doc)
+ .setBaseLocation(baseLocation)
.setCreateTimestamp(System.currentTimeMillis())
.build();
} else {