Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions src/execute/scale.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1416,7 +1416,7 @@ pub fn apply_oob_to_column_discrete(
#[cfg(test)]
mod tests {
use super::*;
use crate::plot::ArrayElement;
use crate::plot::{ArrayElement, Parameters};
use crate::Geom;
use arrow::datatypes::DataType;

Expand Down Expand Up @@ -1722,8 +1722,8 @@ mod tests {
spec.project = Some(Projection {
coord,
aesthetics,
properties: std::collections::HashMap::new(),
computed: std::collections::HashMap::new(),
properties: Parameters::new(),
computed: Parameters::new(),
});

// Create scale for pos2 (theta in polar) without explicit expand
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub mod validate;

// Re-export key types for convenience
pub use plot::{
AestheticValue, DataSource, Facet, FacetLayout, Geom, Layer, Mappings, Plot, Scale,
AestheticValue, DataSource, Facet, FacetLayout, Geom, Layer, Mappings, Parameters, Plot, Scale,
SqlExpression,
};

Expand Down
24 changes: 9 additions & 15 deletions src/parser/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ fn build_layer(node: &Node, source: &SourceTree) -> Result<Layer> {
let mut geom = Geom::point(); // default
let mut aesthetics = Mappings::new();
let mut remappings = Mappings::new();
let mut parameters = HashMap::new();
let mut parameters = Parameters::new();
let mut partition_by = Vec::new();
let mut filter = None;
let mut order_by = None;
Expand Down Expand Up @@ -542,11 +542,8 @@ fn build_place_layer(node: &Node, source: &SourceTree) -> Result<Layer> {
}

/// Parse a setting_clause: SETTING param => value, ...
fn parse_setting_clause(
node: &Node,
source: &SourceTree,
) -> Result<HashMap<String, ParameterValue>> {
let mut parameters = HashMap::new();
fn parse_setting_clause(node: &Node, source: &SourceTree) -> Result<Parameters> {
let mut parameters = Parameters::new();

// Find all parameter_assignment nodes
let query = "(parameter_assignment) @param";
Expand Down Expand Up @@ -671,7 +668,7 @@ fn build_scale(node: &Node, source: &SourceTree) -> Result<Scale> {
let mut output_range: Option<OutputRange> = None;
let mut transform: Option<Transform> = None;
let mut explicit_transform = false;
let mut properties = HashMap::new();
let mut properties = Parameters::new();
let mut label_mapping: Option<HashMap<String, Option<String>>> = None;
let mut label_template = "{}".to_string();

Expand Down Expand Up @@ -904,7 +901,7 @@ fn parse_scale_renaming_clause(
fn build_facet(node: &Node, source: &SourceTree) -> Result<Facet> {
let mut row_vars = Vec::new();
let mut column_vars = Vec::new();
let mut properties = HashMap::new();
let mut properties = Parameters::new();

let mut cursor = node.walk();
let mut next_vars_are_cols = false;
Expand Down Expand Up @@ -971,7 +968,7 @@ fn parse_facet_vars(node: &Node, source: &SourceTree) -> Result<Vec<String>> {
/// Aesthetics are optional and default to the coord's standard names.
fn build_project(node: &Node, source: &SourceTree) -> Result<Projection> {
let mut coord_type_name: Option<String> = None;
let mut properties = HashMap::new();
let mut properties = Parameters::new();
let mut user_aesthetics: Option<Vec<String>> = None;

let mut cursor = node.walk();
Expand Down Expand Up @@ -1032,7 +1029,7 @@ fn build_project(node: &Node, source: &SourceTree) -> Result<Projection> {
coord,
aesthetics,
properties,
computed: HashMap::new(),
computed: Parameters::new(),
})
}

Expand Down Expand Up @@ -1096,18 +1093,15 @@ fn parse_single_project_property(
fn validate_project_properties(
coord: &Coord,
coord_type_name: Option<&str>,
properties: &HashMap<String, ParameterValue>,
properties: &Parameters,
) -> Result<()> {
coord
.resolve_properties(coord_type_name, properties)
.map_err(GgsqlError::ParseError)?;
Ok(())
}

fn parse_coord_system(
name: Option<&str>,
properties: &HashMap<String, ParameterValue>,
) -> Result<Coord> {
fn parse_coord_system(name: Option<&str>, properties: &Parameters) -> Result<Coord> {
use crate::plot::projection::coord::map_projections::NAMED_PROJECTIONS;
match name {
Some("cartesian") | None => Ok(Coord::cartesian()),
Expand Down
7 changes: 3 additions & 4 deletions src/plot/facet/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
//!
//! This module defines faceting configuration for small multiples.

use crate::plot::types::{DefaultParamValue, ParamConstraint, ParamDefinition};
use crate::plot::types::{DefaultParamValue, ParamConstraint, ParamDefinition, Parameters};
use crate::plot::ParameterValue;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Faceting specification (from FACET clause)
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand All @@ -15,7 +14,7 @@ pub struct Facet {
/// Properties from SETTING clause (e.g., scales, ncol, missing)
/// After resolution, includes validated and defaulted values
#[serde(default)]
pub properties: HashMap<String, ParameterValue>,
pub properties: Parameters,
/// Whether properties have been resolved (validated and defaults applied)
#[serde(skip, default)]
pub resolved: bool,
Expand All @@ -41,7 +40,7 @@ impl Facet {
pub fn new(layout: FacetLayout) -> Self {
Self {
layout,
properties: HashMap::new(),
properties: Parameters::new(),
resolved: false,
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/plot/layer/geom/area.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Area geom implementation

use crate::plot::layer::orientation::{ALIGNED, ORIENTATION_VALUES};
use crate::plot::types::DefaultAestheticValue;
use crate::plot::types::{DefaultAestheticValue, Parameters};
use crate::plot::{DefaultParamValue, ParamDefinition};
use crate::Mappings;

Expand Down Expand Up @@ -66,7 +66,7 @@ impl GeomTrait for Area {
schema: &crate::plot::Schema,
aesthetics: &Mappings,
group_by: &[String],
parameters: &std::collections::HashMap<String, crate::plot::ParameterValue>,
parameters: &Parameters,
_execute_query: &dyn Fn(&str) -> crate::Result<crate::DataFrame>,
dialect: &dyn crate::reader::SqlDialect,
aesthetic_ctx: &crate::plot::aesthetic::AestheticContext,
Expand Down
5 changes: 2 additions & 3 deletions src/plot/layer/geom/bar.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Bar geom implementation

use std::collections::HashMap;
use std::collections::HashSet;

use super::stat_aggregate;
Expand All @@ -10,7 +9,7 @@ use super::{
ParamConstraint, ParamDefinition, StatResult,
};
use crate::naming;
use crate::plot::types::{DefaultAestheticValue, ParameterValue};
use crate::plot::types::{DefaultAestheticValue, Parameters};
use crate::reader::SqlDialect;
use crate::{DataFrame, GgsqlError, Mappings, Result};

Expand Down Expand Up @@ -90,7 +89,7 @@ impl GeomTrait for Bar {
schema: &Schema,
aesthetics: &Mappings,
group_by: &[String],
parameters: &HashMap<String, ParameterValue>,
parameters: &Parameters,
_execute_query: &dyn Fn(&str) -> Result<DataFrame>,
dialect: &dyn SqlDialect,
aesthetic_ctx: &crate::plot::aesthetic::AestheticContext,
Expand Down
11 changes: 5 additions & 6 deletions src/plot/layer/geom/boxplot.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
//! Boxplot geom implementation

use std::collections::HashMap;

use super::types::{wrap_with_dummy_axis, POSITION_VALUES, SIDE_VALUES};
use super::{DefaultAesthetics, GeomTrait, GeomType};
use crate::{
naming,
plot::{
geom::types::get_column_name, DefaultAestheticValue, DefaultParamValue, ParamConstraint,
ParamDefinition, ParameterValue, StatResult,
ParamDefinition, ParameterValue, Parameters, StatResult,
},
reader::SqlDialect,
DataFrame, GgsqlError, Mappings, Result,
Expand Down Expand Up @@ -101,7 +99,7 @@ impl GeomTrait for Boxplot {
_schema: &crate::plot::Schema,
aesthetics: &Mappings,
group_by: &[String],
parameters: &HashMap<String, ParameterValue>,
parameters: &Parameters,
_execute_query: &dyn Fn(&str) -> Result<DataFrame>,
dialect: &dyn SqlDialect,
aesthetic_ctx: &crate::plot::aesthetic::AestheticContext,
Expand All @@ -127,7 +125,7 @@ fn stat_boxplot(
query: &str,
aesthetics: &Mappings,
group_by: &[String],
parameters: &HashMap<String, ParameterValue>,
parameters: &Parameters,
dialect: &dyn SqlDialect,
aesthetic_ctx: &crate::plot::aesthetic::AestheticContext,
) -> Result<StatResult> {
Expand Down Expand Up @@ -340,6 +338,7 @@ fn boxplot_sql_append_outliers(
#[cfg(test)]
mod tests {
use super::*;
use crate::plot::Parameters;
use crate::reader::AnsiDialect;

// ==================== SQL Generation Tests (Compact) ====================
Expand Down Expand Up @@ -639,7 +638,7 @@ mod tests {
"pos2".to_string(),
AestheticValue::standard_column("value".to_string()),
);
let mut parameters: HashMap<String, ParameterValue> = HashMap::new();
let mut parameters = Parameters::new();
parameters.insert("coef".to_string(), ParameterValue::Number(1.5));
parameters.insert("outliers".to_string(), ParameterValue::Boolean(true));

Expand Down
32 changes: 14 additions & 18 deletions src/plot/layer/geom/density.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ use crate::{
naming,
plot::{
geom::types::get_column_name, DefaultAestheticValue, DefaultParamValue, ParamConstraint,
ParamDefinition, ParameterValue, StatResult,
ParamDefinition, ParameterValue, Parameters, StatResult,
},
reader::SqlDialect,
GgsqlError, Mappings, Result,
};
use std::collections::HashMap;

/// Gaussian kernel normalization constant: 1/sqrt(2*pi)
/// Precomputed at compile time to avoid repeated SQRT and PI() calls in SQL
const GAUSSIAN_NORM: f64 = 0.3989422804014327; // 1.0 / (2.0 * std::f64::consts::PI).sqrt()
Expand Down Expand Up @@ -104,7 +102,7 @@ impl GeomTrait for Density {
_schema: &crate::plot::Schema,
aesthetics: &Mappings,
group_by: &[String],
parameters: &std::collections::HashMap<String, crate::plot::ParameterValue>,
parameters: &Parameters,
_execute_query: &dyn Fn(&str) -> crate::Result<crate::DataFrame>,
dialect: &dyn SqlDialect,
aesthetic_ctx: &crate::plot::aesthetic::AestheticContext,
Expand Down Expand Up @@ -154,7 +152,7 @@ pub(crate) fn stat_density(
value_aesthetic: &str,
smooth_aesthetic: Option<&str>,
group_by: &[String],
parameters: &HashMap<String, ParameterValue>,
parameters: &Parameters,
dialect: &dyn SqlDialect,
aesthetic_ctx: &crate::plot::aesthetic::AestheticContext,
) -> Result<StatResult> {
Expand Down Expand Up @@ -214,7 +212,7 @@ fn density_sql_bandwidth(
from: &str,
groups: &[String],
value: &str,
parameters: &HashMap<String, ParameterValue>,
parameters: &Parameters,
dialect: &dyn SqlDialect,
) -> String {
let adjust = match parameters.get("adjust") {
Expand Down Expand Up @@ -279,10 +277,7 @@ fn silverman_rule(
format!("{adjust} * {min_expr} * POW(COUNT(*), -0.2)")
}

fn choose_kde_kernel(
parameters: &HashMap<String, ParameterValue>,
smooth: Option<String>,
) -> Result<String> {
fn choose_kde_kernel(parameters: &Parameters, smooth: Option<String>) -> Result<String> {
let kernel = match parameters.get("kernel") {
Some(ParameterValue::String(krnl)) => krnl.as_str(),
_ => {
Expand Down Expand Up @@ -609,6 +604,7 @@ fn compute_density(
#[cfg(test)]
mod tests {
use super::*;
use crate::plot::Parameters;
use crate::reader::duckdb::DuckDBReader;
use crate::reader::AnsiDialect;
use crate::reader::Reader;
Expand All @@ -618,7 +614,7 @@ mod tests {
fn test_density_sql_no_groups() {
let query = "SELECT x FROM (VALUES (1.0), (2.0), (3.0)) AS t(x)";
let groups: Vec<String> = vec![];
let mut parameters = HashMap::new();
let mut parameters = Parameters::new();
parameters.insert("bandwidth".to_string(), ParameterValue::Number(0.5));
parameters.insert(
"kernel".to_string(),
Expand Down Expand Up @@ -694,7 +690,7 @@ mod tests {
fn test_density_sql_with_two_groups() {
let query = "SELECT x, region, category FROM (VALUES (1.0, 'A', 'X'), (2.0, 'B', 'Y')) AS t(x, region, category)";
let groups = vec!["region".to_string(), "category".to_string()];
let mut parameters = HashMap::new();
let mut parameters = Parameters::new();
parameters.insert("bandwidth".to_string(), ParameterValue::Number(0.5));
parameters.insert(
"kernel".to_string(),
Expand Down Expand Up @@ -816,7 +812,7 @@ mod tests {
// Test 1: No groups
let query = "SELECT x FROM (VALUES (1.0), (2.0), (3.0), (4.0), (5.0)) AS t(x)";
let groups: Vec<String> = vec![];
let parameters = HashMap::new(); // No explicit bandwidth - will compute
let parameters = Parameters::new(); // No explicit bandwidth - will compute

let bw_cte = density_sql_bandwidth(query, &groups, "x", &parameters, &AnsiDialect);

Expand Down Expand Up @@ -872,7 +868,7 @@ mod tests {
fn test_kernel_integration(kernel_name: &str, tolerance: f64) {
let query = "SELECT x FROM (VALUES (1.0), (2.0), (3.0), (4.0), (5.0)) AS t(x)";
let groups: Vec<String> = vec![];
let mut parameters = HashMap::new();
let mut parameters = Parameters::new();
parameters.insert("bandwidth".to_string(), ParameterValue::Number(1.0));
parameters.insert(
"kernel".to_string(),
Expand Down Expand Up @@ -968,7 +964,7 @@ mod tests {

#[test]
fn test_kernel_invalid() {
let mut parameters = HashMap::new();
let mut parameters = Parameters::new();
parameters.insert(
"kernel".to_string(),
ParameterValue::String("invalid_kernel".to_string()),
Expand All @@ -991,7 +987,7 @@ mod tests {
// Compare weighted and unweighted results
let query = "SELECT x FROM (VALUES (1.0), (2.0), (3.0)) AS t(x)";
let groups: Vec<String> = vec![];
let mut parameters = HashMap::new();
let mut parameters = Parameters::new();
parameters.insert("bandwidth".to_string(), ParameterValue::Number(0.5));
parameters.insert(
"kernel".to_string(),
Expand Down Expand Up @@ -1148,7 +1144,7 @@ mod tests {

let query = "SELECT x FROM bench_data";
let groups: Vec<String> = vec![];
let mut parameters = HashMap::new();
let mut parameters = Parameters::new();
parameters.insert("bandwidth".to_string(), ParameterValue::Number(5.0));
parameters.insert(
"kernel".to_string(),
Expand Down Expand Up @@ -1197,7 +1193,7 @@ mod tests {
#[test]
fn stat_density_missing_value_aesthetic_emits_user_facing_name() {
let mappings = crate::Mappings::new();
let parameters = std::collections::HashMap::new();
let parameters = Parameters::new();
let dialect = AnsiDialect;
let ctx = crate::plot::aesthetic::AestheticContext::from_static(&["x", "y"], &[]);

Expand Down
Loading
Loading