From 736ebbdd6962aace0f31249038e7c8e22e547245 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Mon, 17 Aug 2026 06:05:22 +0000 Subject: [PATCH] fix(extractors): normalize uppercase JSON field names Closes #6385 --- .../dbx-core/src/data_grid_extractors/json.rs | 2 +- .../src/data_grid_extractors/tests.rs | 67 ++++++++++++++++--- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/crates/dbx-core/src/data_grid_extractors/json.rs b/crates/dbx-core/src/data_grid_extractors/json.rs index 4609603172..9c4f97015e 100644 --- a/crates/dbx-core/src/data_grid_extractors/json.rs +++ b/crates/dbx-core/src/data_grid_extractors/json.rs @@ -143,7 +143,7 @@ fn unique_json_names( fn lower_camel_json_name(name: &str) -> String { if !name.contains('_') { - return name.to_owned(); + return if name.chars().any(char::is_lowercase) { name.to_owned() } else { name.to_lowercase() }; } let mut words = name.split('_').filter(|word| !word.is_empty()); diff --git a/crates/dbx-core/src/data_grid_extractors/tests.rs b/crates/dbx-core/src/data_grid_extractors/tests.rs index 7c51b2d999..6e7ca82755 100644 --- a/crates/dbx-core/src/data_grid_extractors/tests.rs +++ b/crates/dbx-core/src/data_grid_extractors/tests.rs @@ -355,26 +355,60 @@ fn extracts_compact_json_when_pretty_printing_is_disabled() { fn converts_snake_case_json_field_names_only_when_enabled() { let mut request = request(DataGridExtractorId::Json); request.columns = vec![ - column("user_id", 0), - column("ORDER_ITEM_ID", 1), - column("alreadyCamel", 2), - column("_display__name_", 3), - column("naïve_value", 4), + column("ID", 0), + column("CODE", 1), + column("NAME", 2), + column("CREATE_TIME", 3), + column("user_id", 4), + column("ORDER_ITEM_ID", 5), + column("alreadyCamel", 6), + column("_display__name_", 7), + column("naïve_value", 8), ]; - request.selected_column_indexes = vec![0, 1, 2, 3, 4]; - request.rows = vec![vec![json!(7), json!(9), json!("kept"), json!("Ada"), json!(true)]]; + request.selected_column_indexes = vec![0, 1, 2, 3, 4, 5, 6, 7, 8]; + request.rows = vec![vec![ + json!(1), + json!("A01"), + json!("Ada"), + json!("2026-08-16T08:52:23Z"), + json!(7), + json!(9), + json!("kept"), + json!("Ada"), + json!(true), + ]]; let unchanged = extract_data_grid_selection(request.clone()).expect("default JSON extraction"); assert_eq!( serde_json::from_str::(&unchanged.text).expect("valid default JSON"), - json!([{"user_id": 7, "ORDER_ITEM_ID": 9, "alreadyCamel": "kept", "_display__name_": "Ada", "naïve_value": true}]) + json!([{ + "ID": 1, + "CODE": "A01", + "NAME": "Ada", + "CREATE_TIME": "2026-08-16T08:52:23Z", + "user_id": 7, + "ORDER_ITEM_ID": 9, + "alreadyCamel": "kept", + "_display__name_": "Ada", + "naïve_value": true + }]) ); request.options.json.camel_case_field_names = true; let converted = extract_data_grid_selection(request).expect("camel-case JSON extraction"); assert_eq!( serde_json::from_str::(&converted.text).expect("valid converted JSON"), - json!([{"userId": 7, "orderItemId": 9, "alreadyCamel": "kept", "displayName": "Ada", "naïveValue": true}]) + json!([{ + "id": 1, + "code": "A01", + "name": "Ada", + "createTime": "2026-08-16T08:52:23Z", + "userId": 7, + "orderItemId": 9, + "alreadyCamel": "kept", + "displayName": "Ada", + "naïveValue": true + }]) ); } @@ -401,6 +435,21 @@ fn converts_json_lines_names_and_suffixes_post_conversion_collisions() { assert_eq!(result.warnings[0].code, DataGridExtractWarningCode::DuplicateJsonColumnNames); } +#[test] +fn suffixes_collisions_after_normalizing_uppercase_json_names() { + let mut request = request(DataGridExtractorId::Json); + request.columns = vec![column("ID", 0), column("id", 1)]; + request.selected_column_indexes = vec![0, 1]; + request.rows = vec![vec![json!(1), json!(2)]]; + request.options.json.camel_case_field_names = true; + + let result = extract_data_grid_selection(request).expect("normalized JSON extraction"); + + assert_eq!(serde_json::from_str::(&result.text).expect("valid JSON"), json!([{"id": 1, "id_2": 2}])); + assert_eq!(result.warnings.len(), 1); + assert_eq!(result.warnings[0].code, DataGridExtractWarningCode::DuplicateJsonColumnNames); +} + #[test] fn builds_null_safe_where_clause_predicates() { let mut request = request(DataGridExtractorId::WhereClause);