This is an automated email from the ASF dual-hosted git repository.

jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new a583e6ba4a [#9731] feat(paimon): support hash distribution in Paimon 
catalog (#9753)
a583e6ba4a is described below

commit a583e6ba4a0810608ad5c6abded8b279417cce86
Author: FANNG <[email protected]>
AuthorDate: Thu Jan 29 02:32:45 2026 +0900

    [#9731] feat(paimon): support hash distribution in Paimon catalog (#9753)
    
    ### What changes were proposed in this pull request?
    
    Support hash distribution in Paimon catalog
    
    ### Why are the changes needed?
    
    Fix: #9731
    
    ### Does this PR introduce _any_ user-facing change?
    no
    
    ### How was this patch tested?
    existing tests
---
 .../catalog/lakehouse/paimon/PaimonConstants.java  |   1 +
 .../lakehouse/paimon/GravitinoPaimonTable.java     |  73 +++++++++++++
 .../lakehouse/paimon/PaimonCatalogOperations.java  |  76 +++++++++++++-
 .../paimon/PaimonTablePropertiesMetadata.java      |   2 +
 .../lakehouse/paimon/TestGravitinoPaimonTable.java | 114 +++++++++++++++++++++
 docs/lakehouse-paimon-catalog.md                   |   4 +
 6 files changed, 267 insertions(+), 3 deletions(-)

diff --git 
a/catalogs/catalog-common/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConstants.java
 
b/catalogs/catalog-common/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConstants.java
index 291a7ea969..04e8988f49 100644
--- 
a/catalogs/catalog-common/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConstants.java
+++ 
b/catalogs/catalog-common/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonConstants.java
@@ -49,6 +49,7 @@ public class PaimonConstants {
   public static final String COMMENT = "comment";
   public static final String OWNER = "owner";
   public static final String BUCKET_KEY = "bucket-key";
+  public static final String BUCKET_NUM = "bucket";
   public static final String MERGE_ENGINE = "merge-engine";
   public static final String SEQUENCE_FIELD = "sequence.field";
   public static final String ROWKIND_FIELD = "rowkind.field";
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/GravitinoPaimonTable.java
 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/GravitinoPaimonTable.java
index 2853abbbe3..d09d58cdd9 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/GravitinoPaimonTable.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/GravitinoPaimonTable.java
@@ -18,6 +18,8 @@
  */
 package org.apache.gravitino.catalog.lakehouse.paimon;
 
+import static 
org.apache.gravitino.catalog.lakehouse.paimon.PaimonTablePropertiesMetadata.BUCKET_KEY;
+import static 
org.apache.gravitino.catalog.lakehouse.paimon.PaimonTablePropertiesMetadata.BUCKET_NUM;
 import static 
org.apache.gravitino.catalog.lakehouse.paimon.PaimonTablePropertiesMetadata.COMMENT;
 import static 
org.apache.gravitino.dto.rel.partitioning.Partitioning.EMPTY_PARTITIONING;
 import static org.apache.gravitino.meta.AuditInfo.EMPTY;
@@ -34,9 +36,14 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import lombok.Getter;
 import lombok.ToString;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.gravitino.connector.BaseTable;
 import org.apache.gravitino.connector.TableOperations;
+import org.apache.gravitino.rel.expressions.Expression;
 import org.apache.gravitino.rel.expressions.NamedReference;
+import org.apache.gravitino.rel.expressions.distributions.Distribution;
+import org.apache.gravitino.rel.expressions.distributions.Distributions;
+import org.apache.gravitino.rel.expressions.distributions.Strategy;
 import org.apache.gravitino.rel.expressions.transforms.Transform;
 import org.apache.gravitino.rel.expressions.transforms.Transforms;
 import org.apache.gravitino.rel.indexes.Index;
@@ -79,6 +86,9 @@ public class GravitinoPaimonTable extends BaseTable {
 
     Map<String, String> normalizedProperties = new HashMap<>(properties);
     normalizedProperties.remove(COMMENT);
+    normalizedProperties.remove(BUCKET_KEY);
+    normalizedProperties.remove(BUCKET_NUM);
+    applyDistribution(normalizedProperties, distribution);
 
     List<String> partitionKeys = getPartitionKeys(partitioning);
     List<String> primaryKeys = getPrimaryKeysFromIndexes(indexes);
@@ -106,6 +116,7 @@ public class GravitinoPaimonTable extends BaseTable {
             GravitinoPaimonColumn.fromPaimonRowType(table.rowType())
                 .toArray(new GravitinoPaimonColumn[0]))
         .withPartitioning(toGravitinoPartitioning(table.partitionKeys()))
+        .withDistribution(getDistribution(table.options()))
         .withComment(table.comment().orElse(null))
         .withProperties(table.options())
         .withIndexes(constructIndexesFromPrimaryKeys(table))
@@ -188,6 +199,67 @@ public class GravitinoPaimonTable extends BaseTable {
     }
   }
 
+  private static void applyDistribution(Map<String, String> properties, 
Distribution distribution) {
+    if (distribution == null || distribution.strategy() == 
Distributions.NONE.strategy()) {
+      return;
+    }
+
+    List<String> bucketKeys = getBucketKeys(distribution);
+    if (!bucketKeys.isEmpty()) {
+      properties.put(BUCKET_KEY, String.join(",", bucketKeys));
+    }
+
+    properties.put(BUCKET_NUM, String.valueOf(distribution.number()));
+  }
+
+  private static List<String> getBucketKeys(Distribution distribution) {
+    return Arrays.stream(distribution.expressions())
+        .map(
+            expression -> {
+              Preconditions.checkArgument(
+                  expression instanceof NamedReference.FieldReference,
+                  "Paimon bucket keys must be plain column references.");
+              NamedReference.FieldReference reference = 
(NamedReference.FieldReference) expression;
+              String[] fieldName = reference.fieldName();
+              Preconditions.checkArgument(
+                  fieldName.length == 1, "Paimon bucket keys must be single 
columns.");
+              return fieldName[0];
+            })
+        .collect(Collectors.toList());
+  }
+
+  static Distribution getDistribution(Map<String, String> properties) {
+    if (properties == null) {
+      return Distributions.NONE;
+    }
+    String bucketKeys = properties.get(BUCKET_KEY);
+    if (StringUtils.isBlank(bucketKeys)) {
+      return Distributions.NONE;
+    }
+    List<String> bucketKeyList =
+        Arrays.stream(bucketKeys.split(","))
+            .map(String::trim)
+            .filter(StringUtils::isNotBlank)
+            .collect(Collectors.toList());
+    if (bucketKeyList.isEmpty()) {
+      return Distributions.NONE;
+    }
+    Expression[] expressions =
+        
bucketKeyList.stream().map(NamedReference::field).toArray(Expression[]::new);
+    String bucketValue = properties.get(BUCKET_NUM);
+    if (StringUtils.isBlank(bucketValue)) {
+      return Distributions.auto(Strategy.HASH, expressions);
+    }
+    String trimmedBucketValue = bucketValue.trim();
+    try {
+      return Distributions.hash(Integer.parseInt(trimmedBucketValue), 
expressions);
+    } catch (NumberFormatException e) {
+      throw new IllegalArgumentException(
+          String.format("Paimon bucket number must be a valid integer, but was 
'%s'.", bucketValue),
+          e);
+    }
+  }
+
   /** A builder class for constructing {@link GravitinoPaimonTable} instance. 
*/
   public static class Builder extends BaseTableBuilder<Builder, 
GravitinoPaimonTable> {
 
@@ -206,6 +278,7 @@ public class GravitinoPaimonTable extends BaseTable {
       paimonTable.comment = comment;
       paimonTable.columns = columns;
       paimonTable.partitioning = partitioning;
+      paimonTable.distribution = distribution;
       paimonTable.properties = properties == null ? Maps.newHashMap() : 
Maps.newHashMap(properties);
       paimonTable.indexes = indexes;
       paimonTable.auditInfo = auditInfo;
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogOperations.java
 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogOperations.java
index cbcc024170..c1e7f08a30 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogOperations.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonCatalogOperations.java
@@ -29,6 +29,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import java.time.Instant;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -60,6 +61,7 @@ import org.apache.gravitino.rel.TableChange.RenameTable;
 import org.apache.gravitino.rel.expressions.NamedReference;
 import org.apache.gravitino.rel.expressions.distributions.Distribution;
 import org.apache.gravitino.rel.expressions.distributions.Distributions;
+import org.apache.gravitino.rel.expressions.distributions.Strategy;
 import org.apache.gravitino.rel.expressions.sorts.SortOrder;
 import org.apache.gravitino.rel.expressions.transforms.Transform;
 import org.apache.gravitino.rel.indexes.Index;
@@ -348,13 +350,11 @@ public class PaimonCatalogOperations implements 
CatalogOperations, SupportsSchem
                       && references[0] instanceof 
NamedReference.FieldReference;
                 }),
         "Paimon partition columns should not be nested.");
-    Preconditions.checkArgument(
-        distribution == null || distribution.strategy() == 
Distributions.NONE.strategy(),
-        "Distribution is not supported for Paimon in Gravitino now.");
     Preconditions.checkArgument(
         sortOrders == null || sortOrders.length == 0,
         "Sort orders are not supported for Paimon in Gravitino.");
     checkPaimonIndexes(indexes);
+    validateDistribution(distribution, columns, indexes);
     String currentUser = currentUser();
     GravitinoPaimonTable createdTable =
         GravitinoPaimonTable.builder()
@@ -378,6 +378,7 @@ public class PaimonCatalogOperations implements 
CatalogOperations, SupportsSchem
             .withPartitioning(partitioning)
             .withComment(comment)
             .withProperties(properties)
+            .withDistribution(distribution)
             .withIndexes(indexes)
             .withAuditInfo(
                 
AuditInfo.builder().withCreator(currentUser).withCreateTime(Instant.now()).build())
@@ -501,6 +502,75 @@ public class PaimonCatalogOperations implements 
CatalogOperations, SupportsSchem
                     "Paimon only supports primary key Index."));
   }
 
+  private void validateDistribution(Distribution distribution, Column[] 
columns, Index[] indexes) {
+    if (distribution == null || distribution.strategy() == 
Distributions.NONE.strategy()) {
+      return;
+    }
+
+    Preconditions.checkArgument(
+        distribution.strategy() == Strategy.HASH,
+        "Paimon only supports HASH distribution strategy.");
+
+    Preconditions.checkArgument(
+        distribution.expressions() != null && 
distribution.expressions().length > 0,
+        "Paimon bucket keys must be specified for HASH distribution.");
+
+    int bucketNumber = distribution.number();
+    Preconditions.checkArgument(
+        bucketNumber == Distributions.AUTO || bucketNumber > 0,
+        "Paimon bucket number must be positive or AUTO.");
+
+    List<String> bucketKeys = extractBucketKeys(distribution);
+    List<String> columnNames =
+        Arrays.stream(columns).map(Column::name).collect(Collectors.toList());
+    bucketKeys.forEach(
+        bucketKey ->
+            Preconditions.checkArgument(
+                columnNames.stream().anyMatch(name -> name.equals(bucketKey)),
+                "Distribution column %s does not exist in table columns.",
+                bucketKey));
+
+    List<String> primaryKeys = extractPrimaryKeys(indexes);
+    if (!primaryKeys.isEmpty()) {
+      Preconditions.checkArgument(
+          primaryKeys.containsAll(bucketKeys),
+          "Paimon bucket keys must be a subset of primary key columns for 
primary key tables.");
+    }
+  }
+
+  private static List<String> extractBucketKeys(Distribution distribution) {
+    return Arrays.stream(distribution.expressions())
+        .map(
+            expression -> {
+              Preconditions.checkArgument(
+                  expression instanceof NamedReference.FieldReference,
+                  "Paimon bucket keys must be plain column references.");
+              NamedReference.FieldReference reference = 
(NamedReference.FieldReference) expression;
+              String[] fieldNames = reference.fieldName();
+              Preconditions.checkArgument(
+                  fieldNames.length == 1, "Paimon bucket keys must be single 
columns.");
+              return fieldNames[0];
+            })
+        .collect(Collectors.toList());
+  }
+
+  private static List<String> extractPrimaryKeys(Index[] indexes) {
+    if (indexes == null || indexes.length == 0) {
+      return Collections.emptyList();
+    }
+    // Paimon supports at most one index; this is enforced in {@code 
checkPaimonIndexes()}.
+    Index primaryKeyIndex = indexes[0];
+    return Arrays.stream(primaryKeyIndex.fieldNames())
+        .map(
+            fieldName -> {
+              Preconditions.checkArgument(
+                  fieldName != null && fieldName.length == 1,
+                  "Paimon primary keys must be single columns.");
+              return fieldName[0];
+            })
+        .collect(Collectors.toList());
+  }
+
   /**
    * Performs rename table change with the provided identifier.
    *
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonTablePropertiesMetadata.java
 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonTablePropertiesMetadata.java
index ad63df6783..e56e6ea6f3 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonTablePropertiesMetadata.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/main/java/org/apache/gravitino/catalog/lakehouse/paimon/PaimonTablePropertiesMetadata.java
@@ -38,6 +38,7 @@ public class PaimonTablePropertiesMetadata extends 
BasePropertiesMetadata {
   public static final String COMMENT = PaimonConstants.COMMENT;
   public static final String OWNER = PaimonConstants.OWNER;
   public static final String BUCKET_KEY = PaimonConstants.BUCKET_KEY;
+  public static final String BUCKET_NUM = PaimonConstants.BUCKET_NUM;
   public static final String MERGE_ENGINE = PaimonConstants.MERGE_ENGINE;
   public static final String SEQUENCE_FIELD = PaimonConstants.SEQUENCE_FIELD;
   public static final String ROWKIND_FIELD = PaimonConstants.ROWKIND_FIELD;
@@ -52,6 +53,7 @@ public class PaimonTablePropertiesMetadata extends 
BasePropertiesMetadata {
             stringReservedPropertyEntry(COMMENT, "The table comment", true),
             stringReservedPropertyEntry(OWNER, "The table owner", false),
             stringReservedPropertyEntry(BUCKET_KEY, "The table bucket key", 
false),
+            stringReservedPropertyEntry(BUCKET_NUM, "The table bucket number", 
false),
             stringImmutablePropertyEntry(
                 MERGE_ENGINE, "The table merge engine", false, null, false, 
false),
             stringImmutablePropertyEntry(
diff --git 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/TestGravitinoPaimonTable.java
 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/TestGravitinoPaimonTable.java
index 466ecb3459..ae1ecc2707 100644
--- 
a/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/TestGravitinoPaimonTable.java
+++ 
b/catalogs/catalog-lakehouse-paimon/src/test/java/org/apache/gravitino/catalog/lakehouse/paimon/TestGravitinoPaimonTable.java
@@ -23,6 +23,7 @@ import static 
org.apache.gravitino.catalog.lakehouse.paimon.GravitinoPaimonTable
 import static 
org.apache.gravitino.catalog.lakehouse.paimon.TestPaimonCatalog.PAIMON_PROPERTIES_METADATA;
 import static 
org.apache.gravitino.catalog.lakehouse.paimon.utils.TableOpsUtils.checkColumnCapability;
 import static org.apache.gravitino.rel.Column.DEFAULT_VALUE_NOT_SET;
+import static org.apache.gravitino.rel.expressions.distributions.Strategy.HASH;
 import static 
org.apache.gravitino.rel.expressions.transforms.Transforms.identity;
 import static org.apache.gravitino.rel.indexes.Indexes.primary;
 
@@ -51,6 +52,7 @@ import org.apache.gravitino.rel.Column;
 import org.apache.gravitino.rel.Table;
 import org.apache.gravitino.rel.TableCatalog;
 import org.apache.gravitino.rel.expressions.NamedReference;
+import org.apache.gravitino.rel.expressions.distributions.Distribution;
 import org.apache.gravitino.rel.expressions.distributions.Distributions;
 import org.apache.gravitino.rel.expressions.sorts.SortOrder;
 import org.apache.gravitino.rel.expressions.transforms.Transform;
@@ -335,6 +337,118 @@ public class TestGravitinoPaimonTable {
     }
   }
 
+  @Test
+  void testCreatePaimonTableWithDistribution() {
+    String paimonTableName = "test_paimon_table_with_distribution";
+    NameIdentifier tableIdentifier = NameIdentifier.of(paimonSchema.name(), 
paimonTableName);
+    Map<String, String> properties = Maps.newHashMap();
+
+    Column[] columns =
+        new Column[] {
+          fromPaimonColumn(new DataField(0, "col_1", 
DataTypes.INT().notNull(), PAIMON_COMMENT)),
+          fromPaimonColumn(new DataField(1, "col_2", 
DataTypes.STRING().nullable(), PAIMON_COMMENT))
+        };
+
+    Table table =
+        paimonCatalogOperations.createTable(
+            tableIdentifier,
+            columns,
+            PAIMON_COMMENT,
+            properties,
+            new Transform[0],
+            Distributions.hash(4, NamedReference.field("col_1")),
+            new SortOrder[0]);
+
+    Assertions.assertEquals(HASH, table.distribution().strategy());
+    Assertions.assertEquals(4, table.distribution().number());
+    Assertions.assertEquals(
+        "col_1", ((NamedReference) 
table.distribution().expressions()[0]).fieldName()[0]);
+
+    Table loadedTable = paimonCatalogOperations.loadTable(tableIdentifier);
+    Assertions.assertEquals(HASH, loadedTable.distribution().strategy());
+    Assertions.assertEquals(4, loadedTable.distribution().number());
+    Assertions.assertEquals(
+        "col_1", ((NamedReference) 
loadedTable.distribution().expressions()[0]).fieldName()[0]);
+    Assertions.assertEquals(
+        "4", 
loadedTable.properties().get(PaimonTablePropertiesMetadata.BUCKET_NUM));
+    Assertions.assertEquals(
+        "col_1", 
loadedTable.properties().get(PaimonTablePropertiesMetadata.BUCKET_KEY));
+  }
+
+  @Test
+  void testGetDistributionWithAutoBucketNumber() {
+    Map<String, String> options = Maps.newHashMap();
+    options.put(PaimonTablePropertiesMetadata.BUCKET_KEY, "col_1");
+
+    Distribution distribution = GravitinoPaimonTable.getDistribution(options);
+    Assertions.assertEquals(HASH, distribution.strategy());
+    Assertions.assertEquals(Distributions.AUTO, distribution.number());
+    Assertions.assertEquals(
+        "col_1", ((NamedReference) 
distribution.expressions()[0]).fieldName()[0]);
+  }
+
+  @Test
+  void testGetDistributionWithMultipleBucketKeys() {
+    Map<String, String> options = Maps.newHashMap();
+    options.put(PaimonTablePropertiesMetadata.BUCKET_KEY, "col_1,col_2");
+    options.put(PaimonTablePropertiesMetadata.BUCKET_NUM, "4");
+
+    Distribution distribution = GravitinoPaimonTable.getDistribution(options);
+    Assertions.assertEquals(HASH, distribution.strategy());
+    Assertions.assertEquals(4, distribution.number());
+    Assertions.assertEquals(2, distribution.expressions().length);
+    Assertions.assertEquals(
+        "col_1", ((NamedReference) 
distribution.expressions()[0]).fieldName()[0]);
+    Assertions.assertEquals(
+        "col_2", ((NamedReference) 
distribution.expressions()[1]).fieldName()[0]);
+  }
+
+  @Test
+  void testGetDistributionWithInvalidBucketNumber() {
+    Map<String, String> options = Maps.newHashMap();
+    options.put(PaimonTablePropertiesMetadata.BUCKET_KEY, "col_1");
+    options.put(PaimonTablePropertiesMetadata.BUCKET_NUM, "not_a_number");
+
+    IllegalArgumentException exception =
+        Assertions.assertThrows(
+            IllegalArgumentException.class, () -> 
GravitinoPaimonTable.getDistribution(options));
+    Assertions.assertTrue(
+        exception.getMessage().contains("Paimon bucket number must be a valid 
integer"));
+  }
+
+  @Test
+  void testCreatePaimonPrimaryKeyTableWithInvalidBucketKey() {
+    String paimonTableName = "test_paimon_primary_key_table_invalid_bucket";
+    NameIdentifier tableIdentifier = NameIdentifier.of(paimonSchema.name(), 
paimonTableName);
+
+    Column[] columns =
+        new Column[] {
+          fromPaimonColumn(new DataField(0, "col_1", 
DataTypes.INT().notNull(), PAIMON_COMMENT)),
+          fromPaimonColumn(new DataField(1, "col_2", 
DataTypes.STRING().notNull(), PAIMON_COMMENT))
+        };
+
+    Index[] indexes =
+        Collections.singletonList(
+                primary(PAIMON_PRIMARY_KEY_INDEX_NAME, new String[][] {new 
String[] {"col_2"}}))
+            .toArray(new Index[0]);
+
+    IllegalArgumentException exception =
+        Assertions.assertThrows(
+            IllegalArgumentException.class,
+            () ->
+                paimonCatalogOperations.createTable(
+                    tableIdentifier,
+                    columns,
+                    PAIMON_COMMENT,
+                    Maps.newHashMap(),
+                    new Transform[0],
+                    Distributions.hash(2, NamedReference.field("col_1")),
+                    new SortOrder[0],
+                    indexes));
+    Assertions.assertTrue(
+        exception.getMessage().contains("bucket keys must be a subset of 
primary key columns"));
+  }
+
   @Test
   void testDropPaimonTable() {
     NameIdentifier tableIdentifier = NameIdentifier.of(paimonSchema.name(), 
genRandomName());
diff --git a/docs/lakehouse-paimon-catalog.md b/docs/lakehouse-paimon-catalog.md
index 8bb9b0ca2b..20945fe44f 100644
--- a/docs/lakehouse-paimon-catalog.md
+++ b/docs/lakehouse-paimon-catalog.md
@@ -192,6 +192,9 @@ You can pass [Paimon table 
properties](https://paimon.apache.org/docs/0.8/mainte
 **Immutable**: Fields that cannot be modified once set.
 :::
 
+Bucket settings are defined via Gravitino table distribution (HASH strategy). 
The `bucket` and
+`bucket-key` options are reserved and derived from the distribution instead of 
being set directly.
+
 | Configuration item | Description               | Default Value | Required  | 
Reserved | Immutable | Since version     |
 
|--------------------|---------------------------|---------------|-----------|----------|-----------|-------------------|
 | `merge-engine`     | The table merge-engine.   | (none)        | No        | 
No       | Yes       | 0.6.0-incubating  |
@@ -200,6 +203,7 @@ You can pass [Paimon table 
properties](https://paimon.apache.org/docs/0.8/mainte
 | `comment`          | The table comment.        | (none)        | No        | 
Yes      | No        | 0.6.0-incubating  |
 | `owner`            | The table owner.          | (none)        | No        | 
Yes      | No        | 0.6.0-incubating  |
 | `bucket-key`       | The table bucket-key.     | (none)        | No        | 
Yes      | No        | 0.6.0-incubating  |
+| `bucket`           | The table bucket number.  | (none)        | No        | 
Yes      | No        | 1.2.0  |
 | `primary-key`      | The table primary-key.    | (none)        | No        | 
Yes      | No        | 0.6.0-incubating  |
 | `partition`        | The table partition.      | (none)        | No        | 
Yes      | No        | 0.6.0-incubating  |
 

Reply via email to