Implement #216: order by column number

This commit is contained in:
jussisaurio
2024-07-26 14:32:58 +03:00
parent a1093501a0
commit e3cc3da7ca
2 changed files with 25 additions and 2 deletions

View File

@@ -9,7 +9,7 @@ use crate::types::{OwnedRecord, OwnedValue};
use crate::vdbe::{builder::ProgramBuilder, BranchOffset, Program};
use crate::Result;
use sqlite3_parser::ast::{self, JoinOperator, JoinType};
use sqlite3_parser::ast::{self, JoinOperator, JoinType, ResultColumn};
use std::rc::Rc;
@@ -305,7 +305,25 @@ pub fn translate_select(mut select: Select) -> Result<Program> {
let start = program.next_free_register();
for col in sort_columns.iter() {
let target = program.alloc_register();
translate_expr(&mut program, &select, &col.expr, target, None)?;
// if the ORDER BY expression is a number, interpret it as an 1-indexed column number
// otherwise, interpret it normally as an expression
let sort_col_expr = if let ast::Expr::Literal(ast::Literal::Numeric(num)) =
&col.expr
{
let column_number = num.parse::<usize>()?;
if column_number == 0 {
crate::bail_parse_error!("invalid column index: {}", column_number);
}
let maybe_result_column = select.columns.get(column_number - 1);
match maybe_result_column {
Some(ResultColumn::Expr(expr, _)) => expr,
None => crate::bail_parse_error!("invalid column index: {}", column_number),
_ => todo!(),
}
} else {
&col.expr
};
translate_expr(&mut program, &select, sort_col_expr, target, None)?;
}
let (_, result_cols_count) = translate_columns(&mut program, &select, None)?;
sort_info

View File

@@ -45,3 +45,8 @@ do_execsql_test basic-order-by-and-limit-3 {
do_execsql_test order-by-qualified {
select u.first_name from users u order by u.first_name limit 1;
} {Aaron}
do_execsql_test order-by-column-number {
select first_name, last_name, age from users order by 3,2 limit 2;
} {Teresa|Allen|1
David|Baker|1}