sqlparser: Fix parsing binary literals

This commit is contained in:
Simon Binder 2024-04-06 14:48:55 +02:00
parent 039838b2ba
commit 43b7f72bad
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
7 changed files with 32 additions and 2 deletions

View File

@ -4,6 +4,7 @@
generated companion class.
- Add the `TypeConverter.extensionType` factory to create type converters for
extension types.
- Fix invalid SQL syntax being generated for `BLOB` literals on postgres.
## 2.16.0

View File

@ -1,5 +1,6 @@
## 3.35.0-dev
- Fix parsing binary literals.
- Drift extensions: Allow custom class names for `CREATE VIEW` statements.
## 0.34.1

View File

@ -290,7 +290,7 @@ class Scanner {
}
final value = source
.substring(_startOffset + 1, _currentOffset - 1)
.substring(_startOffset + (binary ? 2 : 1), _currentOffset - 1)
.replaceAll("''", "'");
tokens.add(StringLiteralToken(value, _currentSpan, binary: binary));
}

View File

@ -642,7 +642,7 @@ class EqualityEnforcingVisitor implements AstVisitor<void, void> {
@override
void visitStringLiteral(StringLiteral e, void arg) {
final current = _currentAs<StringLiteral>(e);
_assert(current.value == e.value, e);
_assert(current.value == e.value && current.isBinary == e.isBinary, e);
_checkChildren(e);
}

View File

@ -1114,6 +1114,9 @@ class NodeSqlBuilder extends AstVisitor<void, void> {
@override
void visitStringLiteral(StringLiteral e, void arg) {
if (e.isBinary) {
symbol('X', spaceBefore: true);
}
_stringLiteral(e.value);
}

View File

@ -86,6 +86,26 @@ void main() {
);
});
test('binary string literal', () {
final scanner = Scanner("X'1234' x'5678'");
scanner.scanTokens();
expect(scanner.tokens, hasLength(3));
expect(
scanner.tokens[0],
const TypeMatcher<StringLiteralToken>()
.having((token) => token.binary, 'binary', isTrue)
.having((token) => token.value, 'value', '1234'),
);
expect(
scanner.tokens[1],
const TypeMatcher<StringLiteralToken>()
.having((token) => token.binary, 'binary', isTrue)
.having((token) => token.value, 'value', '5678'),
);
expect(scanner.tokens[2].type, TokenType.eof);
});
group('parses numeric literals', () {
void checkLiteral(String lexeme, NumericToken other, num value) {
final scanner = Scanner(lexeme)..scanTokens();

View File

@ -568,6 +568,11 @@ CREATE UNIQUE INDEX my_idx ON t1 (c1, c2, c3) WHERE c1 < c3;
testFormat('SELECT a -> b');
testFormat('SELECT a ->> b');
});
test('blob literal', () {
testFormat(
"select typeof(X'0100000300000000000000000000803F000000000000003F0000803F');");
});
});
test('identifiers', () {