Skip to content

Commit 6aafd68

Browse files
impl(bq_driver): add sql_wvarchar impl
1 parent 5f5036f commit 6aafd68

13 files changed

Lines changed: 150 additions & 43 deletions

google/cloud/odbc/bq_driver/internal/driver_adv_opt_form.cc

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ std::string AdvanceOptions::default_string_length_ = kDefaultStringLength;
5555
std::string AdvanceOptions::session_location_;
5656
std::string AdvanceOptions::additional_projects_;
5757
std::string AdvanceOptions::query_properties_;
58-
std::string AdvanceOptions::use_wchar_;
58+
std::string AdvanceOptions::use_wvarchar_;
5959
std::string AdvanceOptions::enable_session_;
6060
std::string AdvanceOptions::activation_threshold_checkbox_;
6161
std::string AdvanceOptions::allow_large_results_;
@@ -75,7 +75,7 @@ std::string const kSessionLocation = "SessionLocation";
7575
std::string const kAdditionalProjects = "AdditionalProjects";
7676
std::string const kQueryProperties = "QueryProperties";
7777
std::string const kActivationThreshold = "HTAPI_ActivationThreshold";
78-
std::string const kUseWChar = "UseWVarChar";
78+
std::string const kUseWVarchar = "UseWVarChar";
7979
std::string const kEnableSession = "EnableSession";
8080
std::string const kHTAPIActivationThresholdCheck = "AllowHtapiForLargeResults";
8181
std::string const kAllowLargeResults = "AllowLargeResults";
@@ -358,21 +358,20 @@ void AdvanceOptions::CreateAdditionalControls(HFONT h_font) {
358358
SetWindowLongPtr(
359359
h_max_retries_edit, GWL_STYLE,
360360
GetWindowLongPtr(h_max_retries_edit, GWL_STYLE) | ES_RIGHT | ES_NUMBER);
361-
// TODO(b/497725655): Enable UI feature after public release
362-
// HWND h_variables_checkbox = CreateCheckBox(
363-
// adv_hwnd, "Use SQL_WVARCHAR instead of SQL_VARCHAR", kXAxis, kYAxis +
364-
// 390, kWidth * 7, kHeight, kIdcVariableCheckbox);
365-
// CheckDlgButton(adv_hwnd, kIdcVariableCheckbox,
366-
// (use_wchar_ == "1") ? BST_CHECKED : BST_UNCHECKED);
367-
// SendMessage(h_variables_checkbox, WM_SETFONT, (WPARAM)h_font, TRUE);
368-
// SetWindowSubclass(GetDlgItem(adv_hwnd, kIdcVariableCheckbox),
369-
// CheckboxSubclassProc, 0, 0);
361+
HWND h_variables_checkbox = CreateCheckBox(
362+
adv_hwnd, "Use SQL_WVARCHAR instead of SQL_VARCHAR", kXAxis, kYAxis + 415,
363+
kWidth * 7, kHeight, kIdcUseWVarcharCheckbox);
364+
CheckDlgButton(adv_hwnd, kIdcUseWVarcharCheckbox,
365+
(use_wvarchar_ == "1") ? BST_CHECKED : BST_UNCHECKED);
366+
SendMessage(h_variables_checkbox, WM_SETFONT, (WPARAM)h_font, TRUE);
367+
SetWindowSubclass(GetDlgItem(adv_hwnd, kIdcUseWVarcharCheckbox),
368+
CheckboxSubclassProc, 0, 0);
370369
HWND h_additional_projects_label =
371-
CreateLabel(adv_hwnd, "Additional projects:", kXAxis, kYAxis + 420,
370+
CreateLabel(adv_hwnd, "Additional projects:", kXAxis, kYAxis + 440,
372371
kWidth * 5, kHeight, WS_VISIBLE | SS_LEFT);
373372
SendMessage(h_additional_projects_label, WM_SETFONT, (WPARAM)h_font, TRUE);
374373
HWND h_additional_projects_edit =
375-
CreateScrollableEditBox(adv_hwnd, kXAxis, kYAxis + 440, kWidth + 380,
374+
CreateScrollableEditBox(adv_hwnd, kXAxis, kYAxis + 460, kWidth + 380,
376375
kHeight + 32, kIdcAdditionalProjectsEdit);
377376
SendMessage(h_additional_projects_edit, WM_SETFONT, (WPARAM)h_font, TRUE);
378377

@@ -381,11 +380,11 @@ void AdvanceOptions::CreateAdditionalControls(HFONT h_font) {
381380
InputSubclassProc, 0, 0);
382381

383382
HWND h_query_properties_label =
384-
CreateLabel(adv_hwnd, "Query properties:", kXAxis, kYAxis + 500,
383+
CreateLabel(adv_hwnd, "Query properties:", kXAxis, kYAxis + 520,
385384
kWidth * 5, kHeight, WS_VISIBLE | SS_LEFT);
386385
SendMessage(h_query_properties_label, WM_SETFONT, (WPARAM)h_font, TRUE);
387386
HWND h_query_properties_edit =
388-
CreateScrollableEditBox(adv_hwnd, kXAxis, kYAxis + 520, kWidth + 385,
387+
CreateScrollableEditBox(adv_hwnd, kXAxis, kYAxis + 540, kWidth + 385,
389388
kHeight + 13, kIdcQueryPropertiesEdit);
390389
SendMessage(h_query_properties_edit, WM_SETFONT, (WPARAM)h_font, TRUE);
391390

@@ -409,12 +408,12 @@ void AdvanceOptions::CreateAdditionalControls(HFONT h_font) {
409408
}
410409

411410
void AdvanceOptions::CreateButtons(HFONT h_font) {
412-
HWND h_ok_button = CreateButton(adv_hwnd, "OK", kOkButtonX + 2, kButtonY + 38,
411+
HWND h_ok_button = CreateButton(adv_hwnd, "OK", kOkButtonX + 2, kButtonY + 58,
413412
kButtonWidth, kButtonHeight, kIdcOKButton);
414413
SendMessage(h_ok_button, WM_SETFONT, (WPARAM)h_font, TRUE);
415414

416415
HWND h_cancel_button =
417-
CreateButton(adv_hwnd, "Cancel", kCancelButtonX, kButtonY + 38,
416+
CreateButton(adv_hwnd, "Cancel", kCancelButtonX, kButtonY + 58,
418417
kButtonWidth, kButtonHeight, kIdcCancelButton);
419418
SendMessage(h_cancel_button, WM_SETFONT, (WPARAM)h_font, TRUE);
420419
}
@@ -627,11 +626,10 @@ LRESULT CALLBACK AdvanceOptions::AdvanceOptProc(HWND hwnd, UINT u_msg,
627626
GetWindowText(h_activation_threshold, activation_threshold_buffer,
628627
sizeof(activation_threshold_buffer));
629628
activation_threshold_ = activation_threshold_buffer;
630-
// TODO(b/497725655): Enable UI feature after public release
631-
// use_wchar_ =
632-
// (IsDlgButtonChecked(hwnd, kIdcVariableCheckbox) == BST_CHECKED)
633-
// ? "1"
634-
// : "0";
629+
use_wvarchar_ =
630+
(IsDlgButtonChecked(hwnd, kIdcUseWVarcharCheckbox) == BST_CHECKED)
631+
? "1"
632+
: "0";
635633

636634
enable_session_ =
637635
(IsDlgButtonChecked(hwnd, kIdcEnableSessionCheckbox) ==
@@ -779,8 +777,7 @@ void AdvanceOptions::SetValues(Section const& attribute_map) {
779777
query_properties_ = GetValueOrDefault(attribute_map, kQueryProperties);
780778
activation_threshold_ =
781779
GetValueOrDefault(attribute_map, kActivationThreshold);
782-
// TODO(b/497725655): Enable UI feature after public release
783-
// use_wchar_ = GetValueOrDefault(attribute_map, kUseWChar);
780+
use_wvarchar_ = GetValueOrDefault(attribute_map, kUseWVarchar);
784781
enable_session_ = GetValueOrDefault(attribute_map, kSessionLocation);
785782
activation_threshold_checkbox_ =
786783
GetValueOrDefault(attribute_map, kHTAPIActivationThresholdCheck);
@@ -803,7 +800,7 @@ void AdvanceOptions::ResetToDefaults() {
803800
additional_projects_.clear();
804801
query_properties_.clear();
805802
activation_threshold_.clear();
806-
// use_wchar_.clear();
803+
use_wvarchar_.clear();
807804
enable_session_.clear();
808805
activation_threshold_checkbox_.clear();
809806
allow_large_results_.clear();
@@ -831,7 +828,7 @@ void AdvanceOptions::Show(HWND hwnd) {
831828
RegisterClass(&wc_adv);
832829

833830
int window_width = 462;
834-
int window_height = 650;
831+
int window_height = 670;
835832
int screen_width = GetSystemMetrics(SM_CXSCREEN);
836833
int screen_height = GetSystemMetrics(SM_CYSCREEN);
837834
int x_pos = (screen_width - window_width) / 2;

google/cloud/odbc/bq_driver/internal/driver_adv_opt_form.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static int const kIdcQueryPropertiesEdit = 140;
3737
static int const kIdcOKButton = 141;
3838
static int const kIdcCancelButton = 142;
3939
static int const kIdcLanguageDialectComboBox = 143;
40-
static int const kIdcVariableCheckbox = 144;
40+
static int const kIdcUseWVarcharCheckbox = 144;
4141
static int const KIdcLargeResultHeader = 145;
4242
static int const kIdcEncryptionKeyComboBox = 146;
4343
static int const kIdcHyperlink2 = 147;
@@ -85,7 +85,7 @@ class AdvanceOptions {
8585
inline std::string const& GetActivationThreshold() const {
8686
return activation_threshold_;
8787
}
88-
inline std::string const& GetUseWchar() const { return use_wchar_; }
88+
inline std::string const& GetUseWVarChar() const { return use_wvarchar_; }
8989
inline std::string const& GetEnableSession() const { return enable_session_; }
9090
inline std::string const& GetActivationThresholdCheckbox() const {
9191
return activation_threshold_checkbox_;
@@ -119,7 +119,7 @@ class AdvanceOptions {
119119
static std::string additional_projects_;
120120
static std::string query_properties_;
121121
static std::string activation_threshold_;
122-
static std::string use_wchar_;
122+
static std::string use_wvarchar_;
123123
static std::string enable_session_;
124124
static std::string activation_threshold_checkbox_;
125125
static std::string allow_large_results_;

google/cloud/odbc/bq_driver/internal/driver_form.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ static Section BuildTestConnectionAttributes(
224224
attributes_map["QueryProperties"] = adv_form.GetQueryProperties();
225225
attributes_map["HTAPI_ActivationThreshold"] =
226226
adv_form.GetActivationThreshold();
227-
attributes_map["UseWVarChar"] = adv_form.GetUseWchar();
227+
attributes_map["UseWVarChar"] = adv_form.GetUseWVarChar();
228228
attributes_map["EnableSession"] = adv_form.GetEnableSession();
229229
attributes_map["AllowHtapiForLargeResults"] =
230230
adv_form.GetActivationThresholdCheckbox();

google/cloud/odbc/bq_driver/internal/odbc_conn_handle.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ void ConnectionHandle::SetUp(Section& dsn_section,
138138
dsn_.max_retries =
139139
!max_retries.empty() ? std::stoull(max_retries) : kDefaultMaxRetries;
140140

141+
std::string use_wvarchar = dsn_section["USEWVARCHAR"];
142+
if (!use_wvarchar.empty()) {
143+
GetUpperStr(use_wvarchar);
144+
dsn_.use_wvarchar = (use_wvarchar == "1" || use_wvarchar == "TRUE");
145+
}
141146
dsn_.pem_file = dsn_section["TRUSTEDCERTS"];
142147
dsn_.kms_key_name = dsn_section["KMSKEYNAME"];
143148
dsn_.session_location = dsn_section["SESSIONLOCATION"];

google/cloud/odbc/bq_driver/internal/odbc_conn_handle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct Dsn {
7676
bool use_default_large_results_dataset = true;
7777
std::string large_results_dataset_id;
7878
bool allow_htapi = false;
79+
bool use_wvarchar = false;
7980
std::string htapi_activation_threshold = "10000";
8081
std::string large_table_expiration_time = kDefaultLargeResultsTableExpiration;
8182

google/cloud/odbc/bq_driver/internal/odbc_desc_attr.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,12 @@ StatusRecord DescriptorRecord::SetOctetLength(SQLSMALLINT type,
386386
octet_length = value;
387387
break;
388388
case SQL_WCHAR:
389-
case SQL_WVARCHAR:
390389
case SQL_WLONGVARCHAR:
391390
octet_length = value * sizeof(SQLWCHAR);
392391
break;
392+
case SQL_WVARCHAR:
393+
octet_length = value * 4;
394+
break;
393395
case SQL_DECIMAL:
394396
case SQL_NUMERIC:
395397
octet_length = (precision + 2);

google/cloud/odbc/bq_driver/internal/odbc_internal_commons.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,12 +1189,12 @@ odbc_internal::StatusRecordOr<std::string> GetDataTypeInStr(BQDataType type) {
11891189
}
11901190

11911191
odbc_internal::StatusRecordOr<SQLSMALLINT> GetSQLDataType(
1192-
std::string const& type, bool isArray) {
1192+
std::string const& type, bool isArray, bool UseWvarchar) {
11931193
if (isArray) {
11941194
return SQL_VARCHAR;
11951195
}
11961196
if (type == "STRING") {
1197-
return SQL_VARCHAR;
1197+
return UseWvarchar ? SQL_WVARCHAR : SQL_VARCHAR;
11981198
}
11991199
if (type == "INTEGER" || type == "INT64") {
12001200
return SQL_BIGINT;

google/cloud/odbc/bq_driver/internal/odbc_internal_commons.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ odbc_internal::StatusRecordOr<BQDataType> ConvertDSType(
584584
std::string const& type);
585585

586586
odbc_internal::StatusRecordOr<SQLSMALLINT> GetSQLDataType(
587-
std::string const& type, bool isArray = false);
587+
std::string const& type, bool isArray = false, bool UseWvarchar = false);
588588

589589
odbc_internal::StatusRecordOr<
590590
google::cloud::bigquery_v2_minimal_internal::QueryParameter>

google/cloud/odbc/bq_driver/internal/odbc_stmt_handle.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,8 @@ StatusRecord StatementHandle::PopulateIrd(DescriptorHandle& descriptor_handle,
354354
DescriptorRecord descriptor_record;
355355
descriptor_record.SetName(res.name, res.name.length());
356356
descriptor_record.length = res.max_length;
357-
StatusRecordOr<SQLSMALLINT> type_status_record =
358-
GetSQLDataType(res.type, (res.mode == array_field));
357+
StatusRecordOr<SQLSMALLINT> type_status_record = GetSQLDataType(
358+
res.type, (res.mode == array_field), conn_handle.GetDsn().use_wvarchar);
359359

360360
if (!type_status_record.Ok()) {
361361
LOG(ERROR) << "StatementHandle::PopulateIrd::GetSQLDataType:: "

google/cloud/odbc/bq_driver/odbc_sql_results.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ SQLRETURN SQLDescribeColInternal(
484484
case SQL_SMALLINT:
485485
case SQL_TINYINT:
486486
case SQL_BIGINT:
487+
case SQL_WVARCHAR:
487488
IntValueToOutputBufferResponse<SQLSMALLINT, SQLSMALLINT>(
488489
desc_record.precision, column_size, nullptr);
489490
break;
@@ -500,9 +501,6 @@ SQLRETURN SQLDescribeColInternal(
500501
case SQL_INTERVAL_DAY_TO_SECOND:
501502
case SQL_INTERVAL_HOUR_TO_SECOND:
502503
case SQL_INTERVAL_MINUTE_TO_SECOND:
503-
IntValueToOutputBufferResponse<SQLSMALLINT, SQLSMALLINT>(
504-
desc_record.precision, decimal_digits, nullptr);
505-
break;
506504
case SQL_DECIMAL:
507505
case SQL_NUMERIC:
508506
case SQL_SMALLINT:

0 commit comments

Comments
 (0)