You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by "jinchengchenghh (via GitHub)" <gi...@apache.org> on 2024/07/30 06:31:39 UTC
[PR] GH-28866: [Java] Java Dataset CsvFragmentScanOptions expansion [arrow]
jinchengchenghh opened a new pull request, #43482:
URL: https://github.com/apache/arrow/pull/43482
<!--
Thanks for opening a pull request!
If this is your first pull request you can find detailed information on how
to contribute here:
* [New Contributor's Guide](https://arrow.apache.org/docs/dev/developers/guide/step_by_step/pr_lifecycle.html#reviews-and-merge-of-the-pull-request)
* [Contributing Overview](https://arrow.apache.org/docs/dev/developers/overview.html)
If this is not a [minor PR](https://github.com/apache/arrow/blob/main/CONTRIBUTING.md#Minor-Fixes). Could you open an issue for this pull request on GitHub? https://github.com/apache/arrow/issues/new/choose
Opening GitHub issues ahead of time contributes to the [Openness](http://theapacheway.com/open/#:~:text=Openness%20allows%20new%20users%20the,must%20happen%20in%20the%20open.) of the Apache Arrow project.
Then could you also rename the pull request title in the following format?
GH-${GITHUB_ISSUE_ID}: [${COMPONENT}] ${SUMMARY}
or
MINOR: [${COMPONENT}] ${SUMMARY}
In the case of PARQUET issues on JIRA the title also supports:
PARQUET-${JIRA_ISSUE_ID}: [${COMPONENT}] ${SUMMARY}
-->
### Rationale for this change
<!--
Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed.
Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes.
-->
Support more CSV fragment scan options
### What changes are included in this PR?
<!--
There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR.
-->
Implement nearly all cpp code supported CsvFragmentScanOptions
### Are these changes tested?
Yes, new added test and exists UT.
<!--
We typically require tests for all PRs in order to:
1. Prevent the code from being accidentally broken by subsequent changes
2. Serve as another way to document the expected behavior of the code
If tests are not included in your PR, please explain why (for example, are they covered by existing tests)?
-->
### Are there any user-facing changes?
No.
<!--
If there are user-facing changes then we may require documentation to be updated before approving the PR.
-->
<!--
If there are any breaking changes to public APIs, please uncomment the line below and explain which changes are breaking.
-->
<!-- **This PR includes breaking changes to public APIs.** -->
<!--
Please uncomment the line below (and provide explanation) if the changes fix either (a) a security vulnerability, (b) a bug that caused incorrect or invalid data to be produced, or (c) a bug that causes a crash (even when the API contract is upheld). We use this to highlight fixes to issues that may affect users without their knowledge. For this reason, fixing bugs that cause errors don't count, since those are usually obvious.
-->
<!-- **This PR contains a "Critical Fix".** -->
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java] [CPP] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #43482:
URL: https://github.com/apache/arrow/pull/43482#issuecomment-2257672500
:warning: GitHub issue #43483 **has been automatically assigned in GitHub** to PR creator.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1697781838
##########
java/dataset/src/test/java/org/apache/arrow/dataset/TestFragmentScanOptions.java:
##########
@@ -165,4 +165,44 @@ public void testCsvConvertOptionsNoOption() throws Exception {
assertEquals(3, rowCount);
}
}
+
Review Comment:
Plus we might want to check whether all the options are properly used.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java] [CPP] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "danepitkin (via GitHub)" <gi...@apache.org>.
danepitkin commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1697496094
##########
java/dataset/src/test/java/org/apache/arrow/dataset/TestFragmentScanOptions.java:
##########
@@ -165,4 +165,44 @@ public void testCsvConvertOptionsNoOption() throws Exception {
assertEquals(3, rowCount);
}
}
+
Review Comment:
Can we add parameterized tests for the `setCsv*Options` functions?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "lidavidm (via GitHub)" <gi...@apache.org>.
lidavidm commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1701060717
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
Review Comment:
```suggestion
JniThrow("CSV convert option " + value + " should be a char");
```
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
+ }
+ return value.at(0);
+}
+
/// \brief Construct FragmentScanOptions from config map
#ifdef ARROW_CSV
+
+bool SetCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "column_types") {
+ int64_t schema_address = std::stol(value);
+ ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
+ auto schema = JniGetOrThrow(arrow::ImportSchema(c_schema));
+ auto& column_types = options.column_types;
+ for (auto field : schema->fields()) {
+ column_types[field->name()] = field->type();
+ }
+ } else if (key == "strings_can_be_null") {
+ options.strings_can_be_null = ParseBool(value);
+ } else if (key == "check_utf8") {
+ options.check_utf8 = ParseBool(value);
+ } else if (key == "null_values") {
+ options.null_values = {value};
+ } else if (key == "true_values") {
+ options.true_values = {value};
+ } else if (key == "false_values") {
+ options.false_values = {value};
+ } else if (key == "quoted_strings_can_be_null") {
+ options.quoted_strings_can_be_null = ParseBool(value);
+ } else if (key == "auto_dict_encode") {
+ options.auto_dict_encode = ParseBool(value);
+ } else if (key == "auto_dict_max_cardinality") {
+ options.auto_dict_max_cardinality = std::stoi(value);
+ } else if (key == "decimal_point") {
+ options.decimal_point = ParseChar(value);
+ } else if (key == "include_missing_columns") {
+ options.include_missing_columns = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvParseOptions(arrow::csv::ParseOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "delimiter") {
+ options.delimiter = ParseChar(value);
+ } else if (key == "quoting") {
+ options.quoting = ParseBool(value);
+ } else if (key == "quote_char") {
+ options.quote_char = ParseChar(value);
+ } else if (key == "double_quote") {
+ options.double_quote = ParseBool(value);
+ } else if (key == "escaping") {
+ options.escaping = ParseBool(value);
+ } else if (key == "escape_char") {
+ options.escape_char = ParseChar(value);
+ } else if (key == "newlines_in_values") {
+ options.newlines_in_values = ParseBool(value);
+ } else if (key == "ignore_empty_lines") {
+ options.ignore_empty_lines = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvReadOptions(arrow::csv::ReadOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "use_threads") {
+ options.use_threads = ParseBool(value);
+ } else if (key == "block_size") {
+ options.block_size = std::stoi(value);
+ } else if (key == "skip_rows") {
+ options.skip_rows = std::stoi(value);
+ } else if (key == "skip_rows_after_names") {
+ options.skip_rows_after_names = std::stoi(value);
+ } else if (key == "autogenerate_column_names") {
+ options.autogenerate_column_names = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
arrow::Result<std::shared_ptr<arrow::dataset::FragmentScanOptions>>
ToCsvFragmentScanOptions(const std::unordered_map<std::string, std::string>& configs) {
std::shared_ptr<arrow::dataset::CsvFragmentScanOptions> options =
std::make_shared<arrow::dataset::CsvFragmentScanOptions>();
- for (auto const& [key, value] : configs) {
- if (key == "delimiter") {
- options->parse_options.delimiter = value.data()[0];
- } else if (key == "quoting") {
- options->parse_options.quoting = ParseBool(value);
- } else if (key == "column_types") {
- int64_t schema_address = std::stol(value);
- ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
- ARROW_ASSIGN_OR_RAISE(auto schema, arrow::ImportSchema(c_schema));
- auto& column_types = options->convert_options.column_types;
- for (auto field : schema->fields()) {
- column_types[field->name()] = field->type();
- }
- } else if (key == "strings_can_be_null") {
- options->convert_options.strings_can_be_null = ParseBool(value);
- } else {
+ for (const auto& it : configs) {
+ const auto& key = it.first;
+ const auto& value = it.second;
+ bool setValid = SetCsvParseOptions(options->parse_options, key, value) ||
Review Comment:
Since we already use JniThrow, we can just use that consistently instead of mixing error handling routines here.
##########
java/dataset/src/main/java/org/apache/arrow/dataset/scanner/csv/CsvFragmentScanOptions.java:
##########
@@ -32,6 +32,9 @@ public class CsvFragmentScanOptions implements FragmentScanOptions {
* CSV scan options, map to CPP struct CsvFragmentScanOptions. The key in config map is the field
* name of mapping cpp struct
*
+ * <p>If the option type is a std::vector in the CPP code, only support for setting one value. For
+ * example, for convert option null_values, only support set one string as null value.
+ *
Review Comment:
```suggestion
* <p>Currently, multi-valued options (which are std::vector values in C++) only support having a single value set. For
* example, for the null_values option, only one string can be set as the null value.
*
```
##########
java/dataset/src/test/java/org/apache/arrow/dataset/TestFragmentScanOptions.java:
##########
@@ -165,4 +165,44 @@ public void testCsvConvertOptionsNoOption() throws Exception {
assertEquals(3, rowCount);
}
}
+
Review Comment:
Ideally we'd have a brief test of each option, I think
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
Review Comment:
It would be good to show the invalid key as well
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "jinchengchenghh (via GitHub)" <gi...@apache.org>.
jinchengchenghh commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1701065457
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
+ }
+ return value.at(0);
+}
+
/// \brief Construct FragmentScanOptions from config map
#ifdef ARROW_CSV
+
+bool SetCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "column_types") {
+ int64_t schema_address = std::stol(value);
+ ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
+ auto schema = JniGetOrThrow(arrow::ImportSchema(c_schema));
+ auto& column_types = options.column_types;
+ for (auto field : schema->fields()) {
+ column_types[field->name()] = field->type();
+ }
+ } else if (key == "strings_can_be_null") {
+ options.strings_can_be_null = ParseBool(value);
+ } else if (key == "check_utf8") {
+ options.check_utf8 = ParseBool(value);
+ } else if (key == "null_values") {
+ options.null_values = {value};
+ } else if (key == "true_values") {
+ options.true_values = {value};
+ } else if (key == "false_values") {
+ options.false_values = {value};
+ } else if (key == "quoted_strings_can_be_null") {
+ options.quoted_strings_can_be_null = ParseBool(value);
+ } else if (key == "auto_dict_encode") {
+ options.auto_dict_encode = ParseBool(value);
+ } else if (key == "auto_dict_max_cardinality") {
+ options.auto_dict_max_cardinality = std::stoi(value);
+ } else if (key == "decimal_point") {
+ options.decimal_point = ParseChar(value);
+ } else if (key == "include_missing_columns") {
+ options.include_missing_columns = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvParseOptions(arrow::csv::ParseOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "delimiter") {
+ options.delimiter = ParseChar(value);
+ } else if (key == "quoting") {
+ options.quoting = ParseBool(value);
+ } else if (key == "quote_char") {
+ options.quote_char = ParseChar(value);
+ } else if (key == "double_quote") {
+ options.double_quote = ParseBool(value);
+ } else if (key == "escaping") {
+ options.escaping = ParseBool(value);
+ } else if (key == "escape_char") {
+ options.escape_char = ParseChar(value);
+ } else if (key == "newlines_in_values") {
+ options.newlines_in_values = ParseBool(value);
+ } else if (key == "ignore_empty_lines") {
+ options.ignore_empty_lines = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvReadOptions(arrow::csv::ReadOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "use_threads") {
+ options.use_threads = ParseBool(value);
+ } else if (key == "block_size") {
+ options.block_size = std::stoi(value);
+ } else if (key == "skip_rows") {
+ options.skip_rows = std::stoi(value);
+ } else if (key == "skip_rows_after_names") {
+ options.skip_rows_after_names = std::stoi(value);
+ } else if (key == "autogenerate_column_names") {
+ options.autogenerate_column_names = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
arrow::Result<std::shared_ptr<arrow::dataset::FragmentScanOptions>>
ToCsvFragmentScanOptions(const std::unordered_map<std::string, std::string>& configs) {
std::shared_ptr<arrow::dataset::CsvFragmentScanOptions> options =
std::make_shared<arrow::dataset::CsvFragmentScanOptions>();
- for (auto const& [key, value] : configs) {
- if (key == "delimiter") {
- options->parse_options.delimiter = value.data()[0];
- } else if (key == "quoting") {
- options->parse_options.quoting = ParseBool(value);
- } else if (key == "column_types") {
- int64_t schema_address = std::stol(value);
- ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
- ARROW_ASSIGN_OR_RAISE(auto schema, arrow::ImportSchema(c_schema));
- auto& column_types = options->convert_options.column_types;
- for (auto field : schema->fields()) {
- column_types[field->name()] = field->type();
- }
- } else if (key == "strings_can_be_null") {
- options->convert_options.strings_can_be_null = ParseBool(value);
- } else {
+ for (const auto& it : configs) {
Review Comment:
No, I meet exception, so I change to current.
```
/arrow/java/dataset/src/main/cpp/jni_wrapper.cc:464:69: error: binding reference of type ‘std::string&’ {aka ‘std::basic_string<char>&’} to ‘std::tuple_element<1, const std::pair<const std::basic_string<char>, std::basic_string<char> > >::type’ {aka ‘const std::basic_string<char>’} discards qualifiers
464 | bool setValid = setCsvParseOptions(options->parse_options, key, value) &&
| ^~~~~
/arrow/java/dataset/src/main/cpp/jni_wrapper.cc:418:38: note: initializing argument 3 of ‘bool setCsvParseOptions(arrow::csv::ParseOptions&, const string&, std::string&)’
418 | std::string& value) {
|
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1698338790
##########
java/dataset/src/test/java/org/apache/arrow/dataset/TestFragmentScanOptions.java:
##########
@@ -165,4 +169,152 @@ public void testCsvConvertOptionsNoOption() throws Exception {
assertEquals(3, rowCount);
}
}
+
+ @Test
+ public void testCsvReadParseAndReadOptions() throws Exception {
+ final Schema schema =
+ new Schema(
+ Collections.singletonList(Field.nullable("Id;Name;Language", new ArrowType.Utf8())),
+ null);
+ String path = "file://" + getClass().getResource("/").getPath() + "/data/student.csv";
+ BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE);
+ CsvFragmentScanOptions fragmentScanOptions =
+ new CsvFragmentScanOptions(
+ new CsvConvertOptions(ImmutableMap.of()),
+ ImmutableMap.of("skip_rows", "1"),
+ ImmutableMap.of("delimiter", ";"));
+ ScanOptions options =
+ new ScanOptions.Builder(/*batchSize*/ 32768)
+ .columns(Optional.empty())
+ .fragmentScanOptions(fragmentScanOptions)
+ .build();
+ try (DatasetFactory datasetFactory =
+ new FileSystemDatasetFactory(
+ allocator, NativeMemoryPool.getDefault(), FileFormat.CSV, path);
+ Dataset dataset = datasetFactory.finish();
+ Scanner scanner = dataset.newScan(options);
+ ArrowReader reader = scanner.scanBatches()) {
+
+ assertEquals(schema.getFields(), reader.getVectorSchemaRoot().getSchema().getFields());
+ int rowCount = 0;
+ while (reader.loadNextBatch()) {
+ final ValueIterableVector<String> idVector =
+ (ValueIterableVector<String>)
+ reader.getVectorSchemaRoot().getVector("Id;Name;Language");
+ assertThat(
+ idVector.getValueIterable(),
+ IsIterableContainingInOrder.contains("2;Peter;Python\n" + "3;Celin;C++"));
+ rowCount += reader.getVectorSchemaRoot().getRowCount();
+ }
+ assertEquals(2, rowCount);
+ }
+ }
+
+ @Test
+ public void testCsvReadOtherOptions() throws Exception {
Review Comment:
Thanks for adding this.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1698242300
##########
java/dataset/src/test/java/org/apache/arrow/dataset/TestFragmentScanOptions.java:
##########
@@ -17,8 +17,7 @@
package org.apache.arrow.dataset;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
Review Comment:
Lets not remove these, but add `assertNotNull` to the imports.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on PR #43482:
URL: https://github.com/apache/arrow/pull/43482#issuecomment-2260289146
@jinchengchenghh Overall LGTM!, I will review once tomorrow.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "lidavidm (via GitHub)" <gi...@apache.org>.
lidavidm merged PR #43482:
URL: https://github.com/apache/arrow/pull/43482
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-28866: [Java] Java Dataset CsvFragmentScanOptions expansion [arrow]
Posted by "lidavidm (via GitHub)" <gi...@apache.org>.
lidavidm commented on PR #43482:
URL: https://github.com/apache/arrow/pull/43482#issuecomment-2257598098
Sorry, can we make a new issue instead of reusing a closed one?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1697961175
##########
java/dataset/src/test/java/org/apache/arrow/dataset/TestFragmentScanOptions.java:
##########
@@ -165,4 +165,44 @@ public void testCsvConvertOptionsNoOption() throws Exception {
assertEquals(3, rowCount);
}
}
+
Review Comment:
What I meant was just to check if the passed options are retrieved as expected, just a config test. Not to check the functionality.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1700073503
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
+ }
+ return value.at(0);
+}
+
/// \brief Construct FragmentScanOptions from config map
#ifdef ARROW_CSV
+
+bool SetCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "column_types") {
+ int64_t schema_address = std::stol(value);
+ ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
+ auto schema = JniGetOrThrow(arrow::ImportSchema(c_schema));
+ auto& column_types = options.column_types;
+ for (auto field : schema->fields()) {
+ column_types[field->name()] = field->type();
+ }
+ } else if (key == "strings_can_be_null") {
+ options.strings_can_be_null = ParseBool(value);
+ } else if (key == "check_utf8") {
+ options.check_utf8 = ParseBool(value);
+ } else if (key == "null_values") {
+ options.null_values = {value};
+ } else if (key == "true_values") {
+ options.true_values = {value};
+ } else if (key == "false_values") {
+ options.false_values = {value};
+ } else if (key == "quoted_strings_can_be_null") {
+ options.quoted_strings_can_be_null = ParseBool(value);
+ } else if (key == "auto_dict_encode") {
+ options.auto_dict_encode = ParseBool(value);
+ } else if (key == "auto_dict_max_cardinality") {
+ options.auto_dict_max_cardinality = std::stoi(value);
+ } else if (key == "decimal_point") {
+ options.decimal_point = ParseChar(value);
+ } else if (key == "include_missing_columns") {
+ options.include_missing_columns = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvParseOptions(arrow::csv::ParseOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "delimiter") {
+ options.delimiter = ParseChar(value);
+ } else if (key == "quoting") {
+ options.quoting = ParseBool(value);
+ } else if (key == "quote_char") {
+ options.quote_char = ParseChar(value);
+ } else if (key == "double_quote") {
+ options.double_quote = ParseBool(value);
+ } else if (key == "escaping") {
+ options.escaping = ParseBool(value);
+ } else if (key == "escape_char") {
+ options.escape_char = ParseChar(value);
+ } else if (key == "newlines_in_values") {
+ options.newlines_in_values = ParseBool(value);
+ } else if (key == "ignore_empty_lines") {
+ options.ignore_empty_lines = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvReadOptions(arrow::csv::ReadOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "use_threads") {
+ options.use_threads = ParseBool(value);
+ } else if (key == "block_size") {
+ options.block_size = std::stoi(value);
+ } else if (key == "skip_rows") {
+ options.skip_rows = std::stoi(value);
+ } else if (key == "skip_rows_after_names") {
+ options.skip_rows_after_names = std::stoi(value);
+ } else if (key == "autogenerate_column_names") {
+ options.autogenerate_column_names = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
arrow::Result<std::shared_ptr<arrow::dataset::FragmentScanOptions>>
ToCsvFragmentScanOptions(const std::unordered_map<std::string, std::string>& configs) {
std::shared_ptr<arrow::dataset::CsvFragmentScanOptions> options =
std::make_shared<arrow::dataset::CsvFragmentScanOptions>();
- for (auto const& [key, value] : configs) {
- if (key == "delimiter") {
- options->parse_options.delimiter = value.data()[0];
- } else if (key == "quoting") {
- options->parse_options.quoting = ParseBool(value);
- } else if (key == "column_types") {
- int64_t schema_address = std::stol(value);
- ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
- ARROW_ASSIGN_OR_RAISE(auto schema, arrow::ImportSchema(c_schema));
- auto& column_types = options->convert_options.column_types;
- for (auto field : schema->fields()) {
- column_types[field->name()] = field->type();
- }
- } else if (key == "strings_can_be_null") {
- options->convert_options.strings_can_be_null = ParseBool(value);
- } else {
+ for (const auto& it : configs) {
Review Comment:
Could we try something like `for (const auto& [key, value] : configs)`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on PR #43482:
URL: https://github.com/apache/arrow/pull/43482#issuecomment-2260130884
@jinchengchenghh there is a checkstyle error in one of the CIs, could you please try `mvn spotless:apply` and see if it can be fixed? Not sure why is it only occurring in one CI though :thinking:
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "jinchengchenghh (via GitHub)" <gi...@apache.org>.
jinchengchenghh commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1697918189
##########
java/dataset/src/test/java/org/apache/arrow/dataset/TestFragmentScanOptions.java:
##########
@@ -165,4 +165,44 @@ public void testCsvConvertOptionsNoOption() throws Exception {
assertEquals(3, rowCount);
}
}
+
Review Comment:
Then we will need a lot of tests to check whether all the options are properly used. Do you think we should do that? Now I only add test to test one of CsvxxxOptions are properly used. @lidavidm @vibhatha
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1697781125
##########
java/dataset/src/main/java/org/apache/arrow/dataset/scanner/csv/CsvFragmentScanOptions.java:
##########
@@ -32,6 +32,9 @@ public class CsvFragmentScanOptions implements FragmentScanOptions {
* CSV scan options, map to CPP struct CsvFragmentScanOptions. The key in config map is the field
* name of mapping cpp struct
*
+ * If the option type is std::vector in cpp code, only support set one value.
Review Comment:
mayeb:
```suggestion
* If the option type is a std::vector in the CPP code, only support for setting one value.
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1697780025
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
+ }
+ return value.at(0);
+}
+
/// \brief Construct FragmentScanOptions from config map
#ifdef ARROW_CSV
+
+bool setCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
Review Comment:
And probably, capitalize the first letter of the following method names as well.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "vibhatha (via GitHub)" <gi...@apache.org>.
vibhatha commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1697777454
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
+ }
+ return value.at(0);
+}
+
/// \brief Construct FragmentScanOptions from config map
#ifdef ARROW_CSV
+
+bool setCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
Review Comment:
nit
```suggestion
bool SetCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "lidavidm (via GitHub)" <gi...@apache.org>.
lidavidm commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1701071462
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
+ }
+ return value.at(0);
+}
+
/// \brief Construct FragmentScanOptions from config map
#ifdef ARROW_CSV
+
+bool SetCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "column_types") {
+ int64_t schema_address = std::stol(value);
+ ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
+ auto schema = JniGetOrThrow(arrow::ImportSchema(c_schema));
+ auto& column_types = options.column_types;
+ for (auto field : schema->fields()) {
+ column_types[field->name()] = field->type();
+ }
+ } else if (key == "strings_can_be_null") {
+ options.strings_can_be_null = ParseBool(value);
+ } else if (key == "check_utf8") {
+ options.check_utf8 = ParseBool(value);
+ } else if (key == "null_values") {
+ options.null_values = {value};
+ } else if (key == "true_values") {
+ options.true_values = {value};
+ } else if (key == "false_values") {
+ options.false_values = {value};
+ } else if (key == "quoted_strings_can_be_null") {
+ options.quoted_strings_can_be_null = ParseBool(value);
+ } else if (key == "auto_dict_encode") {
+ options.auto_dict_encode = ParseBool(value);
+ } else if (key == "auto_dict_max_cardinality") {
+ options.auto_dict_max_cardinality = std::stoi(value);
+ } else if (key == "decimal_point") {
+ options.decimal_point = ParseChar(value);
+ } else if (key == "include_missing_columns") {
+ options.include_missing_columns = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvParseOptions(arrow::csv::ParseOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "delimiter") {
+ options.delimiter = ParseChar(value);
+ } else if (key == "quoting") {
+ options.quoting = ParseBool(value);
+ } else if (key == "quote_char") {
+ options.quote_char = ParseChar(value);
+ } else if (key == "double_quote") {
+ options.double_quote = ParseBool(value);
+ } else if (key == "escaping") {
+ options.escaping = ParseBool(value);
+ } else if (key == "escape_char") {
+ options.escape_char = ParseChar(value);
+ } else if (key == "newlines_in_values") {
+ options.newlines_in_values = ParseBool(value);
+ } else if (key == "ignore_empty_lines") {
+ options.ignore_empty_lines = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvReadOptions(arrow::csv::ReadOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "use_threads") {
+ options.use_threads = ParseBool(value);
+ } else if (key == "block_size") {
+ options.block_size = std::stoi(value);
+ } else if (key == "skip_rows") {
+ options.skip_rows = std::stoi(value);
+ } else if (key == "skip_rows_after_names") {
+ options.skip_rows_after_names = std::stoi(value);
+ } else if (key == "autogenerate_column_names") {
+ options.autogenerate_column_names = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
arrow::Result<std::shared_ptr<arrow::dataset::FragmentScanOptions>>
ToCsvFragmentScanOptions(const std::unordered_map<std::string, std::string>& configs) {
std::shared_ptr<arrow::dataset::CsvFragmentScanOptions> options =
std::make_shared<arrow::dataset::CsvFragmentScanOptions>();
- for (auto const& [key, value] : configs) {
- if (key == "delimiter") {
- options->parse_options.delimiter = value.data()[0];
- } else if (key == "quoting") {
- options->parse_options.quoting = ParseBool(value);
- } else if (key == "column_types") {
- int64_t schema_address = std::stol(value);
- ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
- ARROW_ASSIGN_OR_RAISE(auto schema, arrow::ImportSchema(c_schema));
- auto& column_types = options->convert_options.column_types;
- for (auto field : schema->fields()) {
- column_types[field->name()] = field->type();
- }
- } else if (key == "strings_can_be_null") {
- options->convert_options.strings_can_be_null = ParseBool(value);
- } else {
+ for (const auto& it : configs) {
Review Comment:
That shouldn't apply. Was the parameter not declared `const` before?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "jinchengchenghh (via GitHub)" <gi...@apache.org>.
jinchengchenghh commented on code in PR #43482:
URL: https://github.com/apache/arrow/pull/43482#discussion_r1701113667
##########
java/dataset/src/main/cpp/jni_wrapper.cc:
##########
@@ -368,28 +368,105 @@ std::shared_ptr<arrow::Buffer> LoadArrowBufferFromByteBuffer(JNIEnv* env, jobjec
inline bool ParseBool(const std::string& value) { return value == "true" ? true : false; }
+inline bool ParseChar(const std::string& value) {
+ if (value.size() != 1) {
+ JniThrow("Csv convert option " + value + " should be a char");
+ }
+ return value.at(0);
+}
+
/// \brief Construct FragmentScanOptions from config map
#ifdef ARROW_CSV
+
+bool SetCsvConvertOptions(arrow::csv::ConvertOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "column_types") {
+ int64_t schema_address = std::stol(value);
+ ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
+ auto schema = JniGetOrThrow(arrow::ImportSchema(c_schema));
+ auto& column_types = options.column_types;
+ for (auto field : schema->fields()) {
+ column_types[field->name()] = field->type();
+ }
+ } else if (key == "strings_can_be_null") {
+ options.strings_can_be_null = ParseBool(value);
+ } else if (key == "check_utf8") {
+ options.check_utf8 = ParseBool(value);
+ } else if (key == "null_values") {
+ options.null_values = {value};
+ } else if (key == "true_values") {
+ options.true_values = {value};
+ } else if (key == "false_values") {
+ options.false_values = {value};
+ } else if (key == "quoted_strings_can_be_null") {
+ options.quoted_strings_can_be_null = ParseBool(value);
+ } else if (key == "auto_dict_encode") {
+ options.auto_dict_encode = ParseBool(value);
+ } else if (key == "auto_dict_max_cardinality") {
+ options.auto_dict_max_cardinality = std::stoi(value);
+ } else if (key == "decimal_point") {
+ options.decimal_point = ParseChar(value);
+ } else if (key == "include_missing_columns") {
+ options.include_missing_columns = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvParseOptions(arrow::csv::ParseOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "delimiter") {
+ options.delimiter = ParseChar(value);
+ } else if (key == "quoting") {
+ options.quoting = ParseBool(value);
+ } else if (key == "quote_char") {
+ options.quote_char = ParseChar(value);
+ } else if (key == "double_quote") {
+ options.double_quote = ParseBool(value);
+ } else if (key == "escaping") {
+ options.escaping = ParseBool(value);
+ } else if (key == "escape_char") {
+ options.escape_char = ParseChar(value);
+ } else if (key == "newlines_in_values") {
+ options.newlines_in_values = ParseBool(value);
+ } else if (key == "ignore_empty_lines") {
+ options.ignore_empty_lines = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool SetCsvReadOptions(arrow::csv::ReadOptions& options, const std::string& key,
+ const std::string& value) {
+ if (key == "use_threads") {
+ options.use_threads = ParseBool(value);
+ } else if (key == "block_size") {
+ options.block_size = std::stoi(value);
+ } else if (key == "skip_rows") {
+ options.skip_rows = std::stoi(value);
+ } else if (key == "skip_rows_after_names") {
+ options.skip_rows_after_names = std::stoi(value);
+ } else if (key == "autogenerate_column_names") {
+ options.autogenerate_column_names = ParseBool(value);
+ } else {
+ return false;
+ }
+ return true;
+}
+
arrow::Result<std::shared_ptr<arrow::dataset::FragmentScanOptions>>
ToCsvFragmentScanOptions(const std::unordered_map<std::string, std::string>& configs) {
std::shared_ptr<arrow::dataset::CsvFragmentScanOptions> options =
std::make_shared<arrow::dataset::CsvFragmentScanOptions>();
- for (auto const& [key, value] : configs) {
- if (key == "delimiter") {
- options->parse_options.delimiter = value.data()[0];
- } else if (key == "quoting") {
- options->parse_options.quoting = ParseBool(value);
- } else if (key == "column_types") {
- int64_t schema_address = std::stol(value);
- ArrowSchema* c_schema = reinterpret_cast<ArrowSchema*>(schema_address);
- ARROW_ASSIGN_OR_RAISE(auto schema, arrow::ImportSchema(c_schema));
- auto& column_types = options->convert_options.column_types;
- for (auto field : schema->fields()) {
- column_types[field->name()] = field->type();
- }
- } else if (key == "strings_can_be_null") {
- options->convert_options.strings_can_be_null = ParseBool(value);
- } else {
+ for (const auto& it : configs) {
Review Comment:
Maybe that case, I will take a try.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] GH-43483: [Java][C++] Support more CsvFragmentScanOptions in JNI call [arrow]
Posted by "conbench-apache-arrow[bot] (via GitHub)" <gi...@apache.org>.
conbench-apache-arrow[bot] commented on PR #43482:
URL: https://github.com/apache/arrow/pull/43482#issuecomment-2270927657
After merging your PR, Conbench analyzed the 4 benchmarking runs that have been run so far on merge-commit e6b05a8e58ad5c20f6daa2fa64488b8efec51993.
There were no benchmark performance regressions. 🎉
The [full Conbench report](https://github.com/apache/arrow/runs/28399365789) has more details.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org