From 56dbd4d0282b5f467e82ea0cfe70a2f53b86d2bd Mon Sep 17 00:00:00 2001 From: Elia Perantoni Date: Thu, 12 Jun 2025 15:23:40 +0200 Subject: [PATCH 1/3] fix: `Ord` of `Ident` --- src/ast/mod.rs | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 04401a48b..82e76a18b 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -33,6 +33,7 @@ use core::{ fmt::{self, Display}, hash, }; +use std::cmp::Ordering; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -172,7 +173,7 @@ fn format_statement_list(f: &mut fmt::Formatter, statements: &[Statement]) -> fm } /// An identifier, decomposed into its value or character data and the quote style. -#[derive(Debug, Clone, PartialOrd, Ord)] +#[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] pub struct Ident { @@ -214,6 +215,34 @@ impl core::hash::Hash for Ident { impl Eq for Ident {} +impl PartialOrd for Ident { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Ident { + fn cmp(&self, other: &Self) -> Ordering { + let Ident { + value, + quote_style, + // exhaustiveness check; we ignore spans in ordering + span: _, + } = self; + + let Ident { + value: other_value, + quote_style: other_quote_style, + // exhaustiveness check; we ignore spans in ordering + span: _, + } = other; + + // First compare by value, then by quote_style + value.cmp(other_value) + .then_with(|| quote_style.cmp(other_quote_style)) + } +} + impl Ident { /// Create a new identifier with the given value and no quotes and an empty span. pub fn new(value: S) -> Self @@ -4181,7 +4210,7 @@ pub enum Statement { /// ```sql /// NOTIFY channel [ , payload ] /// ``` - /// send a notification event together with an optional “payload” string to channel + /// send a notification event together with an optional "payload" string to channel /// /// See Postgres NOTIFY { From 9262fbf0daf183f0c95d70e4a7d71c2104e949f3 Mon Sep 17 00:00:00 2001 From: Elia Perantoni Date: Tue, 24 Jun 2025 08:40:48 +0200 Subject: [PATCH 2/3] test: add `test_ident_ord` --- src/ast/mod.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 82e76a18b..46b101db2 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -238,7 +238,8 @@ impl Ord for Ident { } = other; // First compare by value, then by quote_style - value.cmp(other_value) + value + .cmp(other_value) .then_with(|| quote_style.cmp(other_quote_style)) } } @@ -9768,6 +9769,8 @@ impl fmt::Display for NullInclusion { #[cfg(test)] mod tests { + use crate::tokenizer::Location; + use super::*; #[test] @@ -10063,4 +10066,16 @@ mod tests { test_steps(OneOrManyWithParens::Many(vec![2]), vec![2], 3); test_steps(OneOrManyWithParens::Many(vec![3, 4]), vec![3, 4], 4); } + + // Tests that the position in the code of an `Ident` does not affect its + // ordering. + #[test] + fn test_ident_ord() { + let mut a = Ident::with_span(Span::new(Location::new(1, 1), Location::new(1, 1)), "a"); + let mut b = Ident::with_span(Span::new(Location::new(2, 2), Location::new(2, 2)), "b"); + + assert!(a < b); + std::mem::swap(&mut a.span, &mut b.span); + assert!(a < b); + } } From 4448ea6d92d3fd9eb5c7abebe79d2c21049a9cee Mon Sep 17 00:00:00 2001 From: Elia Perantoni Date: Tue, 24 Jun 2025 08:44:50 +0200 Subject: [PATCH 3/3] fix: `nostd` build --- src/ast/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 46b101db2..be25f1456 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -28,12 +28,12 @@ use helpers::{ stmt_data_loading::{FileStagingCommand, StageLoadSelectItemKind}, }; +use core::cmp::Ordering; use core::ops::Deref; use core::{ fmt::{self, Display}, hash, }; -use std::cmp::Ordering; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize};