@@ -436,6 +436,100 @@ func TestIntegration_App_ListIndexes(t *testing.T) {
436436 assert .True (t , foundEmailIdx , "Should find email index" )
437437}
438438
439+ func TestIntegration_App_ListIndexes_SpecialCharacters (t * testing.T ) {
440+ _ , connectionString , cleanup := setupTestContainer (t )
441+ defer cleanup ()
442+
443+ db , err := sql .Open ("postgres" , connectionString )
444+ require .NoError (t , err )
445+ defer db .Close ()
446+
447+ ctx := context .Background ()
448+
449+ // Create test schema
450+ testSchema := "test_special_chars"
451+ _ , err = db .ExecContext (ctx , fmt .Sprintf ("DROP SCHEMA IF EXISTS %s CASCADE" , testSchema ))
452+ require .NoError (t , err )
453+ _ , err = db .ExecContext (ctx , fmt .Sprintf ("CREATE SCHEMA %s" , testSchema ))
454+ require .NoError (t , err )
455+
456+ // Create table with columns containing special characters
457+ _ , err = db .ExecContext (ctx , fmt .Sprintf (`
458+ CREATE TABLE %s.test_table (
459+ id SERIAL PRIMARY KEY,
460+ "Column Name" VARCHAR(255),
461+ "col,with,commas" VARCHAR(255),
462+ "col{value}" VARCHAR(255),
463+ "col}data" VARCHAR(255),
464+ normal_col VARCHAR(255)
465+ )
466+ ` , testSchema ))
467+ require .NoError (t , err )
468+
469+ // Create indexes with special character column names
470+ _ , err = db .ExecContext (ctx , fmt .Sprintf (`
471+ CREATE INDEX idx_quoted_name ON %s.test_table ("Column Name")
472+ ` , testSchema ))
473+ require .NoError (t , err )
474+
475+ _ , err = db .ExecContext (ctx , fmt .Sprintf (`
476+ CREATE INDEX idx_with_commas ON %s.test_table ("col,with,commas", normal_col)
477+ ` , testSchema ))
478+ require .NoError (t , err )
479+
480+ _ , err = db .ExecContext (ctx , fmt .Sprintf (`
481+ CREATE INDEX idx_braces ON %s.test_table ("col{value}", "col}data")
482+ ` , testSchema ))
483+ require .NoError (t , err )
484+
485+ // Test with app
486+ appInstance , err := app .New ()
487+ require .NoError (t , err )
488+ defer appInstance .Disconnect ()
489+
490+ err = appInstance .Connect (connectionString )
491+ require .NoError (t , err )
492+
493+ indexes , err := appInstance .ListIndexes (testSchema , "test_table" )
494+ assert .NoError (t , err )
495+ assert .NotEmpty (t , indexes )
496+
497+ // Verify each index is parsed correctly
498+ indexMap := make (map [string ]* app.IndexInfo )
499+ for _ , idx := range indexes {
500+ indexMap [idx .Name ] = idx
501+ }
502+
503+ // Check idx_quoted_name
504+ if idx , ok := indexMap ["idx_quoted_name" ]; ok {
505+ assert .Len (t , idx .Columns , 1 , "idx_quoted_name should have 1 column" )
506+ assert .Equal (t , "Column Name" , idx .Columns [0 ], "Column name should be 'Column Name'" )
507+ } else {
508+ t .Error ("idx_quoted_name not found" )
509+ }
510+
511+ // Check idx_with_commas - should have 2 columns, not split by commas inside quotes
512+ if idx , ok := indexMap ["idx_with_commas" ]; ok {
513+ assert .Len (t , idx .Columns , 2 , "idx_with_commas should have exactly 2 columns" )
514+ assert .Contains (t , idx .Columns , "col,with,commas" , "Should contain column with commas" )
515+ assert .Contains (t , idx .Columns , "normal_col" , "Should contain normal_col" )
516+ } else {
517+ t .Error ("idx_with_commas not found" )
518+ }
519+
520+ // Check idx_braces
521+ if idx , ok := indexMap ["idx_braces" ]; ok {
522+ assert .Len (t , idx .Columns , 2 , "idx_braces should have 2 columns" )
523+ assert .Contains (t , idx .Columns , "col{value}" , "Should contain 'col{value}'" )
524+ assert .Contains (t , idx .Columns , "col}data" , "Should contain 'col}data'" )
525+ } else {
526+ t .Error ("idx_braces not found" )
527+ }
528+
529+ // Cleanup
530+ _ , _ = db .ExecContext (ctx , fmt .Sprintf ("DROP SCHEMA IF EXISTS %s CASCADE" , testSchema ))
531+ }
532+
439533func TestIntegration_App_ExplainQuery (t * testing.T ) {
440534 _ , connectionString , cleanup := setupTestDatabase (t )
441535 defer cleanup ()
0 commit comments