apache/shardingsphere · error · SQLWrapperException

Underlying SQL state: %s, underlying error code: %s.

Error message

Underlying SQL state: %s, underlying error code: %s.

What it means

PostgreSQLTimestampValueParser.parse tries a strict formatter, then falls back to TimestampUtils.toTimestamp; when both fail, the SQLException is wrapped in SQLWrapperException ('Underlying SQL state / error code' message). It triggers when a text bind parameter for a timestamp column cannot be parsed by either path.

Source

Thrown at database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/extended/bind/protocol/text/impl/PostgreSQLTimestampValueParser.java:56

                    + "[HH:mm:ss][HHmmss][HH:mm][HHmm]"
                    + "[.SSSSSSSSS][.SSSSSSSS][.SSSSSSS][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]"
                    + "[ ]"
                    + "[XXXXX][XXXX][XXX][XX][X]");
    
    @Override
    public Timestamp parse(final String value) {
        try {
            return Timestamp.valueOf(LocalDateTime.from(POSTGRESQL_DATE_TIME_FORMATTER.parse(value)));
        } catch (final DateTimeParseException ignored) {
            return fallbackToPostgreSQLTimestampUtils(value);
        }
    }
    
    private static Timestamp fallbackToPostgreSQLTimestampUtils(final String value) {
        try {
            return new TimestampUtils(false, null).toTimestamp(null, value);
        } catch (final SQLException ex) {
            throw new SQLWrapperException(ex);
        }
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Send timestamps in ISO-8601 form (yyyy-MM-dd HH:mm:ss[.fff])
  2. Bind java.sql.Timestamp / LocalDateTime typed parameters instead of raw strings
  3. Check the wrapped SQLException state/code for the exact rejection reason
  4. Pre-validate with Timestamp.valueOf or LocalDateTime.parse on the client

Example fix

// before
stmt.setString(1, "31-12-2024 23:59");
// after
stmt.setTimestamp(1, java.sql.Timestamp.valueOf("2024-12-31 23:59:00"));
Defensive patterns

Strategy: validation

Validate before calling

try { java.time.LocalDateTime.parse(value.replace(' ', 'T')); return true; } catch (java.time.format.DateTimeParseException e) { return false; }

Try / catch

catch (SQLWrapperException e) { SQLException c = (SQLException) e.getCause(); /* classify via c.getSQLState() */ }

Prevention

When it happens

Trigger: Binding values like 'yesterday', '2024-13-45 99:00:00', 'DD-MM-YYYY HH:mm' style locale strings, or BCE/infinity spellings the default TimestampUtils(false, null) configuration rejects.

Common situations: Locale-dependent timestamp strings, applications assuming lenient parsing, or special PostgreSQL values ('infinity', 'now') that a non-calendar TimestampUtils without interval support refuses.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/b8cc79d48c8803eb. Report an issue: GitHub.