This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 5355fbe835a [test](jdbc) Add SQL Server bit/boolean predicate pushdown 
regression test (#64756)
5355fbe835a is described below

commit 5355fbe835af848e383469acda19f7becc2ad570
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Wed Jun 24 17:39:32 2026 +0800

    [test](jdbc) Add SQL Server bit/boolean predicate pushdown regression test 
(#64756)
    
    ### What problem does this PR solve?
    
    Issue Number: #64464
    
    Related PR: N/A
    
    Problem Summary:
    
    When querying a SQL Server JDBC catalog, a predicate on a `bit` column
    such as `WHERE bit_value = '1'` is folded to a boolean literal during
    analysis. The pushed-down predicate must be rendered as an integer (`=
    1` / `= 0`) for SQL Server, never the `TRUE` / `FALSE` keyword: SQL
    Server has no boolean literal and reports `SQLServerException: Invalid
    column name 'TRUE'` (see #64464).
    
    On current master this is already handled correctly. The JDBC pushdown
    path was refactored to the connector SPI (`PluginDrivenScanNode` ->
    `ExprToConnectorExpressionConverter` -> `JdbcQueryBuilder`), and
    `JdbcQueryBuilder.formatBooleanLiteral()` renders booleans per dialect
    (`SQLSERVER` / `ORACLE` / `OCEANBASE_ORACLE` / `DB2` -> `1`/`0`, others
    -> `TRUE`/`FALSE`). `JdbcQueryBuilderTest` already unit-tests this.
    
    What was missing is the **end-to-end** regression test that the issue
    triage explicitly asked for. This PR adds it to the SQL Server docker
    JDBC suite (`test_sqlserver_jdbc_catalog.groovy`), covering `bit_value =
    '1'`, `bit_value = '0'` and `bit_value in ('1', '0')`: it asserts via
    `explain` that the pushed remote SQL renders `[bit_value] = 1` /
    `[bit_value] = 0`, and executes the queries end-to-end (which throw
    `Invalid column name 'TRUE'` on the buggy path).
    
    Note: `branch-4.0` still uses the old `JdbcScanNode` /
    `ExprToSqlVisitor` path, which renders the dialect-agnostic
    `TRUE`/`FALSE` and is what triggers the bug reported in #64464. That
    branch needs a separate code fix; this regression test alone would fail
    there and is not sufficient on its own.
---
 .../jdbc/test_sqlserver_jdbc_catalog.out           | 12 ++++++++++
 .../jdbc/test_sqlserver_jdbc_catalog.groovy        | 28 ++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git 
a/regression-test/data/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.out 
b/regression-test/data/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.out
index 368a7b99390..3069fb1904f 100644
--- 
a/regression-test/data/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.out
+++ 
b/regression-test/data/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.out
@@ -184,6 +184,18 @@ varbinary_value    varbinary(20)   Yes     true    \N
 2      true    0x4D616B6520446F72697320477265617421000000      
0x4D616B6520446F72697320477265617421
 3      true    0x4D616B6520446F72697320477265617421000000      
0x4D616B6520446F72697320477265617421
 
+-- !bit_eq_false --
+1      false
+
+-- !bit_eq_true --
+2      true
+3      true
+
+-- !bit_in --
+1      false
+2      true
+3      true
+
 -- !query_after_insert --
 1      false   0x4D616B6520446F72697320477265617421000000      
0x4D616B6520446F72697320477265617421
 2      true    0x4D616B6520446F72697320477265617421000000      
0x4D616B6520446F72697320477265617421
diff --git 
a/regression-test/suites/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.groovy
 
b/regression-test/suites/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.groovy
index 9d284592cbb..f49ac2af22c 100644
--- 
a/regression-test/suites/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.groovy
+++ 
b/regression-test/suites/external_table_p0/jdbc/test_sqlserver_jdbc_catalog.groovy
@@ -140,6 +140,34 @@ suite("test_sqlserver_jdbc_catalog", "p0,external") {
         order_qt_desc """ desc test_binary;  """
         sql """ CALL EXECUTE_STMT("test_sqlserver_jdbc_catalog_binary", 
"DELETE FROM dbo.test_binary WHERE id = 4") """
         order_qt_query """ select * from test_binary order by id; """
+
+        // Regression test for https://github.com/apache/doris/issues/64464
+        // SQL Server `bit` maps to Doris BOOLEAN, so a predicate like 
`bit_value = '1'`
+        // is folded to a boolean literal during analysis. When the filter is 
pushed down it
+        // must be rendered with integer literals (`= 1` / `= 0` / `IN (1, 
0)`) for SQL Server,
+        // never the `TRUE`/`FALSE` keyword: SQL Server has no boolean literal 
and would
+        // otherwise report "Invalid column name 'TRUE'".
+        explain {
+            sql("select * from test_binary where bit_value = '1'")
+            contains "[bit_value] = 1"
+        }
+        explain {
+            sql("select * from test_binary where bit_value = '0'")
+            contains "[bit_value] = 0"
+        }
+        explain {
+            sql("select * from test_binary where bit_value in ('1', '0')")
+            contains "[bit_value] IN (1, 0)"
+        }
+        // Selective execution checks. At this point test_binary holds id=1 
(bit 0),
+        // id=2 and id=3 (bit 1), so `= '0'` returns only id=1 and `= '1'` 
only id=2,3:
+        // these fail if the pushed-down filter is dropped or applied as a 
no-op. The IN
+        // predicate matches every row (a bit is always 0 or 1), so its 1/0 
rendering is
+        // asserted by the explain above rather than by row selectivity.
+        order_qt_bit_eq_false """ select id, bit_value from test_binary where 
bit_value = '0' order by id; """
+        order_qt_bit_eq_true """ select id, bit_value from test_binary where 
bit_value = '1' order by id; """
+        order_qt_bit_in """ select id, bit_value from test_binary where 
bit_value in ('1', '0') order by id; """
+
         sql """ insert into test_binary values (4, 4, X"ABAB", X"AB") """
         order_qt_query_after_insert """ select * from test_binary order by id; 
"""
         sql """ drop catalog if exists ${catalog_name} """


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to