|
1 | 1 | use std::{convert, ffi::c_void, fmt, mem, os::raw::c_char, ptr, str};
|
2 | 2 |
|
3 |
| -use arrow::{array::StructArray, datatypes::DataType}; |
| 3 | +use arrow::{array::StructArray, datatypes::SchemaRef}; |
4 | 4 |
|
5 | 5 | use super::{ffi, AndThenRows, Connection, Error, MappedRows, Params, RawStatement, Result, Row, Rows, ValueRef};
|
6 | 6 | #[cfg(feature = "polars")]
|
@@ -452,6 +452,15 @@ impl Statement<'_> {
|
452 | 452 | Rows::new(self)
|
453 | 453 | }
|
454 | 454 |
|
| 455 | + /// Returns the underlying schema of the prepared statement. |
| 456 | + /// |
| 457 | + /// # Caveats |
| 458 | + /// Panics if the query has not been [`execute`](Statement::execute)d yet. |
| 459 | + #[inline] |
| 460 | + pub fn schema(&self) -> SchemaRef { |
| 461 | + self.stmt.schema() |
| 462 | + } |
| 463 | + |
455 | 464 | // generic because many of these branches can constant fold away.
|
456 | 465 | fn bind_parameter<P: ?Sized + ToSql>(&self, param: &P, col: usize) -> Result<()> {
|
457 | 466 | let value = param.to_sql()?;
|
@@ -542,12 +551,6 @@ impl Statement<'_> {
|
542 | 551 | pub(super) fn new(conn: &Connection, stmt: RawStatement) -> Statement<'_> {
|
543 | 552 | Statement { conn, stmt }
|
544 | 553 | }
|
545 |
| - |
546 |
| - /// column_type |
547 |
| - #[inline] |
548 |
| - pub fn column_type(&self, idx: usize) -> DataType { |
549 |
| - self.stmt.column_type(idx) |
550 |
| - } |
551 | 554 | }
|
552 | 555 |
|
553 | 556 | #[cfg(test)]
|
@@ -806,6 +809,41 @@ mod test {
|
806 | 809 | Ok(())
|
807 | 810 | }
|
808 | 811 |
|
| 812 | + #[test] |
| 813 | + fn test_get_schema_of_executed_result() -> Result<()> { |
| 814 | + use arrow::datatypes::{DataType, Field, Schema}; |
| 815 | + let db = Connection::open_in_memory()?; |
| 816 | + let sql = "BEGIN; |
| 817 | + CREATE TABLE foo(x STRING, y INTEGER); |
| 818 | + INSERT INTO foo VALUES('hello', 3); |
| 819 | + END;"; |
| 820 | + db.execute_batch(sql)?; |
| 821 | + let mut stmt = db.prepare("SELECT x, y FROM foo")?; |
| 822 | + let _ = stmt.execute([]); |
| 823 | + let schema = stmt.schema(); |
| 824 | + assert_eq!( |
| 825 | + *schema, |
| 826 | + Schema::new(vec![ |
| 827 | + Field::new("x", DataType::Utf8, true), |
| 828 | + Field::new("y", DataType::Int32, true) |
| 829 | + ]) |
| 830 | + ); |
| 831 | + Ok(()) |
| 832 | + } |
| 833 | + |
| 834 | + #[test] |
| 835 | + #[should_panic(expected = "called `Option::unwrap()` on a `None` value")] |
| 836 | + fn test_unexecuted_schema_panics() { |
| 837 | + let db = Connection::open_in_memory().unwrap(); |
| 838 | + let sql = "BEGIN; |
| 839 | + CREATE TABLE foo(x STRING, y INTEGER); |
| 840 | + INSERT INTO foo VALUES('hello', 3); |
| 841 | + END;"; |
| 842 | + db.execute_batch(sql).unwrap(); |
| 843 | + let stmt = db.prepare("SELECT x, y FROM foo").unwrap(); |
| 844 | + let _ = stmt.schema(); |
| 845 | + } |
| 846 | + |
809 | 847 | #[test]
|
810 | 848 | fn test_query_by_column_name_ignore_case() -> Result<()> {
|
811 | 849 | let db = Connection::open_in_memory()?;
|
|
0 commit comments