This is an automated email from the ASF dual-hosted git repository.
mchades 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 4acdc498c [#3368] feat(jdbc-doris): support pre-assign partition for
Doris table (#3887)
4acdc498c is described below
commit 4acdc498cfca005b6b4b83890565c16f57d0fe03
Author: XiaoZ <[email protected]>
AuthorDate: Tue Jul 30 11:13:31 2024 +0800
[#3368] feat(jdbc-doris): support pre-assign partition for Doris table
(#3887)
### What changes were proposed in this pull request?
Support pre-assign partition for Doris table.
### Why are the changes needed?
Fix: #3368
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
UT & IT
---------
Co-authored-by: zhanghan18 <[email protected]>
---
.../doris/operation/DorisTableOperations.java | 100 ++++++++---
.../operation/DorisTablePartitionOperations.java | 70 ++------
.../gravitino/catalog/doris/utils/DorisUtils.java | 71 ++++++++
.../doris/integration/test/CatalogDorisIT.java | 200 ++++++++++++++-------
.../doris/operation/TestDorisTableOperations.java | 87 ++++++++-
.../catalog/doris/utils/TestDorisUtils.java | 93 ++++++++--
.../gravitino/integration/test/util/ITUtils.java | 36 ++++
7 files changed, 493 insertions(+), 164 deletions(-)
diff --git
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTableOperations.java
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTableOperations.java
index 2ac519cb5..21795d803 100644
---
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTableOperations.java
+++
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTableOperations.java
@@ -18,6 +18,7 @@
*/
package org.apache.gravitino.catalog.doris.operation;
+import static
org.apache.gravitino.catalog.doris.utils.DorisUtils.generatePartitionSqlFragment;
import static org.apache.gravitino.rel.Column.DEFAULT_VALUE_NOT_SET;
import com.google.common.base.Preconditions;
@@ -54,16 +55,18 @@ import org.apache.gravitino.rel.Column;
import org.apache.gravitino.rel.TableChange;
import org.apache.gravitino.rel.expressions.distributions.Distribution;
import org.apache.gravitino.rel.expressions.distributions.Strategy;
+import org.apache.gravitino.rel.expressions.literals.Literal;
import org.apache.gravitino.rel.expressions.transforms.Transform;
import org.apache.gravitino.rel.expressions.transforms.Transforms;
import org.apache.gravitino.rel.indexes.Index;
import org.apache.gravitino.rel.indexes.Indexes;
+import org.apache.gravitino.rel.partitions.ListPartition;
+import org.apache.gravitino.rel.partitions.RangePartition;
/** Table operations for Apache Doris. */
public class DorisTableOperations extends JdbcTableOperations {
private static final String BACK_QUOTE = "`";
private static final String DORIS_AUTO_INCREMENT = "AUTO_INCREMENT";
-
private static final String NEW_LINE = "\n";
@Override
@@ -194,7 +197,6 @@ public class DorisTableOperations extends
JdbcTableOperations {
}
private static void appendIndexesSql(Index[] indexes, StringBuilder
sqlBuilder) {
-
if (indexes.length == 0) {
return;
}
@@ -224,47 +226,91 @@ public class DorisTableOperations extends
JdbcTableOperations {
Preconditions.checkArgument(
partitioning.length == 1, "Composite partition type is not supported");
- StringBuilder partitionSqlBuilder = new StringBuilder();
+ StringBuilder partitionSqlBuilder;
Set<String> columnNames =
Arrays.stream(columns).map(JdbcColumn::name).collect(Collectors.toSet());
if (partitioning[0] instanceof Transforms.RangeTransform) {
- partitionSqlBuilder.append(NEW_LINE).append(" PARTITION BY RANGE(");
- // TODO support multi-column range partitioning in doris
+ // We do not support multi-column range partitioning in doris for now
Transforms.RangeTransform rangePartition = (Transforms.RangeTransform)
partitioning[0];
+ partitionSqlBuilder = generateRangePartitionSql(rangePartition,
columnNames);
+ } else if (partitioning[0] instanceof Transforms.ListTransform) {
+ Transforms.ListTransform listPartition = (Transforms.ListTransform)
partitioning[0];
+ partitionSqlBuilder = generateListPartitionSql(listPartition,
columnNames);
+ } else {
+ throw new IllegalArgumentException("Unsupported partition type of
Doris");
+ }
+ sqlBuilder.append(partitionSqlBuilder);
+ }
+
+ private static StringBuilder generateRangePartitionSql(
+ Transforms.RangeTransform rangePartition, Set<String> columnNames) {
+ Preconditions.checkArgument(
+ rangePartition.fieldName().length == 1, "Doris partition does not
support nested field");
+ Preconditions.checkArgument(
+ columnNames.contains(rangePartition.fieldName()[0]),
+ "The partition field must be one of the columns");
+
+ StringBuilder partitionSqlBuilder = new StringBuilder(NEW_LINE);
+ String partitionDefinition =
+ String.format(" PARTITION BY RANGE(`%s`)",
rangePartition.fieldName()[0]);
+
partitionSqlBuilder.append(partitionDefinition).append(NEW_LINE).append("(");
+
+ // Assign range partitions
+ RangePartition[] assignments = rangePartition.assignments();
+ if (!ArrayUtils.isEmpty(assignments)) {
+ String partitionSqlFragments =
+ Arrays.stream(assignments)
+ .map(DorisUtils::generatePartitionSqlFragment)
+ .collect(Collectors.joining("," + NEW_LINE));
+ partitionSqlBuilder.append(NEW_LINE).append(partitionSqlFragments);
+ }
+
+ partitionSqlBuilder.append(NEW_LINE).append(")");
+ return partitionSqlBuilder;
+ }
+
+ private static StringBuilder generateListPartitionSql(
+ Transforms.ListTransform listPartition, Set<String> columnNames) {
+ ImmutableList.Builder<String> partitionColumnsBuilder =
ImmutableList.builder();
+ String[][] filedNames = listPartition.fieldNames();
+ for (String[] filedName : filedNames) {
Preconditions.checkArgument(
- rangePartition.fieldName().length == 1, "Doris partition does not
support nested field");
+ filedName.length == 1, "Doris partition does not support nested
field");
Preconditions.checkArgument(
- columnNames.contains(rangePartition.fieldName()[0]),
- "The partition field must be one of the columns");
+ columnNames.contains(filedName[0]), "The partition field must be one
of the columns");
- String partitionColumn = BACK_QUOTE + rangePartition.fieldName()[0] +
BACK_QUOTE;
- // TODO we currently do not support pre-assign partition when creating
range partitioning
- partitionSqlBuilder.append(partitionColumn).append(") () ");
- } else if (partitioning[0] instanceof Transforms.ListTransform) {
- Transforms.ListTransform listPartition = (Transforms.ListTransform)
partitioning[0];
- partitionSqlBuilder.append(" PARTITION BY LIST(");
+ partitionColumnsBuilder.add(BACK_QUOTE + filedName[0] + BACK_QUOTE);
+ }
+ String partitionColumns =
+
partitionColumnsBuilder.build().stream().collect(Collectors.joining(","));
+
+ StringBuilder partitionSqlBuilder = new StringBuilder(NEW_LINE);
+ String partitionDefinition = String.format(" PARTITION BY LIST(%s)",
partitionColumns);
+
partitionSqlBuilder.append(partitionDefinition).append(NEW_LINE).append("(");
- ImmutableList.Builder<String> partitionColumnsBuilder =
ImmutableList.builder();
- String[][] filedNames = listPartition.fieldNames();
- for (String[] filedName : filedNames) {
+ // Assign list partitions
+ ListPartition[] assignments = listPartition.assignments();
+ if (!ArrayUtils.isEmpty(assignments)) {
+ ImmutableList.Builder<String> partitions = ImmutableList.builder();
+ for (ListPartition part : assignments) {
+ Literal<?>[][] lists = part.lists();
Preconditions.checkArgument(
- filedName.length == 1, "Doris partition does not support nested
field");
+ lists.length > 0, "The number of values in list partition must be
greater than 0");
Preconditions.checkArgument(
- columnNames.contains(filedName[0]), "The partition field must be
one of the columns");
+ Arrays.stream(lists).allMatch(p -> p.length == filedNames.length),
+ "The number of partitioning columns must be consistent");
- partitionColumnsBuilder.add(BACK_QUOTE + filedName[0] + BACK_QUOTE);
+ partitions.add(generatePartitionSqlFragment(part));
}
- String partitionColumns =
-
partitionColumnsBuilder.build().stream().collect(Collectors.joining(","));
- // TODO we currently do not support pre-assign partition when creating
list partitioning table
- partitionSqlBuilder.append(partitionColumns).append(") () ");
- } else {
- throw new IllegalArgumentException("Unsupported partition type of
Doris");
+ partitionSqlBuilder
+ .append(NEW_LINE)
+ .append(partitions.build().stream().collect(Collectors.joining("," +
NEW_LINE)));
}
- sqlBuilder.append(partitionSqlBuilder);
+ partitionSqlBuilder.append(NEW_LINE).append(")");
+ return partitionSqlBuilder;
}
@Override
diff --git
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTablePartitionOperations.java
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTablePartitionOperations.java
index c3e5a2bba..e075717f4 100644
---
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTablePartitionOperations.java
+++
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/operation/DorisTablePartitionOperations.java
@@ -28,6 +28,7 @@ import static
org.apache.gravitino.catalog.doris.DorisTablePartitionPropertiesMe
import static
org.apache.gravitino.catalog.doris.DorisTablePartitionPropertiesMetadata.VALUES_RANGE;
import static
org.apache.gravitino.catalog.doris.DorisTablePartitionPropertiesMetadata.VISIBLE_VERSION;
import static
org.apache.gravitino.catalog.doris.DorisTablePartitionPropertiesMetadata.VISIBLE_VERSION_TIME;
+import static
org.apache.gravitino.catalog.doris.utils.DorisUtils.generatePartitionSqlFragment;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -43,7 +44,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.apache.gravitino.catalog.jdbc.JdbcTable;
import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
@@ -145,8 +145,8 @@ public final class DorisTablePartitionOperations extends
JdbcTablePartitionOpera
try (Connection connection = getConnection(loadedTable.databaseName())) {
Transform partitionInfo = loadedTable.partitioning()[0];
- String addPartitionSqlFormat = "ALTER TABLE `%s` ADD PARTITION `%s`
VALUES %s";
- String partitionValues;
+ String addPartitionSqlFormat = "ALTER TABLE `%s` ADD %s";
+ String partitionSqlFragment;
Partition added;
if (partition instanceof RangePartition) {
@@ -156,7 +156,7 @@ public final class DorisTablePartitionOperations extends
JdbcTablePartitionOpera
loadedTable.name());
RangePartition rangePartition = (RangePartition) partition;
- partitionValues = buildRangePartitionValues(rangePartition);
+ partitionSqlFragment = generatePartitionSqlFragment(rangePartition);
// The partition properties actually cannot be passed into Doris, we
just return an empty
// map instead.
@@ -173,9 +173,18 @@ public final class DorisTablePartitionOperations extends
JdbcTablePartitionOpera
loadedTable.name());
ListPartition listPartition = (ListPartition) partition;
- partitionValues =
- buildListPartitionValues(
- listPartition, ((Transforms.ListTransform)
partitionInfo).fieldNames().length);
+ Literal<?>[][] lists = listPartition.lists();
+ Preconditions.checkArgument(
+ lists.length > 0, "The number of values in list partition must be
greater than 0");
+ Preconditions.checkArgument(
+ Arrays.stream(lists)
+ .allMatch(
+ part ->
+ part.length
+ == ((Transforms.ListTransform)
partitionInfo).fieldNames().length),
+ "The number of partitioning columns must be consistent");
+
+ partitionSqlFragment = generatePartitionSqlFragment(listPartition);
added =
Partitions.list(listPartition.name(), listPartition.lists(),
Collections.emptyMap());
@@ -185,8 +194,7 @@ public final class DorisTablePartitionOperations extends
JdbcTablePartitionOpera
try (Statement statement = connection.createStatement()) {
statement.executeUpdate(
- String.format(
- addPartitionSqlFormat, loadedTable.name(), partition.name(),
partitionValues));
+ String.format(addPartitionSqlFormat, loadedTable.name(),
partitionSqlFragment));
return added;
}
} catch (SQLException e) {
@@ -287,48 +295,4 @@ public final class DorisTablePartitionOperations extends
JdbcTablePartitionOpera
return columnTypes.build();
}
}
-
- private String buildRangePartitionValues(RangePartition rangePartition) {
- Literal<?> upper = rangePartition.upper();
- Literal<?> lower = rangePartition.lower();
- String partitionValues;
- if (Literals.NULL.equals(upper) && Literals.NULL.equals(lower)) {
- partitionValues = "LESS THAN MAXVALUE";
- } else if (Literals.NULL.equals(lower)) {
- partitionValues = "LESS THAN (\"" + upper.value() + "\")";
- } else if (Literals.NULL.equals(upper)) {
- partitionValues = "[(\"" + lower.value() + "\"), (MAXVALUE))";
- } else {
- partitionValues = "[(\"" + lower.value() + "\"), (\"" + upper.value() +
"\"))";
- }
- return partitionValues;
- }
-
- private String buildListPartitionValues(ListPartition listPartition, int
partitionedFieldNums) {
- Literal<?>[][] lists = listPartition.lists();
- Preconditions.checkArgument(
- lists.length > 0, "The number of values in list partition must be
greater than 0");
-
- ImmutableList.Builder<String> listValues = ImmutableList.builder();
- for (Literal<?>[] part : lists) {
- Preconditions.checkArgument(
- part.length == partitionedFieldNums,
- "The number of partitioning columns must be consistent");
-
- StringBuilder values = new StringBuilder();
- if (part.length > 1) {
- values
- .append("(")
- .append(
- Arrays.stream(part)
- .map(p -> "\"" + p.value() + "\"")
- .collect(Collectors.joining(",")))
- .append(")");
- } else {
- values.append("\"").append(part[0].value()).append("\"");
- }
- listValues.add(values.toString());
- }
- return String.format("IN (%s)",
listValues.build().stream().collect(Collectors.joining(",")));
- }
}
diff --git
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
index 69eada5ee..a3d2ccc91 100644
---
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
+++
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
@@ -18,6 +18,7 @@
*/
package org.apache.gravitino.catalog.doris.utils;
+import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -25,8 +26,13 @@ import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import org.apache.gravitino.rel.expressions.literals.Literal;
+import org.apache.gravitino.rel.expressions.literals.Literals;
import org.apache.gravitino.rel.expressions.transforms.Transform;
import org.apache.gravitino.rel.expressions.transforms.Transforms;
+import org.apache.gravitino.rel.partitions.ListPartition;
+import org.apache.gravitino.rel.partitions.Partition;
+import org.apache.gravitino.rel.partitions.RangePartition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -105,4 +111,69 @@ public final class DorisUtils {
return Optional.empty();
}
}
+
+ /**
+ * Generate sql fragment that create partition in Apache Doris.
+ *
+ * <p>The sql fragment looks like "PARTITION {partitionName} VALUES
{values}", for example:
+ *
+ * <pre>PARTITION `p20240724` VALUES LESS THAN ("2024-07-24")</pre>
+ *
+ * <pre>PARTITION `p20240724_v1` VALUES IN ("2024-07-24", "v1")</pre>
+ *
+ * @param partition The partition to be created.
+ * @return The partition sql fragment.
+ */
+ public static String generatePartitionSqlFragment(Partition partition) {
+ String partitionSqlFragment = "PARTITION `%s` VALUES %s";
+ if (partition instanceof RangePartition) {
+ return String.format(
+ partitionSqlFragment,
+ partition.name(),
+ generateRangePartitionValues((RangePartition) partition));
+ } else if (partition instanceof ListPartition) {
+ return String.format(
+ partitionSqlFragment,
+ partition.name(),
+ generateListPartitionSqlValues((ListPartition) partition));
+ } else {
+ throw new IllegalArgumentException("Unsupported partition type of
Doris");
+ }
+ }
+
+ private static String generateRangePartitionValues(RangePartition
rangePartition) {
+ Literal<?> upper = rangePartition.upper();
+ Literal<?> lower = rangePartition.lower();
+ String partitionValues;
+ if (Literals.NULL.equals(upper) && Literals.NULL.equals(lower)) {
+ partitionValues = "LESS THAN MAXVALUE";
+ } else if (Literals.NULL.equals(lower)) {
+ partitionValues = String.format("LESS THAN (\"%s\")", upper.value());
+ } else if (Literals.NULL.equals(upper)) {
+ partitionValues = String.format("[(\"%s\"), (MAXVALUE))", lower.value());
+ } else {
+ partitionValues = String.format("[(\"%s\"), (\"%s\"))", lower.value(),
upper.value());
+ }
+ return partitionValues;
+ }
+
+ private static String generateListPartitionSqlValues(ListPartition
listPartition) {
+ Literal<?>[][] lists = listPartition.lists();
+ ImmutableList.Builder<String> listValues = ImmutableList.builder();
+ for (Literal<?>[] part : lists) {
+ String values;
+ if (part.length > 1) {
+ values =
+ String.format(
+ "(%s)",
+ Arrays.stream(part)
+ .map(p -> "\"" + p.value() + "\"")
+ .collect(Collectors.joining(",")));
+ } else {
+ values = String.format("\"%s\"", part[0].value());
+ }
+ listValues.add(values);
+ }
+ return String.format("IN (%s)",
listValues.build().stream().collect(Collectors.joining(",")));
+ }
}
diff --git
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
index 2f32dc155..7bc073a0b 100644
---
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
+++
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
@@ -18,6 +18,7 @@
*/
package org.apache.gravitino.catalog.doris.integration.test;
+import static
org.apache.gravitino.integration.test.util.ITUtils.assertPartition;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -67,6 +68,7 @@ import org.apache.gravitino.rel.indexes.Indexes;
import org.apache.gravitino.rel.partitions.ListPartition;
import org.apache.gravitino.rel.partitions.Partition;
import org.apache.gravitino.rel.partitions.Partitions;
+import org.apache.gravitino.rel.partitions.RangePartition;
import org.apache.gravitino.rel.types.Types;
import org.apache.gravitino.utils.RandomNameUtils;
import org.junit.jupiter.api.AfterAll;
@@ -98,6 +100,7 @@ public class CatalogDorisIT extends AbstractIT {
public String DORIS_COL_NAME1 = "doris_col_name1";
public String DORIS_COL_NAME2 = "doris_col_name2";
public String DORIS_COL_NAME3 = "doris_col_name3";
+ public String DORIS_COL_NAME4 = "doris_col_name4";
// Because the creation of Schema Change is an asynchronous process, we need
to wait for a while
// For more information, you can refer to the comment in
@@ -196,8 +199,9 @@ public class CatalogDorisIT extends AbstractIT {
Column.of(DORIS_COL_NAME1, Types.IntegerType.get(), "col_1_comment",
false, false, null);
Column col2 = Column.of(DORIS_COL_NAME2, Types.VarCharType.of(10),
"col_2_comment");
Column col3 = Column.of(DORIS_COL_NAME3, Types.VarCharType.of(10),
"col_3_comment");
-
- return new Column[] {col1, col2, col3};
+ Column col4 =
+ Column.of(DORIS_COL_NAME4, Types.DateType.get(), "col_4_comment",
false, false, null);
+ return new Column[] {col1, col2, col3, col4};
}
private Map<String, String> createTableProperties() {
@@ -540,29 +544,29 @@ public class CatalogDorisIT extends AbstractIT {
tableCatalog.alterTable(
tableIdentifier,
TableChange.addColumn(
- new String[] {"col_4"}, Types.VarCharType.of(255),
"col_4_comment", true));
+ new String[] {"col_5"}, Types.VarCharType.of(255),
"col_5_comment", true));
Awaitility.await()
.atMost(MAX_WAIT_IN_SECONDS, TimeUnit.SECONDS)
.pollInterval(WAIT_INTERVAL_IN_SECONDS, TimeUnit.SECONDS)
.untilAsserted(
- () -> assertEquals(4,
tableCatalog.loadTable(tableIdentifier).columns().length));
+ () -> assertEquals(5,
tableCatalog.loadTable(tableIdentifier).columns().length));
ITUtils.assertColumn(
- Column.of("col_4", Types.VarCharType.of(255), "col_4_comment"),
- tableCatalog.loadTable(tableIdentifier).columns()[3]);
+ Column.of("col_5", Types.VarCharType.of(255), "col_5_comment"),
+ tableCatalog.loadTable(tableIdentifier).columns()[4]);
// change column position
// TODO: change column position is unstable, add it later
// drop column
tableCatalog.alterTable(
- tableIdentifier, TableChange.deleteColumn(new String[] {"col_4"},
true));
+ tableIdentifier, TableChange.deleteColumn(new String[] {"col_5"},
true));
Awaitility.await()
.atMost(MAX_WAIT_IN_SECONDS, TimeUnit.SECONDS)
.pollInterval(WAIT_INTERVAL_IN_SECONDS, TimeUnit.SECONDS)
.untilAsserted(
- () -> assertEquals(3,
tableCatalog.loadTable(tableIdentifier).columns().length));
+ () -> assertEquals(4,
tableCatalog.loadTable(tableIdentifier).columns().length));
}
@Test
@@ -703,23 +707,11 @@ public class CatalogDorisIT extends AbstractIT {
ListPartition p2 = Partitions.list("p2", p2Values, Collections.emptyMap());
ListPartition p3 = Partitions.list("p3", p3Values, Collections.emptyMap());
ListPartition p1Added = (ListPartition)
tablePartitionOperations.addPartition(p1);
- assertEquals("p1", p1Added.name());
- assertEquals(1, p1Added.lists().length);
- assertEquals(1, p1Added.lists()[0].length);
- assertEquals("1", p1Added.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), p1Added.lists()[0][0].dataType());
+ assertPartition(p1, p1Added);
ListPartition p2Added = (ListPartition)
tablePartitionOperations.addPartition(p2);
- assertEquals("p2", p2Added.name());
- assertEquals(1, p2Added.lists().length);
- assertEquals(1, p2Added.lists()[0].length);
- assertEquals("2", p2Added.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), p2Added.lists()[0][0].dataType());
+ assertPartition(p2, p2Added);
ListPartition p3Added = (ListPartition)
tablePartitionOperations.addPartition(p3);
- assertEquals("p3", p3Added.name());
- assertEquals(1, p3Added.lists().length);
- assertEquals(1, p3Added.lists()[0].length);
- assertEquals("3", p3Added.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), p3Added.lists()[0][0].dataType());
+ assertPartition(p3, p3Added);
// check partitions
Set<String> partitionNames =
@@ -733,43 +725,13 @@ public class CatalogDorisIT extends AbstractIT {
Arrays.stream(tablePartitionOperations.listPartitions())
.collect(Collectors.toMap(p -> p.name(), p -> (ListPartition) p));
assertEquals(3, partitions.size());
- ListPartition actualP1 = partitions.get("p1");
- assertEquals("p1", actualP1.name());
- assertEquals(1, actualP1.lists().length);
- assertEquals(1, actualP1.lists()[0].length);
- assertEquals("1", actualP1.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), actualP1.lists()[0][0].dataType());
- ListPartition actualP2 = partitions.get("p2");
- assertEquals("p2", actualP2.name());
- assertEquals(1, actualP2.lists().length);
- assertEquals(1, actualP2.lists()[0].length);
- assertEquals("2", actualP2.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), actualP2.lists()[0][0].dataType());
- ListPartition actualP3 = partitions.get("p3");
- assertEquals("p3", actualP3.name());
- assertEquals(1, actualP3.lists().length);
- assertEquals(1, actualP3.lists()[0].length);
- assertEquals("3", actualP3.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), actualP3.lists()[0][0].dataType());
-
- actualP1 = (ListPartition) tablePartitionOperations.getPartition("p1");
- assertEquals("p1", actualP1.name());
- assertEquals(1, actualP1.lists().length);
- assertEquals(1, actualP1.lists()[0].length);
- assertEquals("1", actualP1.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), actualP1.lists()[0][0].dataType());
- actualP2 = (ListPartition) tablePartitionOperations.getPartition("p2");
- assertEquals("p2", actualP2.name());
- assertEquals(1, actualP2.lists().length);
- assertEquals(1, actualP2.lists()[0].length);
- assertEquals("2", actualP2.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), actualP2.lists()[0][0].dataType());
- actualP3 = (ListPartition) tablePartitionOperations.getPartition("p3");
- assertEquals("p3", actualP3.name());
- assertEquals(1, actualP3.lists().length);
- assertEquals(1, actualP3.lists()[0].length);
- assertEquals("3", actualP3.lists()[0][0].value());
- assertEquals(Types.IntegerType.get(), actualP3.lists()[0][0].dataType());
+ assertPartition(p1, partitions.get("p1"));
+ assertPartition(p2, partitions.get("p2"));
+ assertPartition(p3, partitions.get("p3"));
+
+ assertPartition(p1, tablePartitionOperations.getPartition("p1"));
+ assertPartition(p2, tablePartitionOperations.getPartition("p2"));
+ assertPartition(p3, tablePartitionOperations.getPartition("p3"));
// drop partition
assertTrue(tablePartitionOperations.dropPartition("p3"));
@@ -783,6 +745,124 @@ public class CatalogDorisIT extends AbstractIT {
assertFalse(tablePartitionOperations.dropPartition("p3"));
}
+ @Test
+ void testCreatePartitionedTable() {
+ // create a range-partitioned table with assignments
+ String tableName =
GravitinoITUtils.genRandomName("test_create_range_partitioned_table");
+ NameIdentifier tableIdentifier = NameIdentifier.of(schemaName, tableName);
+ Column[] columns = createColumns();
+ Distribution distribution = createDistribution();
+ Index[] indexes =
+ new Index[] {
+ Indexes.of(Index.IndexType.PRIMARY_KEY, "k1_index", new String[][]
{{DORIS_COL_NAME1}})
+ };
+ Map<String, String> properties = createTableProperties();
+ Literal todayLiteral = Literals.of("2024-07-24", Types.DateType.get());
+ Literal tomorrowLiteral = Literals.of("2024-07-25", Types.DateType.get());
+ RangePartition p1 = Partitions.range("p1", todayLiteral, Literals.NULL,
Collections.emptyMap());
+ RangePartition p2 =
+ Partitions.range("p2", tomorrowLiteral, todayLiteral,
Collections.emptyMap());
+ RangePartition p3 =
+ Partitions.range("p3", Literals.NULL, tomorrowLiteral,
Collections.emptyMap());
+ Transform[] partitioning = {
+ Transforms.range(new String[] {DORIS_COL_NAME4}, new RangePartition[]
{p1, p2, p3})
+ };
+ TableCatalog tableCatalog = catalog.asTableCatalog();
+ tableCatalog.createTable(
+ tableIdentifier,
+ columns,
+ table_comment,
+ properties,
+ partitioning,
+ distribution,
+ null,
+ indexes);
+ Table loadedTable = tableCatalog.loadTable(tableIdentifier);
+ ITUtils.assertionsTableInfo(
+ tableName,
+ table_comment,
+ Arrays.asList(columns),
+ properties,
+ indexes,
+ new Transform[] {Transforms.range(new String[] {DORIS_COL_NAME4})},
+ loadedTable);
+
+ // assert partition info
+ SupportsPartitions tablePartitionOperations =
loadedTable.supportPartitions();
+ Map<String, RangePartition> loadedRangePartitions =
+ Arrays.stream(tablePartitionOperations.listPartitions())
+ .collect(Collectors.toMap(Partition::name, p -> (RangePartition)
p));
+ assertTrue(loadedRangePartitions.size() == 3);
+ assertTrue(loadedRangePartitions.containsKey("p1"));
+ assertPartition(
+ Partitions.range(
+ "p1",
+ todayLiteral,
+ Literals.of("0000-01-01", Types.DateType.get()),
+ Collections.emptyMap()),
+ loadedRangePartitions.get("p1"));
+ assertTrue(loadedRangePartitions.containsKey("p2"));
+ assertPartition(p2, loadedRangePartitions.get("p2"));
+ assertTrue(loadedRangePartitions.containsKey("p3"));
+ assertPartition(
+ Partitions.range(
+ "p3",
+ Literals.of("MAXVALUE", Types.DateType.get()),
+ tomorrowLiteral,
+ Collections.emptyMap()),
+ loadedRangePartitions.get("p3"));
+
+ // create a list-partitioned table with assignments
+ tableName =
GravitinoITUtils.genRandomName("test_create_list_partitioned_table");
+ tableIdentifier = NameIdentifier.of(schemaName, tableName);
+ Literal<Integer> integerLiteral1 = Literals.integerLiteral(1);
+ Literal<Integer> integerLiteral2 = Literals.integerLiteral(2);
+ ListPartition p4 =
+ Partitions.list(
+ "p4",
+ new Literal[][] {{integerLiteral1, todayLiteral},
{integerLiteral1, tomorrowLiteral}},
+ Collections.emptyMap());
+ ListPartition p5 =
+ Partitions.list(
+ "p5",
+ new Literal[][] {{integerLiteral2, todayLiteral},
{integerLiteral2, tomorrowLiteral}},
+ Collections.emptyMap());
+ partitioning =
+ new Transform[] {
+ Transforms.list(
+ new String[][] {{DORIS_COL_NAME1}, {DORIS_COL_NAME4}}, new
ListPartition[] {p4, p5})
+ };
+ tableCatalog.createTable(
+ tableIdentifier,
+ columns,
+ table_comment,
+ properties,
+ partitioning,
+ distribution,
+ null,
+ indexes);
+ loadedTable = tableCatalog.loadTable(tableIdentifier);
+ ITUtils.assertionsTableInfo(
+ tableName,
+ table_comment,
+ Arrays.asList(columns),
+ properties,
+ indexes,
+ new Transform[] {Transforms.list(new String[][] {{DORIS_COL_NAME1},
{DORIS_COL_NAME4}})},
+ loadedTable);
+
+ // assert partition info
+ tablePartitionOperations = loadedTable.supportPartitions();
+ Map<String, ListPartition> loadedListPartitions =
+ Arrays.stream(tablePartitionOperations.listPartitions())
+ .collect(Collectors.toMap(Partition::name, p -> (ListPartition)
p));
+ assertTrue(loadedListPartitions.size() == 2);
+ assertTrue(loadedListPartitions.containsKey("p4"));
+ assertPartition(p4, loadedListPartitions.get("p4"));
+ assertTrue(loadedListPartitions.containsKey("p5"));
+ assertPartition(p5, loadedListPartitions.get("p5"));
+ }
+
@Test
void testNonPartitionedTable() {
// create a non-partitioned table
diff --git
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/operation/TestDorisTableOperations.java
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/operation/TestDorisTableOperations.java
index 62c763f3d..a252a610b 100644
---
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/operation/TestDorisTableOperations.java
+++
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/operation/TestDorisTableOperations.java
@@ -18,7 +18,11 @@
*/
package org.apache.gravitino.catalog.doris.operation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import com.google.common.collect.Maps;
+import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -26,17 +30,27 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import org.apache.gravitino.catalog.doris.converter.DorisTypeConverter;
import org.apache.gravitino.catalog.jdbc.JdbcColumn;
import org.apache.gravitino.catalog.jdbc.JdbcTable;
+import org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter;
+import
org.apache.gravitino.catalog.jdbc.operation.JdbcTablePartitionOperations;
import org.apache.gravitino.integration.test.util.GravitinoITUtils;
import org.apache.gravitino.rel.TableChange;
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.literals.Literal;
+import org.apache.gravitino.rel.expressions.literals.Literals;
import org.apache.gravitino.rel.expressions.transforms.Transform;
import org.apache.gravitino.rel.expressions.transforms.Transforms;
import org.apache.gravitino.rel.indexes.Index;
import org.apache.gravitino.rel.indexes.Indexes;
+import org.apache.gravitino.rel.partitions.ListPartition;
+import org.apache.gravitino.rel.partitions.Partition;
+import org.apache.gravitino.rel.partitions.Partitions;
+import org.apache.gravitino.rel.partitions.RangePartition;
import org.apache.gravitino.rel.types.Type;
import org.apache.gravitino.rel.types.Types;
import org.apache.gravitino.utils.RandomNameUtils;
@@ -48,6 +62,7 @@ import org.testcontainers.shaded.org.awaitility.Awaitility;
@Tag("gravitino-docker-test")
public class TestDorisTableOperations extends TestDoris {
+ private static final JdbcTypeConverter TYPE_CONVERTER = new
DorisTypeConverter();
private static final Type VARCHAR_255 = Types.VarCharType.of(255);
private static final Type VARCHAR_1024 = Types.VarCharType.of(1024);
@@ -111,7 +126,7 @@ public class TestDorisTableOperations extends TestDoris {
distribution,
indexes);
List<String> listTables = TABLE_OPERATIONS.listTables(databaseName);
- Assertions.assertTrue(listTables.contains(tableName));
+ assertTrue(listTables.contains(tableName));
JdbcTable load = TABLE_OPERATIONS.load(databaseName, tableName);
assertionsTableInfo(
tableName, tableComment, columns, properties, indexes,
Transforms.EMPTY_TRANSFORM, load);
@@ -444,7 +459,7 @@ public class TestDorisTableOperations extends TestDoris {
}
@Test
- public void testCreateTableWithPartition() {
+ public void testCreatePartitionedTable() {
String tableComment = "partition_table_comment";
JdbcColumn col1 =
JdbcColumn.builder()
@@ -469,7 +484,19 @@ public class TestDorisTableOperations extends TestDoris {
// create table with range partition
String rangePartitionTableName =
GravitinoITUtils.genRandomName("range_partition_table");
- Transform[] rangePartition = new Transform[] {Transforms.range(new
String[] {col4.name()})};
+ LocalDate today = LocalDate.now();
+ LocalDate tomorrow = today.plusDays(1);
+ Literal<LocalDate> todayLiteral = Literals.dateLiteral(today);
+ Literal<LocalDate> tomorrowLiteral = Literals.dateLiteral(tomorrow);
+ RangePartition rangePartition1 = Partitions.range("p1", todayLiteral,
Literals.NULL, null);
+ RangePartition rangePartition2 = Partitions.range("p2", tomorrowLiteral,
todayLiteral, null);
+ RangePartition rangePartition3 = Partitions.range("p3", Literals.NULL,
tomorrowLiteral, null);
+ Transform[] rangePartition =
+ new Transform[] {
+ Transforms.range(
+ new String[] {col4.name()},
+ new RangePartition[] {rangePartition1, rangePartition2,
rangePartition3})
+ };
TABLE_OPERATIONS.create(
databaseName,
rangePartitionTableName,
@@ -486,13 +513,49 @@ public class TestDorisTableOperations extends TestDoris {
columns,
Collections.emptyMap(),
null,
- rangePartition,
+ new Transform[] {Transforms.range(new String[] {col4.name()})},
rangePartitionTable);
+ // assert partition info
+ JdbcTablePartitionOperations tablePartitionOperations =
+ new DorisTablePartitionOperations(
+ DATA_SOURCE, rangePartitionTable, JDBC_EXCEPTION_CONVERTER,
TYPE_CONVERTER);
+ Map<String, RangePartition> loadedRangePartitions =
+ Arrays.stream(tablePartitionOperations.listPartitions())
+ .collect(Collectors.toMap(Partition::name, p -> (RangePartition)
p));
+ assertTrue(loadedRangePartitions.containsKey("p1"));
+ RangePartition actualP1 = loadedRangePartitions.get("p1");
+ assertEquals(todayLiteral, actualP1.upper());
+ assertEquals(Literals.of("0000-01-01", Types.DateType.get()),
actualP1.lower());
+ assertTrue(loadedRangePartitions.containsKey("p2"));
+ RangePartition actualP2 = loadedRangePartitions.get("p2");
+ assertEquals(tomorrowLiteral, actualP2.upper());
+ assertEquals(todayLiteral, actualP2.lower());
+ assertTrue(loadedRangePartitions.containsKey("p3"));
+ RangePartition actualP3 = loadedRangePartitions.get("p3");
+ assertEquals(Literals.of("MAXVALUE", Types.DateType.get()),
actualP3.upper());
+ assertEquals(tomorrowLiteral, actualP3.lower());
+
// create table with list partition
String listPartitionTableName =
GravitinoITUtils.genRandomName("list_partition_table");
+ Literal<Integer> integerLiteral1 = Literals.integerLiteral(1);
+ Literal<Integer> integerLiteral2 = Literals.integerLiteral(2);
+ ListPartition listPartition1 =
+ Partitions.list(
+ "p1",
+ new Literal[][] {{integerLiteral1, todayLiteral},
{integerLiteral1, tomorrowLiteral}},
+ null);
+ ListPartition listPartition2 =
+ Partitions.list(
+ "p2",
+ new Literal[][] {{integerLiteral2, todayLiteral},
{integerLiteral2, tomorrowLiteral}},
+ null);
Transform[] listPartition =
- new Transform[] {Transforms.list(new String[] {col1.name()}, new
String[] {col4.name()})};
+ new Transform[] {
+ Transforms.list(
+ new String[][] {{col1.name()}, {col4.name()}},
+ new ListPartition[] {listPartition1, listPartition2})
+ };
TABLE_OPERATIONS.create(
databaseName,
listPartitionTableName,
@@ -509,7 +572,19 @@ public class TestDorisTableOperations extends TestDoris {
columns,
Collections.emptyMap(),
null,
- listPartition,
+ new Transform[] {Transforms.list(new String[][] {{col1.name()},
{col4.name()}})},
listPartitionTable);
+
+ // assert partition info
+ tablePartitionOperations =
+ new DorisTablePartitionOperations(
+ DATA_SOURCE, listPartitionTable, JDBC_EXCEPTION_CONVERTER,
TYPE_CONVERTER);
+ Map<String, ListPartition> loadedListPartitions =
+ Arrays.stream(tablePartitionOperations.listPartitions())
+ .collect(Collectors.toMap(Partition::name, p -> (ListPartition) p,
(p1, p2) -> p2));
+ assertTrue(loadedListPartitions.containsKey("p1"));
+ assertTrue(Arrays.deepEquals(listPartition1.lists(),
loadedListPartitions.get("p1").lists()));
+ assertTrue(loadedListPartitions.containsKey("p2"));
+ assertTrue(Arrays.deepEquals(listPartition2.lists(),
loadedListPartitions.get("p2").lists()));
}
}
diff --git
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
index f1428f2b0..26d011af8 100644
---
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
+++
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
@@ -18,13 +18,21 @@
*/
package org.apache.gravitino.catalog.doris.utils;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
+import org.apache.gravitino.rel.expressions.literals.Literal;
+import org.apache.gravitino.rel.expressions.literals.Literals;
import org.apache.gravitino.rel.expressions.transforms.Transform;
import org.apache.gravitino.rel.expressions.transforms.Transforms;
-import org.junit.jupiter.api.Assertions;
+import org.apache.gravitino.rel.partitions.Partition;
+import org.apache.gravitino.rel.partitions.Partitions;
+import org.apache.gravitino.rel.types.Types;
import org.junit.jupiter.api.Test;
public class TestDorisUtils {
@@ -33,17 +41,17 @@ public class TestDorisUtils {
// Test when properties is null
Map<String, String> properties = null;
String result = DorisUtils.generatePropertiesSql(properties);
- Assertions.assertEquals("", result);
+ assertEquals("", result);
// Test when properties is empty
properties = Collections.emptyMap();
result = DorisUtils.generatePropertiesSql(properties);
- Assertions.assertEquals("", result);
+ assertEquals("", result);
// Test when properties has single entry
properties = Collections.singletonMap("key", "value");
result = DorisUtils.generatePropertiesSql(properties);
- Assertions.assertEquals(" PROPERTIES (\n\"key\"=\"value\"\n)", result);
+ assertEquals(" PROPERTIES (\n\"key\"=\"value\"\n)", result);
// Test when properties has multiple entries
properties = new HashMap<>();
@@ -53,7 +61,7 @@ public class TestDorisUtils {
String expectedStr = " PROPERTIES
(\n\"key1\"=\"value1\",\n\"key2\"=\"value2\"\n)";
result = DorisUtils.generatePropertiesSql(properties);
- Assertions.assertEquals(expectedStr, result);
+ assertEquals(expectedStr, result);
}
@Test
@@ -62,27 +70,27 @@ public class TestDorisUtils {
String createTableSql =
"CREATE TABLE `testTable` (\n`testColumn` STRING NOT NULL COMMENT
'test comment'\n) ENGINE=OLAP\nCOMMENT \"test comment\"";
Map<String, String> result =
DorisUtils.extractPropertiesFromSql(createTableSql);
- Assertions.assertTrue(result.isEmpty());
+ assertTrue(result.isEmpty());
// Test when properties exist
createTableSql =
"CREATE TABLE `testTable` (\n`testColumn` STRING NOT NULL COMMENT
'test comment'\n) ENGINE=OLAP\nCOMMENT \"test comment\"\nPROPERTIES
(\n\"test_property\"=\"test_value\"\n)";
result = DorisUtils.extractPropertiesFromSql(createTableSql);
- Assertions.assertEquals("test_value", result.get("test_property"));
+ assertEquals("test_value", result.get("test_property"));
// Test when multiple properties exist
createTableSql =
"CREATE TABLE `testTable` (\n`testColumn` STRING NOT NULL COMMENT
'test comment'\n) ENGINE=OLAP\nCOMMENT \"test comment\"\nPROPERTIES
(\n\"test_property1\"=\"test_value1\",\n\"test_property2\"=\"test_value2\"\n)";
result = DorisUtils.extractPropertiesFromSql(createTableSql);
- Assertions.assertEquals("test_value1", result.get("test_property1"));
- Assertions.assertEquals("test_value2", result.get("test_property2"));
+ assertEquals("test_value1", result.get("test_property1"));
+ assertEquals("test_value2", result.get("test_property2"));
// test when properties has blank
createTableSql =
"CREATE DATABASE `test`\nPROPERTIES (\n\"property1\" =
\"value1\",\n\"comment\"= \"comment\"\n)";
result = DorisUtils.extractPropertiesFromSql(createTableSql);
- Assertions.assertEquals("value1", result.get("property1"));
- Assertions.assertEquals("comment", result.get("comment"));
+ assertEquals("value1", result.get("property1"));
+ assertEquals("comment", result.get("comment"));
}
@Test
@@ -91,27 +99,76 @@ public class TestDorisUtils {
String createTableSql =
"CREATE TABLE `testTable` (\n`col1` date NOT NULL\n) ENGINE=OLAP\n
PARTITION BY RANGE(`col1`)\n()\n DISTRIBUTED BY HASH(`col1`) BUCKETS 2";
Optional<Transform> transform =
DorisUtils.extractPartitionInfoFromSql(createTableSql);
- Assertions.assertTrue(transform.isPresent());
- Assertions.assertEquals(Transforms.range(new String[] {"col1"}),
transform.get());
+ assertTrue(transform.isPresent());
+ assertEquals(Transforms.range(new String[] {"col1"}), transform.get());
// test list partition
createTableSql =
"CREATE TABLE `testTable` (\n`col1` int(11) NOT NULL\n) ENGINE=OLAP\n
PARTITION BY LIST(`col1`)\n()\n DISTRIBUTED BY HASH(`col1`) BUCKETS 2";
transform = DorisUtils.extractPartitionInfoFromSql(createTableSql);
- Assertions.assertTrue(transform.isPresent());
- Assertions.assertEquals(Transforms.list(new String[][] {{"col1"}}),
transform.get());
+ assertTrue(transform.isPresent());
+ assertEquals(Transforms.list(new String[][] {{"col1"}}), transform.get());
// test multi-column list partition
createTableSql =
"CREATE TABLE `testTable` (\n`col1` date NOT NULL,\n`col2` int(11) NOT
NULL\n) ENGINE=OLAP\n PARTITION BY LIST(`col1`, `col2`)\n()\n DISTRIBUTED BY
HASH(`col1`) BUCKETS 2";
transform = DorisUtils.extractPartitionInfoFromSql(createTableSql);
- Assertions.assertTrue(transform.isPresent());
- Assertions.assertEquals(Transforms.list(new String[][] {{"col1"},
{"col2"}}), transform.get());
+ assertTrue(transform.isPresent());
+ assertEquals(Transforms.list(new String[][] {{"col1"}, {"col2"}}),
transform.get());
// test non-partitioned table
createTableSql =
"CREATE TABLE `testTable` (\n`testColumn` STRING NOT NULL COMMENT
'test comment'\n) ENGINE=OLAP\nCOMMENT \"test comment\"";
transform = DorisUtils.extractPartitionInfoFromSql(createTableSql);
- Assertions.assertFalse(transform.isPresent());
+ assertFalse(transform.isPresent());
+ }
+
+ @Test
+ public void testGeneratePartitionSqlFragment() {
+ // test range partition
+ Partition partition = Partitions.range("p1", Literals.NULL, Literals.NULL,
null);
+ String partitionSqlFragment =
DorisUtils.generatePartitionSqlFragment(partition);
+ assertEquals("PARTITION `p1` VALUES LESS THAN MAXVALUE",
partitionSqlFragment);
+
+ partition =
+ Partitions.range(
+ "p2", Literals.of("2024-07-23", Types.DateType.get()),
Literals.NULL, null);
+ partitionSqlFragment = DorisUtils.generatePartitionSqlFragment(partition);
+ assertEquals("PARTITION `p2` VALUES LESS THAN (\"2024-07-23\")",
partitionSqlFragment);
+
+ partition =
+ Partitions.range(
+ "p3",
+ Literals.of("2024-07-24", Types.DateType.get()),
+ Literals.of("2024-07-23", Types.DateType.get()),
+ null);
+ partitionSqlFragment = DorisUtils.generatePartitionSqlFragment(partition);
+ assertEquals(
+ "PARTITION `p3` VALUES [(\"2024-07-23\"), (\"2024-07-24\"))",
partitionSqlFragment);
+
+ partition =
+ Partitions.range(
+ "p4", Literals.NULL, Literals.of("2024-07-24",
Types.DateType.get()), null);
+ partitionSqlFragment = DorisUtils.generatePartitionSqlFragment(partition);
+ assertEquals("PARTITION `p4` VALUES [(\"2024-07-24\"), (MAXVALUE))",
partitionSqlFragment);
+
+ // test list partition
+ Literal[][] p5values = {{Literals.of("2024-07-24", Types.DateType.get())}};
+ partition = Partitions.list("p5", p5values, Collections.emptyMap());
+ partitionSqlFragment = DorisUtils.generatePartitionSqlFragment(partition);
+ assertEquals("PARTITION `p5` VALUES IN (\"2024-07-24\")",
partitionSqlFragment);
+
+ Literal[][] p6values = {{Literals.integerLiteral(1)},
{Literals.integerLiteral(2)}};
+ partition = Partitions.list("p6", p6values, Collections.emptyMap());
+ partitionSqlFragment = DorisUtils.generatePartitionSqlFragment(partition);
+ assertEquals("PARTITION `p6` VALUES IN (\"1\",\"2\")",
partitionSqlFragment);
+
+ Literal[][] p7values = {
+ {Literals.integerLiteral(1), Literals.integerLiteral(2)},
+ {Literals.integerLiteral(3), Literals.integerLiteral(4)}
+ };
+ partition = Partitions.list("p7", p7values, Collections.emptyMap());
+ partitionSqlFragment = DorisUtils.generatePartitionSqlFragment(partition);
+ assertEquals("PARTITION `p7` VALUES IN ((\"1\",\"2\"),(\"3\",\"4\"))",
partitionSqlFragment);
}
}
diff --git
a/integration-test-common/src/test/java/org/apache/gravitino/integration/test/util/ITUtils.java
b/integration-test-common/src/test/java/org/apache/gravitino/integration/test/util/ITUtils.java
index bb97d04a3..596b0c23c 100644
---
a/integration-test-common/src/test/java/org/apache/gravitino/integration/test/util/ITUtils.java
+++
b/integration-test-common/src/test/java/org/apache/gravitino/integration/test/util/ITUtils.java
@@ -35,10 +35,15 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.gravitino.dto.rel.ColumnDTO;
import org.apache.gravitino.dto.rel.expressions.LiteralDTO;
+import org.apache.gravitino.dto.rel.partitions.IdentityPartitionDTO;
+import org.apache.gravitino.dto.rel.partitions.ListPartitionDTO;
+import org.apache.gravitino.dto.rel.partitions.PartitionDTO;
+import org.apache.gravitino.dto.rel.partitions.RangePartitionDTO;
import org.apache.gravitino.rel.Column;
import org.apache.gravitino.rel.Table;
import org.apache.gravitino.rel.expressions.transforms.Transform;
import org.apache.gravitino.rel.indexes.Index;
+import org.apache.gravitino.rel.partitions.Partition;
import org.junit.jupiter.api.Assertions;
public class ITUtils {
@@ -139,5 +144,36 @@ public class ITUtils {
}
}
+ public static void assertPartition(Partition expected, Partition actual) {
+ if (!(expected instanceof PartitionDTO)) {
+ expected = toDTO(expected);
+ }
+ if (!(actual instanceof PartitionDTO)) {
+ actual = toDTO(actual);
+ }
+
+ Assertions.assertEquals(expected.name(), actual.name());
+ Assertions.assertEquals(((PartitionDTO) expected).type(), ((PartitionDTO)
actual).type());
+ if (expected instanceof RangePartitionDTO) {
+ Assertions.assertEquals(
+ ((RangePartitionDTO) expected).upper(), ((RangePartitionDTO)
actual).upper());
+ Assertions.assertEquals(
+ ((RangePartitionDTO) expected).lower(), ((RangePartitionDTO)
actual).lower());
+ } else if (expected instanceof ListPartitionDTO) {
+ Assertions.assertTrue(
+ Arrays.deepEquals(
+ ((ListPartitionDTO) expected).lists(), ((ListPartitionDTO)
actual).lists()));
+ } else if (expected instanceof IdentityPartitionDTO) {
+ Assertions.assertTrue(
+ Arrays.deepEquals(
+ ((IdentityPartitionDTO) expected).fieldNames(),
+ ((IdentityPartitionDTO) actual).fieldNames()));
+ Assertions.assertTrue(
+ Arrays.equals(
+ ((IdentityPartitionDTO) expected).values(),
+ ((IdentityPartitionDTO) actual).values()));
+ }
+ }
+
private ITUtils() {}
}