Skip to content

GH-50560: [C++][FlightRPC][ODBC] Fix SQLDescribeCol column_size/decimal_digits width#50562

Open
vikrantpuppala wants to merge 1 commit into
apache:mainfrom
vikrantpuppala:fix-odbc-describecol-column-size-width
Open

GH-50560: [C++][FlightRPC][ODBC] Fix SQLDescribeCol column_size/decimal_digits width#50562
vikrantpuppala wants to merge 1 commit into
apache:mainfrom
vikrantpuppala:fix-odbc-describecol-column-size-width

Conversation

@vikrantpuppala

@vikrantpuppala vikrantpuppala commented Jul 20, 2026

Copy link
Copy Markdown

Rationale for this change

SQLDescribeCol returned uninitialized garbage in the upper bytes of its
column_size (ColumnSizePtr) output for numeric / decimal / integer / float
columns.

The numeric path read SQL_DESC_PRECISION — stored internally as a
SQLSMALLINT (2 bytes) — directly into the caller's SQLULEN* column_size_ptr
(8 bytes). The GetAttribute template that ultimately performs the write copies
exactly sizeof(T) bytes (here T = SQLSMALLINT, so 2 bytes) and ignores the
claimed buffer_length. The result: only the low 2 bytes of the 8-byte
SQLULEN were written and the upper 6 bytes were left uninitialized. Any
application reading the full column_size saw a wildly incorrect value.

Two adjacent decimal_digits sites (SQL_DESC_SCALE for exact-numeric columns,
SQL_DESC_PRECISION for datetime/interval columns) passed sizeof(SQLULEN) as
the buffer size even though decimal_digits_ptr is a SQLSMALLINT*. Those did
not corrupt memory (the write width matched the 2-byte target), but the size
argument was wrong and misleading.

Introduced by GH-47724 (#48052).

What changes are included in this PR?

  • Numeric column_size path: read SQL_DESC_PRECISION into a local
    SQLSMALLINT and widen-assign it into *column_size_ptr, so all 8 bytes of
    the SQLULEN output are written.
  • decimal_digits scale and datetime-precision paths: pass
    sizeof(SQLSMALLINT) (the true target width) instead of sizeof(SQLULEN).
  • Added describe_col_test.cc with parameterized (mock + remote) tests that
    pre-fill column_size with an all-ones sentinel, call SQLDescribeCol on a
    DECIMAL column and a TIMESTAMP column, and assert the full 8-byte
    column_size is a sane small value (i.e. the upper bytes were overwritten),
    plus sane decimal_digits. Without the fix these fail because the sentinel's
    upper bytes survive the short write.

Are these changes tested?

Yes — new gtest cases in
cpp/src/arrow/flight/sql/odbc/tests/describe_col_test.cc, wired into the ODBC
test CMakeLists.txt.

Are there any user-facing changes?

Yes. SQLDescribeCol now returns a correct column_size for numeric/decimal
columns instead of a value with uninitialized high bytes. This is a bug fix in
externally-visible ODBC behavior; no API signatures change.

@vikrantpuppala
vikrantpuppala requested a review from lidavidm as a code owner July 20, 2026 15:34
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #50560 has been automatically assigned in GitHub to PR creator.

@lidavidm

Copy link
Copy Markdown
Member

This PR contains a "Critical Fix".

I think we reserve this for things that would be a release blocker, FWIW.

CC @justing-bq for review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes incorrect SQLDescribeCol output widths in the Flight SQL ODBC driver so callers receive fully-initialized column_size for numeric/decimal types (and correct buffer-size arguments for decimal_digits), addressing GH-50560 and preventing nondeterministic garbage in upper bytes.

Changes:

  • In SQLDescribeCol, reads SQL_DESC_PRECISION into a SQLSMALLINT and widens into SQLULEN to avoid short writes into column_size.
  • Corrects decimal_digits GetField buffer sizes to sizeof(SQLSMALLINT) for scale / datetime precision paths.
  • Adds a new gtest file to validate column_size is fully overwritten (and wires it into the ODBC test CMake target).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
cpp/src/arrow/flight/sql/odbc/tests/describe_col_test.cc Adds regression tests intended to catch short writes into SQLULEN column_size and validate decimal_digits.
cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt Includes the new describe_col_test.cc in the ODBC test sources.
cpp/src/arrow/flight/sql/odbc/odbc_api.cc Fixes write-width mismatch for numeric column_size and corrects buffer-size arguments for decimal_digits GetField calls.

Comment thread cpp/src/arrow/flight/sql/odbc/tests/describe_col_test.cc
Comment thread cpp/src/arrow/flight/sql/odbc/tests/describe_col_test.cc Outdated
…/decimal_digits width

SQLDescribeCol read SQL_DESC_PRECISION (a 2-byte SQLSMALLINT) directly into
the caller's 8-byte SQLULEN* column_size output for numeric/decimal columns.
The GetAttribute template writes exactly sizeof(T) bytes and ignores the
claimed buffer_length, so only the low 2 bytes were written and the upper 6
bytes were left uninitialized garbage.

Read the precision into a local SQLSMALLINT and widen-assign it into
*column_size_ptr so all 8 bytes are written. Also fix the two decimal_digits
sites (SQL_DESC_SCALE and datetime SQL_DESC_PRECISION) to pass
sizeof(SQLSMALLINT) -- the true width of the SQLSMALLINT* decimal_digits
output -- instead of sizeof(SQLULEN).

Add describe_col_test.cc, which pre-fills column_size with an all-ones
sentinel and asserts SQLDescribeCol fully overwrites it for DECIMAL and
TIMESTAMP columns.

Introduced by apacheGH-47724 (apache#48052).

Signed-off-by: Vikrant Puppala <vikrantpuppala@gmail.com>
@vikrantpuppala
vikrantpuppala force-pushed the fix-odbc-describecol-column-size-width branch from 5b1944f to 1691e5c Compare July 21, 2026 04:21
@vikrantpuppala

Copy link
Copy Markdown
Author

@lidavidm Dropped the "Critical Fix" wording from the description

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