diff --git a/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/FullyQualifiedTableName.java b/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/FullyQualifiedTableName.java index 5a9fe4d31f..6ed3b7447e 100644 --- a/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/FullyQualifiedTableName.java +++ b/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/FullyQualifiedTableName.java @@ -5,6 +5,9 @@ package org.opensearch.sql.spark.dispatcher.model; +import static org.apache.commons.lang3.StringUtils.strip; +import static org.opensearch.sql.spark.dispatcher.model.IndexQueryDetails.STRIP_CHARS; + import java.util.Arrays; import lombok.Data; import lombok.NoArgsConstructor; @@ -40,4 +43,27 @@ public FullyQualifiedTableName(String fullyQualifiedName) { tableName = parts[0]; } } + + /** + * Convert qualified name to Flint name concat by underscore. + * + * @return Flint name + */ + public String toFlintName() { + StringBuilder builder = new StringBuilder(); + if (datasourceName != null) { + builder + .append(strip(datasourceName, STRIP_CHARS)) + .append("_"); + } + if (schemaName != null) { + builder + .append(strip(schemaName, STRIP_CHARS)) + .append("_"); + } + if (tableName != null) { + builder.append(strip(tableName, STRIP_CHARS)); + } + return builder.toString(); + } } diff --git a/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/IndexQueryDetails.java b/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/IndexQueryDetails.java index 5b4326a10e..961071fa12 100644 --- a/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/IndexQueryDetails.java +++ b/spark/src/main/java/org/opensearch/sql/spark/dispatcher/model/IndexQueryDetails.java @@ -5,6 +5,8 @@ package org.opensearch.sql.spark.dispatcher.model; +import static org.apache.commons.lang3.StringUtils.strip; + import lombok.EqualsAndHashCode; import lombok.Getter; import org.apache.commons.lang3.StringUtils; @@ -83,32 +85,19 @@ public String openSearchIndexName() { switch (getIndexType()) { case COVERING: indexName = - "flint" - + "_" - + StringUtils.strip(fullyQualifiedTableName.getDatasourceName(), STRIP_CHARS) - + "_" - + StringUtils.strip(fullyQualifiedTableName.getSchemaName(), STRIP_CHARS) - + "_" - + StringUtils.strip(fullyQualifiedTableName.getTableName(), STRIP_CHARS) - + "_" - + StringUtils.strip(getIndexName(), STRIP_CHARS) - + "_" + "flint_" + + fullyQualifiedTableName.toFlintName() + "_" + + strip(getIndexName(), STRIP_CHARS) + "_" + getIndexType().getSuffix(); break; case SKIPPING: indexName = - "flint" - + "_" - + StringUtils.strip(fullyQualifiedTableName.getDatasourceName(), STRIP_CHARS) - + "_" - + StringUtils.strip(fullyQualifiedTableName.getSchemaName(), STRIP_CHARS) - + "_" - + StringUtils.strip(fullyQualifiedTableName.getTableName(), STRIP_CHARS) - + "_" + "flint_" + + fullyQualifiedTableName.toFlintName() + "_" + getIndexType().getSuffix(); break; case MATERIALIZED_VIEW: - indexName = "flint" + "_" + StringUtils.strip(getMvName(), STRIP_CHARS).toLowerCase(); + indexName = "flint_" + new FullyQualifiedTableName(mvName).toFlintName(); break; } return indexName.toLowerCase(); diff --git a/spark/src/test/java/org/opensearch/sql/spark/flint/IndexQueryDetailsTest.java b/spark/src/test/java/org/opensearch/sql/spark/flint/IndexQueryDetailsTest.java index e725ddc21e..6299dee0ca 100644 --- a/spark/src/test/java/org/opensearch/sql/spark/flint/IndexQueryDetailsTest.java +++ b/spark/src/test/java/org/opensearch/sql/spark/flint/IndexQueryDetailsTest.java @@ -26,4 +26,81 @@ public void skippingIndexName() { .build() .openSearchIndexName()); } + + @Test + public void coveringIndexName() { + assertEquals( + "flint_mys3_default_http_logs_idx_status_index", + IndexQueryDetails.builder() + .indexName("idx_status") + .fullyQualifiedTableName(new FullyQualifiedTableName("mys3.default.http_logs")) + .indexType(FlintIndexType.COVERING) + .build() + .openSearchIndexName()); + } + + @Test + public void materializedViewIndexName() { + assertEquals( + "flint_mys3_default_http_logs_metrics", + IndexQueryDetails.builder() + .mvName("mys3.default.http_logs_metrics") + .indexType(FlintIndexType.MATERIALIZED_VIEW) + .build() + .openSearchIndexName()); + } + + @Test + public void materializedViewIndexNameWithBackticks() { + assertEquals( + "flint_mys3_default_http_logs_metrics", + IndexQueryDetails.builder() + .mvName("`mys3`.`default`.`http_logs_metrics`") + .indexType(FlintIndexType.MATERIALIZED_VIEW) + .build() + .openSearchIndexName()); + } + + @Test + public void materializedViewIndexNameWithDots() { + assertEquals( + "flint_mys3_default_http_logs_metrics.1026", + IndexQueryDetails.builder() + .mvName("`mys3`.`default`.`http_logs_metrics.1026`") + .indexType(FlintIndexType.MATERIALIZED_VIEW) + .build() + .openSearchIndexName()); + } + + @Test + public void materializedViewIndexNameWithDotsInCatalogName() { + // FIXME: should not use ctx.getText which is hard to split + assertEquals( + "flint_mys3_1026_default`.`http_logs_metrics", + IndexQueryDetails.builder() + .mvName("`mys3.1026`.`default`.`http_logs_metrics`") + .indexType(FlintIndexType.MATERIALIZED_VIEW) + .build() + .openSearchIndexName()); + } + + @Test + public void materializedViewIndexNameNotFullyQualified() { + // Normally this should not happen and can add precondition check once confirmed. + assertEquals( + "flint_default_http_logs_metrics", + IndexQueryDetails.builder() + .mvName("default.http_logs_metrics") + .indexType(FlintIndexType.MATERIALIZED_VIEW) + .build() + .openSearchIndexName()); + + assertEquals( + "flint_http_logs_metrics", + IndexQueryDetails.builder() + .mvName("http_logs_metrics") + .indexType(FlintIndexType.MATERIALIZED_VIEW) + .build() + .openSearchIndexName()); + } }