Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow the SQL Server default keyword as default value for a column #1207

Merged
merged 1 commit into from
Apr 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ abstract class DataTypeProvider {
open fun processForDefaultValue(e: Expression<*>): String = when {
e is LiteralOp<*> -> "$e"
currentDialect is MysqlDialect -> "$e"
currentDialect is SQLServerDialect -> "$e"
else -> "($e)"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,12 @@ open class SQLServerDialect : VendorDialect(dialectName, SQLServerDataTypeProvid
override val supportsSequenceAsGeneratedKeys: Boolean = false
override val supportsOnlyIdentifiersInGeneratedKeys: Boolean = true

override fun isAllowedAsColumnDefault(e: Expression<*>): Boolean = true
private val nonAcceptableDefaults = arrayOf("DEFAULT")

override fun isAllowedAsColumnDefault(e: Expression<*>): Boolean {
val columnDefault = e.toString().toUpperCase().trim()
return columnDefault !in nonAcceptableDefaults
}

override fun modifyColumn(column: Column<*>): String =
super.modifyColumn(column).replace("MODIFY COLUMN", "ALTER COLUMN")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package org.jetbrains.exposed

import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.MatcherAssert.assertThat
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.flushCache
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.dao.id.UUIDTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.`java-time`.*
import org.jetbrains.exposed.sql.statements.BatchDataInconsistentException
Expand All @@ -17,12 +21,12 @@ import org.jetbrains.exposed.sql.tests.shared.assertEqualCollections
import org.jetbrains.exposed.sql.tests.shared.assertEqualLists
import org.jetbrains.exposed.sql.tests.shared.assertEquals
import org.jetbrains.exposed.sql.tests.shared.expectException
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.vendors.MysqlDialect
import org.jetbrains.exposed.sql.vendors.OracleDialect
import org.jetbrains.exposed.sql.vendors.SQLServerDialect
import org.junit.Test
import java.time.*
import java.util.UUID

class DefaultsTest : DatabaseTestsBase() {
object TableWithDBDefault : IntIdTable() {
Expand Down Expand Up @@ -294,4 +298,47 @@ class DefaultsTest : DatabaseTestsBase() {
assertEquals(1, count)
}
}

@Test
fun testDefaultExpressionsForTemporalTable() {

fun databaseGeneratedTimestamp() = object : ExpressionWithColumnType<LocalDateTime>() {
override fun toQueryBuilder(queryBuilder: QueryBuilder) = queryBuilder { +"DEFAULT" }
override val columnType: IColumnType = JavaLocalDateTimeColumnType()
}

val temporalTable = object : UUIDTable("TemporalTable") {
val name = text("name")
val sysStart = datetime("sysStart").defaultExpression(databaseGeneratedTimestamp())
val sysEnd = datetime("sysEnd").defaultExpression(databaseGeneratedTimestamp())
}

withDb(TestDB.SQLSERVER) {
try {
exec("""
CREATE TABLE TemporalTable
(
id uniqueidentifier PRIMARY KEY,
"name" VARCHAR(100) NOT NULL,
sysStart DATETIME2 GENERATED ALWAYS AS ROW START,
sysEnd DATETIME2 GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME ([sysStart], [sysEnd])
)
""".trimIndent())

val names = listOf("name")
val batchInsert: List<ResultRow> =
temporalTable.batchInsert(names, shouldReturnGeneratedValues = true) { name ->
this[temporalTable.name] = "name"
}
val id = batchInsert.first()[temporalTable.id]
val result = temporalTable.select { temporalTable.id eq id }.single()
assertThat(result[temporalTable.name], `is`("name"))
assertThat(result[temporalTable.sysStart], notNullValue())
assertThat(result[temporalTable.sysEnd], notNullValue())
} finally {
SchemaUtils.drop(temporalTable)
}
}
}
}