@@ -927,6 +927,34 @@ func (c *cc) convertParam(n *parser.Expr_bindContext) ast.Node {
927
927
}
928
928
929
929
func (c * cc ) convertInSelectNode (n * parser.Expr_in_selectContext ) ast.Node {
930
+ // Check if this is an EXISTS or NOT EXISTS expression
931
+ if n .EXISTS_ () != nil {
932
+ sublink := & ast.SubLink {
933
+ SubLinkType : ast .EXISTS_SUBLINK ,
934
+ Subselect : c .convert (n .Select_stmt ()),
935
+ Location : n .GetStart ().GetStart (),
936
+ }
937
+
938
+ notExists := n .NOT_ () != nil
939
+ if ! notExists && n .GetStart () != nil {
940
+ notExists = n .GetStart ().GetTokenType () == parser .SQLiteParserNOT_
941
+ }
942
+
943
+ // If NOT EXISTS, wrap in a BoolExpr with NOT
944
+ if notExists {
945
+ return & ast.BoolExpr {
946
+ Boolop : ast .BoolExprTypeNot ,
947
+ Args : & ast.List {
948
+ Items : []ast.Node {sublink },
949
+ },
950
+ Location : n .GetStart ().GetStart (),
951
+ }
952
+ }
953
+
954
+ return sublink
955
+ }
956
+
957
+ // Handle other IN expressions (original behavior)
930
958
return c .convert (n .Select_stmt ())
931
959
}
932
960
@@ -1247,27 +1275,34 @@ func (c *cc) convertCase(n *parser.Expr_caseContext) ast.Node {
1247
1275
}
1248
1276
1249
1277
func (c * cc ) convertUnaryExpr (n * parser.Expr_unaryContext ) ast.Node {
1250
- // Handle unary expressions like NOT NULL
1251
- children := n .GetChildren ()
1252
- if len (children ) >= 2 {
1253
- for i , child := range children {
1254
- if term , ok := child .(antlr.TerminalNode ); ok {
1255
- if term .GetSymbol ().GetTokenType () == parser .SQLiteParserNOT_ {
1256
- if i + 1 < len (children ) {
1257
- if nextTerm , ok := children [i + 1 ].(antlr.TerminalNode ); ok {
1258
- if nextTerm .GetSymbol ().GetTokenType () == parser .SQLiteParserNULL_ {
1259
- return & ast.A_Const {Val : & ast.Null {}}
1260
- }
1261
- }
1262
- }
1278
+ if unary := n .Unary_operator (); unary != nil && unary .NOT_ () != nil {
1279
+ innerExpr := n .Expr ()
1280
+ if innerExpr != nil {
1281
+ if strings .EqualFold (innerExpr .GetText (), "NULL" ) {
1282
+ return & ast.A_Const {Val : & ast.Null {}}
1283
+ }
1284
+ if existsCtx , ok := innerExpr .(* parser.Expr_in_selectContext ); ok {
1285
+ inner := c .convertInSelectNode (existsCtx )
1286
+ if boolNode , ok := inner .(* ast.BoolExpr ); ok {
1287
+ return boolNode
1288
+ }
1289
+ return & ast.BoolExpr {
1290
+ Boolop : ast .BoolExprTypeNot ,
1291
+ Args : & ast.List {Items : []ast.Node {inner }},
1292
+ Location : n .GetStart ().GetStart (),
1263
1293
}
1264
1294
}
1295
+ inner := c .convert (innerExpr )
1296
+ return & ast.BoolExpr {
1297
+ Boolop : ast .BoolExprTypeNot ,
1298
+ Args : & ast.List {Items : []ast.Node {inner }},
1299
+ Location : n .GetStart ().GetStart (),
1300
+ }
1265
1301
}
1266
1302
}
1267
1303
1268
- // For other unary expressions, try to convert the inner expression
1269
- if n .Expr () != nil {
1270
- return c .convert (n .Expr ())
1304
+ if expr := n .Expr (); expr != nil {
1305
+ return c .convert (expr )
1271
1306
}
1272
1307
1273
1308
return todo ("convertUnaryExpr" , n )
0 commit comments