Support signed numbers as a default value

This commit is contained in:
Simon Binder 2021-12-01 20:49:56 +01:00
parent 6d1a4d3c3c
commit c844c86af4
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 45 additions and 8 deletions

View File

@ -716,9 +716,8 @@ class Parser {
final token = _peek;
Literal? _parseInner() {
if (_matchOne(TokenType.numberLiteral)) {
final number = token as NumericToken;
return NumericLiteral(number.parsedNumber, token);
if (_check(TokenType.numberLiteral)) {
return _numericLiteral();
}
if (_matchOne(TokenType.stringLiteral)) {
return StringLiteral(token as StringLiteralToken);
@ -752,6 +751,12 @@ class Parser {
return literal;
}
NumericLiteral _numericLiteral() {
final number = _consume(TokenType.numberLiteral, 'Expected a number here')
as NumericToken;
return NumericLiteral(number.parsedNumber, number)..setSpan(number, number);
}
Expression _primary() {
final literal = _literalOrNull();
if (literal != null) return literal;
@ -2442,10 +2447,17 @@ class Parser {
return CheckColumn(resolvedName, expr)..setSpan(first, _previous);
}
if (_matchOne(TokenType.$default)) {
Expression? expr = _literalOrNull();
Expression expr;
// when not a literal, expect an expression in parentheses
expr ??= _expressionInParentheses();
if (_match(const [TokenType.plus, TokenType.minus])) {
// Signed number
final operator = _previous;
expr = UnaryExpression(operator, _numericLiteral())
..setSpan(operator, _previous);
} else {
// Literal or an expression in parentheses
expr = _literalOrNull() ?? _expressionInParentheses();
}
return Default(resolvedName, expr)..setSpan(first, _previous);
}

View File

@ -300,4 +300,26 @@ void main() {
),
);
});
test('parses DEFAULT with a negative literal', () {
// regression test for https://github.com/simolus3/moor/discussions/1550
testStatement(
'CREATE TABLE a (b INTEGER NOT NULL DEFAULT -1);',
CreateTableStatement(
tableName: 'a',
columns: [
ColumnDefinition(columnName: 'b', typeName: 'INTEGER', constraints: [
NotNull(null),
Default(
null,
UnaryExpression(
Token(TokenType.minus, fakeSpan('-')),
NumericLiteral(1, NumericToken(fakeSpan('1'))),
),
)
])
],
),
);
});
}

View File

@ -38,8 +38,11 @@ void testMoorFile(String moorFile, MoorFile expected) {
}
void testStatement(String sql, AstNode expected, {bool moorMode = false}) {
final parsed =
SqlEngine(EngineOptions(useMoorExtensions: moorMode)).parse(sql).rootNode;
final result =
SqlEngine(EngineOptions(useMoorExtensions: moorMode)).parse(sql);
expect(result.errors, isEmpty);
final parsed = result.rootNode;
enforceHasSpan(parsed);
enforceEqual(parsed, expected);
}