Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cass_result: implement missing functions #136

Merged
merged 6 commits into from
Oct 11, 2024

Conversation

muzarski
Copy link
Collaborator

@muzarski muzarski commented Jul 3, 2024

Fix: #35

Implemented two missing CassResult functions:

  • cass_result_column_type
  • cass_result_column_data_type

Also fixed cass_result_first_row implementation.

Pre-review checklist

  • I have split my patch into logically separate commits.
  • All commit messages clearly explain what they change and why.
  • PR description sums up the changes and reasons why they should be introduced.
  • [ ] I have enabled appropriate tests in .github/workflows/build.yml in gtest_filter.
  • [ ] I have enabled appropriate tests in .github/workflows/cassandra.yml in gtest_filter.

@muzarski muzarski self-assigned this Jul 3, 2024
@muzarski muzarski mentioned this pull request Jul 3, 2024
7 tasks
@muzarski muzarski requested a review from Lorak-mmk July 3, 2024 09:29
@mykaul
Copy link

mykaul commented Jul 3, 2024

Do we have tests to validate this?

@muzarski
Copy link
Collaborator Author

muzarski commented Jul 3, 2024

Do we have tests to validate this?

At first, I wasn't sure if there are integration tests checking this - unfortunately, the answer is no (previous implementation of cass_result_first_row would panic in some cases - this bug was never detected). Tomorrow I'll try to implement some cpp integration tests for the cass_result_* API.

@muzarski muzarski force-pushed the cass_result_missing_functions branch from 0c0ef5b to b7813e3 Compare July 3, 2024 22:27
@muzarski
Copy link
Collaborator Author

muzarski commented Jul 3, 2024

v2: Fixed cass_result_first_row

@wprzytula
Copy link
Collaborator

Do we have tests to validate this?

At first, I wasn't sure if there are integration tests checking this - unfortunately, the answer is no (previous implementation of cass_result_first_row would panic in some cases - this bug was never detected). Tomorrow I'll try to implement some cpp integration tests for the cass_result_* API.

WDYT about adding Rust unit tests first? They should be the first layer to detect errors, they have smaller overhead and, probably the most important for convenience of us maintainers, they are written in Rust, not in Datastax C++ test framework.

@muzarski muzarski force-pushed the cass_result_missing_functions branch from b7813e3 to 12ac9e6 Compare July 5, 2024 15:57
@muzarski muzarski requested a review from wprzytula July 5, 2024 15:58
@muzarski muzarski force-pushed the cass_result_missing_functions branch from 12ac9e6 to ebf360c Compare July 5, 2024 16:00
@muzarski
Copy link
Collaborator Author

muzarski commented Jul 5, 2024

v3: implemented unit tests for basic cass_result_* API.

@muzarski muzarski force-pushed the cass_result_missing_functions branch from ebf360c to d81ecec Compare July 9, 2024 09:43
@wprzytula
Copy link
Collaborator

In this PR, you should instantly enable related integration tests and/or examples.

@Lorak-mmk Lorak-mmk self-assigned this Jul 9, 2024
scylla-rust-wrapper/src/session.rs Outdated Show resolved Hide resolved
scylla-rust-wrapper/src/query_result.rs Outdated Show resolved Hide resolved
@Lorak-mmk Lorak-mmk removed their assignment Jul 31, 2024
@muzarski
Copy link
Collaborator Author

muzarski commented Sep 5, 2024

This PR is waiting for: #143

@dkropachev
Copy link
Collaborator

This PR is waiting for: #143

#143 is in, can you continue working on it ?

@muzarski
Copy link
Collaborator Author

muzarski commented Oct 7, 2024

This PR is waiting for: #143

#143 is in, can you continue working on it ?

Yes

@muzarski muzarski force-pushed the cass_result_missing_functions branch from d81ecec to e99166e Compare October 7, 2024 14:40
@muzarski
Copy link
Collaborator Author

muzarski commented Oct 7, 2024

Rebased on master

@muzarski muzarski force-pushed the cass_result_missing_functions branch from e99166e to de8d745 Compare October 7, 2024 15:26
@muzarski
Copy link
Collaborator Author

muzarski commented Oct 7, 2024

v4:
Now, the result metadata (Vec<Arc<CassDataType>>) is stored in CassPrepared. It allows us to omit the allocations each time we execute the prepared statement. We don't have to construct each CassDataType from scratch (it can be a really costly operation) based on the column specs.

Now, CassResultData::from_result_payload accepts an additional argument, which is an optional vector of result column data types.

  • For simple queries, we provide None - then CassDataTypes are created based on column specs received from the server.
  • For prepared statements, we provide a Some(<metadata cached in CassPrepared>) to avoid additional allocations

@muzarski muzarski force-pushed the cass_result_missing_functions branch 2 times, most recently from 69eb3bf to e488fe7 Compare October 7, 2024 15:37
scylla-rust-wrapper/src/prepared.rs Outdated Show resolved Hide resolved
scylla-rust-wrapper/src/session.rs Show resolved Hide resolved
@muzarski muzarski force-pushed the cass_result_missing_functions branch from e488fe7 to b81fa26 Compare October 8, 2024 10:21
@muzarski
Copy link
Collaborator Author

muzarski commented Oct 8, 2024

v4.1: wrapped the result data type metadata vector with an Arc.

The reason for this is that CassPrepared and CassResultData should share this vector, and this way we can omit an additional allocation each execution.

Note: Each individual CassDataType in the vector still needs to be wrapped with an Arc. This is because each CassValue (contained in CassResult in each CassRow) needs to hold information about the type.

