Differentiate between IDENT and EXPR in SQL
Previously it was possible to CREATE/UPDATE/DELETE path expressions as this would satisfy an IDENT in the SQL parser. Now however, there is a difference between an IDENT and an EXPR… IDENT: person | person_main | person123 EXPR: person | person.path | person[0].path As a result, path expressions are only possible when setting data or setting conditional conditions.
This commit is contained in:
parent
79812544e8
commit
e4bef0c4b7
3 changed files with 14 additions and 5 deletions
|
@ -519,7 +519,7 @@ func (p *parser) parseExpr() (exp Expr, err error) {
|
||||||
func (p *parser) parsePart() (exp Expr, err error) {
|
func (p *parser) parsePart() (exp Expr, err error) {
|
||||||
|
|
||||||
toks := []Token{
|
toks := []Token{
|
||||||
MUL, ID, IDENT, THING,
|
MUL, ID, EXPR, IDENT, THING,
|
||||||
NULL, VOID, EMPTY, MISSING,
|
NULL, VOID, EMPTY, MISSING,
|
||||||
TRUE, FALSE, STRING, REGION, NUMBER, DOUBLE,
|
TRUE, FALSE, STRING, REGION, NUMBER, DOUBLE,
|
||||||
NOW, DATE, TIME, DURATION, JSON, ARRAY, PARAM, LPAREN,
|
NOW, DATE, TIME, DURATION, JSON, ARRAY, PARAM, LPAREN,
|
||||||
|
|
|
@ -395,11 +395,14 @@ func (s *scanner) scanIdent(chp ...rune) (tok Token, lit string, val interface{}
|
||||||
for {
|
for {
|
||||||
if ch := s.next(); ch == eof {
|
if ch := s.next(); ch == eof {
|
||||||
break
|
break
|
||||||
} else if !isIdentChar(ch) {
|
} else if isIdentChar(ch) {
|
||||||
|
buf.WriteRune(ch)
|
||||||
|
} else if isExprsChar(ch) {
|
||||||
|
tok = EXPR
|
||||||
|
buf.WriteRune(ch)
|
||||||
|
} else {
|
||||||
s.undo()
|
s.undo()
|
||||||
break
|
break
|
||||||
} else {
|
|
||||||
buf.WriteRune(ch)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +842,7 @@ func isLetter(ch rune) bool {
|
||||||
|
|
||||||
// isIdentChar returns true if the rune is allowed in a IDENT.
|
// isIdentChar returns true if the rune is allowed in a IDENT.
|
||||||
func isIdentChar(ch rune) bool {
|
func isIdentChar(ch rune) bool {
|
||||||
return isLetter(ch) || isNumber(ch) || ch == '.' || ch == '_' || ch == '*' || ch == '[' || ch == ']'
|
return isLetter(ch) || isNumber(ch) || ch == '_'
|
||||||
}
|
}
|
||||||
|
|
||||||
// isThingChar returns true if the rune is allowed in a THING.
|
// isThingChar returns true if the rune is allowed in a THING.
|
||||||
|
@ -847,5 +850,10 @@ func isThingChar(ch rune) bool {
|
||||||
return isLetter(ch) || isNumber(ch) || ch == '_'
|
return isLetter(ch) || isNumber(ch) || ch == '_'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isExprsChar returns true if the rune is allowed in a IDENT.
|
||||||
|
func isExprsChar(ch rune) bool {
|
||||||
|
return isLetter(ch) || isNumber(ch) || ch == '.' || ch == '_' || ch == '*' || ch == '[' || ch == ']'
|
||||||
|
}
|
||||||
|
|
||||||
// eof represents a marker rune for the end of the reader.
|
// eof represents a marker rune for the end of the reader.
|
||||||
var eof = rune(0)
|
var eof = rune(0)
|
||||||
|
|
|
@ -32,6 +32,7 @@ const (
|
||||||
DATE // 1970-01-01
|
DATE // 1970-01-01
|
||||||
TIME // 1970-01-01T00:00:00+00:00
|
TIME // 1970-01-01T00:00:00+00:00
|
||||||
JSON // {"test":true}
|
JSON // {"test":true}
|
||||||
|
EXPR // something[0].value
|
||||||
IDENT // something
|
IDENT // something
|
||||||
THING // @class:id
|
THING // @class:id
|
||||||
STRING // "something"
|
STRING // "something"
|
||||||
|
|
Loading…
Reference in a new issue