fix: parse text-format array literals according to PostgreSQL array grammar - #4964
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a dedicated ArrayLiteralParser to parse PostgreSQL text-format array literals, replacing the previous implementation in SimpleParser. It also adds support for UUID and INTERVAL array types in ArrayParser along with comprehensive unit tests. The review feedback identifies three key areas for improvement: correcting the dimension validation logic in ArrayLiteralParser to reject [0] (since the default lower bound is 1), adding corresponding test cases for this validation, and treating INTERVAL as string-equivalent in ArrayParser to ensure interval array elements are correctly quoted in alignment with PostgreSQL.
…rammar
Previously, text-format array parameters and COPY FROM rows were parsed using
SimpleParser.readArrayLiteral(), which tokenized elements as SQL string
literals and processed them with Java string unescaping. This caused multiple
data corruption and bind failures:
1. Adjacent quotes inside quoted elements (such as empty string values in JSON:
'{"k":""}') were collapsed as SQL quote-escapes, corrupting element data.
2. Unquoted elements containing SQL comment markers ('--' or '/*') or lexical
tokens (such as apostrophes or dollar quotes) were stripped or caused
parameter binding to fail with SQLState 22023.
3. Elements containing backslashes were subjected to Java unicode unescaping,
causing non-Java escape sequences (like Windows file paths 'C:\users' or
'\uZZZZ') to throw uncaught IllegalArgumentExceptions.
This change introduces ArrayLiteralParser, a dedicated parser implementing
PostgreSQL's text-format array grammar (array_in):
- Preserves adjacent quotes in quoted elements and SQL tokens in unquoted elements.
- Unescapes literal backslash escapes without Java-specific string or unicode processing.
- Conforms to PostgreSQL's ASCII whitespace definition (array_isspace), preserving
Unicode spaces such as CJK ideographic space (\u3000).
- Validates 1-dimensional dimension headers and bounds syntax.
- Adds INTERVAL array parameter binding support in ArrayParser.bind().
- Replaces SimpleParser.readArrayLiteral with a 1-line delegate to ArrayLiteralParser,
removing the obsolete returnRawHexValue overload and helpers.
f8305dd to
4e91116
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a dedicated ArrayLiteralParser class to parse PostgreSQL text-format array literals, replacing the previous implementation in SimpleParser. This new parser supports optional dimension decorations, handles quoted and unquoted elements, preserves adjacent quotes, and correctly manages backslash escapes and comments. Additionally, the PR extends array support to include UUID and INTERVAL types, updating ArrayParser and adding comprehensive unit tests in ArrayLiteralParserTest, ArrayParserTest, and SimpleParserTest. There are no review comments, so I have no feedback to provide.
Previously, text-format array parameters and COPY FROM rows were parsed using SimpleParser.readArrayLiteral(), which tokenized elements as SQL string literals and processed them with Java string unescaping. This caused multiple data corruption and bind failures:
This change introduces ArrayLiteralParser, a dedicated parser implementing PostgreSQL's text-format array grammar (array_in):