Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
283 changes: 282 additions & 1 deletion cpp/src/arrow/flight/sql/odbc/entry_points.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,286 @@
#include "arrow/util/logging.h"

SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT type, SQLHANDLE parent, SQLHANDLE* result) {
return SQL_INVALID_HANDLE;
return arrow::flight::sql::odbc::SQLAllocHandle(type, parent, result);
}

SQLRETURN SQL_API SQLAllocEnv(SQLHENV* env) {
return arrow::flight::sql::odbc::SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, env);
}

SQLRETURN SQL_API SQLAllocConnect(SQLHENV env, SQLHDBC* conn) {
return arrow::flight::sql::odbc::SQLAllocHandle(SQL_HANDLE_DBC, env, conn);
}

SQLRETURN SQL_API SQLAllocStmt(SQLHDBC conn, SQLHSTMT* stmt) {
return arrow::flight::sql::odbc::SQLAllocHandle(SQL_HANDLE_STMT, conn, stmt);
}

SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle) {
return arrow::flight::sql::odbc::SQLFreeHandle(type, handle);
}

SQLRETURN SQL_API SQLFreeEnv(SQLHENV env) {
return arrow::flight::sql::odbc::SQLFreeHandle(SQL_HANDLE_ENV, env);
}

SQLRETURN SQL_API SQLFreeConnect(SQLHDBC conn) {
return arrow::flight::sql::odbc::SQLFreeHandle(SQL_HANDLE_DBC, conn);
}

SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT option) {
return arrow::flight::sql::odbc::SQLFreeStmt(stmt, option);
}

SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT handle_type, SQLHANDLE handle,
SQLSMALLINT rec_number, SQLSMALLINT diag_identifier,
SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length,
SQLSMALLINT* string_length_ptr) {
return arrow::flight::sql::odbc::SQLGetDiagField(handle_type, handle, rec_number,
diag_identifier, diag_info_ptr,
buffer_length, string_length_ptr);
}

SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT handle_type, SQLHANDLE handle,
SQLSMALLINT rec_number, SQLWCHAR* sql_state,
SQLINTEGER* native_error_ptr, SQLWCHAR* message_text,
SQLSMALLINT buffer_length, SQLSMALLINT* text_length_ptr) {
return arrow::flight::sql::odbc::SQLGetDiagRec(
handle_type, handle, rec_number, sql_state, native_error_ptr, message_text,
buffer_length, text_length_ptr);
}

SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER value_ptr,
SQLINTEGER buffer_len, SQLINTEGER* str_len_ptr) {
return arrow::flight::sql::odbc::SQLGetEnvAttr(env, attr, value_ptr, buffer_len,
str_len_ptr);
}

SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER value_ptr,
SQLINTEGER str_len) {
return arrow::flight::sql::odbc::SQLSetEnvAttr(env, attr, value_ptr, str_len);
}

SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC conn, SQLINTEGER attribute,
SQLPOINTER value_ptr, SQLINTEGER buffer_length,
SQLINTEGER* string_length_ptr) {
return arrow::flight::sql::odbc::SQLGetConnectAttr(conn, attribute, value_ptr,
buffer_length, string_length_ptr);
}

SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC conn, SQLINTEGER attr, SQLPOINTER value,
SQLINTEGER value_len) {
return arrow::flight::sql::odbc::SQLSetConnectAttr(conn, attr, value, value_len);
}

SQLRETURN SQL_API SQLGetInfo(SQLHDBC conn, SQLUSMALLINT info_type,
SQLPOINTER info_value_ptr, SQLSMALLINT buf_len,
SQLSMALLINT* length) {
return arrow::flight::sql::odbc::SQLGetInfo(conn, info_type, info_value_ptr, buf_len,
length);
}

SQLRETURN SQL_API SQLDriverConnect(SQLHDBC conn, SQLHWND window_handle,
SQLWCHAR* in_connection_string,
SQLSMALLINT in_connection_stringLen,
SQLWCHAR* out_connection_string,
SQLSMALLINT out_connection_string_buffer_len,
SQLSMALLINT* out_connection_string_len,
SQLUSMALLINT driver_completion) {
return arrow::flight::sql::odbc::SQLDriverConnect(
conn, window_handle, in_connection_string, in_connection_stringLen,
out_connection_string, out_connection_string_buffer_len, out_connection_string_len,
driver_completion);
}

