don't panic on a MIN that isn't a call

parseOperand was assuming that any reference to MIN in a place
where an operand was expected was a call, which it should be,
but it might not be. parseCallExpression panics if it doesn't
find a parenthesis, because it's never supposed to be called
when we don't know we have one.

The test for this is in with MinMaxColumnConstraints, even though it's
actually a test of MinMaxFunctionCalls, because that's where the other
tests involving the special MIN/MAX tokens live.

We also stop checking whether MIN or MAX might actually be QIDENT.
If you use a quoted identifier, we're over in the QIDENT case,
not the MIN/MAX case. If the token was MIN or MAX, it's always
unquoted.
This commit is contained in:
Seebs 2023-04-03 13:51:50 -05:00 committed by seebs
parent 7031f7b968
commit 2af417d5c2
2 changed files with 9 additions and 2 deletions

View file

@ -2742,8 +2742,12 @@ func (p *Parser) parseOperand() (expr Expr, err error) {
case VARIABLE:
return &Variable{Name: lit, NamePos: pos}, nil
case MIN, MAX:
ident := &Ident{Name: lit, NamePos: pos, Quoted: tok == QIDENT}
return p.parseCall(ident)
pk := p.peek()
if pk == LP {
ident := &Ident{Name: lit, NamePos: pos, Quoted: false}
return p.parseCall(ident)
}
return nil, p.errorExpected(p.pos, pk, "call expression")
case STRING:
return &StringLit{ValuePos: pos, Value: lit}, nil
case FLOAT:

View file

@ -40,6 +40,9 @@ func TestParser_ParseMinMaxColumnConstraints(t *testing.T) {
t.Run("ErrNoKey", func(t *testing.T) {
AssertParseStatementError(t, `CREATE TABLE tbl (col1 INT MIN`, `1:30: expected expression, found 'EOF'`)
})
t.Run("ErrNoCall", func(t *testing.T) {
AssertParseStatementError(t, `SELECT MIN;`, `1:11: expected call expression, found ';'`)
})
t.Run("Simple", func(t *testing.T) {
AssertParseStatement(t, `CREATE TABLE tbl (col1 INT MIN 0)`, &parser.CreateTableStatement{
Create: pos(0),