{"record":{"id":"4ceca1d40c91570f","repo":"apache/shardingsphere","slug":"underlying-sql-state-s-underlying-error-code-4ceca1","errorCode":null,"errorMessage":"Underlying SQL state: %s, underlying error code: %s.","messagePattern":"Underlying SQL state: (.+?), underlying error code: (.+?)\\.","errorType":"exception","errorClass":"SQLWrapperException","httpStatus":null,"severity":"error","filePath":"database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/extended/bind/protocol/text/impl/PostgreSQLDateValueParser.java","lineNumber":51,"sourceCode":"public final class PostgreSQLDateValueParser implements PostgreSQLTextValueParser<Date> {\n    \n    private static final DateTimeFormatter POSTGRESQL_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(\n            \"yyyy-MM-dd[ ][G][ ][XXXXX][XXX][X]\");\n    \n    @Override\n    public Date parse(final String value) {\n        try {\n            return Date.valueOf(LocalDate.from(POSTGRESQL_DATE_TIME_FORMATTER.parse(value)));\n        } catch (final DateTimeParseException ignored) {\n            return fallbackToPostgreSQLTimestampUtils(value);\n        }\n    }\n    \n    private static Date fallbackToPostgreSQLTimestampUtils(final String value) {\n        try {\n            return new TimestampUtils(false, null).toDate(null, value);\n        } catch (final SQLException ex) {\n            throw new SQLWrapperException(ex);\n        }\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":55,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/extended/bind/protocol/text/impl/PostgreSQLDateValueParser.java#L33-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"Locale-dependent date strings, migrated applications assuming lenient parsing, or client drivers sending dates in non-ISO formats through the extended protocol.","solutions":["Send dates in unambiguous ISO-8601 form (yyyy-MM-dd)","Convert to java.sql.Date on the client and bind as a typed parameter instead of a free-form string","Read the wrapped SQLException state/code to see why TimestampUtils rejected the value","Normalize date strings at the application boundary before binding"],"exampleFix":"// before\nstmt.setString(1, \"12/31/2024\");\n// after\nstmt.setDate(1, java.sql.Date.valueOf(\"2024-12-31\"));","handlingStrategy":"validation","validationCode":"try { java.time.LocalDate.parse(value); } catch (java.time.format.DateTimeParseException e) { /* reject before binding */ }","typeGuard":null,"tryCatchPattern":"catch (SQLWrapperException e) { SQLException cause = (SQLException) e.getCause(); /* inspect cause.getSQLState() / getErrorCode() */ }","preventionTips":["Standardize on ISO-8601 dates at the application boundary","Use setDate with java.sql.Date rather than setString for date columns","Reject locale-specific date strings in input validation"],"tags":["postgresql","bind","date","value-parsing"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}