SQLRETURN SQL_API SQLConnect(SQLHDBC conn, SQLWCHAR* dsn_name, SQLSMALLINT dsn_name_len,
SQLWCHAR* user_name, SQLSMALLINT user_name_len,
SQLWCHAR* password, SQLSMALLINT password_len) {
return arrow::flight::sql::odbc::SQLConnect(conn, dsn_name, dsn_name_len, user_name,
user_name_len, password, password_len);
}

SQLRETURN SQL_API SQLDisconnect(SQLHDBC conn) {
return arrow::flight::sql::odbc::SQLDisconnect(conn);
}

SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute,
SQLPOINTER value_ptr, SQLINTEGER buffer_length,
SQLINTEGER* string_length_ptr) {
return arrow::flight::sql::odbc::SQLGetStmtAttr(stmt, attribute, value_ptr,
buffer_length, string_length_ptr);
}

SQLRETURN SQL_API SQLExecDirect(SQLHSTMT stmt, SQLWCHAR* query_text,
SQLINTEGER text_length) {
return arrow::flight::sql::odbc::SQLExecDirect(stmt, query_text, text_length);
}

SQLRETURN SQL_API SQLFetch(SQLHSTMT stmt) {
return arrow::flight::sql::odbc::SQLFetch(stmt);
}

SQLRETURN SQL_API SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT fetch_orientation,
SQLLEN fetch_offset, SQLULEN* row_count_ptr,
SQLUSMALLINT* row_status_array) {
return arrow::flight::sql::odbc::SQLExtendedFetch(stmt, fetch_orientation, fetch_offset,
row_count_ptr, row_status_array);
}

SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT fetch_orientation,
SQLLEN fetch_offset) {
return arrow::flight::sql::odbc::SQLFetchScroll(stmt, fetch_orientation, fetch_offset);
}

SQLRETURN SQL_API SQLGetData(SQLHSTMT stmt, SQLUSMALLINT record_number,
SQLSMALLINT c_type, SQLPOINTER data_ptr,
SQLLEN buffer_length, SQLLEN* indicator_ptr) {
return arrow::flight::sql::odbc::SQLGetData(stmt, record_number, c_type, data_ptr,
buffer_length, indicator_ptr);
}

SQLRETURN SQL_API SQLPrepare(SQLHSTMT stmt, SQLWCHAR* query_text,
SQLINTEGER text_length) {
return arrow::flight::sql::odbc::SQLPrepare(stmt, query_text, text_length);
}

SQLRETURN SQL_API SQLExecute(SQLHSTMT stmt) {
return arrow::flight::sql::odbc::SQLExecute(stmt);
}

SQLRETURN SQL_API SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT record_number,
SQLSMALLINT c_type, SQLPOINTER data_ptr,
SQLLEN buffer_length, SQLLEN* indicator_ptr) {
return arrow::flight::sql::odbc::SQLBindCol(stmt, record_number, c_type, data_ptr,
buffer_length, indicator_ptr);
}

SQLRETURN SQL_API SQLCancel(SQLHSTMT stmt) {
ARROW_LOG(DEBUG) << "SQLCancel called with stmt: " << stmt;
return ODBC::ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
throw driver::odbcabstraction::DriverException("SQLCancel is not implemented",
"IM001");
return SQL_ERROR;
});
}

SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT stmt) {
return arrow::flight::sql::odbc::SQLCloseCursor(stmt);
}

SQLRETURN SQL_API SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT record_number,
SQLUSMALLINT field_identifier,
SQLPOINTER character_attribute_ptr,
SQLSMALLINT buffer_length, SQLSMALLINT* output_length,
SQLLEN* numeric_attribute_ptr) {
return arrow::flight::sql::odbc::SQLColAttribute(stmt, record_number, field_identifier,
character_attribute_ptr, buffer_length,
output_length, numeric_attribute_ptr);
}

