diff --git a/src/main/java/com/kingsrook/qbits/objectstorage/model/ObjectStorageSchema.java b/src/main/java/com/kingsrook/qbits/objectstorage/model/ObjectStorageSchema.java
index 896afe2..aa0228b 100644
--- a/src/main/java/com/kingsrook/qbits/objectstorage/model/ObjectStorageSchema.java
+++ b/src/main/java/com/kingsrook/qbits/objectstorage/model/ObjectStorageSchema.java
@@ -52,14 +52,17 @@ public final class ObjectStorageSchema
ObjectStorageTables.OBJECT, List.of(List.of("bucketId", "objectKey")),
ObjectStorageTables.USAGE_DAILY, List.of(List.of("bucketId", "snapshotDate")));
- /** Browse and lookup indexes: table to column lists. */
+ /** Browse and lookup indexes: table to column lists. New entries go at the end of
+ ** a table's list, so the generated names (ix_
_) of existing ones never change.
+ ** The child lists on record pages (folder -> objects, object -> versions and references)
+ ** filter on the parent id alone, so those columns lead an index of their own. */
private static final Map>> INDEXES = Map.of(
ObjectStorageTables.OBJECT, List.of(List.of("bucketId", "folderId"), List.of("bucketId", "lastModified"), List.of("bucketId", "size"), List.of("bucketId", "contentType"),
- List.of("bucketId", "deleted", "referenceCount"), List.of("bucketId", "headersKnown", "deleted")),
- ObjectStorageTables.OBJECT_REFERENCE, List.of(List.of("bucketId", "objectId"), List.of("bucketId", "missing")),
+ List.of("bucketId", "deleted", "referenceCount"), List.of("bucketId", "headersKnown", "deleted"), List.of("folderId")),
+ ObjectStorageTables.OBJECT_REFERENCE, List.of(List.of("bucketId", "objectId"), List.of("bucketId", "missing"), List.of("objectId")),
ObjectStorageTables.OPERATION, List.of(List.of("bucketId", "occurredAt"), List.of("objectKey", "occurredAt")),
ObjectStorageTables.FOLDER, List.of(List.of("parentFolderId")),
- ObjectStorageTables.OBJECT_VERSION, List.of(List.of("bucketId", "objectKey")));
+ ObjectStorageTables.OBJECT_VERSION, List.of(List.of("bucketId", "objectKey"), List.of("objectId")));
diff --git a/src/test/java/com/kingsrook/qbits/objectstorage/internal/TablesAndConfigTest.java b/src/test/java/com/kingsrook/qbits/objectstorage/internal/TablesAndConfigTest.java
index dafb2bd..67ced67 100644
--- a/src/test/java/com/kingsrook/qbits/objectstorage/internal/TablesAndConfigTest.java
+++ b/src/test/java/com/kingsrook/qbits/objectstorage/internal/TablesAndConfigTest.java
@@ -129,6 +129,25 @@ class TablesAndConfigTest
+ /*******************************************************************************
+ ** The record-page child lists filter on the parent id alone (folder ->
+ ** objects, object -> versions and references), so the generated schema
+ ** gives each of those columns its own index, appended so existing generated
+ ** index names keep their numbers.
+ *******************************************************************************/
+ @Test
+ void testChildListColumnsAreIndexed()
+ {
+ String schema = String.join("\n", com.kingsrook.qbits.objectstorage.model.ObjectStorageSchema.postgresStatements(new ObjectStorageQBitConfig().withBackendName("rdbms")));
+ assertThat(schema)
+ .contains("ix_object_storage_object_1 ON object_storage_object (bucket_id, folder_id)")
+ .contains("ix_object_storage_object_7 ON object_storage_object (folder_id)")
+ .contains("ix_object_storage_object_version_2 ON object_storage_object_version (object_id)")
+ .contains("ix_object_storage_object_reference_3 ON object_storage_object_reference (object_id)");
+ }
+
+
+
/*******************************************************************************
** Owner naming rules: every table is lowercase snake_case with the full qbit
** name as prefix; no table has a field that could hold a secret value; the nav