From 899cd70e2e1a08ae737688c74175dea858d29da1 Mon Sep 17 00:00:00 2001 From: zz_y Date: Tue, 18 Aug 2026 16:47:03 -0600 Subject: [PATCH] rename: L3Scalar -> ScalarValue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L3Scalar's name was a holdover from the pre-#205 L2Expr/L3Expr split (where the "L2"/"L3" prefix distinguished unresolved-vs-resolved column-reference state); that distinction never applied to the literal type itself, and it no longer means anything now that scalar variants live directly in QueryExpr. ScalarValue says what it is without the stale prefix. Mechanical rename across every crate that names it. One real wrinkle: asap-frontend-sql's sql/mod.rs and sql/types.rs both already import datafusion::common::ScalarValue unqualified — aliased that import to DfScalarValue in both files (matching the file's existing `DataType as ArrowDataType` convention) rather than renaming the asap type, since this crate is asap-types' own vocabulary. Verified: cargo build/clippy(--all-targets --all-features --locked -- -D warnings)/fmt --check/test(--locked)/doc --workspace all clean. Same test counts as before (61+180+68+81+26+0), no doc warnings beyond the pre-existing baseline. Co-Authored-By: Claude Sonnet 5 --- crates/asap-aware-mapping/src/bind.rs | 10 +++---- crates/frontend-promql/src/promql.rs | 12 ++++---- .../frontend-promql/tests/promql_lowering.rs | 6 ++-- crates/frontend-sql/src/sql/expr.rs | 8 ++--- crates/frontend-sql/src/sql/mod.rs | 24 ++++++++------- crates/frontend-sql/src/sql/types.rs | 30 +++++++++---------- crates/frontend-sql/tests/sql_lowering.rs | 4 +-- crates/integration-tests/tests/nested.rs | 14 ++++----- crates/integration-tests/tests/scan.rs | 10 +++---- crates/types/src/dag_export.rs | 4 +-- crates/types/src/pre_asap/canonicalize.rs | 8 ++--- crates/types/src/pre_asap/expr_ir.rs | 4 +-- crates/types/src/pre_asap/mod.rs | 4 +-- crates/types/src/pre_asap/query_expr.rs | 18 +++++------ 14 files changed, 79 insertions(+), 77 deletions(-) diff --git a/crates/asap-aware-mapping/src/bind.rs b/crates/asap-aware-mapping/src/bind.rs index 25974442..6fbf515d 100644 --- a/crates/asap-aware-mapping/src/bind.rs +++ b/crates/asap-aware-mapping/src/bind.rs @@ -243,7 +243,7 @@ fn lift(schema: &Schema) -> L4Schema { mod tests { use super::*; use asap_types::pre_asap::agg_intent::default_quantile; - use asap_types::pre_asap::expr_ir::{CompareOp, L3Scalar}; + use asap_types::pre_asap::expr_ir::{CompareOp, ScalarValue}; use asap_types::pre_asap::query_expr::{Predicate, Source}; use asap_types::pre_asap::schema::{Column, DataType}; use asap_types::types::AccuracyTarget; @@ -681,7 +681,7 @@ mod tests { pred: Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(0)), op: CompareOp::Gt, - right: Box::new(QueryExpr::Literal(L3Scalar::Float64(0.5))), + right: Box::new(QueryExpr::Literal(ScalarValue::Float64(0.5))), })), child: Box::new(agg(vec![], default_quantile(0.99), metric_scan(&[]))), }; @@ -693,9 +693,9 @@ mod tests { fn having_and_multi_intent_stay_logical() { let mut q = agg(vec![2], default_quantile(0.99), metric_scan(&["job"])); if let QueryExpr::Aggregate { having, .. } = &mut q { - *having = Some(Predicate(Box::new(QueryExpr::Literal(L3Scalar::Boolean( - true, - ))))); + *having = Some(Predicate(Box::new(QueryExpr::Literal( + ScalarValue::Boolean(true), + )))); } assert!(matches!( implement_tree(&q).unwrap().expr, diff --git a/crates/frontend-promql/src/promql.rs b/crates/frontend-promql/src/promql.rs index c51cac0f..e59984a2 100644 --- a/crates/frontend-promql/src/promql.rs +++ b/crates/frontend-promql/src/promql.rs @@ -69,7 +69,7 @@ use asap_types::pre_asap::query_expr::{ AtModifier as L3AtModifier, BinaryOpKind, GroupKeys, GroupSide, L2QueryExpr as L2, Predicate, Reduction, SortKey, Source, TimeShift, VectorGrouping, VectorMatch, VectorMatchKind, }; -use asap_types::pre_asap::{ArithOp, ColumnRef, CompareOp, InfoMatcher, L3Scalar, SampleKind}; +use asap_types::pre_asap::{ArithOp, ColumnRef, CompareOp, InfoMatcher, SampleKind, ScalarValue}; use asap_types::types::AccuracyTarget; use crate::error::PromqlError as LoweringError; @@ -728,7 +728,7 @@ fn walk_histogram_quantiles(call: &Call) -> Result { }; Ok(L2::Relabel { dst: label.clone(), - value: Box::new(L2::Literal(L3Scalar::Utf8(open_metrics_float(phi)))), + value: Box::new(L2::Literal(ScalarValue::Utf8(open_metrics_float(phi)))), child: Box::new(quantile), }) }) @@ -975,8 +975,8 @@ fn walk_label(call: &Call) -> Result { name: "label_replace".into(), args: vec![ L2::Column(ColumnRef::Named(src)), - L2::Literal(L3Scalar::Utf8(regex)), - L2::Literal(L3Scalar::Utf8(replacement)), + L2::Literal(ScalarValue::Utf8(regex)), + L2::Literal(ScalarValue::Utf8(replacement)), ], }; Ok(L2::Relabel { @@ -994,7 +994,7 @@ fn walk_label(call: &Call) -> Result { } let dst = str_arg(call, 1)?; let sep = str_arg(call, 2)?; - let mut args = vec![L2::Literal(L3Scalar::Utf8(sep))]; + let mut args = vec![L2::Literal(ScalarValue::Utf8(sep))]; for i in 3..call.args.args.len() { args.push(L2::Column(ColumnRef::Named(str_arg(call, i)?))); } @@ -1795,7 +1795,7 @@ fn matcher_to_l3expr(m: &Matcher) -> L2 { L2::Compare { left: Box::new(L2::Column(ColumnRef::Named(m.name.clone()))), op, - right: Box::new(L2::Literal(L3Scalar::Utf8(m.value.clone()))), + right: Box::new(L2::Literal(ScalarValue::Utf8(m.value.clone()))), } } diff --git a/crates/frontend-promql/tests/promql_lowering.rs b/crates/frontend-promql/tests/promql_lowering.rs index 1f8a0f2a..0cc40d65 100644 --- a/crates/frontend-promql/tests/promql_lowering.rs +++ b/crates/frontend-promql/tests/promql_lowering.rs @@ -3,7 +3,7 @@ use std::time::Duration; use asap_types::pre_asap::{ - AggIntent, ArithOp, BinaryOpKind, CompareOp, L3Scalar, QueryExpr, Reduction, Source, + AggIntent, ArithOp, BinaryOpKind, CompareOp, QueryExpr, Reduction, ScalarValue, Source, }; use asap_types::types::AccuracyTarget; use asap_types::workload::{BatchEntry, Query, QueryLanguage, QueryRequirements, QueryWorkload}; @@ -50,7 +50,7 @@ fn regex_matcher_lowers_to_regex_compareop() { // The label matcher's column is resolved positionally against the scan schema. let path_id = schema.column_id("path").expect("path in scan schema"); assert!(matches!(left.as_ref(), QueryExpr::Column(id) if *id == path_id)); - assert!(matches!(right.as_ref(), QueryExpr::Literal(L3Scalar::Utf8(v)) if v == "/api/.*")); + assert!(matches!(right.as_ref(), QueryExpr::Literal(ScalarValue::Utf8(v)) if v == "/api/.*")); } // ── *_over_time → Aggregate over TimeRange ────────────────────────────────────── @@ -911,7 +911,7 @@ fn quantile_branches(q: &QueryExpr) -> Vec<(String, AggIntent)> { let QueryExpr::Relabel { value, child, .. } = c else { panic!("expected Relabel per branch, got {c:?}"); }; - let QueryExpr::Literal(L3Scalar::Utf8(v)) = value.as_ref() else { + let QueryExpr::Literal(ScalarValue::Utf8(v)) = value.as_ref() else { panic!("expected a literal label value, got {value:?}"); }; let QueryExpr::Aggregate { measures, .. } = child.as_ref() else { diff --git a/crates/frontend-sql/src/sql/expr.rs b/crates/frontend-sql/src/sql/expr.rs index 61ca690f..f877f14a 100644 --- a/crates/frontend-sql/src/sql/expr.rs +++ b/crates/frontend-sql/src/sql/expr.rs @@ -1,6 +1,6 @@ use datafusion::logical_expr::{BinaryExpr, Expr, Operator}; -use asap_types::pre_asap::{ArithOp, ColumnRef, CompareOp, L3Scalar}; +use asap_types::pre_asap::{ArithOp, ColumnRef, CompareOp, ScalarValue}; use crate::error::SqlError as LoweringError; @@ -88,11 +88,11 @@ pub(super) fn df_expr_to_l2(expr: &Expr) -> Result { Expr::Negative(inner) => { let inner_l3 = df_expr_to_l2(inner)?; match inner_l3 { - L2::Literal(L3Scalar::Int64(v)) => Ok(L2::Literal(L3Scalar::Int64(-v))), - L2::Literal(L3Scalar::Float64(v)) => Ok(L2::Literal(L3Scalar::Float64(-v))), + L2::Literal(ScalarValue::Int64(v)) => Ok(L2::Literal(ScalarValue::Int64(-v))), + L2::Literal(ScalarValue::Float64(v)) => Ok(L2::Literal(ScalarValue::Float64(-v))), other => Ok(L2::Arith { op: ArithOp::Mul, - left: Box::new(L2::Literal(L3Scalar::Int64(-1))), + left: Box::new(L2::Literal(ScalarValue::Int64(-1))), right: Box::new(other), }), } diff --git a/crates/frontend-sql/src/sql/mod.rs b/crates/frontend-sql/src/sql/mod.rs index f4566863..dc44d51f 100644 --- a/crates/frontend-sql/src/sql/mod.rs +++ b/crates/frontend-sql/src/sql/mod.rs @@ -27,7 +27,7 @@ use std::sync::Arc; use datafusion::catalog_common::MemorySchemaProvider; use datafusion::common::tree_node::{Transformed, TreeNode, TreeNodeRecursion}; -use datafusion::common::{Column as DfColumn, ScalarValue}; +use datafusion::common::{Column as DfColumn, ScalarValue as DfScalarValue}; use datafusion::datasource::MemTable; use datafusion::logical_expr::{ self, Distinct, Expr, JoinType, LogicalPlan, WindowFunctionDefinition, @@ -39,7 +39,9 @@ use asap_types::pre_asap::query_expr::{ GroupKeys, L2QueryExpr as L2, Predicate, ProjectItem, Reduction, SortKey, Source, }; use asap_types::pre_asap::schema::{DataType, Schema}; -use asap_types::pre_asap::{ColumnRef, CompareOp, JoinKind, L3Scalar, SetOpKind, WindowFuncKind}; +use asap_types::pre_asap::{ + ColumnRef, CompareOp, JoinKind, ScalarValue, SetOpKind, WindowFuncKind, +}; use asap_types::types::AccuracyTarget; use asap_types::workload::SqlDialect; @@ -375,7 +377,7 @@ impl<'a> SqlLowerer<'a> { // unconditional `JOIN` (`lower_join`, below). let pred = match correlation { Some(e) => Predicate(Box::new(df_expr_to_l2(&e)?)), - None => Predicate(Box::new(L2::Literal(L3Scalar::Boolean(true)))), + None => Predicate(Box::new(L2::Literal(ScalarValue::Boolean(true)))), }; Ok(L2::Join { kind, @@ -458,7 +460,7 @@ impl<'a> SqlLowerer<'a> { } let pred = Predicate(Box::new(match conjuncts.len() { // No condition (a CROSS JOIN) is unconditionally true. - 0 => L2::Literal(L3Scalar::Boolean(true)), + 0 => L2::Literal(ScalarValue::Boolean(true)), 1 => conjuncts.pop().unwrap(), _ => L2::BoolAnd(conjuncts), })); @@ -498,7 +500,7 @@ impl<'a> SqlLowerer<'a> { // Nth_value: lift N from the (literal) 2nd arg, keep only the column. let func = if matches!(func, WindowFuncKind::NthValue(None)) { let n = match args.get(1) { - Some(L2::Literal(L3Scalar::Int64(n))) if *n > 0 => *n as u64, + Some(L2::Literal(ScalarValue::Int64(n))) if *n > 0 => *n as u64, other => { return Err(LoweringError::InvalidExpression(format!( "NTH_VALUE requires a positive integer literal 2nd arg, got {other:?}" @@ -751,7 +753,7 @@ impl<'a> SqlLowerer<'a> { L2::Column(ColumnRef::Named(name.clone())) } else { L2::Cast { - expr: Box::new(L2::Literal(L3Scalar::Null)), + expr: Box::new(L2::Literal(ScalarValue::Null)), to: dtype.clone(), try_cast: false, } @@ -1238,8 +1240,8 @@ fn expr_to_group_ref(expr: &Expr) -> Result { fn extract_percentile_q(args: &[Expr]) -> Result { let q = match args.get(1) { - Some(Expr::Literal(ScalarValue::Float64(Some(q)))) => *q, - Some(Expr::Literal(ScalarValue::Float32(Some(q)))) => *q as f64, + Some(Expr::Literal(DfScalarValue::Float64(Some(q)))) => *q, + Some(Expr::Literal(DfScalarValue::Float32(Some(q)))) => *q as f64, _ => { return Err(LoweringError::InvalidExpression( "percentile value must be a float literal (2nd arg)".into(), @@ -1259,9 +1261,9 @@ fn extract_percentile_q(args: &[Expr]) -> Result { fn eval_fetch(expr_opt: &Option>) -> Option { expr_opt.as_ref().and_then(|e| match e.as_ref() { - Expr::Literal(ScalarValue::Int64(Some(v))) if *v >= 0 => Some(*v as usize), - Expr::Literal(ScalarValue::UInt64(Some(v))) => Some(*v as usize), - Expr::Literal(ScalarValue::Int32(Some(v))) if *v >= 0 => Some(*v as usize), + Expr::Literal(DfScalarValue::Int64(Some(v))) if *v >= 0 => Some(*v as usize), + Expr::Literal(DfScalarValue::UInt64(Some(v))) => Some(*v as usize), + Expr::Literal(DfScalarValue::Int32(Some(v))) if *v >= 0 => Some(*v as usize), _ => None, }) } diff --git a/crates/frontend-sql/src/sql/types.rs b/crates/frontend-sql/src/sql/types.rs index 6eaacb6e..3afca01b 100644 --- a/crates/frontend-sql/src/sql/types.rs +++ b/crates/frontend-sql/src/sql/types.rs @@ -7,10 +7,10 @@ use std::collections::HashMap; use datafusion::arrow::datatypes::{ DataType as ArrowDataType, Field, Fields, Schema as ArrowSchema, }; -use datafusion::common::ScalarValue; +use datafusion::common::ScalarValue as DfScalarValue; use asap_types::pre_asap::schema::{Column, DataType, Schema}; -use asap_types::pre_asap::L3Scalar; +use asap_types::pre_asap::ScalarValue; use crate::error::SqlError as LoweringError; @@ -37,23 +37,23 @@ impl SqlCatalog { } } -pub(super) fn scalar_value_to_l3(sv: &ScalarValue) -> Result { +pub(super) fn scalar_value_to_l3(sv: &DfScalarValue) -> Result { match sv { - ScalarValue::Int64(Some(v)) => Ok(L3Scalar::Int64(*v)), - ScalarValue::Int32(Some(v)) => Ok(L3Scalar::Int64(*v as i64)), - ScalarValue::Int16(Some(v)) => Ok(L3Scalar::Int64(*v as i64)), - ScalarValue::Int8(Some(v)) => Ok(L3Scalar::Int64(*v as i64)), - ScalarValue::UInt64(Some(v)) => i64::try_from(*v).map(L3Scalar::Int64).map_err(|_| { + DfScalarValue::Int64(Some(v)) => Ok(ScalarValue::Int64(*v)), + DfScalarValue::Int32(Some(v)) => Ok(ScalarValue::Int64(*v as i64)), + DfScalarValue::Int16(Some(v)) => Ok(ScalarValue::Int64(*v as i64)), + DfScalarValue::Int8(Some(v)) => Ok(ScalarValue::Int64(*v as i64)), + DfScalarValue::UInt64(Some(v)) => i64::try_from(*v).map(ScalarValue::Int64).map_err(|_| { LoweringError::InvalidExpression(format!("UInt64 value {v} overflows i64")) }), - ScalarValue::UInt32(Some(v)) => Ok(L3Scalar::Int64(*v as i64)), - ScalarValue::Float64(Some(v)) => Ok(L3Scalar::Float64(*v)), - ScalarValue::Float32(Some(v)) => Ok(L3Scalar::Float64(*v as f64)), - ScalarValue::Utf8(Some(s)) | ScalarValue::LargeUtf8(Some(s)) => { - Ok(L3Scalar::Utf8(s.clone())) + DfScalarValue::UInt32(Some(v)) => Ok(ScalarValue::Int64(*v as i64)), + DfScalarValue::Float64(Some(v)) => Ok(ScalarValue::Float64(*v)), + DfScalarValue::Float32(Some(v)) => Ok(ScalarValue::Float64(*v as f64)), + DfScalarValue::Utf8(Some(s)) | DfScalarValue::LargeUtf8(Some(s)) => { + Ok(ScalarValue::Utf8(s.clone())) } - ScalarValue::Boolean(Some(b)) => Ok(L3Scalar::Boolean(*b)), - _ if sv.is_null() => Ok(L3Scalar::Null), + DfScalarValue::Boolean(Some(b)) => Ok(ScalarValue::Boolean(*b)), + _ if sv.is_null() => Ok(ScalarValue::Null), _ => Err(LoweringError::InvalidExpression(format!( "unsupported scalar: {sv:?}" ))), diff --git a/crates/frontend-sql/tests/sql_lowering.rs b/crates/frontend-sql/tests/sql_lowering.rs index 9251ec35..594cc372 100644 --- a/crates/frontend-sql/tests/sql_lowering.rs +++ b/crates/frontend-sql/tests/sql_lowering.rs @@ -8,7 +8,7 @@ use asap_frontend_sql::{lower_sql, SqlCatalog}; use asap_types::pre_asap::schema::{Column, DataType, Schema}; use asap_types::pre_asap::{ - AggIntent, CompareOp, GroupKeys, JoinKind, L3Scalar, QueryExpr, Reduction, Source, + AggIntent, CompareOp, GroupKeys, JoinKind, QueryExpr, Reduction, ScalarValue, Source, WindowFuncKind, }; use asap_types::types::AccuracyTarget; @@ -882,7 +882,7 @@ async fn an_uncorrelated_exists_is_an_unconditional_semi_join() { let qe = lower("SELECT service FROM metrics WHERE EXISTS (SELECT 1 FROM hosts)").await; let (kind, pred, _) = join_parts(&qe); assert_eq!(kind, &JoinKind::Semi); - assert_eq!(*pred, QueryExpr::Literal(L3Scalar::Boolean(true))); + assert_eq!(*pred, QueryExpr::Literal(ScalarValue::Boolean(true))); } #[tokio::test] diff --git a/crates/integration-tests/tests/nested.rs b/crates/integration-tests/tests/nested.rs index 36bfe67b..64dad5b5 100644 --- a/crates/integration-tests/tests/nested.rs +++ b/crates/integration-tests/tests/nested.rs @@ -13,8 +13,8 @@ use std::time::Duration; use asap_frontend_promql::lower_promql; use asap_integration_tests::fixtures::metric_schema; use asap_types::pre_asap::{ - AggIntent, ArithOp, AtModifier, BinaryOpKind, CompareOp, GroupKeys, L3Scalar, Predicate, - QueryExpr, Reduction, Source, TimeShift, VectorMatch, VectorMatchKind, + AggIntent, ArithOp, AtModifier, BinaryOpKind, CompareOp, GroupKeys, Predicate, QueryExpr, + Reduction, ScalarValue, Source, TimeShift, VectorMatch, VectorMatchKind, }; use asap_types::types::AccuracyTarget; @@ -79,7 +79,7 @@ fn q23_sum_by_job_over_filtered_scan() { predicates: vec![Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(3)), op: CompareOp::Eq, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8("200".into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8("200".into()))), }))], schema: metric_schema(&["job", "status"]), }; @@ -104,7 +104,7 @@ fn q25_div_over_complex_subtrees() { predicates: vec![Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(3)), op: CompareOp::Eq, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8("200".into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8("200".into()))), }))], schema: metric_schema(&["job", "status"]), }; @@ -197,7 +197,7 @@ fn q53_outer_group_key_absent_from_nested_aggregate() { predicates: vec![Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(3)), op: CompareOp::Eq, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8("api-server".into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8("api-server".into()))), }))], schema: metric_schema(&["group", "job"]), }; @@ -225,7 +225,7 @@ fn q52_outer_name_label_over_binary_op() { predicates: vec![Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(2)), // env op: CompareOp::Eq, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8(env.into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8(env.into()))), }))], schema: metric_schema(&["env", "__name__"]), }; @@ -352,7 +352,7 @@ fn q24_sum_by_job_over_rate_over_filtered_scan() { predicates: vec![Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(3)), op: CompareOp::Eq, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8("200".into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8("200".into()))), }))], schema: metric_schema(&["job", "status"]), }; diff --git a/crates/integration-tests/tests/scan.rs b/crates/integration-tests/tests/scan.rs index 695e3a95..c1643ad7 100644 --- a/crates/integration-tests/tests/scan.rs +++ b/crates/integration-tests/tests/scan.rs @@ -8,7 +8,7 @@ use asap_frontend_promql::lower_promql; use asap_integration_tests::fixtures::metric_schema; -use asap_types::pre_asap::{CompareOp, L3Scalar, Predicate, QueryExpr, Source}; +use asap_types::pre_asap::{CompareOp, Predicate, QueryExpr, ScalarValue, Source}; use asap_types::types::AccuracyTarget; fn lower(q: &str) -> QueryExpr { @@ -29,7 +29,7 @@ fn eq_pred(col_id: usize, value: &str) -> Predicate { Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(col_id)), op: CompareOp::Eq, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8(value.into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8(value.into()))), })) } @@ -37,7 +37,7 @@ fn ne_pred(col_id: usize, value: &str) -> Predicate { Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(col_id)), op: CompareOp::Ne, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8(value.into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8(value.into()))), })) } @@ -45,7 +45,7 @@ fn regex_pred(col_id: usize, pattern: &str) -> Predicate { Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(col_id)), op: CompareOp::Regex, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8(pattern.into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8(pattern.into()))), })) } @@ -53,7 +53,7 @@ fn notregex_pred(col_id: usize, pattern: &str) -> Predicate { Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(col_id)), op: CompareOp::NotRegex, - right: Box::new(QueryExpr::Literal(L3Scalar::Utf8(pattern.into()))), + right: Box::new(QueryExpr::Literal(ScalarValue::Utf8(pattern.into()))), })) } diff --git a/crates/types/src/dag_export.rs b/crates/types/src/dag_export.rs index ecce6de6..f938a2a4 100644 --- a/crates/types/src/dag_export.rs +++ b/crates/types/src/dag_export.rs @@ -394,7 +394,7 @@ fn build(expr: &QueryExpr, nodes: &mut Vec) -> u32 { mod tests { use super::*; use crate::pre_asap::agg_intent::AggIntent; - use crate::pre_asap::expr_ir::L3Scalar; + use crate::pre_asap::expr_ir::ScalarValue; use crate::pre_asap::query_expr::{GroupKeys, Predicate, Reduction}; use crate::pre_asap::schema::{Column, DataType, Schema}; use crate::types::AccuracyTarget; @@ -430,7 +430,7 @@ mod tests { #[test] fn chain_preserves_shape_and_child_links() { let expr = QueryExpr::Filter { - pred: Predicate(Box::new(QueryExpr::Literal(L3Scalar::Boolean(true)))), + pred: Predicate(Box::new(QueryExpr::Literal(ScalarValue::Boolean(true)))), child: Box::new(QueryExpr::Aggregate { reduction: Reduction::Reduce(GroupKeys::none()), measures: vec![AggIntent::Count { diff --git a/crates/types/src/pre_asap/canonicalize.rs b/crates/types/src/pre_asap/canonicalize.rs index 0c3f516d..125d55e4 100644 --- a/crates/types/src/pre_asap/canonicalize.rs +++ b/crates/types/src/pre_asap/canonicalize.rs @@ -25,7 +25,7 @@ //! is exactly the SQL alias gap (#20) the old front-end gate missed. use super::agg_intent::{is_frequency_heavy_hitter, ranking_measure, AggIntent}; -use super::expr_ir::{CompareOp, L3Scalar}; +use super::expr_ir::{CompareOp, ScalarValue}; use super::query_expr::{Predicate, QueryExpr, Reduction, SortKey, WindowFuncKind}; /// Rewrite `expr` into its canonical form (bottom-up). Idempotent: a tree that @@ -213,7 +213,7 @@ fn try_rewrite_rownumber_topk(expr: &QueryExpr) -> Option { if *op != CompareOp::Le { return None; } - let (QueryExpr::Column(rn_col), QueryExpr::Literal(L3Scalar::Int64(k))) = + let (QueryExpr::Column(rn_col), QueryExpr::Literal(ScalarValue::Int64(k))) = (left.as_ref(), right.as_ref()) else { return None; @@ -468,7 +468,7 @@ mod tests { pred: Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(3)), // rn = the appended window column op: CompareOp::Le, - right: Box::new(QueryExpr::Literal(L3Scalar::Int64(5))), + right: Box::new(QueryExpr::Literal(ScalarValue::Int64(5))), })), child: Box::new(wf), } @@ -552,7 +552,7 @@ mod tests { pred: Predicate(Box::new(QueryExpr::Compare { left: Box::new(QueryExpr::Column(0)), // NOT the rn column (index 3) op: CompareOp::Le, - right: Box::new(QueryExpr::Literal(L3Scalar::Int64(5))), + right: Box::new(QueryExpr::Literal(ScalarValue::Int64(5))), })), child: Box::new(wf), }; diff --git a/crates/types/src/pre_asap/expr_ir.rs b/crates/types/src/pre_asap/expr_ir.rs index 4b04d5ab..85aa9391 100644 --- a/crates/types/src/pre_asap/expr_ir.rs +++ b/crates/types/src/pre_asap/expr_ir.rs @@ -11,7 +11,7 @@ //! [`ColumnId`](super::schema::ColumnId) (positional, once bound). //! //! What's left here is the vocabulary those scalar variants are built from — -//! [`L3Scalar`], [`CompareOp`], [`ArithOp`] — the **union** of what the two +//! [`ScalarValue`], [`CompareOp`], [`ArithOp`] — the **union** of what the two //! front ends need: PromQL contributes `Regex` / `NotRegex` (`=~` / `!~`); SQL //! contributes arithmetic, `CASE`, `IN`, `CAST`, `IS [NOT] NULL`, scalar //! function calls, and the `LIKE` / `ILIKE` comparison family. @@ -41,7 +41,7 @@ pub enum ColumnRef { /// A typed scalar constant. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub enum L3Scalar { +pub enum ScalarValue { Int64(i64), Float64(f64), Utf8(String), diff --git a/crates/types/src/pre_asap/mod.rs b/crates/types/src/pre_asap/mod.rs index 6964bff9..93eefd14 100644 --- a/crates/types/src/pre_asap/mod.rs +++ b/crates/types/src/pre_asap/mod.rs @@ -7,7 +7,7 @@ //! bound, name-based [`ColumnRef`] before). //! - [`agg_intent`] — the L3 aggregation-intent vocabulary. //! - [`expr_ir`] — the [`ColumnRef`] column-reference type and the scalar -//! operator/literal vocabulary ([`L3Scalar`], [`CompareOp`], [`ArithOp`]) +//! operator/literal vocabulary ([`ScalarValue`], [`CompareOp`], [`ArithOp`]) //! [`QueryExpr`]'s scalar variants are built from. //! - [`schema`] — the per-edge [`Schema`] every L3 node carries. //! - [`binder`] / [`column_resolution`] — name resolution: turn a `ColumnRef` @@ -45,7 +45,7 @@ pub use column_resolution::{ output_schema_for_aggregate, resolve_column_ref, resolve_column_refs, resolve_expr, ResolveError, }; -pub use expr_ir::{ArithOp, ColumnRef, CompareOp, L3Scalar}; +pub use expr_ir::{ArithOp, ColumnRef, CompareOp, ScalarValue}; pub use query_expr::{ aggregate_output_schema, AtModifier, BinaryOpKind, ColState, DataModel, GroupKeys, GroupSide, InfoMatcher, JoinKind, L2QueryExpr, L3QueryExpr, Predicate, ProjectItem, QueryExpr, diff --git a/crates/types/src/pre_asap/query_expr.rs b/crates/types/src/pre_asap/query_expr.rs index b6632011..37b224a7 100644 --- a/crates/types/src/pre_asap/query_expr.rs +++ b/crates/types/src/pre_asap/query_expr.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use super::agg_intent::AggIntent; -use super::expr_ir::{ArithOp, ColumnRef, CompareOp, L3Scalar}; +use super::expr_ir::{ArithOp, ColumnRef, CompareOp, ScalarValue}; use super::schema::{Column, ColumnId, DataType, Schema}; /// The column-reference resolution state a [`QueryExpr`] tree carries — @@ -751,7 +751,7 @@ pub enum QueryExpr { /// ColumnRef`) or positional [`ColumnId`] (once bound, `C = ColumnId`). Column(C), /// A constant literal value. - Literal(L3Scalar), + Literal(ScalarValue), /// `left op right` — binary comparison. Compare { left: Box>, @@ -1359,11 +1359,11 @@ fn infer_expr_type(expr: &QueryExpr, schema: &Schema) -> (DataType, bo .map(|c| (c.dtype.clone(), c.nullable)) .unwrap_or((DataType::Float64, true)), QueryExpr::Literal(s) => match s { - L3Scalar::Int64(_) => (DataType::Int64, false), - L3Scalar::Float64(_) => (DataType::Float64, false), - L3Scalar::Utf8(_) => (DataType::Utf8, false), - L3Scalar::Boolean(_) => (DataType::Bool, false), - L3Scalar::Null => (DataType::Float64, true), + ScalarValue::Int64(_) => (DataType::Int64, false), + ScalarValue::Float64(_) => (DataType::Float64, false), + ScalarValue::Utf8(_) => (DataType::Utf8, false), + ScalarValue::Boolean(_) => (DataType::Bool, false), + ScalarValue::Null => (DataType::Float64, true), }, // Boolean-valued expressions (SQL three-valued logic → nullable). QueryExpr::Compare { .. } @@ -1544,7 +1544,7 @@ mod tests { expr: QueryExpr::Compare { left: Box::new(QueryExpr::Column(2)), op: CompareOp::Gt, - right: Box::new(QueryExpr::Literal(L3Scalar::Float64(0.0))), + right: Box::new(QueryExpr::Literal(ScalarValue::Float64(0.0))), }, }, ], @@ -1836,7 +1836,7 @@ mod tests { let right = scan(vec![col("b", DataType::Utf8, false)], None, vec![]); QueryExpr::Join { kind, - pred: Predicate(Box::new(QueryExpr::Literal(L3Scalar::Boolean(true)))), + pred: Predicate(Box::new(QueryExpr::Literal(ScalarValue::Boolean(true)))), left: Box::new(left), right: Box::new(right), }