SQLRETURN SQL_API SQLTables(SQLHSTMT stmt, SQLWCHAR* catalog_name,
SQLSMALLINT catalog_name_length, SQLWCHAR* schema_name,
SQLSMALLINT schema_name_length, SQLWCHAR* table_name,
SQLSMALLINT table_name_length, SQLWCHAR* table_type,
SQLSMALLINT table_type_length) {
return arrow::flight::sql::odbc::SQLTables(
stmt, catalog_name, catalog_name_length, schema_name, schema_name_length,
table_name, table_name_length, table_type, table_type_length);
}

SQLRETURN SQL_API SQLColumns(SQLHSTMT stmt, SQLWCHAR* catalog_name,
SQLSMALLINT catalog_name_length, SQLWCHAR* schema_name,
SQLSMALLINT schema_name_length, SQLWCHAR* table_name,
SQLSMALLINT table_name_length, SQLWCHAR* columnName,
SQLSMALLINT column_name_length) {
return arrow::flight::sql::odbc::SQLColumns(
stmt, catalog_name, catalog_name_length, schema_name, schema_name_length,
table_name, table_name_length, columnName, column_name_length);
}

SQLRETURN SQL_API SQLForeignKeys(
SQLHSTMT stmt, SQLWCHAR* pk_catalog_name, SQLSMALLINT pk_catalog_name_length,
SQLWCHAR* pk_schema_name, SQLSMALLINT pk_schema_name_length, SQLWCHAR* pk_table_name,
SQLSMALLINT pk_table_name_length, SQLWCHAR* fk_catalog_name,
SQLSMALLINT fk_catalog_name_length, SQLWCHAR* fk_schema_name,
SQLSMALLINT fk_schema_name_length, SQLWCHAR* fk_table_name,
SQLSMALLINT fk_table_name_length) {
ARROW_LOG(DEBUG) << "SQLForeignKeysW called with stmt: " << stmt
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ARROW_LOG(DEBUG) << "SQLForeignKeysW called with stmt: " << stmt
ARROW_LOG(DEBUG) << "SQLForeignKeys called with stmt: " << stmt

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unicode support will be added in upcoming PRs. Some ODBC unicode APIs will have a W at the end after compilation, because some of the function names are macros that expand to names with W. Please see:
https://github.com/microsoft/ODBC-Specification/blob/4dda95986bda5d3b55d7749315d3e5a0951c1e50/Windows/inc/sqlucode.h#L952-L996

Copy link
Member

Choose a reason for hiding this comment

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

OK. This may be better then:

Suggested change
ARROW_LOG(DEBUG) << "SQLForeignKeysW called with stmt: " << stmt
ARROW_LOG(DEBUG) << #SQLColAttribute " called with stmt: " << stmt

<< ", pk_catalog_name: " << static_cast<const void*>(pk_catalog_name)
<< ", pk_catalog_name_length: " << pk_catalog_name_length
Comment on lines +242 to +243
Copy link
Member

Choose a reason for hiding this comment

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

Should we print as string...?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To get the variable names in string, the user can use ODBC driver manager to trace the API calls and the inputs. I hope printing the addresses for now is ok

<< ", pk_schema_name: " << static_cast<const void*>(pk_schema_name)
<< ", pk_schema_name_length: " << pk_schema_name_length
<< ", pk_table_name: " << static_cast<const void*>(pk_table_name)
<< ", pk_table_name_length: " << pk_table_name_length
<< ", fk_catalog_name: " << static_cast<const void*>(fk_catalog_name)
<< ", fk_catalog_name_length: " << fk_catalog_name_length
<< ", fk_schema_name: " << static_cast<const void*>(fk_schema_name)
<< ", fk_schema_name_length: " << fk_schema_name_length
<< ", fk_table_name: " << static_cast<const void*>(fk_table_name)
<< ", fk_table_name_length: " << fk_table_name_length;
return ODBC::ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
throw driver::odbcabstraction::DriverException("SQLForeignKeysW is not implemented",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
throw driver::odbcabstraction::DriverException("SQLForeignKeysW is not implemented",
throw driver::odbcabstraction::DriverException("SQLForeignKeys is not implemented",

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please see #47725 (comment)

"IM001");
return SQL_ERROR;
});
}

SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT data_type) {
return arrow::flight::sql::odbc::SQLGetTypeInfo(stmt, data_type);
}

SQLRETURN SQL_API SQLMoreResults(SQLHSTMT stmt) {
return arrow::flight::sql::odbc::SQLMoreResults(stmt);
}

SQLRETURN SQL_API SQLNativeSql(SQLHDBC conn, SQLWCHAR* in_statement_text,
SQLINTEGER in_statement_text_length,
SQLWCHAR* out_statement_text, SQLINTEGER buffer_length,
SQLINTEGER* out_statement_text_length) {
return arrow::flight::sql::odbc::SQLNativeSql(
conn, in_statement_text, in_statement_text_length, out_statement_text,
buffer_length, out_statement_text_length);
}

SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT* column_count_ptr) {
return arrow::flight::sql::odbc::SQLNumResultCols(stmt, column_count_ptr);
}

SQLRETURN SQL_API SQLRowCount(SQLHSTMT stmt, SQLLEN* row_count_ptr) {
return arrow::flight::sql::odbc::SQLRowCount(stmt, row_count_ptr);
}

SQLRETURN SQL_API SQLPrimaryKeys(SQLHSTMT stmt, SQLWCHAR* catalog_name,
SQLSMALLINT catalog_name_length, SQLWCHAR* schema_name,
SQLSMALLINT schema_name_length, SQLWCHAR* table_name,
SQLSMALLINT table_name_length) {
ARROW_LOG(DEBUG) << "SQLPrimaryKeysW called with stmt: " << stmt
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ARROW_LOG(DEBUG) << "SQLPrimaryKeysW called with stmt: " << stmt
ARROW_LOG(DEBUG) << "SQLPrimaryKeys called with stmt: " << stmt

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please see #47725 (comment)

<< ", catalog_name: " << static_cast<const void*>(catalog_name)
<< ", catalog_name_length: " << catalog_name_length
<< ", schema_name: " << static_cast<const void*>(schema_name)
<< ", schema_name_length: " << schema_name_length
<< ", table_name: " << static_cast<const void*>(table_name)
<< ", table_name_length: " << table_name_length;
return ODBC::ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
throw driver::odbcabstraction::DriverException("SQLPrimaryKeysW is not implemented",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
throw driver::odbcabstraction::DriverException("SQLPrimaryKeysW is not implemented",
throw driver::odbcabstraction::DriverException("SQLPrimaryKeys is not implemented",

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please see #47725 (comment)

"IM001");
return SQL_ERROR;
});
}

SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute,
SQLPOINTER value_ptr, SQLINTEGER stringLength) {
return arrow::flight::sql::odbc::SQLSetStmtAttr(stmt, attribute, value_ptr,
stringLength);
}

SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT column_number,
SQLWCHAR* column_name, SQLSMALLINT buffer_length,
SQLSMALLINT* name_length_ptr, SQLSMALLINT* data_type_ptr,
SQLULEN* column_size_ptr,
SQLSMALLINT* decimal_digits_ptr,
SQLSMALLINT* nullable_ptr) {
return arrow::flight::sql::odbc::SQLDescribeCol(
stmt, column_number, column_name, buffer_length, name_length_ptr, data_type_ptr,
column_size_ptr, decimal_digits_ptr, nullable_ptr);
}
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ int DsnConfigurationWindow::CreatePropertiesGroup(int pos_x, int pos_y, int size

const auto keys = config_.GetCustomKeys();
for (const auto& key : keys) {
property_list_->ListAddItem({std::string(key), config.Get(key)});
property_list_->ListAddItem({std::string(key), config_.Get(key)});
}

SendMessage(property_list_->GetHandle(), LVM_SETEXTENDEDLISTVIEWSTYLE,
Expand Down
Loading
Loading