diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 163c732..c63d196 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,7 +107,11 @@ jobs: - name: Extract corpus run: tar --zstd -xf datasets.tar.zst - name: Run coverage - run: cargo tarpaulin --out Xml + # Exclude timemachine: it links several sqlglot-rust versions side by side, + # each exporting the same unmangled extern "C" FFI symbols, which collide at + # link time once tarpaulin disables dead-code stripping. It has no unit tests + # of its own, so excluding it loses no coverage. + run: cargo tarpaulin --workspace --exclude timemachine --out Xml - name: Upload to Codecov uses: codecov/codecov-action@v5 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index a07f422..50b53dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## June 2026: parser refresh and a failed-to-parse badge + +- Updated the benchmarked parsers to their latest versions: polyglot-sql 0.4.4 to 0.5.1, sqlglot-rust 0.10.0 to 0.10.1, and the git-tracked sqlparser-rs and pg_query.rs to their current commits (sqlparser-rs now at b3760221). turso_parser stays on 0.6.1 since the only newer version is a prerelease. +- The time machine gains the new release points (polyglot-sql 0.5.1 and sqlglot-rust 0.10.1) so the trends end at the current code. +- Each parser page gains a failed-to-parse badge in the meta-grid showing how many statements the parser rejected that it was expected to accept, summed across every dialect. It is a neutral coverage figure (every parser misses some real-world SQL), with the percentage and denominator in the tooltip. +- Added three CI-practice badges per parser: cargo deny (whether CI enforces a dependency policy with cargo deny), cargo audit (whether CI scans dependencies against the RustSec advisory database, via cargo audit or cargo deny check advisories), and cargo mutants (whether CI runs mutation testing). As of this snapshot turso is the only parser running cargo deny (its licenses check only), and none run cargo audit or cargo mutants. + ## June 2026: robustness badges - Each parser page gains a Robustness section with six per-parser badges mined from the parser's own source and behavior, so a chooser can weigh crash-safety alongside speed and coverage. diff --git a/Cargo.toml b/Cargo.toml index 871089f..f813457 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ qusql-parse = "0.8.0" polyglot-sql = { git = "https://github.com/tobilg/polyglot" } databend-common-ast = "0.2.5" orql = { git = "https://codeberg.org/xitep/orql" } -sqlglot-rust = "0.10.0" +sqlglot-rust = "0.10.1" sqlite3-parser = "0.16.0" turso_parser = "0.6.1" fallible-iterator = "0.3.0" diff --git a/README.md b/README.md index 0dc83a9..d9d9fa4 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ On their home dialect the reference bindings are exact by construction, so the m | Parser | Version | Source | Implementation | Dialects | | --- | --- | --- | --- | --- | -| **[sqlparser-rs](https://github.com/sqlparser-rs/sqlparser-rs)** | 0.62.0 | git [`575ee26`](https://github.com/sqlparser-rs/sqlparser-rs/commit/575ee264dffa3c5039dc3d15abd903fd420eba2b) | Pure Rust, handwritten recursive descent | 14 dedicated dialects | -| **[sqlglot-rust](https://crates.io/crates/sqlglot-rust)** | 0.10.0 | crates.io | Pure Rust, standalone port of Python sqlglot | 30 (parser currently dialect-agnostic) | -| **[polyglot-sql](https://github.com/tobilg/polyglot)** | 0.4.4 | git [`320cfa8`](https://github.com/tobilg/polyglot/commit/320cfa8a148d624caeff2145f2e5bf1432ec8604) | Pure Rust, transpiler | 32 | +| **[sqlparser-rs](https://github.com/sqlparser-rs/sqlparser-rs)** | 0.62.0 | git [`b376022`](https://github.com/sqlparser-rs/sqlparser-rs/commit/b3760221) | Pure Rust, handwritten recursive descent | 14 dedicated dialects | +| **[sqlglot-rust](https://crates.io/crates/sqlglot-rust)** | 0.10.1 | crates.io | Pure Rust, standalone port of Python sqlglot | 30 (parser currently dialect-agnostic) | +| **[polyglot-sql](https://github.com/tobilg/polyglot)** | 0.5.1 | git [`e3a8913`](https://github.com/tobilg/polyglot/commit/e3a8913a) | Pure Rust, transpiler | 32 | | **[pg_query.rs](https://github.com/pganalyze/pg_query.rs)** | 6.1.1 | git [`7e189a9`](https://github.com/pganalyze/pg_query.rs/commit/7e189a9dd1d4e441a2d44e6655c793f101bba3fa) | Rust FFI to C (libpg_query) | PostgreSQL | | **[qusql-parse](https://crates.io/crates/qusql-parse)** | 0.8.0 | crates.io | Pure Rust, zero-copy | PostgreSQL, MariaDB/MySQL, SQLite | | **[databend-common-ast](https://github.com/datafuselabs/databend)** | 0.2.5 | crates.io | Pure Rust, zero-copy, Pratt | PostgreSQL, MySQL, Hive | diff --git a/featurescan/data/depth.json b/featurescan/data/depth.json index de1fedc..361f571 100644 --- a/featurescan/data/depth.json +++ b/featurescan/data/depth.json @@ -72,7 +72,7 @@ "guarded": false, "shape_rejected": false, "limit_depth": null, - "crash_depth": 548, + "crash_depth": 412, "ceil": 50000 }, { diff --git a/featurescan/data/featurescan.json b/featurescan/data/featurescan.json index 3b945f5..5033046 100644 --- a/featurescan/data/featurescan.json +++ b/featurescan/data/featurescan.json @@ -6,9 +6,9 @@ "package": "sqlparser", "version": "0.62.0", "counts": { - "loc": 68907, + "loc": 69033, "test_lines": 4276, - "code_loc": 64631, + "code_loc": 64757, "files": 43, "parse_failures": 0, "panic": 3, @@ -27,11 +27,12 @@ }, "lints": { "lints": { - "unreachable": "forbid" + "unreachable": "forbid", + "unsafe_code": "forbid" }, "workspace_inherited": false }, - "forbids_unsafe": false, + "forbids_unsafe": true, "direct_deps": 6, "serde_dep": true }, @@ -134,12 +135,12 @@ { "parser": "polyglot-sql", "package": "polyglot-sql", - "version": "0.4.4", + "version": "0.5.1", "counts": { - "loc": 239954, - "test_lines": 16786, - "code_loc": 223168, - "files": 74, + "loc": 241432, + "test_lines": 16915, + "code_loc": 224517, + "files": 75, "parse_failures": 0, "panic": 5, "unreachable": 212, @@ -198,22 +199,22 @@ { "parser": "sqlglot-rust", "package": "sqlglot-rust", - "version": "0.10.0", + "version": "0.10.1", "counts": { - "loc": 29937, - "test_lines": 3951, - "code_loc": 25986, + "loc": 36480, + "test_lines": 3986, + "code_loc": 32494, "files": 29, "parse_failures": 0, "panic": 0, - "unreachable": 4, + "unreachable": 6, "unimplemented": 0, "todo": 0, "assert": 1, - "unwrap": 21, + "unwrap": 33, "expect": 4, "unwrap_unchecked": 0, - "index": 162, + "index": 165, "unsafe_blocks": 11, "unsafe_fns": 5, "unsafe_impls": 2, diff --git a/src/lib.rs b/src/lib.rs index bdac671..4c0397b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -386,10 +386,10 @@ impl BenchParser { Self::Sqlparser => "0.62.0", Self::PgQuery | Self::PgQuerySummary => "6.1.1", Self::Qusql => "0.8.0", - Self::Polyglot => "0.4.4", + Self::Polyglot => "0.5.1", Self::Databend => "0.2.5", Self::Orql => "0.1.0", - Self::Sqlglot => "0.10.0", + Self::Sqlglot => "0.10.1", Self::Sqlite3 => "0.16.0", Self::Turso => "0.6.1", } diff --git a/timemachine/Cargo.toml b/timemachine/Cargo.toml index b61a17b..ca4c7e5 100644 --- a/timemachine/Cargo.toml +++ b/timemachine/Cargo.toml @@ -58,13 +58,14 @@ sqlparser_v0_62 = { package = "sqlparser", version = "=0.62.0" } # sqlglot-rust minors (0.9 and 0.10 are the two semver-incompatible groups). sqlglot_v0_9 = { package = "sqlglot-rust", version = "=0.9.37" } -sqlglot_v0_10 = { package = "sqlglot-rust", version = "=0.10.0" } +sqlglot_v0_10 = { package = "sqlglot-rust", version = "=0.10.1" } # polyglot-sql minors (latest patch of each). polyglot_v0_1 = { package = "polyglot-sql", version = "=0.1.15" } polyglot_v0_2 = { package = "polyglot-sql", version = "=0.2.3" } polyglot_v0_3 = { package = "polyglot-sql", version = "=0.3.11" } polyglot_v0_4 = { package = "polyglot-sql", version = "=0.4.4" } +polyglot_v0_5 = { package = "polyglot-sql", version = "=0.5.1" } # databend-common-ast minors (single-statement parser). databend_v0_0 = { package = "databend-common-ast", version = "=0.0.3" } diff --git a/timemachine/src/families/polyglot.rs b/timemachine/src/families/polyglot.rs index 2e0dfb0..20d6d01 100644 --- a/timemachine/src/families/polyglot.rs +++ b/timemachine/src/families/polyglot.rs @@ -101,3 +101,4 @@ polyglot_version!(PolyglotV0_1, polyglot_v0_1, "0.1.15", "2026-03-16"); polyglot_version!(PolyglotV0_2, polyglot_v0_2, "0.2.3", "2026-04-05"); polyglot_version!(PolyglotV0_3, polyglot_v0_3, "0.3.11", "2026-05-15"); polyglot_version!(PolyglotV0_4, polyglot_v0_4, "0.4.4", "2026-06-03"); +polyglot_version!(PolyglotV0_5, polyglot_v0_5, "0.5.1", "2026-06-09"); diff --git a/timemachine/src/families/sqlglot.rs b/timemachine/src/families/sqlglot.rs index d1058e3..e65522f 100644 --- a/timemachine/src/families/sqlglot.rs +++ b/timemachine/src/families/sqlglot.rs @@ -108,4 +108,4 @@ macro_rules! sqlglot_version { } sqlglot_version!(SqlglotV0_9, sqlglot_v0_9, "0.9.37", "2026-05-28"); -sqlglot_version!(SqlglotV0_10, sqlglot_v0_10, "0.10.0", "2026-06-03"); +sqlglot_version!(SqlglotV0_10, sqlglot_v0_10, "0.10.1", "2026-06-05"); diff --git a/timemachine/src/registry.rs b/timemachine/src/registry.rs index 3585aea..8a381ce 100644 --- a/timemachine/src/registry.rs +++ b/timemachine/src/registry.rs @@ -50,6 +50,7 @@ pub fn all() -> Vec> { Box::new(polyglot::PolyglotV0_2), Box::new(polyglot::PolyglotV0_3), Box::new(polyglot::PolyglotV0_4), + Box::new(polyglot::PolyglotV0_5), Box::new(databend::DatabendV0_0), Box::new(databend::DatabendV0_1), Box::new(databend::DatabendV0_2), diff --git a/web/assets/bench.json.zst b/web/assets/bench.json.zst index 5665632..cab8c08 100644 Binary files a/web/assets/bench.json.zst and b/web/assets/bench.json.zst differ diff --git a/web/assets/history.json.zst b/web/assets/history.json.zst index 16449cb..315d9a5 100644 Binary files a/web/assets/history.json.zst and b/web/assets/history.json.zst differ diff --git a/web/src/components.rs b/web/src/components.rs index be79c81..97cb0ef 100644 --- a/web/src/components.rs +++ b/web/src/components.rs @@ -6,11 +6,11 @@ use crate::Route; use dioxus::prelude::*; use dioxus_free_icons::icons::fa_brands_icons::{FaGit, FaGithub, FaRust}; use dioxus_free_icons::icons::fa_solid_icons::{ - FaArrowLeftLong, FaArrowsRotate, FaBomb, FaBox, FaBug, FaBuilding, FaCalendarDays, - FaChartColumn, FaChartLine, FaCode, FaCodeCommit, FaCodeFork, FaCopy, FaCube, FaDatabase, - FaDownload, FaFlaskVial, FaHeartPulse, FaLayerGroup, FaMicrochip, FaMobileScreen, - FaScaleBalanced, FaServer, FaShieldHalved, FaSitemap, FaStar, FaStopwatch, FaTableCells, FaTag, - FaTriangleExclamation, FaUsers, FaVial, + FaArrowLeftLong, FaArrowsRotate, FaBan, FaBomb, FaBox, FaBug, FaBuilding, FaCalendarDays, + FaChartColumn, FaChartLine, FaCircleXmark, FaCode, FaCodeCommit, FaCodeFork, FaCopy, FaCube, + FaDatabase, FaDna, FaDownload, FaFileShield, FaFlaskVial, FaHeartPulse, FaLayerGroup, + FaMicrochip, FaMobileScreen, FaScaleBalanced, FaServer, FaShieldHalved, FaSitemap, FaStar, + FaStopwatch, FaTableCells, FaTag, FaTriangleExclamation, FaUsers, FaVial, }; use dioxus_free_icons::Icon; use std::cmp::Ordering; @@ -1458,8 +1458,12 @@ fn parser_meta_pills(parser: &str) -> Element { {meta_flag(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaRust } }, "impl", if m.pure_rust { "pure Rust".to_string() } else { "C FFI".to_string() }, m.pure_rust, crate::metadata::pure_rust_description(m.pure_rust))} {meta_flag(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaHeartPulse } }, "maintained", if crate::metadata::maintained(m.last_release) { "active".to_string() } else { "stale".to_string() }, crate::metadata::maintained(m.last_release), &crate::metadata::maintenance_description(m.last_release))} {meta_flag(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaFlaskVial } }, "miri/san", if m.sanitizers.is_empty() { "no".to_string() } else { m.sanitizers.to_string() }, !m.sanitizers.is_empty(), &crate::metadata::sanitizer_description(m.sanitizers))} + {meta_flag(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaBan } }, "cargo deny", if m.cargo_deny { "yes".to_string() } else { "no".to_string() }, m.cargo_deny, crate::metadata::cargo_deny_description(m.cargo_deny))} + {meta_flag(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaFileShield } }, "cargo audit", if m.cargo_audit { "yes".to_string() } else { "no".to_string() }, m.cargo_audit, crate::metadata::cargo_audit_description(m.cargo_audit))} + {meta_flag(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaDna } }, "cargo mutants", if m.cargo_mutants { "yes".to_string() } else { "no".to_string() }, m.cargo_mutants, crate::metadata::cargo_mutants_description(m.cargo_mutants))} {feat.map_or_else(|| rsx! {}, panic_discipline_pill)} {empirical_panic_pill(panic)} + {failures_pill(crate::data::failure_totals(parser))} {feat.map_or_else(|| rsx! {}, |f| unsafe_pill(f, m.unsafe_note))} {depth.map_or_else(|| rsx! {}, depth_pill)} {feat.map_or_else(|| rsx! {}, deps_pill)} @@ -1553,6 +1557,43 @@ fn empirical_panic_pill(totals: Option<(usize, usize)>) -> Element { ) } +/// Failed-to-parse pill: how many statements the parser rejected that it was +/// expected to accept, summed across every dialect. Neutral (informational): +/// every parser misses some real-world SQL, so this is a coverage figure, not an +/// alarm, and a red flag on every parser would dilute the genuine red flags. The +/// value is the absolute count the user asked for; the rate is in the tooltip. +fn failures_pill(totals: Option<(usize, usize)>) -> Element { + let (value, desc) = match totals { + None => ( + "n/a".to_string(), + "Failed-to-parse count not available in this snapshot.".to_string(), + ), + Some((rejected, expected)) => { + let pct = if expected > 0 { + 100.0 * rejected as f64 / expected as f64 + } else { + 0.0 + }; + ( + commas(rejected), + format!( + "Failed to parse: {} of {} statements ({pct:.2}%) that this parser was \ + expected to accept were rejected, summed across every dialect. These are the \ + statements listed on the parser's failures download.", + commas(rejected), + commas(expected) + ), + ) + } + }; + meta_item( + rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaCircleXmark } }, + "failed to parse", + value, + desc, + ) +} + /// Unsafe-surface pill: forbidden, none, or a count of unsafe occurrences. fn unsafe_pill(f: &viz::ParserFeatures, note: &str) -> Element { let total = f.counts.unsafe_total(); diff --git a/web/src/data.rs b/web/src/data.rs index 6836474..c617e06 100644 --- a/web/src/data.rs +++ b/web/src/data.rs @@ -92,6 +92,25 @@ pub fn panic_totals(parser: &str) -> Option<(usize, usize)> { (attempted > 0).then_some((panicked, attempted)) } +/// Aggregate failed-to-parse totals for one parser across every dialect: +/// `(rejected, expected)`. A statement counts as failed when the parser was +/// expected to accept it (reference-valid statements in reference dialects, every +/// statement in provenance dialects) but rejected it. This is the same set the +/// per-parser failures download lists. Returns `None` when nothing was expected +/// (e.g. an older snapshot without the failures section), so the caller can show +/// the badge as unmeasured rather than 0. +#[must_use] +pub fn failure_totals(parser: &str) -> Option<(usize, usize)> { + let (mut rejected, mut expected) = (0usize, 0usize); + for dialect in &bundle().dialects { + if let Some(f) = dialect.failures.iter().find(|f| f.parser == parser) { + rejected += f.rejected_total; + expected += f.expected_total; + } + } + (expected > 0).then_some((rejected, expected)) +} + #[cfg(test)] mod tests { /// The committed snapshot must decompress and deserialize into the shared diff --git a/web/src/metadata.rs b/web/src/metadata.rs index b248cfd..188fabf 100644 --- a/web/src/metadata.rs +++ b/web/src/metadata.rs @@ -242,6 +242,14 @@ pub struct ParserMeta { pub last_release: &'static str, /// Sanitizer/Miri run in CI (short label, e.g. `"leak"`), or `""` for none. pub sanitizers: &'static str, + /// Whether CI scans dependencies against the RustSec advisory database, via + /// `cargo audit` or `cargo deny check advisories`. + pub cargo_audit: bool, + /// Whether CI runs mutation testing with `cargo mutants`. + pub cargo_mutants: bool, + /// Whether CI runs `cargo deny` to enforce a dependency policy (licenses, + /// banned or duplicate crates, untrusted sources, and/or advisories). + pub cargo_deny: bool, } /// Releases at least this recent count as actively maintained. Roughly twelve @@ -284,6 +292,40 @@ pub fn sanitizer_description(sanitizers: &str) -> String { } } +/// A full sentence describing whether CI scans dependencies for known security +/// advisories (`cargo audit` or `cargo deny check advisories`). +#[must_use] +pub const fn cargo_audit_description(has: bool) -> &'static str { + if has { + "Audits dependencies in CI: runs cargo audit (or cargo deny check advisories) against the RustSec database, so a dependency with a known vulnerability fails the build." + } else { + "No dependency audit in CI: does not run cargo audit or cargo deny check advisories, so a known vulnerability in a dependency would go unflagged." + } +} + +/// A full sentence describing whether CI runs mutation testing with +/// `cargo mutants`, a measure of how thoroughly the test suite catches bugs. +#[must_use] +pub const fn cargo_mutants_description(has: bool) -> &'static str { + if has { + "Runs mutation testing in CI: cargo mutants injects deliberate bugs and checks the test suite catches them, a strong signal the tests actually exercise behavior." + } else { + "No mutation testing in CI: does not run cargo mutants, so there is no automated measure of how many real bugs its tests would actually catch." + } +} + +/// A full sentence describing whether CI runs `cargo deny` to enforce a +/// dependency policy (licenses, banned or duplicate crates, untrusted sources, +/// and/or RustSec advisories). +#[must_use] +pub const fn cargo_deny_description(has: bool) -> &'static str { + if has { + "Enforces a dependency policy in CI with cargo deny, gating on some of licenses, banned or duplicate crates, untrusted sources, and RustSec advisories (which checks are on depends on the project's deny.toml)." + } else { + "No cargo deny in CI: dependency licenses, banned or duplicate crates, untrusted sources, and advisories are not gated automatically." + } +} + /// A full sentence describing whether the crate is published on crates.io, which /// decides if it can be depended on with a plain version requirement. #[must_use] @@ -344,6 +386,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "", last_release: "2026-05", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, // Both libpg_query bindings: own crate has no harness, but libpg_query // (PostgreSQL's own C parser) is fuzzed upstream. @@ -367,6 +412,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "the C FFI bindings to libpg_query", last_release: "2025-08", sanitizers: "leak", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, "qusql-parse" => ParserMeta { stars: 17, @@ -388,6 +436,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "one unchecked UTF-8 conversion in the lexer", last_release: "2026-05", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, "polyglot-sql" => ParserMeta { stars: 829, @@ -409,6 +460,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "", last_release: "2026-06", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, "databend-common-ast" => ParserMeta { stars: 9308, @@ -430,6 +484,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "", last_release: "2026-03", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, "sqlglot-rust" => ParserMeta { stars: 15, @@ -451,6 +508,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "its C-ABI export layer", last_release: "2026-05", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, "sqlite3-parser" => ParserMeta { stars: 62, @@ -472,6 +532,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "one unchecked UTF-8 conversion in keyword lookup", last_release: "2026-04", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, "turso_parser" => ParserMeta { stars: 19043, @@ -493,6 +556,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "unchecked UTF-8 conversions in the lexer and parser", last_release: "2026-05", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: true, }, "orql" => ParserMeta { stars: 0, @@ -514,6 +580,9 @@ pub fn parser_meta(name: &str) -> Option { unsafe_note: "an unchecked UTF-8 conversion and a transmute", last_release: "2026-01", sanitizers: "", + cargo_audit: false, + cargo_mutants: false, + cargo_deny: false, }, _ => return None, }) diff --git a/web/static/failures/bigquery__sqlglot_rust.tsv.zst b/web/static/failures/bigquery__sqlglot_rust.tsv.zst index d8f7149..abad56c 100644 Binary files a/web/static/failures/bigquery__sqlglot_rust.tsv.zst and b/web/static/failures/bigquery__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/clickhouse__sqlglot_rust.tsv.zst b/web/static/failures/clickhouse__sqlglot_rust.tsv.zst index ad678c8..db85330 100644 Binary files a/web/static/failures/clickhouse__sqlglot_rust.tsv.zst and b/web/static/failures/clickhouse__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/duckdb__sqlglot_rust.tsv.zst b/web/static/failures/duckdb__sqlglot_rust.tsv.zst index 4869206..01101b4 100644 Binary files a/web/static/failures/duckdb__sqlglot_rust.tsv.zst and b/web/static/failures/duckdb__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/duckdb__sqlparser_rs.tsv.zst b/web/static/failures/duckdb__sqlparser_rs.tsv.zst index f0c34f7..935df02 100644 Binary files a/web/static/failures/duckdb__sqlparser_rs.tsv.zst and b/web/static/failures/duckdb__sqlparser_rs.tsv.zst differ diff --git a/web/static/failures/hive__sqlglot_rust.tsv.zst b/web/static/failures/hive__sqlglot_rust.tsv.zst index 399afaa..50560fd 100644 Binary files a/web/static/failures/hive__sqlglot_rust.tsv.zst and b/web/static/failures/hive__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/multi__sqlglot_rust.tsv.zst b/web/static/failures/multi__sqlglot_rust.tsv.zst index 7aaa86b..389f081 100644 Binary files a/web/static/failures/multi__sqlglot_rust.tsv.zst and b/web/static/failures/multi__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/mysql__sqlglot_rust.tsv.zst b/web/static/failures/mysql__sqlglot_rust.tsv.zst index b7c5fe1..84fd5b6 100644 Binary files a/web/static/failures/mysql__sqlglot_rust.tsv.zst and b/web/static/failures/mysql__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/oracle__sqlglot_rust.tsv.zst b/web/static/failures/oracle__sqlglot_rust.tsv.zst index e00c05e..fe720af 100644 Binary files a/web/static/failures/oracle__sqlglot_rust.tsv.zst and b/web/static/failures/oracle__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/postgresql__sqlglot_rust.tsv.zst b/web/static/failures/postgresql__sqlglot_rust.tsv.zst index 49d024c..8050096 100644 Binary files a/web/static/failures/postgresql__sqlglot_rust.tsv.zst and b/web/static/failures/postgresql__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/redshift__sqlglot_rust.tsv.zst b/web/static/failures/redshift__sqlglot_rust.tsv.zst index fed5e7b..9f1c0f2 100644 Binary files a/web/static/failures/redshift__sqlglot_rust.tsv.zst and b/web/static/failures/redshift__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/spark_sql__sqlglot_rust.tsv.zst b/web/static/failures/spark_sql__sqlglot_rust.tsv.zst index 0652bc7..1a1ec19 100644 Binary files a/web/static/failures/spark_sql__sqlglot_rust.tsv.zst and b/web/static/failures/spark_sql__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/sqlite__sqlglot_rust.tsv.zst b/web/static/failures/sqlite__sqlglot_rust.tsv.zst index 4e378c3..514a5ca 100644 Binary files a/web/static/failures/sqlite__sqlglot_rust.tsv.zst and b/web/static/failures/sqlite__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/sqlite__sqlparser_rs.tsv.zst b/web/static/failures/sqlite__sqlparser_rs.tsv.zst index 2f7ea2f..4fae0d7 100644 Binary files a/web/static/failures/sqlite__sqlparser_rs.tsv.zst and b/web/static/failures/sqlite__sqlparser_rs.tsv.zst differ diff --git a/web/static/failures/trino__sqlglot_rust.tsv.zst b/web/static/failures/trino__sqlglot_rust.tsv.zst index f0779b2..7ca5e99 100644 Binary files a/web/static/failures/trino__sqlglot_rust.tsv.zst and b/web/static/failures/trino__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/tsql__sqlglot_rust.tsv.zst b/web/static/failures/tsql__sqlglot_rust.tsv.zst index 60cf2ee..848859f 100644 Binary files a/web/static/failures/tsql__sqlglot_rust.tsv.zst and b/web/static/failures/tsql__sqlglot_rust.tsv.zst differ diff --git a/web/static/failures/tsql__sqlparser_rs.tsv.zst b/web/static/failures/tsql__sqlparser_rs.tsv.zst index 372e0e5..274b024 100644 Binary files a/web/static/failures/tsql__sqlparser_rs.tsv.zst and b/web/static/failures/tsql__sqlparser_rs.tsv.zst differ