Skip to content

Commit d3ec359

Browse files
authored
feat: support COUNT(DISTINCT expr) in Cypher queries (#116)
1 parent 7586012 commit d3ec359

7 files changed

Lines changed: 591 additions & 115 deletions

File tree

crates/lance-graph/src/ast.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,11 +316,20 @@ pub enum ValueExpression {
316316
Property(PropertyRef),
317317
/// Literal value
318318
Literal(PropertyValue),
319-
/// Function call
320-
Function {
319+
/// Scalar function call (toLower, upper, etc.)
320+
/// These are row-level functions that operate on individual values
321+
ScalarFunction {
321322
name: String,
322323
args: Vec<ValueExpression>,
323324
},
325+
/// Aggregate function call (COUNT, SUM, AVG, MIN, MAX, COLLECT)
326+
/// These functions operate across multiple rows and support DISTINCT
327+
AggregateFunction {
328+
name: String,
329+
args: Vec<ValueExpression>,
330+
/// Whether DISTINCT keyword was specified (e.g., COUNT(DISTINCT x))
331+
distinct: bool,
332+
},
324333
/// Arithmetic operation
325334
Arithmetic {
326335
left: Box<ValueExpression>,
@@ -348,6 +357,27 @@ pub enum ValueExpression {
348357
VectorLiteral(Vec<f32>),
349358
}
350359

360+
/// Function type classification
361+
#[derive(Debug, Clone, PartialEq)]
362+
pub enum FunctionType {
363+
/// Aggregate function (operates across multiple rows)
364+
Aggregate,
365+
/// Scalar function (operates on individual values)
366+
Scalar,
367+
/// Unknown function type
368+
Unknown,
369+
}
370+
371+
/// Classify a function by name
372+
pub fn classify_function(name: &str) -> FunctionType {
373+
match name.to_lowercase().as_str() {
374+
"count" | "sum" | "avg" | "min" | "max" | "collect" => FunctionType::Aggregate,
375+
"tolower" | "lower" | "toupper" | "upper" => FunctionType::Scalar,
376+
// Vector functions are handled separately as special variants
377+
_ => FunctionType::Unknown,
378+
}
379+
}
380+
351381
/// Arithmetic operators
352382
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
353383
pub enum ArithmeticOperator {

crates/lance-graph/src/datafusion_planner/builder/aggregate_ops.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ mod tests {
8888
let project = LogicalOperator::Project {
8989
input: Box::new(scan),
9090
projections: vec![ProjectionItem {
91-
expression: ValueExpression::Function {
91+
expression: ValueExpression::AggregateFunction {
9292
name: "count".to_string(),
9393
args: vec![ValueExpression::Variable("*".to_string())],
94+
distinct: false,
9495
},
9596
alias: Some("total".to_string()),
9697
}],
@@ -114,9 +115,10 @@ mod tests {
114115
let project = LogicalOperator::Project {
115116
input: Box::new(scan),
116117
projections: vec![ProjectionItem {
117-
expression: ValueExpression::Function {
118+
expression: ValueExpression::AggregateFunction {
118119
name: "count".to_string(),
119120
args: vec![ValueExpression::Variable("*".to_string())],
121+
distinct: false,
120122
},
121123
alias: None,
122124
}],

0 commit comments

Comments
 (0)