Skip to content

Commit

Permalink
Add H2 version 2.0.202 dialect / Fixes for bitwise operations
Browse files Browse the repository at this point in the history
  • Loading branch information
Tapac committed Dec 20, 2021
1 parent 5b88af0 commit 89105b0
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Op.kt
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,11 @@ class ModOp<T : Number?, S : Number?>(
}
}


// https://github.com/h2database/h2database/issues/3253
private fun <T> ExpressionWithColumnType<T>.castToExpressionTypeForH2BitWiseIps(e: Expression<out T>) =
if (e !is Column<*> && e !is LiteralOp<*>) e.castTo(columnType) else e

/**
* Represents an SQL operator that performs a bitwise `and` on [expr1] and [expr2].
*/
Expand All @@ -311,8 +316,14 @@ class AndBitOp<T, S : T>(
override val columnType: IColumnType
) : ExpressionWithColumnType<T>() {
override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder {
when (currentDialectIfAvailable) {
is OracleDialect, is H2Dialect -> append("BITAND(", expr1, ", ", expr2, ")")
when (val dialect = currentDialectIfAvailable) {
is OracleDialect -> append("BITAND(", expr1, ", ", expr2, ")")
is H2Dialect -> {
when (dialect.isSecondVersion) {
false -> append("BITAND(", expr1, ", ", expr2, ")")
true -> append("BITAND(", castToExpressionTypeForH2BitWiseIps(expr1), ", ", castToExpressionTypeForH2BitWiseIps(expr2), ")")
}
}
else -> append('(', expr1, " & ", expr2, ')')
}
}
Expand All @@ -330,10 +341,15 @@ class OrBitOp<T, S : T>(
override val columnType: IColumnType
) : ExpressionWithColumnType<T>() {
override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder {
when (currentDialectIfAvailable) {
when (val dialect = currentDialectIfAvailable) {
// Oracle doesn't natively support bitwise OR, thus emulate it with 'and'
is OracleDialect -> append("(", expr1, "+", expr2, "-", AndBitOp(expr1, expr2, columnType), ")")
is H2Dialect -> append("BITOR(", expr1, ", ", expr2, ")")
is H2Dialect -> {
when (dialect.isSecondVersion) {
false -> append("BITOR(", expr1, ", ", expr2, ")")
true -> append("BITOR(", castToExpressionTypeForH2BitWiseIps(expr1), ", ", castToExpressionTypeForH2BitWiseIps(expr2), ")")
}
}
else -> append('(', expr1, " | ", expr2, ')')
}
}
Expand All @@ -351,13 +367,18 @@ class XorBitOp<T, S : T>(
override val columnType: IColumnType
) : ExpressionWithColumnType<T>() {
override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder {
when (currentDialectIfAvailable) {
when (val dialect = currentDialectIfAvailable) {
// Oracle and SQLite don't natively support bitwise XOR, thus emulate it with 'or' and 'and'
is OracleDialect, is SQLiteDialect -> append(
"(", OrBitOp(expr1, expr2, columnType), "-", AndBitOp(expr1, expr2, columnType), ")"
)
is PostgreSQLDialect -> append('(', expr1, " # ", expr2, ')')
is H2Dialect -> append("BITXOR(", expr1, ", ", expr2, ")")
is H2Dialect -> {
when (dialect.isSecondVersion) {
false -> append("BITXOR(", expr1, ", ", expr2, ")")
true -> append("BITXOR(", castToExpressionTypeForH2BitWiseIps(expr1), ", ", castToExpressionTypeForH2BitWiseIps(expr2), ")")
}
}
else -> append('(', expr1, " ^ ", expr2, ')')
}
}
Expand Down Expand Up @@ -391,7 +412,6 @@ class RegexpOp<T : String?>(
}
}


// Subquery Expressions

/**
Expand Down

0 comments on commit 89105b0

Please sign in to comment.