pgjdbc/pgjdbc GitHub issues and pull requests (mirror)  
help / color / mirror / Atom feed
[pgjdbc/pgjdbc] issue #3567: Surprising behaviour with jagged arrays
5+ messages / 3 participants
[nested] [flat]

* [pgjdbc/pgjdbc] issue #3567: Surprising behaviour with jagged arrays
@ 2025-03-17 11:15  "jerrinot (@jerrinot)" <[email protected]>
  0 siblings, 0 replies; 5+ messages in thread

From: jerrinot (@jerrinot) @ 2025-03-17 11:15 UTC (permalink / raw)
  To: pgjdbc/pgjdbc <[email protected]>

**Describe the issue**
It appears codecs for 2D primitive arrays implicitly assume rectangular arrays. This leads to surprising behaviour when jagged arrays are used. In some cases, there are hard-to-interpret errors. In other instances, arrays are silently transformed into a regular shape. 

**Driver Version?** 
42.7.5

**Java Version?**
JDK 23

**OS Version?**
Linux

**PostgreSQL Version?**
16.4

**To Reproduce**
TestContainers reproducer:
```java
package info.jerrinot.sanbox.pgjdbc;

import org.junit.Test;

import java.sql.*;

public class JaggedArraysTest {

    private static final String JDBC_URL = "jdbc:tc:postgresql:16.4:///postgres";

    @Test
    public void testJaggedArrayBadMessage() throws SQLException {
        // this creates a bad binding message, server can detect it and throw an error
        // still, the error is not very informative and hard to tell what's wrong:
        // ERROR: insufficient data left in message
        //  Where: unnamed portal parameter $1

        try (Connection conn = DriverManager.getConnection(JDBC_URL);
             PreparedStatement stmt = conn.prepareStatement("select ? ")) {
            stmt.setArray(1, conn.createArrayOf("int8", new long[][]{{1L, 2L}, {3L}, {4L}}));
            try (ResultSet rs = stmt.executeQuery()) {

            }
        }
    }

    @Test
    public void testJaggedArraysMetamorphosis() throws SQLException {
        // changes shape of the array, creates a rectangular array from a jagged array
        // there is no error, no warning. with binary encoding the server has no way
        // to tell anything is wrong.

        try (Connection conn = DriverManager.getConnection(JDBC_URL);
             PreparedStatement stmt = conn.prepareStatement("select ? ")) {
            stmt.setArray(1, conn.createArrayOf("int8", new long[][]{
                    {1L, 2L},
                    {3L},
                    {4L, 5L, 6L}
            }));
            try (ResultSet rs = stmt.executeQuery()) {
                assert rs.next();

                Array array = rs.getArray(1);
                Long[][] items = (Long[][]) array.getArray();
                printArray(items);
            }
        }
    }

    private static void printArray(Long[][] items) {
        for (Long[] row : items) {
            for (Long item : row) {
                System.out.print(item + " ");
            }
            System.out.println();
        }
    }
}
```

deps:
```xml
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <version>1.20.6</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.5</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.5.11</version>
        </dependency>
```

logback.xml
```
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
```

**Expected behaviour**
I'd expect client to validate the array is not jagged. 

^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: [pgjdbc/pgjdbc] issue #3567: Surprising behaviour with jagged arrays
@ 2025-03-17 11:16  "davecramer (@davecramer)" <[email protected]>
  3 siblings, 0 replies; 5+ messages in thread

From: davecramer (@davecramer) @ 2025-03-17 11:16 UTC (permalink / raw)
  To: pgjdbc/pgjdbc <[email protected]>

Cool!. Does PostgreSQL support jagged arrays ?


^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: [pgjdbc/pgjdbc] issue #3567: Surprising behaviour with jagged arrays
@ 2025-03-17 12:05  "jerrinot (@jerrinot)" <[email protected]>
  3 siblings, 0 replies; 5+ messages in thread

From: jerrinot (@jerrinot) @ 2025-03-17 12:05 UTC (permalink / raw)
  To: pgjdbc/pgjdbc <[email protected]>

@davecramer wow, you are fast! 🙇 

PostgreSQL does not support jagged arrays. I guess the codec could validate that the array shape is rectangular. `ArrayEncoding` already [iterates over all rows](https://github.com/pgjdbc/pgjdbc/blob/d86d7ce19030230f14e573b8095f04721d1d8e35/pgjdbc/src/main/java/...) anyway so it could validate the size of each row is the same. I can send a PR draft if that helps. 

^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: [pgjdbc/pgjdbc] issue #3567: Surprising behaviour with jagged arrays
@ 2025-03-17 12:10  "davecramer (@davecramer)" <[email protected]>
  3 siblings, 0 replies; 5+ messages in thread

From: davecramer (@davecramer) @ 2025-03-17 12:10 UTC (permalink / raw)
  To: pgjdbc/pgjdbc <[email protected]>

> [@davecramer](https://github.com/davecramer) wow, you are fast! 🙇
> 
Depends on the day :)

> PostgreSQL does not support jagged arrays. I guess the codec could validate that the array shape is rectangular. `ArrayEncoding` already [iterates over all rows](https://github.com/pgjdbc/pgjdbc/blob/d86d7ce19030230f14e573b8095f04721d1d8e35/pgjdbc/src/main/java/...) anyway so it could validate the size of each row is the same. I can send a PR draft if that helps.
Please do


^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: [pgjdbc/pgjdbc] issue #3567: Surprising behaviour with jagged arrays
@ 2025-05-17 08:51  "awadhesh14 (@awadhesh14)" <[email protected]>
  3 siblings, 0 replies; 5+ messages in thread

From: awadhesh14 (@awadhesh14) @ 2025-05-17 08:51 UTC (permalink / raw)
  To: pgjdbc/pgjdbc <[email protected]>

@davecramer @jerrinot 

https://github.com/pgjdbc/pgjdbc/pull/3633 fixes the silent corruption and bad formatted message.

The changes:

- Validate array rectangularity during encoding
- Throw clear errors with indices (e.g., Jagged array at [1][0])
- Preserve NULL/empty array behavior
- Include tests

Please review when convenient. 

^ permalink  raw  reply  [nested|flat] 5+ messages in thread


end of thread, other threads:[~2025-05-17 08:51 UTC | newest]

Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2025-03-17 11:15 [pgjdbc/pgjdbc] issue #3567: Surprising behaviour with jagged arrays "jerrinot (@jerrinot)" <[email protected]>
2025-03-17 11:16 ` "davecramer (@davecramer)" <[email protected]>
2025-03-17 12:05 ` "jerrinot (@jerrinot)" <[email protected]>
2025-03-17 12:10 ` "davecramer (@davecramer)" <[email protected]>
2025-05-17 08:51 ` "awadhesh14 (@awadhesh14)" <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox