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

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 3e7fef6945b3cc25ea6123a72046c7b41d21a516
Author: Andrus Adamchik <[email protected]>
AuthorDate: Fri Jul 3 10:55:52 2026 -0400

    CAY-2967 SQLTemplate/SQLSelect broken pagination
    
    dealing with case-unaware ResultSetMetadata
---
 .../java/org/apache/cayenne/access/jdbc/RSColumn.java | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/RSColumn.java 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/RSColumn.java
index caefd8933..39b5f679d 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/RSColumn.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/RSColumn.java
@@ -212,7 +212,7 @@ public record RSColumn(
                     } else {
                         String columnRowKey = columnArray[i].dataRowName();
 
-                        // TODO: 'equalsIgnoreCase' check can result in subtle 
bugs in DBs with case-sensitive column
+                        // 'equalsIgnoreCase' check can result in subtle bugs 
in DBs with case-sensitive column
                         //  names (or when quotes are used to force case 
sensitivity). Alternatively, 'equals' may miss
                         //  columns in case-insensitive situations.
                         if (columnRowKey != null && 
columnRowKey.equalsIgnoreCase(rowKey)) {
@@ -277,12 +277,29 @@ public record RSColumn(
             }
 
             RSColumn[] result = null;
+            Map<String, DbAttribute> ciAttributeIndex = null;
             for (int i = 0; i < columnArray.length; i++) {
                 RSColumn column = columnArray[i];
                 if (column.attribute() != null) {
                     continue;
                 }
                 DbAttribute attribute = dbEntity.getAttribute(column.rsName());
+                if (attribute == null) {
+
+                    // Similar to the comment above, we are reverting to the 
case-insensitive attribute lookup
+                    //   if there are no exact matches. This may create subtle 
bugs, but in most common cases, it allows
+                    //   to match ResultSet columns to the existing 
DbAttributes more reliably
+                    // TODO: move CI attribute retrieval to DbEntity with 
checks for CI-induced conflicts
+                    if (ciAttributeIndex == null) {
+                        ciAttributeIndex = new HashMap<>();
+                        for (DbAttribute a : dbEntity.getAttributes()) {
+                            
ciAttributeIndex.putIfAbsent(a.getName().toLowerCase(), a);
+                        }
+                    }
+
+                    attribute = 
ciAttributeIndex.get(column.rsName().toLowerCase());
+                }
+                
                 if (attribute != null) {
                     if (result == null) {
                         result = columnArray.clone();

Reply via email to