@@ -11,6 +11,7 @@ import org.apache.arrow.vector.TimeStampSecVector
1111import org.apache.arrow.vector.VectorSchemaRoot
1212import org.apache.arrow.vector.ipc.ArrowFileReader
1313import org.apache.arrow.vector.ipc.ArrowFileWriter
14+ import org.apache.arrow.vector.ipc.ArrowReader
1415import org.apache.arrow.vector.ipc.ArrowStreamReader
1516import org.apache.arrow.vector.ipc.ArrowStreamWriter
1617import org.apache.arrow.vector.types.FloatingPointPrecision
@@ -21,6 +22,9 @@ import org.apache.arrow.vector.types.pojo.FieldType
2122import org.apache.arrow.vector.types.pojo.Schema
2223import org.apache.arrow.vector.util.ByteArrayReadableSeekableByteChannel
2324import org.apache.arrow.vector.util.Text
25+ import org.duckdb.DuckDBConnection
26+ import org.duckdb.DuckDBResultSet
27+ import org.jetbrains.kotlinx.dataframe.AnyFrame
2428import org.jetbrains.kotlinx.dataframe.DataColumn
2529import org.jetbrains.kotlinx.dataframe.DataFrame
2630import org.jetbrains.kotlinx.dataframe.api.NullabilityOptions
@@ -34,12 +38,14 @@ import org.jetbrains.kotlinx.dataframe.api.pathOf
3438import org.jetbrains.kotlinx.dataframe.api.remove
3539import org.jetbrains.kotlinx.dataframe.api.toColumn
3640import org.jetbrains.kotlinx.dataframe.exceptions.TypeConverterNotFoundException
41+ import org.junit.Assert
3742import org.junit.Test
3843import java.io.ByteArrayInputStream
3944import java.io.ByteArrayOutputStream
4045import java.io.File
4146import java.net.URL
4247import java.nio.channels.Channels
48+ import java.sql.DriverManager
4349import java.time.LocalDate
4450import java.time.LocalDateTime
4551import java.time.ZoneOffset
@@ -558,23 +564,26 @@ internal class ArrowKtTest {
558564 }
559565 }
560566
561- @Test
562- fun testArrowReaderExtension () {
567+ private fun expectedSimpleDataFrame (): AnyFrame {
563568 val dates = listOf (
564- LocalDateTime .of(2023 , 11 , 23 , 9 , 30 , 25 ),
569+ LocalDateTime .of(2020 , 11 , 23 , 9 , 30 , 25 ),
565570 LocalDateTime .of(2015 , 5 , 25 , 14 , 20 , 13 ),
566571 LocalDateTime .of(2013 , 6 , 19 , 11 , 20 , 13 ),
567572 LocalDateTime .of(2000 , 1 , 1 , 0 , 0 , 0 )
568573 )
569574
570- val expected = dataFrameOf(
575+ return dataFrameOf(
571576 " string" to listOf (" a" , " b" , " c" , " d" ),
572577 " int" to listOf (1 , 2 , 3 , 4 ),
573578 " float" to listOf (1.0f , 2.0f , 3.0f , 4.0f ),
574579 " double" to listOf (1.0 , 2.0 , 3.0 , 4.0 ),
575580 " datetime" to dates
576581 )
582+ }
577583
584+ @Test
585+ fun testArrowReaderExtension () {
586+ val expected = expectedSimpleDataFrame()
578587 val featherChannel = ByteArrayReadableSeekableByteChannel (expected.saveArrowFeatherToByteArray())
579588 val arrowFileReader = ArrowFileReader (featherChannel, RootAllocator ())
580589 arrowFileReader.toDataFrame() shouldBe expected
@@ -583,4 +592,24 @@ internal class ArrowKtTest {
583592 val arrowStreamReader = ArrowStreamReader (ipcInputStream, RootAllocator ())
584593 arrowStreamReader.toDataFrame() shouldBe expected
585594 }
595+
596+ @Test
597+ fun testDuckDBArrowIntegration () {
598+ val expected = expectedSimpleDataFrame()
599+ val query = """
600+ select 'a' as string, 1 as int, CAST(1.0 as FLOAT) as float, CAST(1.0 as DOUBLE) as double, TIMESTAMP '2020-11-23 09:30:25' as datetime
601+ UNION ALL SELECT 'b', 2, 2.0, 2.0, TIMESTAMP '2015-05-25 14:20:13'
602+ UNION ALL SELECT 'c', 3, 3.0, 3.0, TIMESTAMP '2013-06-19 11:20:13'
603+ UNION ALL SELECT 'd', 4, 4.0, 4.0, TIMESTAMP '2000-01-01 00:00:00'
604+ """ .trimIndent()
605+
606+ Class .forName(" org.duckdb.DuckDBDriver" )
607+ val conn = DriverManager .getConnection(" jdbc:duckdb:" ) as DuckDBConnection
608+ conn.use {
609+ val resultSet = it.createStatement().executeQuery(query) as DuckDBResultSet
610+ val dbArrowReader = resultSet.arrowExportStream(RootAllocator (), 256 ) as ArrowReader
611+ Assert .assertTrue(dbArrowReader.javaClass.name.equals(" org.apache.arrow.c.ArrowArrayStreamReader" ))
612+ DataFrame .readArrow(dbArrowReader) shouldBe expected
613+ }
614+ }
586615}
0 commit comments