diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.cc index 2a6bb8970b4d..1af2ab42bff1 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.cc @@ -23,11 +23,21 @@ #include "arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h" #include "arrow/flight/sql/odbc/odbc_impl/util.h" #include "arrow/flight/types.h" +#include "arrow/util/string.h" namespace arrow::flight::sql::odbc { using arrow::Result; +static void AddTableType(std::string& table_type, std::vector& table_types) { + std::string trimmed_type = arrow::internal::TrimString(table_type); + + // Only put the string if the trimmed result is non-empty + if (!trimmed_type.empty()) { + table_types.emplace_back(std::move(trimmed_type)); + } +} + void ParseTableTypes(const std::string& table_type, std::vector& table_types) { bool encountered = false; // for checking if there is a single quote @@ -36,36 +46,23 @@ void ParseTableTypes(const std::string& table_type, for (char temp : table_type) { // while still in the string switch (temp) { // switch depending on the character case '\'': // if the character is a single quote - if (encountered) { - encountered = false; // if we already found a single quote, reset encountered - } else { - encountered = - true; // if we haven't found a single quote, set encountered to true - } + // track when we've encountered a single opening quote + // and are still looking for the closing quote + encountered = !encountered; break; - case ',': // if it is a comma - if (!encountered) { // if we have not found a single quote - table_types.push_back(curr_parse); // put our current string into our vector - curr_parse = ""; // reset the current string + case ',': // if it is a comma + if (!encountered) { // if we have not found a single quote + AddTableType(curr_parse, table_types); // put current string into vector + curr_parse = ""; // reset the current string break; } - default: // if it is a normal character - if (encountered && isspace(temp)) { - curr_parse.push_back(temp); // if we have found a single quote put the - // whitespace, we don't care - } else if (temp == '\'' || temp == ' ') { - break; // if the current character is a single quote, trash it and go to - // the next character. - } else { - curr_parse.push_back(temp); // if all of the above failed, put the - // character into the current string - } - break; // go to the next character + [[fallthrough]]; + default: // if it is a normal character + curr_parse.push_back(temp); // put the character into the current string + break; // go to the next character } } - table_types.emplace_back( - curr_parse); // if we have found a single quote put the whitespace, - // we don't care + AddTableType(curr_parse, table_types); } std::shared_ptr GetTablesForSQLAllCatalogs( diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc index 544430539bd7..cf1e5930a827 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc @@ -49,4 +49,17 @@ TEST(TableTypeParser, ParsingWithSingleQuotesWithoutLeadingWhiteSpace) { TEST(TableTypeParser, ParsingWithCommaInsideSingleQuotes) { AssertParseTest("'TABLE, TEST', 'VIEW, TEMPORARY'", {"TABLE, TEST", "VIEW, TEMPORARY"}); } + +TEST(TableTypeParser, ParsingWithManyLeadingAndTrailingWhiteSpaces) { + AssertParseTest(" TABLE , VIEW ", {"TABLE", "VIEW"}); +} + +TEST(TableTypeParser, ParsingWithOnlyWhiteSpaceBetweenCommas) { + AssertParseTest("TABLE, ,VIEW", {"TABLE", "VIEW"}); +} + +TEST(TableTypeParser, ParsingWithWhiteSpaceInsideValue) { + AssertParseTest("BASE TABLE", {"BASE TABLE"}); +} + } // namespace arrow::flight::sql::odbc