sqrust_rules/ambiguous/
order_by_position.rs1use sqrust_core::{Diagnostic, FileContext, Rule};
2
3use crate::capitalisation::SkipMap;
4
5use super::group_by_position::{
6 match_keyword, scan_positional_list, skip_whitespace, ORDER_BY_STOP_KEYWORDS,
7};
8
9pub struct OrderByPosition;
10
11impl Rule for OrderByPosition {
12 fn name(&self) -> &'static str {
13 "Ambiguous/OrderByPosition"
14 }
15
16 fn check(&self, ctx: &FileContext) -> Vec<Diagnostic> {
17 let source = &ctx.source;
18 let bytes = source.as_bytes();
19 let len = bytes.len();
20 let skip_map = SkipMap::build(source);
21
22 let mut diags = Vec::new();
23 let mut i = 0;
24
25 while i < len {
26 if !skip_map.is_code(i) {
28 i += 1;
29 continue;
30 }
31
32 if let Some(after_order) = match_keyword(bytes, &skip_map, i, b"ORDER") {
34 let after_ws = skip_whitespace(bytes, after_order);
35
36 if let Some(after_by) = match_keyword(bytes, &skip_map, after_ws, b"BY") {
37 scan_positional_list(
38 bytes,
39 &skip_map,
40 source,
41 after_by,
42 self.name(),
43 "Avoid positional ORDER BY references; use column names",
44 ORDER_BY_STOP_KEYWORDS,
45 &mut diags,
46 );
47 i = after_by;
48 continue;
49 }
50 }
51
52 i += 1;
53 }
54
55 diags
56 }
57}