Skip to content

Mistakenly assumes Long value as INT4 on update #67605

@jorgeacetozi

Description

@jorgeacetozi

Describe the problem

After updating CockroachDB from version 20.2.10 to 21.1.5, we started getting this exception when issuing an update:

Unexpected Exception during request processing - return 500 Internal Server Error org.jdbi.v3.core.statement.UnableToExecuteStatementException: org.postgresql.util.PSQLException: ERROR: integer out of range for type int4

After some debugging, we were able to figured out that the issue happens when:

  1. Insert a row with a null value for a column where the type is INT8 in the table, but set as a INT4 (JDBI defaults to INT4 when a null value is provided);
  2. Issue an update to this row, also with a null value;
  3. Issue another update to the same row, but now with a Long value;

To Reproduce

We set up a simple unit test that spins up a CockroachDB container (version 21.1.5) and uses Postgres JDBC Driver (version 42.2.23) to reproduce the steps described:

    @Test
    @DisplayName("cockroachdb should respect column type")
    public void testCockroachWrongType() throws IOException, InterruptedException, SQLException {
        Long expected = 1626256150696L;

        try(CockroachContainer cockroachContainer = new CockroachContainer(
                "dbName",
                "cockroachdb/cockroach:v21.1.5")){
            cockroachContainer.start();

            cockroachContainer.executeSql("CREATE TABLE dbName.someNumber (theNumber INT, someId INT NOT NULL);");

            Connection con = getConnection(cockroachContainer.getUsername(), cockroachContainer.getPassword(), cockroachContainer.getJdbcUrl());
            con.setAutoCommit(true);

            int integerType = Types.INTEGER; // some libraries defaults to int when value being passed is null, i.e.: jdbi

            try (PreparedStatement firstInsert = con.prepareStatement("INSERT INTO dbName.someNumber (theNumber, someId) VALUES(?, ?);")) {
                firstInsert.setNull(1, integerType);
                firstInsert.setLong(2, 1);
                firstInsert.execute();
            }

            try (PreparedStatement firstUpdate = con.prepareStatement("UPDATE dbName.someNumber SET theNumber = ? WHERE someId = ?;")) {
                firstUpdate.setNull(1, integerType);
                firstUpdate.setLong(2, 1);
                firstUpdate.execute();
            }

            try (PreparedStatement secondUpdate = con.prepareStatement("UPDATE dbName.someNumber SET theNumber = ? WHERE someId = ?;")) {
                secondUpdate.setLong(1, expected);
                secondUpdate.setLong(2, 1);
                secondUpdate.execute(); // org.postgresql.util.PSQLException: ERROR: integer out of range for type int4
            }

            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT theNumber FROM dbName.someNumber WHERE someId = 1;");
            rs.next();
            long actual = rs.getLong("theNumber");

            assertEquals(expected, actual);
        }
    }

If the CockroachDB container version in this test is set to 20.2.10, then the test work as expected and the issue does not happen.

Expected behavior
The expectation is that the last update works properly since the value being sent is a Long and the column type is a INT8.

Environment:

  • CockroachDB version: 21.1.5
  • Server OS: Linux 4.15.0-1021-aws
  • Client app: JDBI -> Postgres JDBC

Additional context
Unexpected behavior in update queries.

Metadata

Metadata

Assignees

Labels

A-sql-vecSQL vectorized engineC-bugCode not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior.O-communityOriginated from the communityT-sql-queriesSQL Queries Team

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions