(tc: &TestCase)
| 68 | } |
| 69 | |
| 70 | fn parse_statement(tc: &TestCase) -> String { |
| 71 | let input = tc.input.strip_suffix('\n').unwrap_or(&tc.input); |
| 72 | match parser::parse_statements(input) { |
| 73 | Ok(s) => { |
| 74 | let stmt = s.into_element().ast; |
| 75 | for printed in [stmt.to_ast_string_simple(), stmt.to_ast_string_stable()] { |
| 76 | let mut parsed = match parser::parse_statements(&printed) { |
| 77 | Ok(parsed) => parsed.into_element().ast, |
| 78 | Err(err) => panic!("reparse failed: {}: {}\n", stmt, err), |
| 79 | }; |
| 80 | match (&mut parsed, &stmt) { |
| 81 | // DECLARE remembers the original SQL. Erase that here so it can differ if |
| 82 | // needed (for example, quoting identifiers vs not). This is ok because we |
| 83 | // still compare that the resulting ASTs are identical, and it's valid for |
| 84 | // those to come from different original strings. |
| 85 | (Statement::Declare(parsed), Statement::Declare(stmt)) => { |
| 86 | parsed.sql.clone_from(&stmt.sql); |
| 87 | } |
| 88 | _ => {} |
| 89 | } |
| 90 | if parsed != stmt { |
| 91 | panic!( |
| 92 | "reparse comparison failed:\n{:?}\n!=\n{:?}\n{printed}\n", |
| 93 | stmt, parsed |
| 94 | ); |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | // Also check that the redacted version of the statement can be reparsed. This is |
| 99 | // important so that we are still able to pretty-print redacted statements, which |
| 100 | // helps during debugging. |
| 101 | let redacted = stmt.to_ast_string_redacted(); |
| 102 | let res = parser::parse_statements(&redacted); |
| 103 | assert!( |
| 104 | res.is_ok(), |
| 105 | "redacted statement could not be reparsed: {res:?}\noriginal:\n{stmt}\nredacted:\n{redacted}" |
| 106 | ); |
| 107 | |
| 108 | if tc.args.contains_key("roundtrip") { |
| 109 | format!("{}\n", stmt) |
| 110 | } else { |
| 111 | // TODO(justin): it would be nice to have a middle-ground between this |
| 112 | // all-on-one-line and {:#?}'s huge number of lines. |
| 113 | format!("{}\n=>\n{:?}\n", stmt, stmt) |
| 114 | } |
| 115 | } |
| 116 | Err(e) => render_error(input, e.error), |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | fn parse_scalar(tc: &TestCase) -> String { |
| 121 | let input = tc.input.trim(); |
no test coverage detected