splitter_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package sqlutil
  2. import (
  3. "reflect"
  4. "testing"
  5. )
  6. func TestSplitStatements(t *testing.T) {
  7. tests := []struct {
  8. name string
  9. input string
  10. expected []string
  11. }{
  12. {
  13. name: "Simple single statement",
  14. input: "SELECT * FROM users",
  15. expected: []string{"SELECT * FROM users"},
  16. },
  17. {
  18. name: "Multiple statements",
  19. input: "SELECT * FROM users; SELECT * FROM orders;",
  20. expected: []string{"SELECT * FROM users", "SELECT * FROM orders"},
  21. },
  22. {
  23. name: "Semicolon in single quotes",
  24. input: "SELECT 'hello;world' FROM users; SELECT * FROM orders;",
  25. expected: []string{"SELECT 'hello;world' FROM users", "SELECT * FROM orders"},
  26. },
  27. {
  28. name: "Semicolon in double quotes",
  29. input: `SELECT "column;name" FROM users; SELECT * FROM orders;`,
  30. expected: []string{`SELECT "column;name" FROM users`, "SELECT * FROM orders"},
  31. },
  32. {
  33. name: "Escaped quotes in strings",
  34. input: `SELECT 'don''t split; here' FROM users; SELECT * FROM orders;`,
  35. expected: []string{`SELECT 'don''t split; here' FROM users`, "SELECT * FROM orders"},
  36. },
  37. {
  38. name: "Escaped quotes in identifiers",
  39. input: `SELECT "column""name" FROM users; SELECT * FROM orders;`,
  40. expected: []string{`SELECT "column""name" FROM users`, "SELECT * FROM orders"},
  41. },
  42. {
  43. name: "Single line comment",
  44. input: "SELECT * FROM users; -- This is a comment\nSELECT * FROM orders;",
  45. expected: []string{"SELECT * FROM users", "SELECT * FROM orders"},
  46. },
  47. {
  48. name: "Single line comment with semicolon",
  49. input: "SELECT * FROM users; -- Comment with; semicolon\nSELECT * FROM orders;",
  50. expected: []string{"SELECT * FROM users", "SELECT * FROM orders"},
  51. },
  52. {
  53. name: "Multi-line comment",
  54. input: "SELECT * FROM users; /* Multi-line\ncomment */ SELECT * FROM orders;",
  55. expected: []string{"SELECT * FROM users", "SELECT * FROM orders"},
  56. },
  57. {
  58. name: "Multi-line comment with semicolon",
  59. input: "SELECT * FROM users; /* Comment with; semicolon */ SELECT * FROM orders;",
  60. expected: []string{"SELECT * FROM users", "SELECT * FROM orders"},
  61. },
  62. {
  63. name: "Complex mixed case",
  64. input: `SELECT 'test;string', "quoted;id" FROM users; -- Comment; here
  65. /* Another; comment */
  66. INSERT INTO users VALUES ('name''s value', "id""field");`,
  67. expected: []string{
  68. `SELECT 'test;string', "quoted;id" FROM users`,
  69. `INSERT INTO users VALUES ('name''s value', "id""field")`,
  70. },
  71. },
  72. {
  73. name: "Empty statements filtered",
  74. input: "SELECT * FROM users;;; SELECT * FROM orders;",
  75. expected: []string{"SELECT * FROM users", "SELECT * FROM orders"},
  76. },
  77. {
  78. name: "Whitespace handling",
  79. input: " SELECT * FROM users ; SELECT * FROM orders ; ",
  80. expected: []string{"SELECT * FROM users", "SELECT * FROM orders"},
  81. },
  82. {
  83. name: "Single statement without semicolon",
  84. input: "SELECT * FROM users",
  85. expected: []string{"SELECT * FROM users"},
  86. },
  87. {
  88. name: "Empty query",
  89. input: "",
  90. expected: []string{},
  91. },
  92. {
  93. name: "Only whitespace",
  94. input: " \n\t ",
  95. expected: []string{},
  96. },
  97. }
  98. for _, tt := range tests {
  99. t.Run(tt.name, func(t *testing.T) {
  100. result := SplitStatements(tt.input)
  101. if !reflect.DeepEqual(result, tt.expected) {
  102. t.Errorf("SplitStatements() = %v, expected %v", result, tt.expected)
  103. }
  104. })
  105. }
  106. }
  107. func TestSplitStatements_EdgeCases(t *testing.T) {
  108. tests := []struct {
  109. name string
  110. input string
  111. expected []string
  112. }{
  113. {
  114. name: "Nested comments are not supported but handled gracefully",
  115. input: "SELECT * FROM users; /* Outer /* inner */ comment */ SELECT * FROM orders;",
  116. expected: []string{"SELECT * FROM users", "comment */ SELECT * FROM orders"},
  117. },
  118. {
  119. name: "Unterminated string (malformed SQL)",
  120. input: "SELECT 'unterminated string; SELECT * FROM orders;",
  121. expected: []string{"SELECT 'unterminated string; SELECT * FROM orders;"},
  122. },
  123. {
  124. name: "Unterminated comment (malformed SQL)",
  125. input: "SELECT * FROM users; /* unterminated comment",
  126. expected: []string{"SELECT * FROM users"},
  127. },
  128. {
  129. name: "Multiple semicolons in quotes",
  130. input: "SELECT ';;;' FROM users; SELECT ';;;' FROM orders;",
  131. expected: []string{"SELECT ';;;' FROM users", "SELECT ';;;' FROM orders"},
  132. },
  133. }
  134. for _, tt := range tests {
  135. t.Run(tt.name, func(t *testing.T) {
  136. result := SplitStatements(tt.input)
  137. if !reflect.DeepEqual(result, tt.expected) {
  138. t.Errorf("SplitStatements() = %v, expected %v", result, tt.expected)
  139. }
  140. })
  141. }
  142. }