Skip to content

Odbc driver feature#596

Open
Ylonies wants to merge 26 commits into
ydb-platform:mainfrom
Ylonies:odbc-driver-feature
Open

Odbc driver feature#596
Ylonies wants to merge 26 commits into
ydb-platform:mainfrom
Ylonies:odbc-driver-feature

Conversation

@Ylonies
Copy link
Copy Markdown

@Ylonies Ylonies commented Apr 8, 2026

No description provided.

Comment thread odbc/src/utils/bindings.h Outdated
Comment on lines +34 to +36
virtual void OnStreamPartError(const TStatus& status) {
(void)status;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
virtual void OnStreamPartError(const TStatus& status) {
(void)status;
}
virtual void OnStreamPartError([[maybe_unused]] const TStatus& status) {
}

Comment thread odbc/src/odbc_driver.cpp
}
}

SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT handleType,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

А SQLGetDiagField чем от SQLGetDiagRec отличается?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Необходимо по спеке, SQLGetDiagRec возвращает целую диагностическую запись, SQLGetDiagRec - одно поле по diagIdentifier

Comment thread odbc/src/statement.cpp
if (txSettings.GetMode() == NQuery::TTxSettings::TS_SERIALIZABLE_RW) {
return session.StreamExecuteQuery(
PreparedQuery_,
NQuery::TTxControl::NoTx(),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

А почему NoTx? Есть же Serializable

Comment thread odbc/src/statement.cpp Outdated
auto iterator = CreateExecuteIterator(session, params);
NStatusHelpers::ThrowOnError(iterator);

std::optional<NQuery::TExecuteQueryPart> prefetchedResultPart = PrefetchFirstResultPart(iterator);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

А зачем делать prefetch?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  1. ранняя диагностика 2) retry при autocommit прямо в execute

Comment thread odbc/src/connection_attributes.cpp Outdated
Comment on lines +8 to +30
std::optional<NQuery::TTxSettings::ETransactionMode> TConnectionAttributes::ResolveTxMode(SQLUINTEGER accessMode, SQLUINTEGER txnIsolation) {
if (accessMode == SQL_MODE_READ_ONLY) {
switch (txnIsolation) {
case SQL_TXN_READ_UNCOMMITTED:
return NQuery::TTxSettings::TS_STALE_RO;
case SQL_TXN_READ_COMMITTED:
return NQuery::TTxSettings::TS_ONLINE_RO;
case SQL_TXN_REPEATABLE_READ:
case SQL_TXN_SERIALIZABLE:
return NQuery::TTxSettings::TS_SNAPSHOT_RO;
default:
return std::nullopt;
}
}

switch (txnIsolation) {
case SQL_TXN_REPEATABLE_READ:
case SQL_TXN_SERIALIZABLE:
return NQuery::TTxSettings::TS_SERIALIZABLE_RW;
default:
return std::nullopt;
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Мы не поддерживаем SQL_TXN_READ_UNCOMMITTED и SQL_TXN_READ_COMMITTED.

SQL_TXN_REPEATABLE_READ поддерживаем в виде SnapshotRW.

SQL_TXN_SERIALIZABLE.

Про accessMode, как это работает в ODBC?

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an initial YDB ODBC driver implementation (handles, connections, statements, attribute handling, basic metadata queries, and ODBC escape rewriting) along with unit/integration tests and CMake build integration so the driver can be built as part of the SDK.

Changes:

  • Introduces ydb-odbc shared library with core ODBC entrypoints and supporting utilities (conversion, diagnostics, cursors, attribute parsing, escape rewriting).
  • Adds ODBC unit tests (escape rewriting, SQL LIKE matching, param conversion) and integration tests (basic query flow, env/conn/stmt attrs).
  • Integrates ODBC build/test targets into the SDK CMake configuration (option, preset, external ODBC dependency, test helper).

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 19 comments.

Show a summary per file
File Description
tests/unit/library/operation_id/CMakeLists.txt Adds proto library dependency to operation_id unit test.
odbc/tests/unit/sql_like_ut.cpp Unit tests for SQL LIKE pattern matching helper.
odbc/tests/unit/escape_ut.cpp Unit tests for ODBC escape sequence rewriting.
odbc/tests/unit/convert_ut.cpp Unit tests for ODBC parameter conversion to YDB params.
odbc/tests/unit/CMakeLists.txt Defines ODBC unit test targets and include paths.
odbc/tests/integration/test_utils.h Common ODBC integration test helpers (connect, error formatting).
odbc/tests/integration/stmt_attr_it.cpp Integration tests for statement attributes + metadata-id behavior.
odbc/tests/integration/env_it.cpp Integration tests for environment-level transactions (SQLEndTran).
odbc/tests/integration/CMakeLists.txt Defines ODBC integration test targets.
odbc/tests/integration/basic_it.cpp Integration tests for simple query, parameters, and column binding.
odbc/tests/integration/attr_it.cpp Integration tests for env/connection attribute behavior.
odbc/tests/CMakeLists.txt Adds ODBC tests subdirectories.
odbc/src/utils/util.h Declares helper for converting ODBC strings to std::string.
odbc/src/utils/util.cpp Implements ODBC string conversion helper.
odbc/src/utils/types.h Declares YDB-type to ODBC-metadata helpers.
odbc/src/utils/types.cpp Implements (partially) YDB-type to ODBC-metadata helpers.
odbc/src/utils/sql_like.h Adds inline SQL LIKE matcher used by metadata filtering.
odbc/src/utils/escape.h Declares ODBC escape rewrite function.
odbc/src/utils/escape.cpp Implements ODBC escape rewriting (+ CONVERT-to-CAST rewriting).
odbc/src/utils/error_manager.h Adds diagnostic record storage + exception-to-diagnostic helpers.
odbc/src/utils/error_manager.cpp Implements diagnostic record mapping and retrieval.
odbc/src/utils/diag.h Provides small helpers for standard SQLSTATE diagnostics.
odbc/src/utils/cursor.h Declares cursor abstraction for exec/virtual cursors.
odbc/src/utils/cursor.cpp Implements exec cursor (stream iterator) and virtual cursor (in-memory table).
odbc/src/utils/convert.h Declares parameter and column conversion helpers.
odbc/src/utils/convert.cpp Implements ODBC param conversion registry + YDB->ODBC column conversion.
odbc/src/utils/bindings.h Defines bound parameter/column structs and binding filler interface.
odbc/src/utils/attr.h Declares attribute read/write helpers (string + integer tokens).
odbc/src/utils/attr.cpp Implements attribute string read/write and truncation diagnostics.
odbc/src/statement.h Declares statement handle (prepare/execute/fetch/metadata/attrs).
odbc/src/statement.cpp Implements statement execution, binding, metadata queries, and pattern scanning.
odbc/src/statement_attr.h Declares statement attribute storage + get/set API.
odbc/src/statement_attr.cpp Implements statement attribute get/set logic.
odbc/src/odbc_driver.cpp Implements ODBC C entrypoints wiring to internal handle objects.
odbc/src/environment.h Declares environment handle (attrs, connection registry, EndTran).
odbc/src/environment.cpp Implements environment attrs and env-level EndTran across connections.
odbc/src/connection.h Declares connection handle (connect/attrs/tx/session/client mgmt).
odbc/src/connection.cpp Implements connection string parsing, driver pooling, tx control, catalog routing.
odbc/src/connection_attr.h Declares connection attribute storage + catalog routing helpers.
odbc/src/connection_attr.cpp Implements connection attributes (autocommit, access mode, isolation, catalog).
odbc/README.md Adds build/config/usage documentation for the ODBC driver.
odbc/odbcinst.ini Provides installed driver registration template.
odbc/odbc.ini Provides sample DSN configuration template.
odbc/examples/scheme/main.cpp Example program using SQLTables to enumerate tables.
odbc/examples/scheme/CMakeLists.txt Builds scheme example and injects built driver path macro.
odbc/examples/CMakeLists.txt Adds example subdirectories.
odbc/examples/basic/main.cpp Example program using params and result fetching/binding.
odbc/examples/basic/CMakeLists.txt Builds basic example and injects built driver path macro.
odbc/CMakeLists.txt Builds/install ydb-odbc and adds tests/examples subdirs.
CMakePresets.json Enables YDB_SDK_ODBC in presets.
CMakeLists.txt Adds YDB_SDK_ODBC option and includes odbc/ when enabled.
cmake/testing.cmake Adds add_odbc_test() helper when ODBC is enabled.
cmake/external_libs.cmake Adds find_package(ODBC REQUIRED) under YDB_SDK_ODBC.
cmake/common.cmake Extends _ydb_sdk_add_library options and changes global lib creation helper.
Comments suppressed due to low confidence (1)

cmake/common.cmake:126

  • add_global_library_for() now calls _ydb_sdk_add_library(${TgtName} STATIC ...), but _ydb_sdk_add_library() does not recognize a STATIC option. As a result, the created library type depends on CMake defaults/BUILD_SHARED_LIBS instead of being explicitly STATIC, which can break link behavior (whole-archive) and packaging. Please either teach _ydb_sdk_add_library() to accept STATIC, or change add_global_library_for() to call add_library(${TgtName} STATIC) (or _ydb_sdk_add_library with an explicit mode it supports).
function(add_global_library_for TgtName MainName)
  _ydb_sdk_add_library(${TgtName} STATIC ${ARGN})
  if(APPLE)
    target_link_options(${MainName} INTERFACE "SHELL:-Wl,-force_load,$<TARGET_FILE:$<INSTALL_INTERFACE:YDB-CPP-SDK::>${TgtName}>")
  else()
    target_link_options(${MainName} INTERFACE "SHELL:-Wl,--whole-archive $<TARGET_FILE:$<INSTALL_INTERFACE:YDB-CPP-SDK::>${TgtName}> -Wl,--no-whole-archive")
  endif()
  add_dependencies(${MainName} ${TgtName})
  target_link_libraries(${MainName} INTERFACE ${TgtName})
endfunction()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread odbc/src/utils/error_manager.h
Comment thread odbc/src/utils/types.h
Comment thread odbc/src/utils/util.cpp
Comment on lines +5 to +10
std::string GetString(SQLCHAR* str, SQLSMALLINT length) {
if (length == SQL_NTS) {
return std::string(reinterpret_cast<const char*>(str));
}
return std::string(reinterpret_cast<const char*>(str), length);
}
Comment thread odbc/src/utils/types.cpp
Comment on lines +6 to +9
SQLSMALLINT GetTypeId(const TType& type) {
// TODO: implement
return 0;
}
Comment thread odbc/src/utils/convert.cpp
Comment thread odbc/src/utils/types.cpp
Comment on lines +20 to +45
std::optional<SQLSMALLINT> GetDecimalDigits(const TType& type) {
TTypeParser typeParser(type);
if (typeParser.GetKind() != TTypeParser::ETypeKind::Primitive) {
return std::nullopt;
}

switch (typeParser.GetPrimitive()) {
case EPrimitiveType::Int64:
return 64;
case EPrimitiveType::Uint64:
return 64;
case EPrimitiveType::Int32:
return 32;
case EPrimitiveType::Uint32:
return 32;
case EPrimitiveType::Int16:
return 16;
case EPrimitiveType::Uint16:
return 16;
case EPrimitiveType::Int8:
return 8;
case EPrimitiveType::Uint8:
return 8;
default:
return std::nullopt;
}
Comment on lines +35 to +48
TTypedValue(const TBoundParam& param) {
Data = *static_cast<const TSrcType*>(param.ParameterValuePtr);
}
};

template<>
TTypedValue<SQL_C_CHAR>::TTypedValue(const TBoundParam& param) {
Data = std::string(static_cast<const char*>(param.ParameterValuePtr), param.BufferLength);
}

template<>
TTypedValue<SQL_C_BINARY>::TTypedValue(const TBoundParam& param) {
Data = std::string(static_cast<const char*>(param.ParameterValuePtr), param.BufferLength);
}
Comment thread odbc/odbc.ini Outdated
Comment on lines +4 to +9
[YDB]
Driver=YDB
Description=YDB Database Connection
Server=grpc://localhost:2136
Database=local
AuthMode=none No newline at end of file
Comment thread odbc/README.md
Comment on lines +30 to +38

3. Edit `/etc/odbc.ini` to configure the connection:
```ini
[YDB]
Driver=YDB
Description=YDB Database Connection
Server=your-server:port
Database=/path/to/database
```
Comment thread odbc/src/utils/cursor.h
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 63 out of 63 changed files in this pull request and generated 16 comments.

Comments suppressed due to low confidence (1)

cmake/common.cmake:123

  • add_global_library_for() now calls _ydb_sdk_add_library(${TgtName} STATIC ${ARGN}), but _ydb_sdk_add_library() doesn’t handle the STATIC keyword or forward ${ARGN} as sources. This effectively creates an (empty) library target and drops the intended source list, which will break builds if/when add_global_library_for is used. Consider either restoring add_library(${TgtName} STATIC ${ARGN}) here, or extending _ydb_sdk_add_library to accept a library type + source list (or call target_sources() with the unparsed args).
function(add_global_library_for TgtName MainName)
  _ydb_sdk_add_library(${TgtName} STATIC ${ARGN})
  if(APPLE)
    target_link_options(${MainName} INTERFACE "SHELL:-Wl,-force_load,$<TARGET_FILE:$<INSTALL_INTERFACE:YDB-CPP-SDK::>${TgtName}>")
  else()
    target_link_options(${MainName} INTERFACE "SHELL:-Wl,--whole-archive $<TARGET_FILE:$<INSTALL_INTERFACE:YDB-CPP-SDK::>${TgtName}> -Wl,--no-whole-archive")
  endif()

Comment on lines +1 to +7
#pragma once

#include <sql.h>
#include <sqlext.h>
#include <vector>
#include <string>

Comment thread odbc/src/utils/types.h
Comment on lines +1 to +6
#pragma once

#include <ydb-cpp-sdk/client/value/value.h>

#include <sql.h>
#include <sqlext.h>
Comment on lines +1 to +8
#include "convert.h"

#include <util/datetime/base.h>
#include <util/generic/singleton.h>

#include <algorithm>

namespace NYdb {
Comment thread odbc/src/utils/convert.h
Comment on lines +10 to +17
namespace NYdb {
namespace NOdbc {

SQLRETURN ConvertParam(const TBoundParam& param, TParamValueBuilder& builder);
SQLRETURN ConvertColumn(TValueParser& parser, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLLEN bufferLength, SQLLEN* strLenOrInd);

} // namespace NYdb
} // namespace NOdbc
Comment thread odbc/src/utils/error_manager.cpp Outdated
Comment on lines +136 to +150
const auto& err = Errors_[recNumber-1];
if (sqlState) {
strncpy((char*)sqlState, err.SqlState.c_str(), 6);
}

if (nativeError) {
*nativeError = err.NativeError;
}

if (messageText && bufferLength > 0) {
strncpy((char*)messageText, err.Message.c_str(), bufferLength);
if (textLength) {
*textLength = (SQLSMALLINT)std::min((int)err.Message.size(), (int)bufferLength);
}
}
Comment thread odbc/src/statement.cpp Outdated
Comment on lines +387 to +389
if (entries.empty()) {
throw TOdbcException("HYC00", 0, "No tables found");
}
Comment thread odbc/src/utils/cursor.h
Comment on lines +3 to +12
#include "bindings.h"

#include <ydb-cpp-sdk/client/query/client.h>

#include <sql.h>

#include <optional>
#include <string>
#include <vector>

Comment thread odbc/src/statement.cpp Outdated

#include <optional>
#include <cctype>
#include <cstring>
Comment thread odbc/src/connection.cpp
Comment on lines +5 to +8
#include <map>
#include <string>
#include <unordered_map>

Comment thread odbc/src/environment.cpp
@@ -0,0 +1,82 @@
#include "environment.h"
#include "connection.h"
@Ylonies Ylonies force-pushed the odbc-driver-feature branch from 90c479b to 835c5d1 Compare May 12, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants