From cf83b941b7a7ebcebe5318a73a56b764078b6baa Mon Sep 17 00:00:00 2001 From: David Li Date: Tue, 30 Dec 2025 11:26:45 +0900 Subject: [PATCH] GH-47721: [C++][FlightRPC] Revert #48050 This reverts commit 16de22038825b2f22687ee873d0240c619da2db2. --- cpp/src/arrow/flight/sql/column_metadata.cc | 6 +- cpp/src/arrow/flight/sql/odbc/odbc_api.cc | 86 +- .../flight_sql_result_set_metadata.cc | 32 +- .../flight_sql_result_set_metadata.h | 3 +- .../sql/odbc/odbc_impl/odbc_descriptor.cc | 62 +- .../odbc/odbc_impl/spi/result_set_metadata.h | 6 +- .../flight/sql/odbc/tests/columns_test.cc | 1224 ----------------- 7 files changed, 54 insertions(+), 1365 deletions(-) diff --git a/cpp/src/arrow/flight/sql/column_metadata.cc b/cpp/src/arrow/flight/sql/column_metadata.cc index 6501e3c7166..30f557084b2 100644 --- a/cpp/src/arrow/flight/sql/column_metadata.cc +++ b/cpp/src/arrow/flight/sql/column_metadata.cc @@ -58,10 +58,8 @@ const char* ColumnMetadata::kIsSearchable = "ARROW:FLIGHT:SQL:IS_SEARCHABLE"; const char* ColumnMetadata::kRemarks = "ARROW:FLIGHT:SQL:REMARKS"; ColumnMetadata::ColumnMetadata( - std::shared_ptr metadata_map) { - metadata_map_ = std::move(metadata_map ? metadata_map - : std::make_shared()); -} + std::shared_ptr metadata_map) + : metadata_map_(std::move(metadata_map)) {} arrow::Result ColumnMetadata::GetCatalogName() const { return metadata_map_->Get(kCatalogName); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc index 4eec8dcbf22..f7a3acc8081 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc @@ -1297,90 +1297,8 @@ SQLRETURN SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT record_number, << ", output_length: " << static_cast(output_length) << ", numeric_attribute_ptr: " << static_cast(numeric_attribute_ptr); - - using ODBC::ODBCDescriptor; - using ODBC::ODBCStatement; - return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() { - ODBCStatement* statement = reinterpret_cast(stmt); - ODBCDescriptor* ird = statement->GetIRD(); - SQLINTEGER output_length_int; - switch (field_identifier) { - // Numeric attributes - // internal is SQLLEN, no conversion is needed - case SQL_DESC_DISPLAY_SIZE: - case SQL_DESC_OCTET_LENGTH: { - ird->GetField(record_number, field_identifier, numeric_attribute_ptr, - buffer_length, &output_length_int); - break; - } - // internal is SQLULEN, conversion is needed. - case SQL_COLUMN_LENGTH: // ODBC 2.0 - case SQL_DESC_LENGTH: { - SQLULEN temp; - ird->GetField(record_number, field_identifier, &temp, buffer_length, - &output_length_int); - if (numeric_attribute_ptr) { - *numeric_attribute_ptr = static_cast(temp); - } - break; - } - // internal is SQLINTEGER, conversion is needed. - case SQL_DESC_AUTO_UNIQUE_VALUE: - case SQL_DESC_CASE_SENSITIVE: - case SQL_DESC_NUM_PREC_RADIX: { - SQLINTEGER temp; - ird->GetField(record_number, field_identifier, &temp, buffer_length, - &output_length_int); - if (numeric_attribute_ptr) { - *numeric_attribute_ptr = static_cast(temp); - } - break; - } - // internal is SQLSMALLINT, conversion is needed. - case SQL_DESC_CONCISE_TYPE: - case SQL_DESC_COUNT: - case SQL_DESC_FIXED_PREC_SCALE: - case SQL_DESC_TYPE: - case SQL_DESC_NULLABLE: - case SQL_COLUMN_PRECISION: // ODBC 2.0 - case SQL_DESC_PRECISION: - case SQL_COLUMN_SCALE: // ODBC 2.0 - case SQL_DESC_SCALE: - case SQL_DESC_SEARCHABLE: - case SQL_DESC_UNNAMED: - case SQL_DESC_UNSIGNED: - case SQL_DESC_UPDATABLE: { - SQLSMALLINT temp; - ird->GetField(record_number, field_identifier, &temp, buffer_length, - &output_length_int); - if (numeric_attribute_ptr) { - *numeric_attribute_ptr = static_cast(temp); - } - break; - } - // Character attributes - case SQL_DESC_BASE_COLUMN_NAME: - case SQL_DESC_BASE_TABLE_NAME: - case SQL_DESC_CATALOG_NAME: - case SQL_DESC_LABEL: - case SQL_DESC_LITERAL_PREFIX: - case SQL_DESC_LITERAL_SUFFIX: - case SQL_DESC_LOCAL_TYPE_NAME: - case SQL_DESC_NAME: - case SQL_DESC_SCHEMA_NAME: - case SQL_DESC_TABLE_NAME: - case SQL_DESC_TYPE_NAME: - ird->GetField(record_number, field_identifier, character_attribute_ptr, - buffer_length, &output_length_int); - break; - default: - throw DriverException("Invalid descriptor field", "HY091"); - } - if (output_length) { - *output_length = static_cast(output_length_int); - } - return SQL_SUCCESS; - }); + // GH-47721 TODO: Implement SQLColAttribute, pre-requisite requires SQLColumns + return SQL_INVALID_HANDLE; } SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT data_type) { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc index 11f6c60080f..8ac3c7ed752 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc @@ -20,8 +20,6 @@ #include "arrow/flight/sql/column_metadata.h" #include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include "arrow/flight/sql/odbc/odbc_impl/util.h" -#include "arrow/type_traits.h" -#include "arrow/util/key_value_metadata.h" #include #include "arrow/flight/sql/odbc/odbc_impl/exceptions.h" @@ -42,8 +40,12 @@ constexpr int32_t DefaultDecimalPrecision = 38; constexpr int32_t DefaultLengthForVariableLengthColumns = 1024; namespace { +std::shared_ptr empty_metadata_map(new KeyValueMetadata); + inline ColumnMetadata GetMetadata(const std::shared_ptr& field) { - ColumnMetadata metadata(field->metadata()); + const auto& metadata_map = field->metadata(); + + ColumnMetadata metadata(metadata_map ? metadata_map : empty_metadata_map); return metadata; } @@ -205,14 +207,10 @@ size_t FlightSqlResultSetMetadata::GetOctetLength(int column_position) { .value_or(DefaultLengthForVariableLengthColumns); } -std::string FlightSqlResultSetMetadata::GetTypeName(int column_position, - int16_t data_type) { +std::string FlightSqlResultSetMetadata::GetTypeName(int column_position) { ColumnMetadata metadata = GetMetadata(schema_->field(column_position - 1)); - return metadata.GetTypeName().ValueOrElse([data_type] { - // If we get an empty type name, figure out the type name from the data_type. - return util::GetTypeNameFromSqlDataType(data_type); - }); + return metadata.GetTypeName().ValueOrElse([] { return ""; }); } Updatability FlightSqlResultSetMetadata::GetUpdatable(int column_position) { @@ -241,14 +239,20 @@ Searchability FlightSqlResultSetMetadata::IsSearchable(int column_position) { bool FlightSqlResultSetMetadata::IsUnsigned(int column_position) { const std::shared_ptr& field = schema_->field(column_position - 1); - arrow::Type::type type_id = field->type()->id(); - // non-decimal and non-numeric types are unsigned. - return !arrow::is_decimal(type_id) && - (!arrow::is_numeric(type_id) || arrow::is_unsigned_integer(type_id)); + + switch (field->type()->id()) { + case Type::UINT8: + case Type::UINT16: + case Type::UINT32: + case Type::UINT64: + return true; + default: + return false; + } } bool FlightSqlResultSetMetadata::IsFixedPrecScale(int column_position) { - // Precision for Arrow data types are modifiable by the user + // TODO: Flight SQL column metadata does not have this, should we add to the spec? return false; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.h index b502494f711..0d141a4bb9c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.h @@ -77,7 +77,7 @@ class FlightSqlResultSetMetadata : public ResultSetMetadata { size_t GetOctetLength(int column_position) override; - std::string GetTypeName(int column_position, int16_t data_type) override; + std::string GetTypeName(int column_position) override; Updatability GetUpdatable(int column_position) override; @@ -87,7 +87,6 @@ class FlightSqlResultSetMetadata : public ResultSetMetadata { Searchability IsSearchable(int column_position) override; - /// \brief Return true if the column is unsigned or not numeric bool IsUnsigned(int column_position) override; bool IsFixedPrecScale(int column_position) override; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc index eae90ac2b77..d2b7f8865ca 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc @@ -276,9 +276,7 @@ void ODBCDescriptor::GetHeaderField(SQLSMALLINT field_identifier, SQLPOINTER val GetAttribute(rows_processed_ptr_, value, buffer_length, output_length); break; case SQL_DESC_COUNT: { - // highest_one_based_bound_record_ equals number of records + 1 - GetAttribute(static_cast(highest_one_based_bound_record_ - 1), value, - buffer_length, output_length); + GetAttribute(highest_one_based_bound_record_, value, buffer_length, output_length); break; } default: @@ -312,55 +310,54 @@ void ODBCDescriptor::GetField(SQLSMALLINT record_number, SQLSMALLINT field_ident throw DriverException("Invalid descriptor index", "07009"); } - // GH-47867 TODO: Restrict fields based on AppDescriptor IPD, and IRD. + // TODO: Restrict fields based on AppDescriptor IPD, and IRD. - bool length_in_bytes = true; SQLSMALLINT zero_based_record = record_number - 1; const DescriptorRecord& record = records_[zero_based_record]; switch (field_identifier) { case SQL_DESC_BASE_COLUMN_NAME: - GetAttributeSQLWCHAR(record.base_column_name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.base_column_name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_BASE_TABLE_NAME: - GetAttributeSQLWCHAR(record.base_table_name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.base_table_name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_CATALOG_NAME: - GetAttributeSQLWCHAR(record.catalog_name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.catalog_name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_LABEL: - GetAttributeSQLWCHAR(record.label, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.label, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_LITERAL_PREFIX: - GetAttributeSQLWCHAR(record.literal_prefix, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.literal_prefix, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_LITERAL_SUFFIX: - GetAttributeSQLWCHAR(record.literal_suffix, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.literal_suffix, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_LOCAL_TYPE_NAME: - GetAttributeSQLWCHAR(record.local_type_name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.local_type_name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_NAME: - GetAttributeSQLWCHAR(record.name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_SCHEMA_NAME: - GetAttributeSQLWCHAR(record.schema_name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.schema_name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_TABLE_NAME: - GetAttributeSQLWCHAR(record.table_name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.table_name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_TYPE_NAME: - GetAttributeSQLWCHAR(record.type_name, length_in_bytes, value, buffer_length, - output_length, GetDiagnostics()); + GetAttributeUTF8(record.type_name, value, buffer_length, output_length, + GetDiagnostics()); break; case SQL_DESC_DATA_PTR: @@ -370,7 +367,7 @@ void ODBCDescriptor::GetField(SQLSMALLINT record_number, SQLSMALLINT field_ident case SQL_DESC_OCTET_LENGTH_PTR: GetAttribute(record.indicator_ptr, value, buffer_length, output_length); break; - case SQL_COLUMN_LENGTH: // ODBC 2.0 + case SQL_DESC_LENGTH: GetAttribute(record.length, value, buffer_length, output_length); break; @@ -410,14 +407,12 @@ void ODBCDescriptor::GetField(SQLSMALLINT record_number, SQLSMALLINT field_ident case SQL_DESC_PARAMETER_TYPE: GetAttribute(record.param_type, value, buffer_length, output_length); break; - case SQL_COLUMN_PRECISION: // ODBC 2.0 case SQL_DESC_PRECISION: GetAttribute(record.precision, value, buffer_length, output_length); break; case SQL_DESC_ROWVER: GetAttribute(record.row_ver, value, buffer_length, output_length); break; - case SQL_COLUMN_SCALE: // ODBC 2.0 case SQL_DESC_SCALE: GetAttribute(record.scale, value, buffer_length, output_length); break; @@ -484,8 +479,6 @@ void ODBCDescriptor::PopulateFromResultSetMetadata(ResultSetMetadata* rsmd) { for (size_t i = 0; i < records_.size(); ++i) { size_t one_based_index = i + 1; - int16_t concise_type = rsmd->GetConciseType(one_based_index); - records_[i].base_column_name = rsmd->GetBaseColumnName(one_based_index); records_[i].base_table_name = rsmd->GetBaseTableName(one_based_index); records_[i].catalog_name = rsmd->GetCatalogName(one_based_index); @@ -496,8 +489,9 @@ void ODBCDescriptor::PopulateFromResultSetMetadata(ResultSetMetadata* rsmd) { records_[i].name = rsmd->GetName(one_based_index); records_[i].schema_name = rsmd->GetSchemaName(one_based_index); records_[i].table_name = rsmd->GetTableName(one_based_index); - records_[i].type_name = rsmd->GetTypeName(one_based_index, concise_type); - records_[i].concise_type = GetSqlTypeForODBCVersion(concise_type, is_2x_connection_); + records_[i].type_name = rsmd->GetTypeName(one_based_index); + records_[i].concise_type = GetSqlTypeForODBCVersion( + rsmd->GetConciseType(one_based_index), is_2x_connection_); records_[i].data_ptr = nullptr; records_[i].indicator_ptr = nullptr; records_[i].display_size = rsmd->GetColumnDisplaySize(one_based_index); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/result_set_metadata.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/result_set_metadata.h index 63da402db7c..38f81fc9c3e 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/result_set_metadata.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/result_set_metadata.h @@ -17,9 +17,10 @@ #pragma once -#include #include "arrow/flight/sql/odbc/odbc_impl/types.h" +#include + namespace arrow::flight::sql::odbc { /// \brief High Level representation of the ResultSetMetadata from ODBC. @@ -142,9 +143,8 @@ class ResultSetMetadata { /// \brief It returns the data type as a string. /// \param column_position [in] the position of the column, starting from 1. - /// \param data_type [in] the data type of the column. /// \return the data type string. - virtual std::string GetTypeName(int column_position, int16_t data_type) = 0; + virtual std::string GetTypeName(int column_position) = 0; /// \brief It returns a numeric values indicate the updatability of the /// column. diff --git a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc index 87e9193b7c2..81e97a09284 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc @@ -124,260 +124,6 @@ void CheckRemoteSQLColumns( expected_is_nullable); } -void CheckSQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT idx, - const std::wstring& expected_column_name, - SQLLEN expected_data_type, SQLLEN expected_concise_type, - SQLLEN expected_display_size, SQLLEN expected_prec_scale, - SQLLEN expected_length, - const std::wstring& expected_literal_prefix, - const std::wstring& expected_literal_suffix, - SQLLEN expected_column_size, SQLLEN expected_column_scale, - SQLLEN expected_column_nullability, - SQLLEN expected_num_prec_radix, SQLLEN expected_octet_length, - SQLLEN expected_searchable, SQLLEN expected_unsigned_column) { - std::vector name(kOdbcBufferSize); - SQLSMALLINT name_len = 0; - std::vector base_column_name(kOdbcBufferSize); - SQLSMALLINT column_name_len = 0; - std::vector label(kOdbcBufferSize); - SQLSMALLINT label_len = 0; - std::vector prefix(kOdbcBufferSize); - SQLSMALLINT prefix_len = 0; - std::vector suffix(kOdbcBufferSize); - SQLSMALLINT suffix_len = 0; - SQLLEN data_type = 0; - SQLLEN concise_type = 0; - SQLLEN display_size = 0; - SQLLEN prec_scale = 0; - SQLLEN length = 0; - SQLLEN size = 0; - SQLLEN scale = 0; - SQLLEN nullability = 0; - SQLLEN num_prec_radix = 0; - SQLLEN octet_length = 0; - SQLLEN searchable = 0; - SQLLEN unsigned_col = 0; - - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_NAME, &name[0], - (SQLSMALLINT)name.size(), &name_len, nullptr)); - - EXPECT_EQ( - SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_BASE_COLUMN_NAME, &base_column_name[0], - (SQLSMALLINT)base_column_name.size(), &column_name_len, nullptr)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_LABEL, &label[0], - (SQLSMALLINT)label.size(), &label_len, nullptr)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_TYPE, 0, 0, nullptr, &data_type)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_CONCISE_TYPE, 0, 0, nullptr, - &concise_type)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_DISPLAY_SIZE, 0, 0, nullptr, - &display_size)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_FIXED_PREC_SCALE, 0, 0, - nullptr, &prec_scale)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_LENGTH, 0, 0, nullptr, &length)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_LITERAL_PREFIX, &prefix[0], - (SQLSMALLINT)prefix.size(), &prefix_len, nullptr)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_LITERAL_SUFFIX, &suffix[0], - (SQLSMALLINT)suffix.size(), &suffix_len, nullptr)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_PRECISION, 0, 0, nullptr, &size)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_SCALE, 0, 0, nullptr, &scale)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_NULLABLE, 0, 0, nullptr, &nullability)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_NUM_PREC_RADIX, 0, 0, 0, - &num_prec_radix)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_OCTET_LENGTH, 0, 0, nullptr, - &octet_length)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_SEARCHABLE, 0, 0, nullptr, &searchable)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_UNSIGNED, 0, 0, nullptr, &unsigned_col)); - - std::wstring name_str = ConvertToWString(name, name_len); - std::wstring base_column_name_str = ConvertToWString(base_column_name, column_name_len); - std::wstring label_str = ConvertToWString(label, label_len); - std::wstring prefixStr = ConvertToWString(prefix, prefix_len); - - // Assume column name, base column name, and label are equivalent in the result set - EXPECT_EQ(expected_column_name, name_str); - EXPECT_EQ(expected_column_name, base_column_name_str); - EXPECT_EQ(expected_column_name, label_str); - EXPECT_EQ(expected_data_type, data_type); - EXPECT_EQ(expected_concise_type, concise_type); - EXPECT_EQ(expected_display_size, display_size); - EXPECT_EQ(expected_prec_scale, prec_scale); - EXPECT_EQ(expected_length, length); - EXPECT_EQ(expected_literal_prefix, prefixStr); - EXPECT_EQ(expected_column_size, size); - EXPECT_EQ(expected_column_scale, scale); - EXPECT_EQ(expected_column_nullability, nullability); - EXPECT_EQ(expected_num_prec_radix, num_prec_radix); - EXPECT_EQ(expected_octet_length, octet_length); - EXPECT_EQ(expected_searchable, searchable); - EXPECT_EQ(expected_unsigned_column, unsigned_col); -} - -void CheckSQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT idx, - const std::wstring& expected_column_name, - SQLLEN expected_data_type, SQLLEN expected_display_size, - SQLLEN expected_prec_scale, SQLLEN expected_length, - SQLLEN expected_column_size, SQLLEN expected_column_scale, - SQLLEN expected_column_nullability, SQLLEN expected_searchable, - SQLLEN expected_unsigned_column) { - std::vector name(kOdbcBufferSize); - SQLSMALLINT name_len = 0; - std::vector label(kOdbcBufferSize); - SQLSMALLINT label_len = 0; - SQLLEN data_type = 0; - SQLLEN display_size = 0; - SQLLEN prec_scale = 0; - SQLLEN length = 0; - SQLLEN size = 0; - SQLLEN scale = 0; - SQLLEN nullability = 0; - SQLLEN searchable = 0; - SQLLEN unsigned_col = 0; - - EXPECT_EQ(SQL_SUCCESS, SQLColAttributes(stmt, idx, SQL_COLUMN_NAME, &name[0], - (SQLSMALLINT)name.size(), &name_len, nullptr)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttributes(stmt, idx, SQL_COLUMN_LABEL, &label[0], - (SQLSMALLINT)label.size(), &label_len, nullptr)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttributes(stmt, idx, SQL_COLUMN_TYPE, 0, 0, nullptr, &data_type)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttributes(stmt, idx, SQL_COLUMN_DISPLAY_SIZE, 0, 0, - nullptr, &display_size)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_COLUMN_MONEY, 0, 0, nullptr, &prec_scale)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttributes(stmt, idx, SQL_COLUMN_LENGTH, 0, 0, nullptr, &length)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttributes(stmt, idx, SQL_COLUMN_PRECISION, 0, 0, nullptr, &size)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttributes(stmt, idx, SQL_COLUMN_SCALE, 0, 0, nullptr, &scale)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttributes(stmt, idx, SQL_COLUMN_NULLABLE, 0, 0, nullptr, - &nullability)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttributes(stmt, idx, SQL_COLUMN_SEARCHABLE, 0, 0, nullptr, - &searchable)); - - EXPECT_EQ(SQL_SUCCESS, SQLColAttributes(stmt, idx, SQL_COLUMN_UNSIGNED, 0, 0, nullptr, - &unsigned_col)); - - std::wstring name_str = ConvertToWString(name, name_len); - std::wstring label_str = ConvertToWString(label, label_len); - - EXPECT_EQ(expected_column_name, name_str); - EXPECT_EQ(expected_column_name, label_str); - EXPECT_EQ(expected_data_type, data_type); - EXPECT_EQ(expected_display_size, display_size); - EXPECT_EQ(expected_length, length); - EXPECT_EQ(expected_column_size, size); - EXPECT_EQ(expected_column_scale, scale); - EXPECT_EQ(expected_column_nullability, nullability); - EXPECT_EQ(expected_searchable, searchable); - EXPECT_EQ(expected_unsigned_column, unsigned_col); -} - -void GetSQLColAttributeString(SQLHSTMT stmt, const std::wstring& wsql, SQLUSMALLINT idx, - SQLUSMALLINT field_identifier, std::wstring& value) { - if (!wsql.empty()) { - // Execute query - std::vector sql0(wsql.begin(), wsql.end()); - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - } - - // check SQLColAttribute string attribute - std::vector str_val(kOdbcBufferSize); - SQLSMALLINT str_len = 0; - - ASSERT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, field_identifier, &str_val[0], - (SQLSMALLINT)str_val.size(), &str_len, nullptr)); - - value = ConvertToWString(str_val, str_len); -} - -void GetSQLColAttributesString(SQLHSTMT stmt, const std::wstring& wsql, SQLUSMALLINT idx, - SQLUSMALLINT field_identifier, std::wstring& value) { - if (!wsql.empty()) { - // Execute query - std::vector sql0(wsql.begin(), wsql.end()); - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - } - - // check SQLColAttribute string attribute - std::vector str_val(kOdbcBufferSize); - SQLSMALLINT str_len = 0; - - ASSERT_EQ(SQL_SUCCESS, - SQLColAttributes(stmt, idx, field_identifier, &str_val[0], - (SQLSMALLINT)str_val.size(), &str_len, nullptr)); - - value = ConvertToWString(str_val, str_len); -} - -void GetSQLColAttributeNumeric(SQLHSTMT stmt, const std::wstring& wsql, SQLUSMALLINT idx, - SQLUSMALLINT field_identifier, SQLLEN* value) { - // Execute query and check SQLColAttribute numeric attribute - std::vector sql0(wsql.begin(), wsql.end()); - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - - SQLLEN num_val = 0; - ASSERT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, field_identifier, 0, 0, nullptr, value)); -} - -void GetSQLColAttributesNumeric(SQLHSTMT stmt, const std::wstring& wsql, SQLUSMALLINT idx, - SQLUSMALLINT field_identifier, SQLLEN* value) { - // Execute query and check SQLColAttribute numeric attribute - std::vector sql0(wsql.begin(), wsql.end()); - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - - SQLLEN num_val = 0; - ASSERT_EQ(SQL_SUCCESS, - SQLColAttributes(stmt, idx, field_identifier, 0, 0, nullptr, value)); -} - } // namespace TYPED_TEST(ColumnsTest, SQLColumnsTestInputData) { @@ -1214,974 +960,4 @@ TEST_F(ColumnsMockTest, TestSQLColumnsInvalidTablePattern) { EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } -TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { - std::wstring wsql = L"SELECT 1 as col1;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - SQLUSMALLINT idx = 1; - std::vector character_attr(kOdbcBufferSize); - SQLSMALLINT character_attr_len = 0; - SQLLEN numeric_attr = 0; - - // All character values populated - EXPECT_EQ( - SQL_SUCCESS, - SQLColAttribute(this->stmt, idx, SQL_DESC_NAME, &character_attr[0], - (SQLSMALLINT)character_attr.size(), &character_attr_len, nullptr)); - - // All numeric values populated - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, - &numeric_attr)); - - // Pass null values, driver should not throw error - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, idx, SQL_COLUMN_TABLE_NAME, 0, 0, - nullptr, nullptr)); - - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(this->stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, nullptr)); -} - -TYPED_TEST(ColumnsTest, SQLColAttributeGetCharacterLen) { - std::wstring wsql = L"SELECT 1 as col1;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - SQLSMALLINT character_attr_len = 0; - - // Check length of character attribute - ASSERT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, 1, SQL_DESC_BASE_COLUMN_NAME, 0, 0, - &character_attr_len, nullptr)); - EXPECT_EQ(4 * GetSqlWCharSize(), character_attr_len); -} - -TYPED_TEST(ColumnsTest, SQLColAttributeInvalidFieldId) { - std::wstring wsql = L"SELECT 1 as col1;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - SQLUSMALLINT invalid_field_id = -100; - SQLUSMALLINT idx = 1; - std::vector character_attr(kOdbcBufferSize); - SQLSMALLINT character_attr_len = 0; - SQLLEN numeric_attr = 0; - - ASSERT_EQ( - SQL_ERROR, - SQLColAttribute(this->stmt, idx, invalid_field_id, &character_attr[0], - (SQLSMALLINT)character_attr.size(), &character_attr_len, nullptr)); - // Verify invalid descriptor field identifier error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY091); -} - -TYPED_TEST(ColumnsTest, SQLColAttributeInvalidColId) { - std::wstring wsql = L"SELECT 1 as col1;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - SQLUSMALLINT invalid_col_id = 2; - std::vector character_attr(kOdbcBufferSize); - SQLSMALLINT character_attr_len = 0; - - ASSERT_EQ(SQL_ERROR, - SQLColAttribute(this->stmt, invalid_col_id, SQL_DESC_BASE_COLUMN_NAME, - &character_attr[0], (SQLSMALLINT)character_attr.size(), - &character_attr_len, nullptr)); - // Verify invalid descriptor index error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - CheckSQLColAttribute(this->stmt, 1, - std::wstring(L"bigint_col"), // expected_column_name - SQL_BIGINT, // expected_data_type - SQL_BIGINT, // expected_concise_type - 20, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 10, // expected_num_prec_radix - 8, // expected_octet_length - SQL_PRED_NONE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 2, - std::wstring(L"char_col"), // expected_column_name - SQL_WVARCHAR, // expected_data_type - SQL_WVARCHAR, // expected_concise_type - 0, // expected_display_size - SQL_FALSE, // expected_prec_scale - 0, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 0, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 0, // expected_octet_length - SQL_PRED_NONE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 3, - std::wstring(L"varbinary_col"), // expected_column_name - SQL_BINARY, // expected_data_type - SQL_BINARY, // expected_concise_type - 0, // expected_display_size - SQL_FALSE, // expected_prec_scale - 0, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 0, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 0, // expected_octet_length - SQL_PRED_NONE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 4, - std::wstring(L"double_col"), // expected_column_name - SQL_DOUBLE, // expected_data_type - SQL_DOUBLE, // expected_concise_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 2, // expected_num_prec_radix - 8, // expected_octet_length - SQL_PRED_NONE, // expected_searchable - SQL_FALSE); // expected_unsigned_column -} - -TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypesODBCVer2) { - // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttributes(this->stmt, 1, - std::wstring(L"bigint_col"), // expected_column_name - SQL_BIGINT, // expected_data_type - 20, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_PRED_NONE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 2, - std::wstring(L"char_col"), // expected_column_name - SQL_WVARCHAR, // expected_data_type - 0, // expected_display_size - SQL_FALSE, // expected_prec_scale - 0, // expected_length - 0, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_PRED_NONE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 3, - std::wstring(L"varbinary_col"), // expected_column_name - SQL_BINARY, // expected_data_type - 0, // expected_display_size - SQL_FALSE, // expected_prec_scale - 0, // expected_length - 0, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_PRED_NONE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 4, - std::wstring(L"double_col"), // expected_column_name - SQL_DOUBLE, // expected_data_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_PRED_NONE, // expected_searchable - SQL_FALSE); // expected_unsigned_column -} - -TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { - // Test assumes there is a table $scratch.ODBCTest in remote server - - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - CheckSQLColAttribute(this->stmt, 1, - std::wstring(L"sinteger_max"), // expected_column_name - SQL_INTEGER, // expected_data_type - SQL_INTEGER, // expected_concise_type - 11, // expected_display_size - SQL_FALSE, // expected_prec_scale - 4, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 4, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 10, // expected_num_prec_radix - 4, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 2, - std::wstring(L"sbigint_max"), // expected_column_name - SQL_BIGINT, // expected_data_type - SQL_BIGINT, // expected_concise_type - 20, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 10, // expected_num_prec_radix - 8, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 3, - std::wstring(L"decimal_positive"), // expected_column_name - SQL_DECIMAL, // expected_data_type - SQL_DECIMAL, // expected_concise_type - 40, // expected_display_size - SQL_FALSE, // expected_prec_scale - 19, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 19, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 10, // expected_num_prec_radix - 40, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 4, - std::wstring(L"float_max"), // expected_column_name - SQL_FLOAT, // expected_data_type - SQL_FLOAT, // expected_concise_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 2, // expected_num_prec_radix - 8, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 5, - std::wstring(L"double_max"), // expected_column_name - SQL_DOUBLE, // expected_data_type - SQL_DOUBLE, // expected_concise_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 2, // expected_num_prec_radix - 8, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 6, - std::wstring(L"bit_true"), // expected_column_name - SQL_BIT, // expected_data_type - SQL_BIT, // expected_concise_type - 1, // expected_display_size - SQL_FALSE, // expected_prec_scale - 1, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 1, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 1, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 7, - std::wstring(L"date_max"), // expected_column_name - SQL_DATETIME, // expected_data_type - SQL_TYPE_DATE, // expected_concise_type - 10, // expected_display_size - SQL_FALSE, // expected_prec_scale - 10, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 10, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 6, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 8, - std::wstring(L"time_max"), // expected_column_name - SQL_DATETIME, // expected_data_type - SQL_TYPE_TIME, // expected_concise_type - 12, // expected_display_size - SQL_FALSE, // expected_prec_scale - 12, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 12, // expected_column_size - 3, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 6, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 9, - std::wstring(L"timestamp_max"), // expected_column_name - SQL_DATETIME, // expected_data_type - SQL_TYPE_TIMESTAMP, // expected_concise_type - 23, // expected_display_size - SQL_FALSE, // expected_prec_scale - 23, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 23, // expected_column_size - 3, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 16, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column -} - -TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypesODBCVer2) { - // Test assumes there is a table $scratch.ODBCTest in remote server - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - CheckSQLColAttribute(this->stmt, 1, - std::wstring(L"sinteger_max"), // expected_column_name - SQL_INTEGER, // expected_data_type - SQL_INTEGER, // expected_concise_type - 11, // expected_display_size - SQL_FALSE, // expected_prec_scale - 4, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 4, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 10, // expected_num_prec_radix - 4, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 2, - std::wstring(L"sbigint_max"), // expected_column_name - SQL_BIGINT, // expected_data_type - SQL_BIGINT, // expected_concise_type - 20, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 10, // expected_num_prec_radix - 8, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 3, - std::wstring(L"decimal_positive"), // expected_column_name - SQL_DECIMAL, // expected_data_type - SQL_DECIMAL, // expected_concise_type - 40, // expected_display_size - SQL_FALSE, // expected_prec_scale - 19, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 19, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 10, // expected_num_prec_radix - 40, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 4, - std::wstring(L"float_max"), // expected_column_name - SQL_FLOAT, // expected_data_type - SQL_FLOAT, // expected_concise_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 2, // expected_num_prec_radix - 8, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 5, - std::wstring(L"double_max"), // expected_column_name - SQL_DOUBLE, // expected_data_type - SQL_DOUBLE, // expected_concise_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 2, // expected_num_prec_radix - 8, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 6, - std::wstring(L"bit_true"), // expected_column_name - SQL_BIT, // expected_data_type - SQL_BIT, // expected_concise_type - 1, // expected_display_size - SQL_FALSE, // expected_prec_scale - 1, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 1, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 1, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 7, - std::wstring(L"date_max"), // expected_column_name - SQL_DATETIME, // expected_data_type - SQL_DATE, // expected_concise_type - 10, // expected_display_size - SQL_FALSE, // expected_prec_scale - 10, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 10, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 6, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 8, - std::wstring(L"time_max"), // expected_column_name - SQL_DATETIME, // expected_data_type - SQL_TIME, // expected_concise_type - 12, // expected_display_size - SQL_FALSE, // expected_prec_scale - 12, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 12, // expected_column_size - 3, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 6, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttribute(this->stmt, 9, - std::wstring(L"timestamp_max"), // expected_column_name - SQL_DATETIME, // expected_data_type - SQL_TIMESTAMP, // expected_concise_type - 23, // expected_display_size - SQL_FALSE, // expected_prec_scale - 23, // expected_length - std::wstring(L""), // expected_literal_prefix - std::wstring(L""), // expected_literal_suffix - 23, // expected_column_size - 3, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - 0, // expected_num_prec_radix - 16, // expected_octet_length - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column -} - -TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypesODBCVer2) { - // Tests ODBC 2.0 API SQLColAttributes - // Test assumes there is a table $scratch.ODBCTest in remote server - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - std::vector sql0(wsql.begin(), wsql.end()); - - ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - - ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - - CheckSQLColAttributes(this->stmt, 1, - std::wstring(L"sinteger_max"), // expected_column_name - SQL_INTEGER, // expected_data_type - 11, // expected_display_size - SQL_FALSE, // expected_prec_scale - 4, // expected_length - 4, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 2, - std::wstring(L"sbigint_max"), // expected_column_name - SQL_BIGINT, // expected_data_type - 20, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 3, - std::wstring(L"decimal_positive"), // expected_column_name - SQL_DECIMAL, // expected_data_type - 40, // expected_display_size - SQL_FALSE, // expected_prec_scale - 19, // expected_length - 19, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 4, - std::wstring(L"float_max"), // expected_column_name - SQL_FLOAT, // expected_data_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 5, - std::wstring(L"double_max"), // expected_column_name - SQL_DOUBLE, // expected_data_type - 24, // expected_display_size - SQL_FALSE, // expected_prec_scale - 8, // expected_length - 8, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_FALSE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 6, - std::wstring(L"bit_true"), // expected_column_name - SQL_BIT, // expected_data_type - 1, // expected_display_size - SQL_FALSE, // expected_prec_scale - 1, // expected_length - 1, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 7, - std::wstring(L"date_max"), // expected_column_name - SQL_DATE, // expected_data_type - 10, // expected_display_size - SQL_FALSE, // expected_prec_scale - 10, // expected_length - 10, // expected_column_size - 0, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 8, - std::wstring(L"time_max"), // expected_column_name - SQL_TIME, // expected_data_type - 12, // expected_display_size - SQL_FALSE, // expected_prec_scale - 12, // expected_length - 12, // expected_column_size - 3, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column - - CheckSQLColAttributes(this->stmt, 9, - std::wstring(L"timestamp_max"), // expected_column_name - SQL_TIMESTAMP, // expected_data_type - 23, // expected_display_size - SQL_FALSE, // expected_prec_scale - 23, // expected_length - 23, // expected_column_size - 3, // expected_column_scale - SQL_NULLABLE, // expected_column_nullability - SQL_SEARCHABLE, // expected_searchable - SQL_TRUE); // expected_unsigned_column -} - -TYPED_TEST(ColumnsTest, TestSQLColAttributeCaseSensitive) { - // Arrow limitation: returns SQL_FALSE for case sensitive column - - std::wstring wsql = this->GetQueryAllDataTypes(); - // Int column - SQLLEN value; - GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_CASE_SENSITIVE, &value); - ASSERT_EQ(SQL_FALSE, value); - SQLFreeStmt(this->stmt, SQL_CLOSE); - // Varchar column - GetSQLColAttributeNumeric(this->stmt, wsql, 28, SQL_DESC_CASE_SENSITIVE, &value); - ASSERT_EQ(SQL_FALSE, value); -} - -TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesCaseSensitive) { - // Arrow limitation: returns SQL_FALSE for case sensitive column - // Tests ODBC 2.0 API SQLColAttributes - - std::wstring wsql = this->GetQueryAllDataTypes(); - // Int column - SQLLEN value; - GetSQLColAttributesNumeric(this->stmt, wsql, 1, SQL_COLUMN_CASE_SENSITIVE, &value); - ASSERT_EQ(SQL_FALSE, value); - SQLFreeStmt(this->stmt, SQL_CLOSE); - // Varchar column - GetSQLColAttributesNumeric(this->stmt, wsql, 28, SQL_COLUMN_CASE_SENSITIVE, &value); - ASSERT_EQ(SQL_FALSE, value); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeUniqueValue) { - // Mock server limitation: returns false for auto-increment column - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - SQLLEN value; - GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_AUTO_UNIQUE_VALUE, &value); - ASSERT_EQ(SQL_FALSE, value); -} - -TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAutoIncrement) { - // Tests ODBC 2.0 API SQLColAttributes - // Mock server limitation: returns false for auto-increment column - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - SQLLEN value; - GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_COLUMN_AUTO_INCREMENT, &value); - ASSERT_EQ(SQL_FALSE, value); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeBaseTableName) { - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_BASE_TABLE_NAME, value); - ASSERT_EQ(std::wstring(L"AllTypesTable"), value); -} - -TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTableName) { - // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::wstring value; - GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TABLE_NAME, value); - ASSERT_EQ(std::wstring(L"AllTypesTable"), value); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeCatalogName) { - // Mock server limitattion: mock doesn't return catalog for result metadata, - // and the defautl catalog should be 'main' - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsRemoteTest, TestSQLColAttributeCatalogName) { - // Remote server does not have catalogs - - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesQualifierName) { - // Mock server limitattion: mock doesn't return catalog for result metadata, - // and the defautl catalog should be 'main' - // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesQualifierName) { - // Remote server does not have catalogs - // Tests ODBC 2.0 API SQLColAttributes - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TYPED_TEST(ColumnsTest, TestSQLColAttributeCount) { - std::wstring wsql = this->GetQueryAllDataTypes(); - // Pass 0 as column number, driver should ignore it - SQLLEN value; - GetSQLColAttributeNumeric(this->stmt, wsql, 0, SQL_DESC_COUNT, &value); - ASSERT_EQ(32, value); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeLocalTypeName) { - std::wstring wsql = this->GetQueryAllDataTypes(); - // Mock server doesn't have local type name - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsRemoteTest, TestSQLColAttributeLocalTypeName) { - std::wstring wsql = this->GetQueryAllDataTypes(); - std::wstring value; - GetSQLColAttributesString(this->stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"INTEGER"), value); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeSchemaName) { - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - // Mock server doesn't have schemas - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsRemoteTest, TestSQLColAttributeSchemaName) { - // Test assumes there is a table $scratch.ODBCTest in remote server - - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - // Remote server limitation: doesn't return schema name, expected schema name is - // $scratch - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesOwnerName) { - // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - // Mock server doesn't have schemas - std::wstring value; - GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesOwnerName) { - // Test assumes there is a table $scratch.ODBCTest in remote server - // Tests ODBC 2.0 API SQLColAttributes - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - // Remote server limitation: doesn't return schema name, expected schema name is - // $scratch - std::wstring value; - GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); - ASSERT_EQ(std::wstring(L""), value); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeTableName) { - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TABLE_NAME, value); - ASSERT_EQ(std::wstring(L"AllTypesTable"), value); -} - -TEST_F(ColumnsMockTest, TestSQLColAttributeTypeName) { - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributeString(this->stmt, L"", 2, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"WVARCHAR"), value); - GetSQLColAttributeString(this->stmt, L"", 3, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BINARY"), value); - GetSQLColAttributeString(this->stmt, L"", 4, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DOUBLE"), value); -} - -TEST_F(ColumnsRemoteTest, TestSQLColAttributeTypeName) { - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - std::wstring value; - GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"INTEGER"), value); - GetSQLColAttributeString(this->stmt, L"", 2, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributeString(this->stmt, L"", 3, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DECIMAL"), value); - GetSQLColAttributeString(this->stmt, L"", 4, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"FLOAT"), value); - GetSQLColAttributeString(this->stmt, L"", 5, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DOUBLE"), value); - GetSQLColAttributeString(this->stmt, L"", 6, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BOOLEAN"), value); - GetSQLColAttributeString(this->stmt, L"", 7, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DATE"), value); - GetSQLColAttributeString(this->stmt, L"", 8, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"TIME"), value); - GetSQLColAttributeString(this->stmt, L"", 9, SQL_DESC_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"TIMESTAMP"), value); -} - -TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTypeName) { - // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); - - std::wstring wsql = L"SELECT * from AllTypesTable;"; - // Mock server doesn't return data source-dependent data type name - std::wstring value; - GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributesString(this->stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"WVARCHAR"), value); - GetSQLColAttributesString(this->stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BINARY"), value); - GetSQLColAttributesString(this->stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DOUBLE"), value); -} - -TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesTypeName) { - // Tests ODBC 2.0 API SQLColAttributes - std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; - std::wstring value; - GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"INTEGER"), value); - GetSQLColAttributesString(this->stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributesString(this->stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DECIMAL"), value); - GetSQLColAttributesString(this->stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"FLOAT"), value); - GetSQLColAttributesString(this->stmt, L"", 5, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DOUBLE"), value); - GetSQLColAttributesString(this->stmt, L"", 6, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"BOOLEAN"), value); - GetSQLColAttributesString(this->stmt, L"", 7, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"DATE"), value); - GetSQLColAttributesString(this->stmt, L"", 8, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"TIME"), value); - GetSQLColAttributesString(this->stmt, L"", 9, SQL_COLUMN_TYPE_NAME, value); - ASSERT_EQ(std::wstring(L"TIMESTAMP"), value); -} - -TYPED_TEST(ColumnsTest, TestSQLColAttributeUnnamed) { - std::wstring wsql = this->GetQueryAllDataTypes(); - SQLLEN value; - GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_UNNAMED, &value); - ASSERT_EQ(SQL_NAMED, value); -} - -TYPED_TEST(ColumnsTest, TestSQLColAttributeUpdatable) { - std::wstring wsql = this->GetQueryAllDataTypes(); - // Mock server and remote server do not return updatable information - SQLLEN value; - GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_UPDATABLE, &value); - ASSERT_EQ(SQL_ATTR_READWRITE_UNKNOWN, value); -} - -TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesUpdatable) { - // Tests ODBC 2.0 API SQLColAttributes - std::wstring wsql = this->GetQueryAllDataTypes(); - // Mock server and remote server do not return updatable information - SQLLEN value; - GetSQLColAttributesNumeric(this->stmt, wsql, 1, SQL_COLUMN_UPDATABLE, &value); - ASSERT_EQ(SQL_ATTR_READWRITE_UNKNOWN, value); -} - } // namespace arrow::flight::sql::odbc