add empty table references, and error out in case if the table references are present in limit/offset

This commit is contained in:
bit-aloo
2025-08-24 17:55:30 +05:30
parent a3b87cd97f
commit 51d40092db
4 changed files with 24 additions and 9 deletions

View File

@@ -2,7 +2,7 @@ use crate::schema::Table;
use crate::translate::emitter::emit_program;
use crate::translate::optimizer::optimize_plan;
use crate::translate::plan::{DeletePlan, Operation, Plan};
use crate::translate::planner::parse_where;
use crate::translate::planner::{parse_limit, parse_where};
use crate::util::normalize_ident;
use crate::vdbe::builder::{ProgramBuilder, ProgramBuilderOpts, TableRefIdCounter};
use crate::{schema::Schema, Result, SymbolTable};
@@ -108,7 +108,7 @@ pub fn prepare_delete_plan(
// Parse the LIMIT/OFFSET clause
let (resolved_limit, resolved_offset) =
limit.map_or((None, None), |l| (Some(l.expr), l.offset));
limit.map_or(Ok((None, None)), |mut l| parse_limit(&mut l, connection))?;
let plan = DeletePlan {
table_references,

View File

@@ -12,6 +12,7 @@ use super::{
};
use crate::translate::expr::WalkControl;
use crate::{
ast::Limit,
function::Func,
schema::{Schema, Table},
translate::expr::walk_expr_mut,
@@ -1138,3 +1139,16 @@ where
}
Ok(None)
}
#[allow(clippy::type_complexity)]
pub fn parse_limit(
limit: &mut Limit,
connection: &std::sync::Arc<crate::Connection>,
) -> Result<(Option<Box<Expr>>, Option<Box<Expr>>)> {
let mut empty_refs = TableReferences::new(Vec::new(), Vec::new());
bind_column_references(&mut limit.expr, &mut empty_refs, None, connection)?;
if let Some(ref mut off_expr) = limit.offset {
bind_column_references(off_expr, &mut empty_refs, None, connection)?;
}
Ok((Some(limit.expr.clone()), limit.offset.clone()))
}

View File

@@ -8,8 +8,8 @@ use crate::schema::Table;
use crate::translate::optimizer::optimize_plan;
use crate::translate::plan::{Aggregate, GroupBy, Plan, ResultSetColumn, SelectPlan};
use crate::translate::planner::{
bind_column_references, break_predicate_at_and_boundaries, parse_from, parse_where,
resolve_aggregates,
bind_column_references, break_predicate_at_and_boundaries, parse_from, parse_limit,
parse_where, resolve_aggregates,
};
use crate::util::normalize_ident;
use crate::vdbe::builder::{ProgramBuilderOpts, TableRefIdCounter};
@@ -151,7 +151,7 @@ pub fn prepare_select_plan(
}
let (limit, offset) = select
.limit
.map_or((None, None), |l| (Some(l.expr), l.offset));
.map_or(Ok((None, None)), |mut l| parse_limit(&mut l, connection))?;
// FIXME: handle ORDER BY for compound selects
if !select.order_by.is_empty() {
@@ -621,8 +621,8 @@ fn prepare_one_select_plan(
plan.order_by = key;
// Parse the LIMIT/OFFSET clause
(plan.limit, plan.offset) = limit.map_or((None, None), |l| (Some(l.expr), l.offset));
(plan.limit, plan.offset) =
limit.map_or(Ok((None, None)), |mut l| parse_limit(&mut l, connection))?;
// Return the unoptimized query plan
Ok(plan)
}

View File

@@ -4,6 +4,7 @@ use std::sync::Arc;
use crate::schema::{BTreeTable, Column, Type};
use crate::translate::optimizer::optimize_select_plan;
use crate::translate::plan::{Operation, QueryDestination, Scan, Search, SelectPlan};
use crate::translate::planner::parse_limit;
use crate::vdbe::builder::CursorType;
use crate::{
bail_parse_error,
@@ -332,8 +333,8 @@ pub fn prepare_update_plan(
// Parse the LIMIT/OFFSET clause
let (limit, offset) = body
.limit
.as_ref()
.map_or((None, None), |l| (Some(l.expr.clone()), l.offset.clone()));
.as_mut()
.map_or(Ok((None, None)), |l| parse_limit(l, connection))?;
// Check what indexes will need to be updated by checking set_clauses and see
// if a column is contained in an index.