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

PostgreSQLDateValueParser.parse first tries a strict formatter, then falls back to TimestampUtils.toDate; if that also throws SQLException, it is wrapped in SQLWrapperException with the 'Underlying SQL state / error code' message. It fires when a text-format bind parameter for a date column cannot be parsed by either the built-in pattern or the PostgreSQL timestamp utilities.

Source

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

public final class PostgreSQLDateValueParser implements PostgreSQLTextValueParser<Date> {
    
    private static final DateTimeFormatter POSTGRESQL_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(
            "yyyy-MM-dd[ ][G][ ][XXXXX][XXX][X]");
    
    @Override
    public Date parse(final String value) {
        try {
            return Date.valueOf(LocalDate.from(POSTGRESQL_DATE_TIME_FORMATTER.parse(value)));
        } catch (final DateTimeParseException ignored) {
            return fallbackToPostgreSQLTimestampUtils(value);
        }
    }
    
    private static Date fallbackToPostgreSQLTimestampUtils(final String value) {
        try {
            return new TimestampUtils(false, null).toDate(null, value);
        } catch (final SQLException ex) {
            throw new SQLWrapperException(ex);
        }
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Send dates in unambiguous ISO-8601 form (yyyy-MM-dd)
  2. Convert to java.sql.Date on the client and bind as a typed parameter instead of a free-form string
  3. Read the wrapped SQLException state/code to see why TimestampUtils rejected the value
  4. Normalize date strings at the application boundary before binding

Example fix

// before
stmt.setString(1, "12/31/2024");
// after
stmt.setDate(1, java.sql.Date.valueOf("2024-12-31"));
Defensive patterns

Strategy: validation

Validate before calling

try { java.time.LocalDate.parse(value); } catch (java.time.format.DateTimeParseException e) { /* reject before binding */ }

Try / catch

catch (SQLWrapperException e) { SQLException cause = (SQLException) e.getCause(); /* inspect cause.getSQLState() / getErrorCode() */ }

Prevention

When it happens

Trigger: Binding a text parameter to a date column with a value like 'not-a-date', an unsupported locale/format (e.g. '31/12/2024' when day-first is not configured), or an empty string, so both POSTGRESQL_DATE_TIME_FORMATTER and new TimestampUtils(false, null).toDate(null, value) fail.

Common situations: Locale-dependent date strings, migrated applications assuming lenient parsing, or client drivers sending dates in non-ISO formats through the extended protocol.

Related errors


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