Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions web/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,16 @@ main { display: block; }
text-decoration: none;
transition: color 0.12s ease, border-color 0.12s ease;
}
.copy-btn:hover,
.report-btn:hover { color: #1f2328; border-color: #b9b9b9; }
.copy-btn:hover { color: #1f2328; border-color: #b9b9b9; }
/* Each feedback button is tinted by its meaning: red for "should be rejected"
(the statement is an error), amber for "propose contentious" (a judgment
call), blue for "dispute" (push back on the tag). Copy stays neutral. */
.report-reject { color: #c0202a; }
.report-reject:hover { color: #c0202a; border-color: #e7a3a3; background: #fdf3f3; }
.report-propose { color: #b06e1f; }
.report-propose:hover { color: #b06e1f; border-color: #e3c08a; background: #fdf7ee; }
.report-dispute { color: #1c4e80; }
.report-dispute:hover { color: #1c4e80; border-color: #a9c6e6; background: #eef4fb; }
/* The parser's error message for a rejected statement, under its preview. */
.fail-reason {
margin: 0.2rem 0 0;
Expand Down
10 changes: 5 additions & 5 deletions web/src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ fn fail_preview_row(
if has_ref {
if let Some(sql) = sql {
a {
class: "report-btn",
class: "report-btn report-reject",
href: issue_url("should-be-rejected.yml", dialect, parser, sql, reason, &[]),
target: "_blank",
rel: "noopener noreferrer",
Expand All @@ -1244,7 +1244,7 @@ fn fail_preview_row(
if let Some(rule) = rule {
// Already tagged contentious: let people argue it is not.
a {
class: "report-btn",
class: "report-btn report-dispute",
href: issue_url("not-contentious.yml", dialect, parser, sql, reason, &[("rule", rule.title.as_str())]),
target: "_blank",
rel: "noopener noreferrer",
Expand All @@ -1254,7 +1254,7 @@ fn fail_preview_row(
}
} else {
a {
class: "report-btn",
class: "report-btn report-propose",
href: issue_url("contentious-construct.yml", dialect, parser, sql, reason, &[]),
target: "_blank",
rel: "noopener noreferrer",
Expand Down Expand Up @@ -1747,7 +1747,7 @@ fn parser_score_section(parser: &str) -> Element {
"A composite of every dimension, 0 to 100, weighting correctness 40 percent, robustness 30, speed 18, memory 7, and project health 5. Computed only over the dialects this parser models. Speed and memory are ranked against the other parsers on each dialect, while correctness and health are absolute. Each badge also shows this parser's rank on that dimension among all parsers."
}
div { class: "meta-grid score-grid",
{score_badge(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaBullseye } }, "correctness", s.correctness, crate::score::rank(parser, |x| x.correctness), "Correctness sub-score (0 to 100): recall or acceptance, false-positive avoidance, and round-trip, averaged over the dialects this parser models.".to_string())}
{score_badge(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaBullseye } }, "correctness", s.correctness, crate::score::rank(parser, |x| x.correctness), "Correctness sub-score (0 to 100): recall (excluding contentious constructs) or acceptance, false-positive avoidance, and round-trip, averaged over the dialects this parser models.".to_string())}
{score_badge(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaShieldHalved } }, "robustness", s.robustness, crate::score::rank(parser, |x| x.robustness), "Robustness sub-score (0 to 100): empirical panic rate on the real corpus, recursion-depth guarding, unsafe surface, and static panic discipline.".to_string())}
{score_badge(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaGaugeHigh } }, "speed", s.speed, crate::score::rank(parser, |x| x.speed), "Speed sub-score (0 to 100): median parse time ranked against the other parsers within each dialect on a log scale, then averaged.".to_string())}
{score_badge(rsx! { Icon { width: 12, height: 12, fill: "currentColor".to_string(), icon: FaMicrochip } }, "memory", s.memory, crate::score::rank(parser, |x| x.memory), "Memory sub-score (0 to 100): peak and retained per-statement footprints ranked against the field within each dialect. Shown n/a for FFI parsers, whose C-side allocations are not measured.".to_string())}
Expand Down Expand Up @@ -2253,7 +2253,7 @@ fn col_help(name: &str) -> Option<&'static str> {
"parser" => "The SQL parser library under test.",
"dialect" => "The SQL dialect the row reports on.",
"overall" => "Overall score (0 to 100): correctness 40 percent, robustness 30, speed 18, memory 7, project health 5, computed only over the dialects the parser models. Higher is better.",
"correctness" => "Correctness sub-score (0 to 100): recall or acceptance, false-positive avoidance, and round-trip, averaged over the parser's dialects. Higher is better.",
"correctness" => "Correctness sub-score (0 to 100): recall (excluding contentious constructs) or acceptance, false-positive avoidance, and round-trip, averaged over the parser's dialects. Higher is better.",
"robustness" => "Robustness sub-score (0 to 100): empirical panic rate, recursion-depth guarding, unsafe surface, and static panic discipline. Higher is better.",
"speed" => "Speed sub-score (0 to 100): median parse time ranked against the field within each dialect on a log scale, then averaged. Higher is better.",
"memory" => "Memory sub-score (0 to 100): peak and retained per-statement footprints ranked against the field within each dialect. n/a for FFI parsers. Higher is better.",
Expand Down
8 changes: 7 additions & 1 deletion web/src/score.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,13 @@ const PROVENANCE_DIALECT_WEIGHT: f64 = 0.4;
/// (recall on reference dialects, acceptance elsewhere), plus false-positive
/// avoidance and round-trip where they exist.
fn correctness_in_dialect(m: &viz::ParserMetrics) -> Option<f64> {
let primary = m.recall_pct.or(m.accept_pct)?;
// Recall excluding contentious constructs, so a parser is not ranked down for
// deliberately declining an engine-accepted quirk. Falls back to strict recall
// where there is no contentious layer, then to acceptance on provenance dialects.
let primary = m
.recall_excl_contentious_pct
.or(m.recall_pct)
.or(m.accept_pct)?;
let mut num = 0.5 * (primary / 100.0);
let mut den = 0.5;
if let Some(fp) = m.false_positive_pct {
Expand Down
Loading