Skip to content

impl(bigquery): basic row parsing#5916

Open
alvarowolfx wants to merge 8 commits into
googleapis:mainfrom
alvarowolfx:impl-bq-row-basic-parse
Open

impl(bigquery): basic row parsing#5916
alvarowolfx wants to merge 8 commits into
googleapis:mainfrom
alvarowolfx:impl-bq-row-basic-parse

Conversation

@alvarowolfx

Copy link
Copy Markdown
Contributor

Towards #5844

@product-auto-label product-auto-label Bot added the api: bigquery Issues related to the BigQuery API. label Jun 18, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces robust error handling and type conversion capabilities for BigQuery query results, including the FromSql trait for mapping database values to Rust types and a schema-aware Row parser. The reviewer feedback highlights critical correctness and performance improvements: addressing unnecessary clones and allocations during row parsing, preventing silent data corruption when handling special float values (like NaN and Infinity), ensuring consistent row-to-schema length validation, and improving error diagnostics by propagating actual field names instead of hardcoding 'unknown' in conversion errors.

Comment thread src/bigquery/src/query/row.rs
Comment thread src/bigquery/src/query/row.rs
Comment thread src/bigquery/src/query/row.rs Outdated
Comment thread src/bigquery/src/query/row.rs Outdated
Comment thread src/bigquery/src/query/row.rs Outdated
Comment thread src/bigquery/src/query/row.rs
Comment thread src/bigquery/src/query/row.rs
@alvarowolfx

Copy link
Copy Markdown
Contributor Author

Splitting errors into #5917. Later will split FromSql initial impl.

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.15842% with 32 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.85%. Comparing base (63de49f) to head (832db90).

Files with missing lines Patch % Lines
src/bigquery/src/query/row.rs 83.06% 32 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5916      +/-   ##
==========================================
- Coverage   97.88%   97.85%   -0.04%     
==========================================
  Files         236      236              
  Lines       60183    60379     +196     
==========================================
+ Hits        58913    59083     +170     
- Misses       1270     1296      +26     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@alvarowolfx

Copy link
Copy Markdown
Contributor Author

Split FromSql trait and some basic conversion into PR #5924

@alvarowolfx alvarowolfx marked this pull request as ready for review June 23, 2026 20:32
@alvarowolfx alvarowolfx requested a review from a team as a code owner June 23, 2026 20:32
Comment on lines +29 to +31
pub(crate) mod private {
/// A sealed trait to prevent external implementation of `ColumnIndex`.
pub trait Sealed {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we more commonly say:

mod sealed {
  pub trait ColumnIndex {}
}

Comment on lines +167 to +178
"STRING" => Ok(Value::String(value)),
"BYTES" => Ok(Value::String(value)),
"TIMESTAMP" => Ok(Value::String(value)),
"DATE" => Ok(Value::String(value)),
"TIME" => Ok(Value::String(value)),
"DATETIME" => Ok(Value::String(value)),
"NUMERIC" | "BIGNUMERIC" => Ok(Value::String(value)),
"BIGINT" => Ok(Value::String(value)),
"GEOGRAPHY" => Ok(Value::String(value)),
"JSON" => Ok(Value::String(value)),
"INTERVAL" => Ok(Value::String(value)),
"RANGE" => Ok(Value::String(value)),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional style nit: combine all of these? "STRING" | "BYTES" | ... | "RANGE" => Ok(Value::String(value))

})
.as_object()
.expect("row is an object")
.clone();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optionally, you could make the json Map directly and avoid expect() and the clone():

use serde_json::{json, Map};

let raw_row = Map::from_iter([(
    "f".to_string(),
    json!([
        { "v": "James" },
        { "v": "272793" },
        { "v": "TRUE" },
        { "v": null },
        { "v": "64.0" },
    ]),
)]);

#[test_case("UNKNOWN", "value", None; "unknown type")]
fn convert_basic_type_cases(field_type: &str, value: &str, expected: Option<Value>) {
let res = convert_basic_type(value.to_string(), "test_col", field_type);
match expected {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any ifs in a test are a hint that we should separate the tests. We probably want 3 tests:

  • convert_basic_type_cases_success
  • convert_basic_type_cases_conversion_fail
  • convert_basic_type_cases_invalid_row_format

len: self.schema.len(),
})?;

T::from_sql(val.clone()).map_err(|e| {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: we could probably have an API like a:

pub fn take<T: FromSql, I: ColumnIndex>(&mut self, index: I) -> Result<T>

that can extract the value without needing to clone.

It has downsides of replacing with a default value though.


I think it is not necessary if we have a zero-clone way to convert the whole row into an application struct. Just a thought.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: bigquery Issues related to the BigQuery API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants