@@ -451,7 +451,7 @@ func TestParser_TupleIn_ComplexConditions(t *testing.T) {
451451 }
452452}
453453
454- // TestParser_TupleIn_NestedTuples tests deeply nested tuple structures
454+ // TestParser_TupleIn_MixedTypes tests tuple with mixed literal types
455455func TestParser_TupleIn_MixedTypes (t * testing.T ) {
456456 // Tuple with mixed literal types
457457 sql := "SELECT * FROM t WHERE (id, name, active, score) IN ((1, 'john', TRUE, 95.5), (2, 'jane', FALSE, 87.3))"
@@ -478,20 +478,154 @@ func TestParser_TupleIn_MixedTypes(t *testing.T) {
478478 }
479479 defer ast .ReleaseAST (tree )
480480
481- stmt := tree .Statements [0 ].(* ast.SelectStatement )
482- inExpr := stmt .Where .(* ast.InExpression )
481+ stmt , ok := tree .Statements [0 ].(* ast.SelectStatement )
482+ if ! ok {
483+ t .Fatalf ("expected SelectStatement, got %T" , tree .Statements [0 ])
484+ }
485+
486+ inExpr , ok := stmt .Where .(* ast.InExpression )
487+ if ! ok {
488+ t .Fatalf ("expected InExpression, got %T" , stmt .Where )
489+ }
483490
484491 // Verify left tuple has 4 elements
485- leftTuple := inExpr .Expr .(* ast.TupleExpression )
492+ leftTuple , ok := inExpr .Expr .(* ast.TupleExpression )
493+ if ! ok {
494+ t .Fatalf ("expected TupleExpression, got %T" , inExpr .Expr )
495+ }
486496 if len (leftTuple .Expressions ) != 4 {
487497 t .Errorf ("expected 4 elements in left tuple, got %d" , len (leftTuple .Expressions ))
488498 }
489499
490500 // Verify right tuples have 4 elements with mixed types
491501 for i , item := range inExpr .List {
492- tuple := item .(* ast.TupleExpression )
502+ tuple , ok := item .(* ast.TupleExpression )
503+ if ! ok {
504+ t .Errorf ("expected TupleExpression at List[%d], got %T" , i , item )
505+ continue
506+ }
493507 if len (tuple .Expressions ) != 4 {
494508 t .Errorf ("expected 4 elements in List[%d], got %d" , i , len (tuple .Expressions ))
495509 }
496510 }
497511}
512+
513+ // TestParser_TupleIn_ErrorCases tests invalid tuple IN syntax that should fail
514+ func TestParser_TupleIn_ErrorCases (t * testing.T ) {
515+ errorCases := []struct {
516+ name string
517+ sql string
518+ }{
519+ {
520+ name : "Empty IN list" ,
521+ sql : "SELECT * FROM t WHERE (a, b) IN ()" ,
522+ },
523+ {
524+ name : "Empty tuple" ,
525+ sql : "SELECT * FROM t WHERE () IN ((1, 2))" ,
526+ },
527+ {
528+ name : "Malformed tuple - missing value" ,
529+ sql : "SELECT * FROM t WHERE (a, b) IN ((1,))" ,
530+ },
531+ {
532+ name : "Unclosed tuple" ,
533+ sql : "SELECT * FROM t WHERE (a, b) IN ((1, 2)" ,
534+ },
535+ {
536+ name : "Missing IN keyword" ,
537+ sql : "SELECT * FROM t WHERE (a, b) ((1, 2))" ,
538+ },
539+ }
540+
541+ for _ , tc := range errorCases {
542+ t .Run (tc .name , func (t * testing.T ) {
543+ tkz := tokenizer .GetTokenizer ()
544+ defer tokenizer .PutTokenizer (tkz )
545+
546+ tokens , err := tkz .Tokenize ([]byte (tc .sql ))
547+ if err != nil {
548+ // Tokenizer error is acceptable for malformed input
549+ t .Logf ("Tokenizer error (expected): %v" , err )
550+ return
551+ }
552+
553+ parserTokens , err := ConvertTokensForParser (tokens )
554+ if err != nil {
555+ // Token conversion error is acceptable
556+ t .Logf ("Token conversion error (expected): %v" , err )
557+ return
558+ }
559+
560+ parser := NewParser ()
561+ defer parser .Release ()
562+
563+ tree , err := parser .Parse (parserTokens )
564+ if err != nil {
565+ // Parser error is expected for invalid syntax
566+ t .Logf ("Parser error (expected): %v" , err )
567+ return
568+ }
569+ defer ast .ReleaseAST (tree )
570+
571+ // If we get here without error, the test should note this
572+ // Some cases may parse but produce unexpected AST
573+ t .Logf ("Parsed without error - may have different interpretation: %s" , tc .sql )
574+ })
575+ }
576+ }
577+
578+ // TestParser_TupleIn_MismatchedSizes tests tuples with mismatched element counts
579+ // Note: SQL parsers typically don't validate tuple size matching - that's semantic validation
580+ func TestParser_TupleIn_MismatchedSizes (t * testing.T ) {
581+ // These should parse successfully - size validation is semantic, not syntactic
582+ cases := []struct {
583+ name string
584+ sql string
585+ }{
586+ {
587+ name : "2-element tuple vs 1-element values" ,
588+ sql : "SELECT * FROM t WHERE (a, b) IN ((1), (2))" ,
589+ },
590+ {
591+ name : "1-element tuple vs 2-element values" ,
592+ sql : "SELECT * FROM t WHERE (a) IN ((1, 2), (3, 4))" ,
593+ },
594+ {
595+ name : "Mixed sizes in value list" ,
596+ sql : "SELECT * FROM t WHERE (a, b) IN ((1, 2), (3))" ,
597+ },
598+ }
599+
600+ for _ , tc := range cases {
601+ t .Run (tc .name , func (t * testing.T ) {
602+ tkz := tokenizer .GetTokenizer ()
603+ defer tokenizer .PutTokenizer (tkz )
604+
605+ tokens , err := tkz .Tokenize ([]byte (tc .sql ))
606+ if err != nil {
607+ t .Fatalf ("tokenizer error: %v" , err )
608+ }
609+
610+ parserTokens , err := ConvertTokensForParser (tokens )
611+ if err != nil {
612+ t .Fatalf ("token conversion error: %v" , err )
613+ }
614+
615+ parser := NewParser ()
616+ defer parser .Release ()
617+
618+ tree , err := parser .Parse (parserTokens )
619+ if err != nil {
620+ // Some implementations may reject mismatched tuples at parse time
621+ t .Logf ("Parser rejected mismatched sizes: %v" , err )
622+ return
623+ }
624+ defer ast .ReleaseAST (tree )
625+
626+ // Parser accepted the query - this is valid behavior
627+ // Semantic validation would catch size mismatches
628+ t .Logf ("Parser accepted query (semantic validation would catch mismatches): %s" , tc .sql )
629+ })
630+ }
631+ }
0 commit comments