Skip to content

Commit 476ddab

Browse files
authored
Merge pull request #869 from dbascoules/feat/oracle-decimal128
Support Oracle Decimal in arrowstream
2 parents 43b0ca3 + bdb1f0b commit 476ddab

File tree

5 files changed

+38
-2
lines changed

5 files changed

+38
-2
lines changed

connectorx/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ src_csv = ["csv", "regex"]
8484
src_dummy = ["num-traits"]
8585
src_mssql = ["rust_decimal", "num-traits", "tiberius", "bb8-tiberius", "bb8", "tokio", "tokio-util", "uuid_old", "futures", "urlencoding"]
8686
src_mysql = ["r2d2_mysql", "mysql_common", "rust_decimal", "num-traits", "r2d2"]
87-
src_oracle = ["oracle", "r2d2-oracle","r2d2", "urlencoding"]
87+
src_oracle = ["oracle", "r2d2-oracle","r2d2", "urlencoding", "rust_decimal"]
8888
src_postgres = [
8989
"postgres",
9090
"r2d2_postgres",

connectorx/src/sources/oracle/errors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ pub enum OracleSourceError {
1818
#[error(transparent)]
1919
OracleUrlDecodeError(#[from] FromUtf8Error),
2020

21+
#[error(transparent)]
22+
DecimalError(#[from] rust_decimal::Error),
23+
2124
/// Any other errors that are too trivial to be put here explicitly.
2225
#[error(transparent)]
2326
Other(#[from] anyhow::Error),

connectorx/src/sources/oracle/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use r2d2_oracle::{
2323
oracle::{Connector, Row, Statement},
2424
OracleConnectionManager,
2525
};
26+
use rust_decimal::Decimal;
2627
use sqlparser::dialect::Dialect;
2728
use url::Url;
2829
use urlencoding::decode;
@@ -372,3 +373,30 @@ impl_produce_text!(
372373
DateTime<Utc>,
373374
Vec<u8>,
374375
);
376+
377+
// Manual implementation for Decimal since Oracle doesn't support it directly via FromSql
378+
impl<'r, 'a> Produce<'r, Decimal> for OracleTextSourceParser<'a> {
379+
type Error = OracleSourceError;
380+
381+
#[throws(OracleSourceError)]
382+
fn produce(&'r mut self) -> Decimal {
383+
let (ridx, cidx) = self.next_loc()?;
384+
let s: String = self.rowbuf[ridx].get(cidx)?;
385+
let res = s.parse::<Decimal>()?;
386+
res
387+
}
388+
}
389+
390+
impl<'r, 'a> Produce<'r, Option<Decimal>> for OracleTextSourceParser<'a> {
391+
type Error = OracleSourceError;
392+
393+
#[throws(OracleSourceError)]
394+
fn produce(&'r mut self) -> Option<Decimal> {
395+
let (ridx, cidx) = self.next_loc()?;
396+
let s: Option<String> = self.rowbuf[ridx].get(cidx)?;
397+
match s {
398+
Some(val) => Some(val.parse::<Decimal>()?),
399+
None => None,
400+
}
401+
}
402+
}

connectorx/src/sources/oracle/typesystem.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use chrono::{DateTime, NaiveDateTime, Utc};
22
use r2d2_oracle::oracle::sql_type::OracleType;
3+
use rust_decimal::Decimal;
34

45
#[derive(Copy, Clone, Debug)]
56
pub enum OracleTypeSystem {
67
NumInt(bool),
8+
NumDecimal(bool),
79
Float(bool),
810
NumFloat(bool),
911
BinaryFloat(bool),
@@ -25,6 +27,7 @@ impl_typesystem! {
2527
system = OracleTypeSystem,
2628
mappings = {
2729
{ NumInt => i64 }
30+
{ NumDecimal => Decimal }
2831
{ Float | NumFloat | BinaryFloat | BinaryDouble => f64 }
2932
{ Blob => Vec<u8>}
3033
{ Clob | VarChar | Char | NVarChar | NChar => String }
@@ -39,7 +42,7 @@ impl<'a> From<&'a OracleType> for OracleTypeSystem {
3942
match ty {
4043
OracleType::Number(0, 0) => NumFloat(true),
4144
OracleType::Number(_, 0) => NumInt(true),
42-
OracleType::Number(_, _) => NumFloat(true),
45+
OracleType::Number(_, _) => NumDecimal(true),
4346
OracleType::Float(_) => Float(true),
4447
OracleType::BinaryFloat => BinaryFloat(true),
4548
OracleType::BinaryDouble => BinaryDouble(true),

connectorx/src/transports/oracle_arrowstream.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
typesystem::TypeConversion,
88
};
99
use chrono::{DateTime, NaiveDateTime, Utc};
10+
use rust_decimal::Decimal;
1011
use thiserror::Error;
1112

1213
#[derive(Error, Debug)]
@@ -30,6 +31,7 @@ impl_transport!(
3031
route = OracleSource => ArrowDestination,
3132
mappings = {
3233
{ NumFloat[f64] => Float64[f64] | conversion auto }
34+
{ NumDecimal[Decimal] => Decimal[Decimal] | conversion auto }
3335
{ Float[f64] => Float64[f64] | conversion none }
3436
{ BinaryFloat[f64] => Float64[f64] | conversion none }
3537
{ BinaryDouble[f64] => Float64[f64] | conversion none }

0 commit comments

Comments
 (0)