-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor!: proof_of_sql_parser::intermediate_ast::OrderBy
with sqlparser::ast::OrderByExpr
in the proof-of-sql crate
#450
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ use crate::base::{ | |
}; | ||
use alloc::vec::Vec; | ||
use core::cmp::Ordering; | ||
use proof_of_sql_parser::intermediate_ast::OrderByDirection; | ||
use sqlparser::ast::{Expr, OrderByExpr}; | ||
|
||
/// Compares the tuples `(order_by[0][i], order_by[1][i], ...)` and | ||
/// `(order_by[0][j], order_by[1][j], ...)` in lexicographic order. | ||
|
@@ -110,22 +110,47 @@ pub(crate) fn compare_indexes_by_owned_columns<S: Scalar>( | |
) -> Ordering { | ||
let order_by_pairs = order_by | ||
.iter() | ||
.map(|&col| (col.clone(), OrderByDirection::Asc)) | ||
.map(|&col| { | ||
( | ||
col.clone(), | ||
OrderByExpr { | ||
expr: owned_column_to_expr(col), | ||
asc: Some(true), | ||
nulls_first: None, | ||
}, | ||
) | ||
}) | ||
.collect::<Vec<_>>(); | ||
compare_indexes_by_owned_columns_with_direction(&order_by_pairs, i, j) | ||
} | ||
|
||
/// Converts an `OwnedColumn` into an SQL `Expr` for use in `OrderByExpr`. | ||
fn owned_column_to_expr<S: Scalar>(col: &OwnedColumn<S>) -> Expr { | ||
match col { | ||
OwnedColumn::Boolean(_) => Expr::Identifier("BooleanColumn".into()), | ||
OwnedColumn::TinyInt(_) => Expr::Identifier("TinyIntColumn".into()), | ||
OwnedColumn::SmallInt(_) => Expr::Identifier("SmallIntColumn".into()), | ||
OwnedColumn::Int(_) => Expr::Identifier("IntColumn".into()), | ||
OwnedColumn::BigInt(_) => Expr::Identifier("BigIntColumn".into()), | ||
OwnedColumn::VarChar(_) => Expr::Identifier("VarCharColumn".into()), | ||
OwnedColumn::Int128(_) => Expr::Identifier("Int128Column".into()), | ||
OwnedColumn::Decimal75(_, _, _) => Expr::Identifier("DecimalColumn".into()), | ||
OwnedColumn::Scalar(_) => Expr::Identifier("ScalarColumn".into()), | ||
OwnedColumn::TimestampTZ(_, _, _) => Expr::Identifier("TimestampColumn".into()), | ||
} | ||
} | ||
Comment on lines
+128
to
+141
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm this leads to duplicates, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I ha ve implemented it for bidirectional as some places needed it. i will debug and fix if we doesn't needed it |
||
|
||
/// Compares the tuples `(left[0][i], left[1][i], ...)` and | ||
/// `(right[0][j], right[1][j], ...)` in lexicographic order. | ||
/// Note that direction flips the ordering. | ||
pub(crate) fn compare_indexes_by_owned_columns_with_direction<S: Scalar>( | ||
order_by_pairs: &[(OwnedColumn<S>, OrderByDirection)], | ||
order_by_pairs: &[(OwnedColumn<S>, OrderByExpr)], | ||
i: usize, | ||
j: usize, | ||
) -> Ordering { | ||
order_by_pairs | ||
.iter() | ||
.map(|(col, direction)| { | ||
.map(|(col, order_by_expr)| { | ||
let ordering = match col { | ||
OwnedColumn::Boolean(col) => col[i].cmp(&col[j]), | ||
OwnedColumn::TinyInt(col) => col[i].cmp(&col[j]), | ||
|
@@ -139,9 +164,9 @@ pub(crate) fn compare_indexes_by_owned_columns_with_direction<S: Scalar>( | |
OwnedColumn::Scalar(col) => col[i].cmp(&col[j]), | ||
OwnedColumn::VarChar(col) => col[i].cmp(&col[j]), | ||
}; | ||
match direction { | ||
OrderByDirection::Asc => ordering, | ||
OrderByDirection::Desc => ordering.reverse(), | ||
match order_by_expr.asc { | ||
Some(false) => ordering.reverse(), // DESC | ||
None | Some(true) => ordering, // Default to ASC or explicitly ASC | ||
} | ||
}) | ||
.find(|&ord| ord != Ordering::Equal) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,20 +7,20 @@ use crate::base::{ | |
scalar::Scalar, | ||
}; | ||
use alloc::{string::ToString, vec::Vec}; | ||
use proof_of_sql_parser::intermediate_ast::{OrderBy, OrderByDirection}; | ||
use serde::{Deserialize, Serialize}; | ||
use sqlparser::ast::{Expr, OrderByExpr}; | ||
|
||
/// A node representing a list of `OrderBy` expressions. | ||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||
pub struct OrderByPostprocessing { | ||
by_exprs: Vec<OrderBy>, | ||
order_by_exprs: Vec<OrderByExpr>, | ||
} | ||
|
||
impl OrderByPostprocessing { | ||
/// Create a new `OrderByPostprocessing` node. | ||
#[must_use] | ||
pub fn new(by_exprs: Vec<OrderBy>) -> Self { | ||
Self { by_exprs } | ||
pub fn new(order_by_exprs: Vec<OrderByExpr>) -> Self { | ||
Self { order_by_exprs } | ||
} | ||
} | ||
|
||
|
@@ -29,25 +29,38 @@ impl<S: Scalar> PostprocessingStep<S> for OrderByPostprocessing { | |
fn apply(&self, owned_table: OwnedTable<S>) -> PostprocessingResult<OwnedTable<S>> { | ||
// Evaluate the columns by which we order | ||
// Once we allow OrderBy for general aggregation-free expressions here we will need to call eval() | ||
let order_by_pairs: Vec<(OwnedColumn<S>, OrderByDirection)> = self | ||
.by_exprs | ||
let order_by_pairs: Vec<(OwnedColumn<S>, OrderByExpr)> = self | ||
.order_by_exprs | ||
.iter() | ||
.map( | ||
|order_by| -> PostprocessingResult<(OwnedColumn<S>, OrderByDirection)> { | ||
let identifier: sqlparser::ast::Ident = order_by.expr.into(); | ||
Ok(( | ||
owned_table | ||
.inner_table() | ||
.get(&identifier) | ||
.ok_or(PostprocessingError::ColumnNotFound { | ||
column: order_by.expr.to_string(), | ||
})? | ||
.clone(), | ||
order_by.direction, | ||
)) | ||
|order_by| -> PostprocessingResult<(OwnedColumn<S>, OrderByExpr)> { | ||
let identifier = match &order_by.expr { | ||
Expr::Identifier(ident) => ident.clone(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can order by expressions such as c0 + c1, not identifiers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If expressions are needed I think we need some rework here and I will revisit later here once all the open PRs are get merged |
||
_ => { | ||
return Err(PostprocessingError::InvalidExpression { | ||
expression: order_by.expr.to_string(), | ||
}); | ||
} | ||
}; | ||
|
||
let column = owned_table | ||
.inner_table() | ||
.get(&identifier) | ||
.ok_or(PostprocessingError::ColumnNotFound { | ||
column: order_by.expr.to_string(), | ||
})? | ||
.clone(); | ||
|
||
let order_by_expr = OrderByExpr { | ||
expr: Expr::Identifier(identifier.clone()), | ||
asc: order_by.asc, | ||
nulls_first: order_by.nulls_first, | ||
}; | ||
|
||
Ok((column, order_by_expr)) | ||
}, | ||
) | ||
.collect::<PostprocessingResult<Vec<(OwnedColumn<S>, OrderByDirection)>>>()?; | ||
.collect::<PostprocessingResult<Vec<(OwnedColumn<S>, OrderByExpr)>>>()?; | ||
// Define the ordering | ||
let permutation = Permutation::unchecked_new_from_cmp(owned_table.num_rows(), |&a, &b| { | ||
compare_indexes_by_owned_columns_with_direction(&order_by_pairs, a, b) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK we can't do this since expressions are not by default identifiers.