@muzarski muzarski requested a review from Lorak-mmk October 8, 2024 10:26
scylla-rust-wrapper/src/prepared.rs Outdated Show resolved Hide resolved
scylla-rust-wrapper/src/session.rs Outdated Show resolved Hide resolved
scylla-rust-wrapper/src/session.rs Outdated Show resolved Hide resolved
scylla-rust-wrapper/src/query_result.rs Outdated Show resolved Hide resolved
Comment on lines 949 to 958
#[no_mangle]
pub unsafe extern "C" fn cass_result_column_data_type(
result: *const CassResult,
index: size_t,
) -> *const CassDataType {
let result_from_raw: &CassResult = ptr_to_ref(result);
let index_usize: usize = index.try_into().unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Justify unwrap.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, I have a question. Here is the definition of size_t in types.rs:

pub type size_t = cass_uint64_t;
pub type cass_uint64_t = u64;

Why? There is a libc::size_t which is an alias for usize. Couldn't we make use of it? Then, we wouldn't need to do a possibly lossy conversion each time (from u64 to usize).

cc: @Lorak-mmk

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I believe that sizes of both size_t and usize depend on the architecture. I don't understand why we assume that size_t is always u64 (8 bytes long)

Copy link
Collaborator

Choose a reason for hiding this comment

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

You are right of course. This alias was added probably by accident by @wprzytula in de6143a#diff-fffb385b3ac71791e0a2ddee4b04afa8c2d889e2713f4b1e4f29d216ec6045fd
Before that we already had definition for size_t generated by bindgen in build.rs:

fn prepare_basic_types(out_path: &Path) {
let basic_bindings = bindgen::Builder::default()
.header("extern/cassandra.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.layout_tests(true)
.generate_comments(false)
.allowlist_type("size_t")
.generate()
.expect("Unable to generate bindings");
basic_bindings
.write_to_file(out_path.join("basic_types.rs"))
.expect("Couldn't write bindings!");
}

This generated header is included in types.rs, so it should be safe to remove this wrong alias - even more, they should crash and not compile. However for some reason I can't remove it, it causes errors. This needs investigation and proper fix.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Generated basic_types.rs file is empty for some reason...

Copy link
Collaborator

@Lorak-mmk Lorak-mmk Oct 10, 2024

Choose a reason for hiding this comment

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

Adding .size_t_is_usize(false) call to the builder makes the definition generate again:

───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: ./target/debug/build/scylla-cpp-driver-rust-e897748878d67d0e/out/basic_types.rs
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ /* automatically generated by rust-bindgen 0.65.1 */
   2   │ 
   3   │ pub type size_t = ::std::os::raw::c_ulong;
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Generated basic_types.rs file is empty for some reason...

Same happened for me when I was playing with build.rs and types.rs

Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you apply this fix and remove the redundant size_t alias?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I opened a separate PR that solves issues regarding bindings in basic_types.rs: #188

scylla-rust-wrapper/src/query_result.rs Show resolved Hide resolved
scylla-rust-wrapper/src/query_result.rs Outdated Show resolved Hide resolved
scylla-rust-wrapper/src/session.rs Outdated Show resolved Hide resolved
@muzarski muzarski force-pushed the cass_result_missing_functions branch from b81fa26 to 9bfa0c7 Compare October 10, 2024 14:00
@muzarski
Copy link
Collaborator Author

Rebased on master

This way, we won't need to construct the data types from
the `QueryResult` each time statement is executed. We will be able
to simply make use of result metadata cached in prepared statement.
CassDataType can be a heavy object if the type is nested.
In this commit we include info about column data types in
result metadata (Arc<Vec<Arc<CassDataType>>>).

This will be needed to implement cass_result_column_data_type function.

We also adjust the construction of `CassValue::value_type` field
and avoid allocations. We simply clone Arc from result metadata.
@muzarski muzarski force-pushed the cass_result_missing_functions branch from 9bfa0c7 to 056feb1 Compare October 10, 2024 16:05
@muzarski
Copy link
Collaborator Author

v4.2: addressed @wprzytula comments

I'd like to introduce the size_t fix (maybe next to other binding fixes) in other PRs. I'm currently investigating it.

@muzarski muzarski force-pushed the cass_result_missing_functions branch from 056feb1 to 072ec01 Compare October 10, 2024 16:08
@muzarski
Copy link
Collaborator Author

v4.2.1: fixed clippy lint

Implemented two missing CassResult functions:
- cass_result_column_type
- cass_result_column_data_type
Previous implementation of cass_result_first_row
is buggy. It panics when rows are empty.

This commit fixes the implementation.
Implemented tests for two cases:
- Rows result - i.e. result of SELECT query.
- non-Rows result - e.g. result of INSERT query
This function unnecessarily accepted and returned an Option.
It should be the caller's responsibility to call this function
only if `result.rows` is Some.
@muzarski muzarski force-pushed the cass_result_missing_functions branch from 072ec01 to 538ffaf Compare October 10, 2024 18:24
@muzarski
Copy link
Collaborator Author

v4.2.2: replaced unwrap() with expect() for u64 to usize conversion.

@muzarski muzarski requested a review from wprzytula October 10, 2024 18:25
@muzarski muzarski requested a review from Lorak-mmk October 11, 2024 11:24
@muzarski muzarski merged commit 4d006df into scylladb:master Oct 11, 2024
11 checks passed
@muzarski muzarski mentioned this pull request Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CassResult missing functions
5 participants