@@ -1582,6 +1582,13 @@ func (p *Parser) parseBooleanPrimaryExpression() (ast.BooleanExpression, error)
15821582 return nil , err
15831583 }
15841584
1585+ // Check for NOT before IN/LIKE/BETWEEN
1586+ notDefined := false
1587+ if p .curTok .Type == TokenNot {
1588+ notDefined = true
1589+ p .nextToken () // consume NOT
1590+ }
1591+
15851592 // Check for IS NULL / IS NOT NULL
15861593 if p .curTok .Type == TokenIs {
15871594 p .nextToken () // consume IS
@@ -1603,6 +1610,114 @@ func (p *Parser) parseBooleanPrimaryExpression() (ast.BooleanExpression, error)
16031610 }, nil
16041611 }
16051612
1613+ // Check for IN expression
1614+ if p .curTok .Type == TokenIn {
1615+ p .nextToken () // consume IN
1616+
1617+ if p .curTok .Type != TokenLParen {
1618+ return nil , fmt .Errorf ("expected ( after IN, got %s" , p .curTok .Literal )
1619+ }
1620+ p .nextToken () // consume (
1621+
1622+ // Check if it's a subquery or value list
1623+ if p .curTok .Type == TokenSelect {
1624+ subquery , err := p .parseQueryExpression ()
1625+ if err != nil {
1626+ return nil , err
1627+ }
1628+ if p .curTok .Type != TokenRParen {
1629+ return nil , fmt .Errorf ("expected ), got %s" , p .curTok .Literal )
1630+ }
1631+ p .nextToken () // consume )
1632+ return & ast.BooleanInExpression {
1633+ Expression : left ,
1634+ NotDefined : notDefined ,
1635+ Subquery : subquery ,
1636+ }, nil
1637+ }
1638+
1639+ // Parse value list
1640+ var values []ast.ScalarExpression
1641+ for {
1642+ val , err := p .parseScalarExpression ()
1643+ if err != nil {
1644+ return nil , err
1645+ }
1646+ values = append (values , val )
1647+ if p .curTok .Type != TokenComma {
1648+ break
1649+ }
1650+ p .nextToken () // consume ,
1651+ }
1652+ if p .curTok .Type != TokenRParen {
1653+ return nil , fmt .Errorf ("expected ), got %s" , p .curTok .Literal )
1654+ }
1655+ p .nextToken () // consume )
1656+ return & ast.BooleanInExpression {
1657+ Expression : left ,
1658+ NotDefined : notDefined ,
1659+ Values : values ,
1660+ }, nil
1661+ }
1662+
1663+ // Check for LIKE expression
1664+ if p .curTok .Type == TokenLike {
1665+ p .nextToken () // consume LIKE
1666+
1667+ pattern , err := p .parseScalarExpression ()
1668+ if err != nil {
1669+ return nil , err
1670+ }
1671+
1672+ var escapeExpr ast.ScalarExpression
1673+ if p .curTok .Type == TokenEscape {
1674+ p .nextToken () // consume ESCAPE
1675+ escapeExpr , err = p .parseScalarExpression ()
1676+ if err != nil {
1677+ return nil , err
1678+ }
1679+ }
1680+
1681+ return & ast.BooleanLikeExpression {
1682+ FirstExpression : left ,
1683+ SecondExpression : pattern ,
1684+ EscapeExpression : escapeExpr ,
1685+ NotDefined : notDefined ,
1686+ }, nil
1687+ }
1688+
1689+ // Check for BETWEEN expression
1690+ if p .curTok .Type == TokenBetween {
1691+ p .nextToken () // consume BETWEEN
1692+
1693+ low , err := p .parseScalarExpression ()
1694+ if err != nil {
1695+ return nil , err
1696+ }
1697+
1698+ if p .curTok .Type != TokenAnd {
1699+ return nil , fmt .Errorf ("expected AND in BETWEEN, got %s" , p .curTok .Literal )
1700+ }
1701+ p .nextToken () // consume AND
1702+
1703+ high , err := p .parseScalarExpression ()
1704+ if err != nil {
1705+ return nil , err
1706+ }
1707+
1708+ return & ast.BooleanBetweenExpression {
1709+ FirstExpression : left ,
1710+ SecondExpression : low ,
1711+ ThirdExpression : high ,
1712+ NotDefined : notDefined ,
1713+ }, nil
1714+ }
1715+
1716+ // If we saw NOT but didn't get IN/LIKE/BETWEEN, error
1717+ if notDefined {
1718+ return nil , fmt .Errorf ("expected IN, LIKE, or BETWEEN after NOT, got %s" , p .curTok .Literal )
1719+ }
1720+
16061721 // Check for comparison operator
16071722 var compType string
16081723 switch p .curTok .Type {
@@ -4647,6 +4762,55 @@ func booleanExpressionToJSON(expr ast.BooleanExpression) jsonNode {
46474762 node ["Expression" ] = scalarExpressionToJSON (e .Expression )
46484763 }
46494764 return node
4765+ case * ast.BooleanInExpression :
4766+ node := jsonNode {
4767+ "$type" : "BooleanInExpression" ,
4768+ }
4769+ if e .Expression != nil {
4770+ node ["Expression" ] = scalarExpressionToJSON (e .Expression )
4771+ }
4772+ node ["NotDefined" ] = e .NotDefined
4773+ if len (e .Values ) > 0 {
4774+ values := make ([]jsonNode , len (e .Values ))
4775+ for i , v := range e .Values {
4776+ values [i ] = scalarExpressionToJSON (v )
4777+ }
4778+ node ["Values" ] = values
4779+ }
4780+ if e .Subquery != nil {
4781+ node ["Subquery" ] = queryExpressionToJSON (e .Subquery )
4782+ }
4783+ return node
4784+ case * ast.BooleanLikeExpression :
4785+ node := jsonNode {
4786+ "$type" : "BooleanLikeExpression" ,
4787+ }
4788+ if e .FirstExpression != nil {
4789+ node ["FirstExpression" ] = scalarExpressionToJSON (e .FirstExpression )
4790+ }
4791+ if e .SecondExpression != nil {
4792+ node ["SecondExpression" ] = scalarExpressionToJSON (e .SecondExpression )
4793+ }
4794+ if e .EscapeExpression != nil {
4795+ node ["EscapeExpression" ] = scalarExpressionToJSON (e .EscapeExpression )
4796+ }
4797+ node ["NotDefined" ] = e .NotDefined
4798+ return node
4799+ case * ast.BooleanBetweenExpression :
4800+ node := jsonNode {
4801+ "$type" : "BooleanBetweenExpression" ,
4802+ }
4803+ if e .FirstExpression != nil {
4804+ node ["FirstExpression" ] = scalarExpressionToJSON (e .FirstExpression )
4805+ }
4806+ if e .SecondExpression != nil {
4807+ node ["SecondExpression" ] = scalarExpressionToJSON (e .SecondExpression )
4808+ }
4809+ if e .ThirdExpression != nil {
4810+ node ["ThirdExpression" ] = scalarExpressionToJSON (e .ThirdExpression )
4811+ }
4812+ node ["NotDefined" ] = e .NotDefined
4813+ return node
46504814 default :
46514815 return jsonNode {"$type" : "UnknownBooleanExpression" }
46524816 }
0 commit comments