{"record":{"id":"51f5c5ecb4074994","repo":"dbt-labs/dbt-core","slug":"projection-order-drift-should-be-ignored-even-with","errorCode":null,"errorMessage":"projection order drift should be ignored even with apostrophes in comments","messagePattern":"projection order drift should be ignored even with apostrophes in comments","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-adapter/src/sql/diff.rs","lineNumber":3633,"sourceCode":"        let expected_sql = format!(\n            \"select {} from t\",\n            expected_alias_order\n                .iter()\n                .map(|a| projection_for(a))\n                .collect::<Vec<_>>()\n                .join(\", \")\n        );\n        let actual_sql = format!(\n            \"select {} from t\",\n            actual_alias_order\n                .iter()\n                .map(|a| projection_for(a))\n                .collect::<Vec<_>>()\n                .join(\", \")\n        );\n\n        compare_sql(&actual_sql, &expected_sql, AdapterType::Bigquery)\n            .expect(\"projection order drift should be ignored even with apostrophes in comments\");\n    }\n\n    #[test]\n    fn test_bigquery_simple_projection_order_drift_with_comment_apostrophe_should_be_ignorable() {\n        // Minimal repro for the next Snowplow ordering drift surface:\n        //\n        // Downstream models may select the already-built context columns as plain identifiers:\n        //   , experiment_entity\n        //   , feature_flag_context\n        //   , ...\n        //\n        // Mantle vs Fusion can emit these in different orders due to map iteration. This should be\n        // ignorable for replay, even when the SELECT list contains `--` comments with apostrophes.\n        //\n        // This test is expected to FAIL (SqlMismatch) until we canonicalize identifier projection\n        // ordering drift for this pattern.\n        let expected_order = [\n            \"service_configuration_context\",","sourceCodeStart":3615,"sourceCodeEnd":3651,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/sql/diff.rs#L3615-L3651","documentation":"Test panic from .expect at crates/dbt-adapter/src/sql/diff.rs:3633: compare_sql(actual, expected, AdapterType::Bigquery) returned Err for queries whose only difference is projection order plus SQL comments containing apostrophes. The tokenizer/canonicalizer must strip comments before matching projections; failing here means comment handling (specifically apostrophe/quote characters inside /* */ comments) corrupts tokenization so the projection reordering never applies.","triggerScenarios":"cargo test -p dbt-adapter with test at diff.rs:3633: the minimal Snowplow repro whose comments contain apostrophes (e.g. `/* user's metric */`) makes compare_sql under AdapterType::Bigquery report a mismatch that the same test without apostrophes (diff.rs:3559) does not.","commonSituations":"Comments with single quotes in hand-written or generated SQL confuse the string-literal scanner, causing apostrophe-balancing bugs that shift token boundaries and break alias extraction; replay of Snowplow-style models with commented projections fails only on comment-bearing lines.","solutions":["Strip /* */ and -- comments (respecting string literals) before projection matching, without treating apostrophes inside comments as string delimiters","Inspect the tokenizer's quote-state machine: ensure comment state consumes characters until */ regardless of embedded quotes","Compare with the passing no-comment test (diff.rs:3559) to confirm the delta is purely comment handling","Add a unit test for the tokenizer with `/* it's */` style comments"],"exampleFix":"// before: tokenizer treats ' inside /* */ as string start\nlet sql = \"select a /* user's col */, b\";\n// after: comment scanner consumes until */ ignoring quotes\nlet stripped = strip_comments(sql); // -> \"select a , b\"\ncompare_sql(stripped_actual, stripped_expected, AdapterType::Bigquery)\n    .expect(\"projection order drift should be ignored even with apostrophes in comments\");","handlingStrategy":"validation","validationCode":"// strip comments safely before any comparison\nfn strip_comments(sql: &str) -> String { /* consume -- and /* */ respecting string literals */ }\nassert_eq!(strip_comments(\"select a /* it's */\"), \"select a\");","typeGuard":null,"tryCatchPattern":"let (a, b) = (strip_comments(&actual), strip_comments(&expected));\ncompare_sql(&a, &b, AdapterType::Bigquery)\n    .unwrap_or_else(|e| eprintln!(\"comment-stripped diff still fails: {e}\"));","preventionTips":["Strip comments before tokenization in any SQL comparison pipeline","Make the comment scanner ignore quote characters inside /* */","Add apostrophe-in-comment fixtures to tokenizer tests","Keep string-literal detection and comment detection in one state machine"],"tags":["rust","sql-diff","test-panic","bigquery","comment-parsing","tokenizer"],"backgroundTag":"sql-diff-mismatch","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}