Skip to content

Commit

Permalink
WIP. Test gen doc from macros
Browse files Browse the repository at this point in the history
  • Loading branch information
comphead committed Oct 8, 2024
1 parent 577e4bb commit dca1a33
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ members = [
"datafusion-examples",
"test-utils",
"benchmarks",
"datafusion/macros",
"datafusion/pre-macros"
]
resolver = "2"

Expand Down Expand Up @@ -105,11 +107,13 @@ datafusion-functions-aggregate-common = { path = "datafusion/functions-aggregate
datafusion-functions-nested = { path = "datafusion/functions-nested", version = "42.0.0" }
datafusion-functions-window = { path = "datafusion/functions-window", version = "42.0.0" }
datafusion-functions-window-common = { path = "datafusion/functions-window-common", version = "42.0.0" }
datafusion-macros = { path = "datafusion/macros", version = "42.0.0" }
datafusion-optimizer = { path = "datafusion/optimizer", version = "42.0.0", default-features = false }
datafusion-physical-expr = { path = "datafusion/physical-expr", version = "42.0.0", default-features = false }
datafusion-physical-expr-common = { path = "datafusion/physical-expr-common", version = "42.0.0", default-features = false }
datafusion-physical-optimizer = { path = "datafusion/physical-optimizer", version = "42.0.0" }
datafusion-physical-plan = { path = "datafusion/physical-plan", version = "42.0.0" }
datafusion-pre-macros = { path = "datafusion/pre-macros", version = "42.0.0" }
datafusion-proto = { path = "datafusion/proto", version = "42.0.0" }
datafusion-proto-common = { path = "datafusion/proto-common", version = "42.0.0" }
datafusion-sql = { path = "datafusion/sql", version = "42.0.0" }
Expand Down
42 changes: 42 additions & 0 deletions datafusion/common/src/macros/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, AttributeArgs, ItemFn, Lit, Meta};
#[proc_macro_attribute]
pub fn generate_fn_with_params(attr: TokenStream, item: TokenStream) -> TokenStream {
// Parse the input tokens into a syntax tree
let args = parse_macro_input!(attr as AttributeArgs);
let input_fn = parse_macro_input!(item as ItemFn);

// Extract parameters from the attribute
let mut param1 = String::new();
let mut param2 = String::new();

if let Some(syn::NestedMeta::Meta(Meta::NameValue(meta))) = args.get(0) {
if let Lit::Str(lit_str) = &meta.lit {
param1 = lit_str.value();
}
}

if let Some(syn::NestedMeta::Meta(Meta::NameValue(meta))) = args.get(1) {
if let Lit::Str(lit_str) = &meta.lit {
param2 = lit_str.value();
}
}

// Get the original function's name
let fn_name = &input_fn.sig.ident;

// Generate the new function that prints the two parameters
let expanded = quote! {
#input_fn

pub fn #fn_name() {
println!("Param1: {}", #param1);
println!("Param2: {}", #param2);
}
};

// Return the generated code as a TokenStream
TokenStream::from(expanded)
}
2 changes: 2 additions & 0 deletions datafusion/functions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ blake2 = { version = "^0.10.2", optional = true }
blake3 = { version = "1.0", optional = true }
chrono = { workspace = true }
datafusion-common = { workspace = true }
datafusion-pre-macros = { workspace = true }
datafusion-macros = { workspace = true }
datafusion-execution = { workspace = true }
datafusion-expr = { workspace = true }
hashbrown = { workspace = true, optional = true }
Expand Down
16 changes: 12 additions & 4 deletions datafusion/functions/src/math/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

//! Math function: `log()`.

use datafusion_macros::udf_doc;
use std::any::Any;
use std::sync::{Arc, OnceLock};

Expand All @@ -37,6 +38,7 @@ use datafusion_expr::{
};
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};

#[udf_doc(description="log_description", example="log_example")]
#[derive(Debug)]
pub struct LogFunc {
signature: Signature,
Expand Down Expand Up @@ -183,10 +185,6 @@ impl ScalarUDFImpl for LogFunc {
Ok(ColumnarValue::Array(arr))
}

fn documentation(&self) -> Option<&Documentation> {
Some(get_log_doc())
}

/// Simplify the `log` function by the relevant rules:
/// 1. Log(a, 1) ===> 0
/// 2. Log(a, Power(a, b)) ===> b
Expand Down Expand Up @@ -264,6 +262,7 @@ mod tests {
use datafusion_common::DFSchema;
use datafusion_expr::execution_props::ExecutionProps;
use datafusion_expr::simplify::SimplifyContext;
use datafusion_pre_macros::DocumentationTest;

#[test]
fn test_log_f64() {
Expand Down Expand Up @@ -472,4 +471,13 @@ mod tests {
SortProperties::Unordered
);
}

#[test]
fn test_doc() {
let log = LogFunc::new();
assert_eq!(log.documentation_test(), Some(DocumentationTest {
description: "log_description".to_string(),
syntax_example: "log_example".to_string(),
}));
}
}
43 changes: 43 additions & 0 deletions datafusion/macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

[package]
name = "datafusion-macros"
description = "Proc macros for DataFusion query engine"
keywords = ["datafusion", "query", "sql"]
version = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
license = { workspace = true }
authors = { workspace = true }
rust-version = { workspace = true }

[lints]
workspace = true

[lib]
name = "datafusion_macros"
path = "src/lib.rs"
proc-macro = true

[dependencies]
quote = "1.0.37"
syn = "2.0.79"
proc-macro2 = "1.0"
datafusion-pre-macros = { workspace = true }

47 changes: 47 additions & 0 deletions datafusion/macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Lit, LitStr, Meta, MetaNameValue};
use datafusion_pre_macros::DocumentationTest;

#[proc_macro_attribute]
pub fn udf_doc(args: TokenStream, input: TokenStream) -> TokenStream {
let mut description: Option<LitStr> = None;
let mut example: Option<LitStr> = None;

let parser = syn::meta::parser(|meta| {
if meta.path.is_ident("description") {
description = Some(meta.value()?.parse()?);
Ok(())
} else if meta.path.is_ident("example") {
example = Some(meta.value()?.parse()?);
Ok(())
} else {
Err(meta.error("unsupported property"))
}
});
parse_macro_input!(args with parser);
eprintln!("description={description:?} example={example:?}");

// Parse the input struct
let input = parse_macro_input!(input as DeriveInput);
let name = input.clone().ident;

//eprintln!("input={input:?}");


let expanded = quote! {
#input

use datafusion_pre_macros::DocumentationTest;

impl #name {
fn documentation_test(&self) -> Option<DocumentationTest> {
Some(DocumentationTest { description: #description.to_string(), syntax_example: #example.to_string() })
}
}
};

// Return the generated code
TokenStream::from(expanded)
}
35 changes: 35 additions & 0 deletions datafusion/pre-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

[package]
name = "datafusion-pre-macros"
description = "Proc pre macros for DataFusion query engine"
keywords = ["datafusion", "query", "sql"]
version = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
license = { workspace = true }
authors = { workspace = true }
rust-version = { workspace = true }

[lints]
workspace = true

[lib]
name = "datafusion_pre_macros"
path = "src/lib.rs"
7 changes: 7 additions & 0 deletions datafusion/pre-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[derive(Debug, Clone, PartialEq)]
pub struct DocumentationTest {
/// the description for the UDF
pub description: String,
/// a brief example of the syntax. For example "ascii(str)"
pub syntax_example: String,
}

0 comments on commit dca1a33

Please sign in to comment.