feat: InfluxQL learns LOG function (arity 2) (#7333)

pull/24376/head
Stuart Carnie 2023-03-29 07:22:27 +11:00 committed by GitHub
parent 43e236e040
commit a26cb6032a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 19 deletions

View File

@ -154,8 +154,7 @@ SELECT
atan(f64),
atan2(f64, 2),
exp(f64),
-- TODO(sgc): Dependent on https://github.com/apache/arrow-datafusion/issues/5206
-- log(f64, 8),
log(f64, 8),
ln(f64),
log2(f64),
log10(f64),
@ -179,8 +178,7 @@ SELECT
atan(i64),
atan2(i64, 2),
exp(i64),
-- TODO(sgc): Dependent on https://github.com/apache/arrow-datafusion/issues/5206
-- log(i64, 8),
log(i64, 8),
ln(i64),
log2(i64),
log10(i64),
@ -191,6 +189,9 @@ SELECT
round(i64)
FROM m0 LIMIT 1;
-- validate log requires two arguments
SELECT log(f64) FROM m0 LIMIT 1;
-- Deviation from InfluxQL is that NaNs are not coalesced to NULL
-- The InfluxQL compatibility later will be responsible for this translation
SELECT f64, asin(f64), acos(f64) FROM m0 LIMIT 1;

View File

@ -273,18 +273,20 @@
| m0 | 2022-10-31T02:00:00Z | 11.3 | 211 | lo | val01 | |
| m0 | 2022-10-31T02:00:00Z | 10.4 | 101 | lo | val02 | |
+------------------+----------------------+------+-----+-----+-------+-------+
-- InfluxQL: SELECT f64, abs(f64 * -1), sin(f64), cos(f64), tan(f64), asin(1/f64), acos(1/f64), atan(f64), atan2(f64, 2), exp(f64), ln(f64), log2(f64), log10(f64), sqrt(f64), pow(f64, 2), floor(f64), ceil(f64), round(f64) FROM m0 LIMIT 1;
+------------------+----------------------+------+------+---------------------+---------------------+--------------------+--------------------+-------------------+------------------+--------------------+-------------------+-------------------+--------------------+--------------------+--------------------+--------------------+-------+------+-------+
| iox::measurement | time | f64 | abs | sin | cos | tan | asin | acos | atan | atan2 | exp | ln | log2 | log10 | sqrt | pow | floor | ceil | round |
+------------------+----------------------+------+------+---------------------+---------------------+--------------------+--------------------+-------------------+------------------+--------------------+-------------------+-------------------+--------------------+--------------------+--------------------+--------------------+-------+------+-------+
| m0 | 2022-10-31T02:00:00Z | 10.1 | 10.1 | -0.6250706488928821 | -0.7805681801691837 | 0.8007893029375109 | 0.0991723838059207 | 1.471623942988976 | 1.47210806614649 | 1.3753055265462157 | 24343.00942440838 | 2.312535423847214 | 3.3362833878644325 | 1.0043213737826426 | 3.1780497164141406 | 102.00999999999999 | 10.0 | 11.0 | 10.0 |
+------------------+----------------------+------+------+---------------------+---------------------+--------------------+--------------------+-------------------+------------------+--------------------+-------------------+-------------------+--------------------+--------------------+--------------------+--------------------+-------+------+-------+
-- InfluxQL: SELECT i64, abs(i64 * -1), sin(i64), cos(i64), tan(i64), acos(1/i64), atan(i64), atan2(i64, 2), exp(i64), ln(i64), log2(i64), log10(i64), sqrt(i64), pow(i64, 2), floor(i64), ceil(i64), round(i64) FROM m0 LIMIT 1;
+------------------+----------------------+-----+-------+---------------------+--------------------+--------------------+--------------------+-------------------+-----------+----------------------+------------------+-------------------+--------------------+-------------------+-------+-------+-------+-------+
| iox::measurement | time | i64 | abs | sin | cos | tan | acos | atan | atan2 | exp | ln | log2 | log10 | sqrt | pow | floor | ceil | round |
+------------------+----------------------+-----+-------+---------------------+--------------------+--------------------+--------------------+-------------------+-----------+----------------------+------------------+-------------------+--------------------+-------------------+-------+-------+-------+-------+
| m0 | 2022-10-31T02:00:00Z | 101 | 101.0 | 0.45202578717835057 | 0.8920048697881602 | 0.5067526002248183 | 1.5707963267948966 | 1.560895660206908 | 1.5509969 | 7.307059979368067e43 | 4.61512051684126 | 6.658211482751795 | 2.0043213737826426 | 10.04987562112089 | 10201 | 101.0 | 101.0 | 101.0 |
+------------------+----------------------+-----+-------+---------------------+--------------------+--------------------+--------------------+-------------------+-----------+----------------------+------------------+-------------------+--------------------+-------------------+-------+-------+-------+-------+
-- InfluxQL: SELECT f64, abs(f64 * -1), sin(f64), cos(f64), tan(f64), asin(1/f64), acos(1/f64), atan(f64), atan2(f64, 2), exp(f64), log(f64, 8), ln(f64), log2(f64), log10(f64), sqrt(f64), pow(f64, 2), floor(f64), ceil(f64), round(f64) FROM m0 LIMIT 1;
+------------------+----------------------+------+------+---------------------+---------------------+--------------------+--------------------+-------------------+------------------+--------------------+-------------------+--------------------+-------------------+--------------------+--------------------+--------------------+--------------------+-------+------+-------+
| iox::measurement | time | f64 | abs | sin | cos | tan | asin | acos | atan | atan2 | exp | log | ln | log2 | log10 | sqrt | pow | floor | ceil | round |
+------------------+----------------------+------+------+---------------------+---------------------+--------------------+--------------------+-------------------+------------------+--------------------+-------------------+--------------------+-------------------+--------------------+--------------------+--------------------+--------------------+-------+------+-------+
| m0 | 2022-10-31T02:00:00Z | 10.1 | 10.1 | -0.6250706488928821 | -0.7805681801691837 | 0.8007893029375109 | 0.0991723838059207 | 1.471623942988976 | 1.47210806614649 | 1.3753055265462157 | 24343.00942440838 | 1.1120944626214775 | 2.312535423847214 | 3.3362833878644325 | 1.0043213737826426 | 3.1780497164141406 | 102.00999999999999 | 10.0 | 11.0 | 10.0 |
+------------------+----------------------+------+------+---------------------+---------------------+--------------------+--------------------+-------------------+------------------+--------------------+-------------------+--------------------+-------------------+--------------------+--------------------+--------------------+--------------------+-------+------+-------+
-- InfluxQL: SELECT i64, abs(i64 * -1), sin(i64), cos(i64), tan(i64), acos(1/i64), atan(i64), atan2(i64, 2), exp(i64), log(i64, 8), ln(i64), log2(i64), log10(i64), sqrt(i64), pow(i64, 2), floor(i64), ceil(i64), round(i64) FROM m0 LIMIT 1;
+------------------+----------------------+-----+-------+---------------------+--------------------+--------------------+--------------------+-------------------+-----------+----------------------+-----------+------------------+-------------------+--------------------+-------------------+-------+-------+-------+-------+
| iox::measurement | time | i64 | abs | sin | cos | tan | acos | atan | atan2 | exp | log | ln | log2 | log10 | sqrt | pow | floor | ceil | round |
+------------------+----------------------+-----+-------+---------------------+--------------------+--------------------+--------------------+-------------------+-----------+----------------------+-----------+------------------+-------------------+--------------------+-------------------+-------+-------+-------+-------+
| m0 | 2022-10-31T02:00:00Z | 101 | 101.0 | 0.45202578717835057 | 0.8920048697881602 | 0.5067526002248183 | 1.5707963267948966 | 1.560895660206908 | 1.5509969 | 7.307059979368067e43 | 2.2194037 | 4.61512051684126 | 6.658211482751795 | 2.0043213737826426 | 10.04987562112089 | 10201 | 101.0 | 101.0 | 101.0 |
+------------------+----------------------+-----+-------+---------------------+--------------------+--------------------+--------------------+-------------------+-----------+----------------------+-----------+------------------+-------------------+--------------------+-------------------+-------+-------+-------+-------+
-- InfluxQL: SELECT log(f64) FROM m0 LIMIT 1;
Error while planning query: Error during planning: invalid number of arguments for log, expected 2, got 1
-- InfluxQL: SELECT f64, asin(f64), acos(f64) FROM m0 LIMIT 1;
+------------------+----------------------+------+------+------+
| iox::measurement | time | f64 | asin | acos |

View File

@ -108,7 +108,7 @@ struct Context<'a> {
scope: ExprScope,
tz: Option<Tz>,
//
/// `true` if the query projects aggregates.
is_aggregate: bool,
// GROUP BY information
@ -874,12 +874,26 @@ impl<'a> InfluxQLToLogicalPlan<'a> {
args: &[IQLExpr],
schemas: &Schemas,
) -> Result<Expr> {
let fun = BuiltinScalarFunction::from_str(name)?;
let args = args
.iter()
.map(|e| self.expr_to_df_expr(ctx, e, schemas))
.collect::<Result<Vec<Expr>>>()?;
Ok(Expr::ScalarFunction { fun, args })
match BuiltinScalarFunction::from_str(name)? {
BuiltinScalarFunction::Log => {
if args.len() != 2 {
Err(DataFusionError::Plan(
"invalid number of arguments for log, expected 2, got 1".to_owned(),
))
} else {
Ok(Expr::ScalarFunction {
fun: BuiltinScalarFunction::Log,
args: args.into_iter().rev().collect(),
})
}
}
fun => Ok(Expr::ScalarFunction { fun, args }),
}
}
/// Map an InfluxQL arithmetic expression to a DataFusion [`Expr`].
@ -1310,6 +1324,23 @@ mod test {
mod select {
use super::*;
/// Test InfluxQL-specific behaviour of scalar functions that differ
/// from DataFusion
#[test]
fn test_scalar_functions() {
// LOG requires two arguments, and first argument is field
assert_snapshot!(plan("SELECT LOG(usage_idle, 8) FROM cpu"), @r###"
Sort: time ASC NULLS LAST [iox::measurement:Dictionary(Int32, Utf8), time:Timestamp(Nanosecond, None), log:Float64;N]
Projection: Dictionary(Int32, Utf8("cpu")) AS iox::measurement, cpu.time AS time, log(Int64(8), cpu.usage_idle) AS log [iox::measurement:Dictionary(Int32, Utf8), time:Timestamp(Nanosecond, None), log:Float64;N]
TableScan: cpu [cpu:Dictionary(Int32, Utf8);N, host:Dictionary(Int32, Utf8);N, region:Dictionary(Int32, Utf8);N, time:Timestamp(Nanosecond, None), usage_idle:Float64;N, usage_system:Float64;N, usage_user:Float64;N]
"###);
// Fallible
// LOG requires two arguments
assert_snapshot!(plan("SELECT LOG(usage_idle) FROM cpu"), @"Error during planning: invalid number of arguments for log, expected 2, got 1");
}
/// Validate the metadata is correctly encoded in the schema.
///
/// Properties that are tested: