diff --git a/exposed-jdbc/src/main/kotlin/org/jetbrains/exposed/sql/statements/jdbc/JdbcPreparedStatementImpl.kt b/exposed-jdbc/src/main/kotlin/org/jetbrains/exposed/sql/statements/jdbc/JdbcPreparedStatementImpl.kt index d21bb694a9..05c51b5091 100644 --- a/exposed-jdbc/src/main/kotlin/org/jetbrains/exposed/sql/statements/jdbc/JdbcPreparedStatementImpl.kt +++ b/exposed-jdbc/src/main/kotlin/org/jetbrains/exposed/sql/statements/jdbc/JdbcPreparedStatementImpl.kt @@ -5,12 +5,15 @@ import org.jetbrains.exposed.sql.BlobColumnType import org.jetbrains.exposed.sql.IColumnType import org.jetbrains.exposed.sql.statements.StatementResult import org.jetbrains.exposed.sql.statements.api.PreparedStatementApi +import java.io.ByteArrayInputStream +import java.io.FileInputStream import org.jetbrains.exposed.sql.vendors.SQLiteDialect import org.jetbrains.exposed.sql.vendors.currentDialect import java.io.InputStream import java.sql.PreparedStatement import java.sql.ResultSet import java.sql.Statement +import java.sql.SQLFeatureNotSupportedException import java.sql.Types /** @@ -80,7 +83,25 @@ class JdbcPreparedStatementImpl( } override fun setInputStream(index: Int, inputStream: InputStream) { - statement.setBinaryStream(index, inputStream, inputStream.available()) + try { + when { + // streams with known length where available matches the actual length + inputStream is ByteArrayInputStream -> + statement.setBinaryStream(index, inputStream, inputStream.available()) + + // FileInputStream.available() returns returns Int.MAX_VALUE + // if the underlying file is larger than 2GB + inputStream is FileInputStream && inputStream.available() < Int.MAX_VALUE -> + statement.setBinaryStream(index, inputStream, inputStream.available()) + + // default handling for unknown length + else -> statement.setBinaryStream(index, inputStream) + + } + } catch (e: SQLFeatureNotSupportedException) { + // fallback to bytes + statement.setBytes(index, inputStream.readBytes()) + } } override fun setArray(index: Int, type: String, array: Array<*>) { diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt index 89ddab0fcd..620a49e469 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt @@ -25,6 +25,8 @@ import org.jetbrains.exposed.sql.vendors.SQLiteDialect import org.junit.Assume import org.junit.Test import org.postgresql.util.PGobject +import java.io.ByteArrayInputStream +import java.io.SequenceInputStream import java.util.* import kotlin.random.Random import kotlin.test.assertNotNull @@ -612,7 +614,12 @@ class DDLTests : DatabaseTestsBase() { val shortBytes = "Hello there!".toByteArray() val longBytes = Random.nextBytes(1024) val shortBlob = ExposedBlob(shortBytes) - val longBlob = ExposedBlob(longBytes) + val longBlob = ExposedBlob( + inputStream = SequenceInputStream( + ByteArrayInputStream(longBytes, 0, 512), + ByteArrayInputStream(longBytes, 512, 512) + ) + ) val id1 = t.insert { it[t.b] = shortBlob