Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions datafusion/functions/src/math/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,18 @@ fn log_decimal128(value: i128, scale: i8, base: f64) -> Result<f64, ArrowError>
)));
}

let unscaled_value = decimal128_to_i128(value, scale)?;
if unscaled_value > 0 {
if value <= 0 {
// Reflect f64::log behaviour
return Ok(f64::NAN);
}

if scale < 0 {
let actual_value = (value as f64) * 10.0_f64.powi(-scale as i32);
Ok(actual_value.log(base))
} else {
let unscaled_value = decimal128_to_i128(value, scale)?;
let log_value: u32 = unscaled_value.ilog(base as i128);
Ok(log_value as f64)
} else {
// Reflect f64::log behaviour
Ok(f64::NAN)
}
}

Expand Down Expand Up @@ -289,6 +294,19 @@ impl ScalarUDFImpl for LogFunc {
if num_args != 1 && num_args != 2 {
return plan_err!("Expected log to have 1 or 2 arguments, got {num_args}");
}

match arg_types.last().unwrap() {
DataType::Decimal32(_, scale)
| DataType::Decimal64(_, scale)
| DataType::Decimal128(_, scale)
| DataType::Decimal256(_, scale)
if *scale < 0 =>
{
return Ok(ExprSimplifyResult::Original(args));
}
_ => (),
};

let number = args.pop().unwrap();
let number_datatype = arg_types.pop().unwrap();
// default to base 10
Expand Down
51 changes: 51 additions & 0 deletions datafusion/sqllogictest/test_files/decimal.slt
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,57 @@ select log(2.0, null);
----
NULL

# log with negative scale decimals
# Using scientific notation to create decimals with negative scales
# 1e4 = 10000 with scale -4, log10(10000) = 4.0
query R
select log(1e4);
----
4

# log with negative scale and explicit base 10
query R
select log(10, 1e4);
----
4

# log with negative scale and base 2
# 8e1 = 80 with scale -1, log2(80) ≈ 6.321928
query R
select log(2.0, 8e1);
----
6.321928094887

# log with negative scale and base 2 (another value)
# 16e1 = 160 with scale -1, log2(160) ≈ 7.321928
query R
select log(2.0, 16e1);
----
7.321928094887

# log with negative scale -3
# 5e3 = 5000 with scale -3, log10(5000) ≈ 3.69897
query R
select log(5e3);
----
3.698970004336

# log with negative scale array values
query R rowsort
select log(value) from (values (1e3), (1e4), (1e5)) as t(value);
----
3
4
5

# log with negative scale and different bases
query R rowsort
select log(base, 1e4) from (values (10.0), (2.0), (3.0)) as t(base);
----
13.287712379549
4
8.383613097158

# power with decimals

query RT
Expand Down