Added parsing of offset clause

This commit is contained in:
ben594
2025-01-23 10:16:35 -05:00
parent a3c0602452
commit d03a0dbd39
4 changed files with 28 additions and 10 deletions

View File

@@ -44,8 +44,8 @@ pub fn prepare_delete_plan(
// Parse the WHERE clause
let resolved_where_clauses = parse_where(where_clause, &referenced_tables)?;
// Parse the LIMIT clause
let resolved_limit = limit.and_then(|l| parse_limit(*l));
// Parse the LIMIT/OFFSET clause
let (resolved_limit, resolved_offset) = limit.map_or(Ok((None, None)), |l| parse_limit(*l))?;
let plan = DeletePlan {
source: SourceOperator::Scan {
@@ -58,6 +58,7 @@ pub fn prepare_delete_plan(
where_clause: resolved_where_clauses,
order_by: None,
limit: resolved_limit,
offset: resolved_offset,
referenced_tables,
available_indexes: vec![],
contains_constant_false_condition: false,

View File

@@ -65,6 +65,8 @@ pub struct SelectPlan {
pub aggregates: Vec<Aggregate>,
/// limit clause
pub limit: Option<usize>,
/// offset clause
pub offset: Option<usize>,
/// all the tables referenced in the query
pub referenced_tables: Vec<TableReference>,
/// all the indexes available
@@ -88,6 +90,8 @@ pub struct DeletePlan {
pub order_by: Option<Vec<(ast::Expr, Direction)>>,
/// limit clause
pub limit: Option<usize>,
/// offset clause
pub offset: Option<usize>,
/// all the tables referenced in the query
pub referenced_tables: Vec<TableReference>,
/// all the indexes available

View File

@@ -566,19 +566,30 @@ fn parse_join(
})
}
pub fn parse_limit(limit: Limit) -> Option<usize> {
pub fn parse_limit(limit: Limit) -> Result<(Option<usize>, Option<usize>)> {
let offset = match limit.offset {
Some(offset_expr) => {
if let Expr::Literal(ast::Literal::Numeric(n)) = offset_expr {
n.parse().ok()
} else {
crate::bail_parse_error!("Invalid OFFSET clause");
}
}
None => Some(0),
};
if let Expr::Literal(ast::Literal::Numeric(n)) = limit.expr {
n.parse().ok()
Ok((n.parse().ok(), offset))
} else if let Expr::Id(id) = limit.expr {
if id.0.eq_ignore_ascii_case("true") {
Some(1)
Ok((Some(1), offset))
} else if id.0.eq_ignore_ascii_case("false") {
Some(0)
Ok((Some(0), offset))
} else {
None
crate::bail_parse_error!("Invalid LIMIT clause");
}
} else {
None
crate::bail_parse_error!("Invalid LIMIT clause");
}
}

View File

@@ -57,6 +57,7 @@ pub fn prepare_select_plan(
order_by: None,
aggregates: vec![],
limit: None,
offset: None,
referenced_tables,
available_indexes: schema.indexes.clone().into_values().flatten().collect(),
contains_constant_false_condition: false,
@@ -326,8 +327,9 @@ pub fn prepare_select_plan(
plan.order_by = Some(key);
}
// Parse the LIMIT clause
plan.limit = select.limit.and_then(|l| parse_limit(*l));
// Parse the LIMIT/OFFSET clause
(plan.limit, plan.offset) =
select.limit.map_or(Ok((None, None)), |l| parse_limit(*l))?;
// Return the unoptimized query plan
Ok(Plan::Select(plan))