Skip to content

Commit f3207db

Browse files
g-sg-vSergei Galiamichev
andauthored
noticket: Support ASYNC secondary indexes
Co-authored-by: Sergei Galiamichev <gsv@nebius.com>
1 parent 06bd8ec commit f3207db

File tree

8 files changed

+39
-14
lines changed

8 files changed

+39
-14
lines changed

databind/src/main/java/tech/ydb/yoj/databind/schema/GlobalIndex.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
enum Type {
4040
GLOBAL,
41+
GLOBAL_ASYNC,
4142
UNIQUE
4243
}
4344
}

databind/src/main/java/tech/ydb/yoj/databind/schema/Schema.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.google.common.base.Preconditions;
55
import com.google.common.collect.Lists;
66
import lombok.AllArgsConstructor;
7+
import lombok.Builder;
78
import lombok.Getter;
89
import lombok.NonNull;
910
import lombok.SneakyThrows;
@@ -186,7 +187,12 @@ name, getType(), fieldPath)
186187
}
187188
columns.add(field.getName());
188189
}
189-
outputIndexes.add(new Index(name, List.copyOf(columns), index.type() == GlobalIndex.Type.UNIQUE));
190+
outputIndexes.add(Index.builder()
191+
.indexName(name)
192+
.fieldNames(List.copyOf(columns))
193+
.unique(index.type() == GlobalIndex.Type.UNIQUE)
194+
.async(index.type() == GlobalIndex.Type.GLOBAL_ASYNC)
195+
.build());
190196
}
191197
return outputIndexes;
192198
}
@@ -831,9 +837,10 @@ public FieldValueType getFieldValueType() {
831837

832838
@Value
833839
@AllArgsConstructor
840+
@Builder
834841
public static class Index {
835842
public Index(@NonNull String indexName, @NonNull List<String> fieldNames) {
836-
this(indexName, fieldNames, false);
843+
this(indexName, fieldNames, false, false);
837844
}
838845

839846
@NonNull
@@ -844,6 +851,8 @@ public Index(@NonNull String indexName, @NonNull List<String> fieldNames) {
844851
List<String> fieldNames;
845852

846853
boolean unique;
854+
855+
boolean async;
847856
}
848857

849858
@Value

repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/client/YdbSchemaOperations.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ public void createTable(String name, List<EntitySchema.JavaField> columns, List<
107107
globalIndexes.forEach(index -> {
108108
if (index.isUnique()) {
109109
builder.addGlobalUniqueIndex(index.getIndexName(), index.getFieldNames());
110+
} else if (index.isAsync()) {
111+
builder.addGlobalAsyncIndex(index.getIndexName(), index.getFieldNames());
110112
} else {
111113
builder.addGlobalIndex(index.getIndexName(), index.getFieldNames());
112114
}
@@ -223,7 +225,7 @@ public Table describeTable(String name, List<EntitySchema.JavaField> columns, Li
223225
})
224226
.toList();
225227
List<Index> ydbIndexes = indexes.stream()
226-
.map(i -> new Index(i.getIndexName(), i.getFieldNames(), i.isUnique()))
228+
.map(i -> new Index(i.getIndexName(), i.getFieldNames(), i.isUnique(), i.isAsync()))
227229
.toList();
228230
TtlModifier tableTtl = ttlModifier == null
229231
? null
@@ -342,7 +344,7 @@ private Table describeTableInternal(String path) {
342344
})
343345
.toList(),
344346
table.getIndexes().stream()
345-
.map(i -> new Index(i.getName(), i.getColumns(), i.getType() == TableIndex.Type.GLOBAL_UNIQUE))
347+
.map(i -> new Index(i.getName(), i.getColumns(), i.getType() == TableIndex.Type.GLOBAL_UNIQUE, i.getType() == TableIndex.Type.GLOBAL_ASYNC))
346348
.toList(),
347349
table.getTableTtl() == null || table.getTableTtl().getTtlMode() == TableTtl.TtlMode.NOT_SET
348350
? null
@@ -484,6 +486,7 @@ public static class Index {
484486
String name;
485487
List<String> columns;
486488
boolean unique;
489+
boolean async;
487490
}
488491

489492
@Value

repository-ydb-v2/src/main/java/tech/ydb/yoj/repository/ydb/compatibility/YdbSchemaCompatibilityChecker.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ private static String builderDDLPrimaryKey(YdbSchemaOperations.Table table) {
292292

293293
private static String builderDDLIndexes(YdbSchemaOperations.Table table) {
294294
return table.getIndexes().stream()
295-
.map(idx -> "\t\t.addGlobalIndex(" + javaLiteral(idx.getName()) + ", " +
295+
.map(idx -> (idx.isAsync() ? "\t\t.addGlobalAsyncIndex(" : "\t\t.addGlobalIndex(") + javaLiteral(idx.getName()) + ", " +
296296
idx.getColumns().stream()
297297
.map(YdbSchemaCompatibilityChecker::javaLiteral)
298298
.collect(joining(", "))
@@ -352,8 +352,13 @@ private static String indexes(YdbSchemaOperations.Table table) {
352352
return "\n";
353353
}
354354
return ",\n" + indexes.stream()
355-
.map(idx -> "\tINDEX `" + idx.getName() + "` GLOBAL " + (idx.isUnique() ? "UNIQUE " : "") + "ON (" + indexColumns(idx.getColumns()) + ")")
356-
.collect(Collectors.joining(",\n")) + "\n";
355+
.map(idx -> "\t" + indexStatement(idx))
356+
.collect(Collectors.joining(",\n")) + "\n";
357+
}
358+
359+
private static String indexStatement(YdbSchemaOperations.Index idx) {
360+
return String.format("INDEX `%s` GLOBAL %sON (%s)",
361+
idx.getName(), idx.isUnique() ? "UNIQUE " : idx.isAsync() ? "ASYNC " : "", indexColumns(idx.getColumns()));
357362
}
358363

359364
private static String indexColumns(List<String> columns) {
@@ -408,9 +413,7 @@ private void makeMigrationTableIndexInstructions(YdbSchemaOperations.Table from,
408413
.collect(toMap(YdbSchemaOperations.Index::getName, Function.identity()));
409414

410415
Function<YdbSchemaOperations.Index, String> createIndex = i ->
411-
String.format("ALTER TABLE `%s` ADD INDEX `%s` GLOBAL " + (i.isUnique() ? "UNIQUE " : "") + "ON (%s);",
412-
to.getName(), i.getName(), i.getColumns().stream().map(c -> "`" + c + "`").collect(joining(","))
413-
);
416+
String.format("ALTER TABLE `%s` ADD %s;", to.getName(), indexStatement(i));
414417

415418
Function<YdbSchemaOperations.Index, String> dropIndex = i ->
416419
String.format("ALTER TABLE `%s` DROP INDEX `%s`;", from.getName(), i.getName());

repository-ydb-v2/src/test/java/tech/ydb/yoj/repository/ydb/YdbRepositoryIntegrationTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,8 @@ public void testCompatibilityNewIndexedTable() {
797797
"\tPRIMARY KEY(`version_id`),\n" +
798798
"\tINDEX `key_index` GLOBAL ON (`key_id`),\n" +
799799
"\tINDEX `value_index` GLOBAL ON (`value_id`,`valueId2`),\n" +
800-
"\tINDEX `key2_index` GLOBAL ON (`key_id`,`valueId2`)\n" +
800+
"\tINDEX `key2_index` GLOBAL ON (`key_id`,`valueId2`),\n" +
801+
"\tINDEX `key3_index` GLOBAL ASYNC ON (`key_id`,`value_id`)\n" +
801802
");",
802803
ts);
803804
Assert.assertEquals(expected, checker.getShouldExecuteMessages().get(0));

repository-ydb-v2/src/test/java/tech/ydb/yoj/repository/ydb/YqlTypeLegacyTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,13 @@ public void testGlobalIndexSimple() {
212212
public void testGlobalIndexMultiIndex() {
213213
var schema = ObjectSchema.of(GlobalIndexMultiIndex.class);
214214
Assert.assertEquals(List.of(
215-
new Schema.Index("idx1", List.of("id_id1", "id_3")),
216-
new Schema.Index("idx2", List.of("id_2", "id_3"), true)),
215+
Schema.Index.builder().indexName("idx1")
216+
.fieldNames(List.of("id_id1", "id_3"))
217+
.build(),
218+
Schema.Index.builder().indexName("idx2")
219+
.fieldNames(List.of("id_2", "id_3"))
220+
.unique(true)
221+
.build()),
217222
schema.getGlobalIndexes());
218223
}
219224

repository-ydb-v2/src/test/java/tech/ydb/yoj/repository/ydb/YqlTypeRecommendedTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ public void testGlobalIndexMultiIndex() {
213213
var schema = ObjectSchema.of(GlobalIndexMultiIndex.class);
214214
Assert.assertEquals(List.of(
215215
new Schema.Index("idx1", List.of("id_id1", "id_3")),
216-
new Schema.Index("idx2", List.of("id_2", "id_3"), true)),
216+
new Schema.Index("idx2", List.of("id_2", "id_3"), true, false),
217+
new Schema.Index("idx3", List.of("id_3"), false, true)),
217218
schema.getGlobalIndexes());
218219
}
219220

@@ -367,6 +368,7 @@ public static class Id implements Entity.Id<GlobalIndexSimple> {
367368

368369
@GlobalIndex(name = "idx1", fields = {"id.id1", "id3"})
369370
@GlobalIndex(name = "idx2", fields = {"id.id2", "id3"}, type = GlobalIndex.Type.UNIQUE)
371+
@GlobalIndex(name = "idx3", fields = {"id3"}, type = GlobalIndex.Type.GLOBAL_ASYNC)
370372
@AllArgsConstructor
371373
public static class GlobalIndexMultiIndex implements Entity<GlobalIndexMultiIndex> {
372374
Id id;

repository-ydb-v2/src/test/java/tech/ydb/yoj/repository/ydb/model/IndexedEntityNew.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
@GlobalIndex(name = "key_index", fields = {"keyId"})
1111
@GlobalIndex(name = "value_index", fields = {"valueId", "valueId2"})
1212
@GlobalIndex(name = "key2_index", fields = {"keyId", "valueId2"})
13+
@GlobalIndex(name = "key3_index", fields = {"keyId", "valueId"}, type = GlobalIndex.Type.GLOBAL_ASYNC)
1314
@Table(name = "new_table_with_indexes")
1415
public class IndexedEntityNew implements Entity<IndexedEntityNew> {
1516
@Column(name = "version_id")

0 commit comments

Comments
 (0)