Skip to content

Commit

Permalink
feat: EXPOSED-66 Extend partial index to SQLServer and SQLite
Browse files Browse the repository at this point in the history
If creation of a partial index was attempted using a dialect that doesn't support
it, the filter condition was being ignored and a full index was being created
instead. This has been switched so that no index at all is created, which is
more consistent with existing behavior (e.g. if a typed index is attempted in
an unsupporting dialect, the index is also not created). A warning is also logged.

Test names changed to be more descriptive and internal test function renamed
to be consistent with Table property 'indices'.
  • Loading branch information
bog-walk committed Jun 19, 2023
1 parent c9f175d commit 5fe401b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1065,20 +1065,38 @@ abstract class VendorDialect(
resetCaches()
}

fun filterCondition(index: Index): String? {
/*fun filterCondition(index: Index): String? {
return when (currentDialect) {
is PostgreSQLDialect, is SQLServerDialect, is SQLiteDialect -> {
index.filterCondition?.let {
QueryBuilder(false)
.append(" WHERE ").append(it)
.toString()
}
} ?: ""
}
else -> {
exposedLogger.warn("Index creation with a filter condition is not supported in ${currentDialect.name}")
null
index.filterCondition?.let {
exposedLogger.warn("Index creation with a filter condition is not supported in ${currentDialect.name}")
return null
} ?: ""
}
}
}*/

fun filterCondition(index: Index): String? {
return index.filterCondition?.let {
when (currentDialect) {
is PostgreSQLDialect, is SQLServerDialect, is SQLiteDialect -> {
QueryBuilder(false)
.append(" WHERE ").append(it)
.toString()
}
else -> {
exposedLogger.warn("Index creation with a filter condition is not supported in ${currentDialect.name}")
return null
}
}
} ?: ""
}

/**
Expand All @@ -1094,7 +1112,7 @@ abstract class VendorDialect(
val quotedIndexName = t.db.identifierManager.cutIfNecessaryAndQuote(index.indexName)
val columnsList = index.columns.joinToString(prefix = "(", postfix = ")") { t.identity(it) }

val maybeFilterCondition = filterCondition(index) ?: ""
val maybeFilterCondition = filterCondition(index) ?: return ""

return when {
// unique and no filter -> constraint, the type is not supported
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class CreateIndexTests : DatabaseTestsBase() {


@Test
fun testPartialIndex01() {
fun testCreateAndDropPartialIndexWithPostgres() {
val partialIndexTable = object : IntIdTable("PartialIndexTableTest") {
val name = varchar("name", 50)
val value = integer("value")
Expand Down Expand Up @@ -134,7 +134,7 @@ class CreateIndexTests : DatabaseTestsBase() {
kotlin.test.assertEquals(totalIndexCount, 3, "Indexes expected to be created")
}

fun getIndexes(): List<Index> {
fun getIndices(): List<Index> {
db.dialect.resetCaches()
return currentDialect.existingIndices(partialIndexTable)[partialIndexTable].orEmpty()
}
Expand All @@ -146,13 +146,13 @@ class CreateIndexTests : DatabaseTestsBase() {

execInBatch(listOf(dropUniqueConstraint, dropIndex))

assertEquals(getIndexes().size, 1)
assertEquals(getIndices().size, 1)
SchemaUtils.drop(partialIndexTable)
}
}

@Test
fun testPartialIndex02() {
fun testCreateAndDropPartialIndex() {
val tester = object : Table("tester") {
val name = varchar("name", 32).uniqueIndex()
val age = integer("age")
Expand All @@ -179,19 +179,19 @@ class CreateIndexTests : DatabaseTestsBase() {

assertEquals(2, tester.indices.count { it.filterCondition != null })

fun getIndexes(): List<Index> {
fun getIndices(): List<Index> {
db.dialect.resetCaches()
return currentDialect.existingIndices(tester)[tester].orEmpty()
}

var indices = getIndexes()
var indices = getIndices()
assertEquals(3, indices.size)

val uniqueWithPartial = Index(listOf(tester.team), true, "team_only_index", null, Op.TRUE).dropStatement().first()
val dropStatements = indices.map { it.dropStatement().first() }
expect(Unit) { execInBatch(dropStatements + uniqueWithPartial) }

indices = getIndexes()
indices = getIndices()
assertEquals(0, indices.size)

// test for non-unique partial index with type
Expand All @@ -211,4 +211,27 @@ class CreateIndexTests : DatabaseTestsBase() {
SchemaUtils.drop(tester)
}
}

@Test
fun testPartialIndexNotCreated() {
val tester = object : Table("tester") {
val age = integer("age")

init {
index("age_index", false, age) { age greaterEq 10 }
}
}

withTables(tester) {
SchemaUtils.createMissingTablesAndColumns()
assertTrue(tester.exists())

val expectedIndexCount = when (currentDialectTest) {
is PostgreSQLDialect, is SQLServerDialect, is SQLiteDialect -> 1
else -> 0
}
val actualIndexCount = currentDialectTest.existingIndices(tester)[tester].orEmpty().size
assertEquals(expectedIndexCount, actualIndexCount)
}
}
}

0 comments on commit 5fe401b

Please sign in to comment.