parser_test.go 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805
  1. package parser
  2. import (
  3. "testing"
  4. "github.com/danfragoso/pizzasql-next/pkg/lexer"
  5. )
  6. func parse(t *testing.T, input string) Statement {
  7. t.Helper()
  8. l := lexer.New(input)
  9. p := New(l)
  10. stmt, err := p.Parse()
  11. if err != nil {
  12. t.Fatalf("parse error: %v", err)
  13. }
  14. return stmt
  15. }
  16. func parseExpr(t *testing.T, input string) Expr {
  17. t.Helper()
  18. // Wrap in SELECT to parse as expression
  19. l := lexer.New("SELECT " + input)
  20. p := New(l)
  21. stmt, err := p.Parse()
  22. if err != nil {
  23. t.Fatalf("parse error: %v", err)
  24. }
  25. sel := stmt.(*SelectStmt)
  26. return sel.Columns[0].Expr
  27. }
  28. // SELECT statement tests
  29. func TestParseSelectStar(t *testing.T) {
  30. stmt := parse(t, "SELECT * FROM users")
  31. sel, ok := stmt.(*SelectStmt)
  32. if !ok {
  33. t.Fatalf("expected SelectStmt, got %T", stmt)
  34. }
  35. if len(sel.Columns) != 1 || !sel.Columns[0].Star {
  36. t.Error("expected SELECT *")
  37. }
  38. if len(sel.From) != 1 || sel.From[0].Name != "users" {
  39. t.Error("expected FROM users")
  40. }
  41. }
  42. func TestParseSelectColumns(t *testing.T) {
  43. stmt := parse(t, "SELECT id, name, email FROM users")
  44. sel := stmt.(*SelectStmt)
  45. if len(sel.Columns) != 3 {
  46. t.Fatalf("expected 3 columns, got %d", len(sel.Columns))
  47. }
  48. cols := []string{"id", "name", "email"}
  49. for i, col := range sel.Columns {
  50. ref, ok := col.Expr.(*ColumnRef)
  51. if !ok {
  52. t.Errorf("column %d: expected ColumnRef", i)
  53. continue
  54. }
  55. if ref.Column != cols[i] {
  56. t.Errorf("column %d: expected %s, got %s", i, cols[i], ref.Column)
  57. }
  58. }
  59. }
  60. func TestParseSelectQualifiedWildcard(t *testing.T) {
  61. stmt := parse(t, "SELECT DISTINCT repo.* FROM repository AS repo LEFT JOIN access ON access.repo_id = repo.id")
  62. sel := stmt.(*SelectStmt)
  63. if !sel.Distinct {
  64. t.Error("expected DISTINCT")
  65. }
  66. if len(sel.Columns) != 1 {
  67. t.Fatalf("expected 1 column, got %d", len(sel.Columns))
  68. }
  69. col := sel.Columns[0]
  70. if col.TableStar != "repo" {
  71. t.Errorf("expected TableStar=repo, got %q", col.TableStar)
  72. }
  73. if col.Star || col.Expr != nil || col.Alias != "" {
  74. t.Errorf("qualified wildcard should not set Star/Expr/Alias: %+v", col)
  75. }
  76. }
  77. func TestParseSelectQualifiedWildcardMixed(t *testing.T) {
  78. stmt := parse(t, "SELECT repo.*, access.mode FROM repository AS repo LEFT JOIN access ON access.repo_id = repo.id")
  79. sel := stmt.(*SelectStmt)
  80. if len(sel.Columns) != 2 {
  81. t.Fatalf("expected 2 columns, got %d", len(sel.Columns))
  82. }
  83. if sel.Columns[0].TableStar != "repo" {
  84. t.Errorf("column 0 TableStar = %q, want repo", sel.Columns[0].TableStar)
  85. }
  86. ref, ok := sel.Columns[1].Expr.(*ColumnRef)
  87. if !ok || ref.Table != "access" || ref.Column != "mode" {
  88. t.Errorf("column 1 = %+v, want access.mode ColumnRef", sel.Columns[1].Expr)
  89. }
  90. }
  91. func TestParseSelectCountStarStillWorks(t *testing.T) {
  92. stmt := parse(t, "SELECT COUNT(*) FROM users")
  93. sel := stmt.(*SelectStmt)
  94. if len(sel.Columns) != 1 {
  95. t.Fatalf("expected 1 column, got %d", len(sel.Columns))
  96. }
  97. col := sel.Columns[0]
  98. if col.TableStar != "" || col.Star {
  99. t.Errorf("COUNT(*) should not be a wildcard: %+v", col)
  100. }
  101. fn, ok := col.Expr.(*FunctionCall)
  102. if !ok || !fn.Star || fn.Name != "COUNT" {
  103. t.Errorf("expected COUNT(*) FunctionCall, got %+v", col.Expr)
  104. }
  105. }
  106. func TestParseSelectWithAlias(t *testing.T) {
  107. stmt := parse(t, "SELECT id AS user_id, name AS full_name FROM users u")
  108. sel := stmt.(*SelectStmt)
  109. if sel.Columns[0].Alias != "user_id" {
  110. t.Errorf("expected alias user_id, got %s", sel.Columns[0].Alias)
  111. }
  112. if sel.Columns[1].Alias != "full_name" {
  113. t.Errorf("expected alias full_name, got %s", sel.Columns[1].Alias)
  114. }
  115. if sel.From[0].Alias != "u" {
  116. t.Errorf("expected table alias u, got %s", sel.From[0].Alias)
  117. }
  118. }
  119. func TestParseSelectDistinct(t *testing.T) {
  120. stmt := parse(t, "SELECT DISTINCT name FROM users")
  121. sel := stmt.(*SelectStmt)
  122. if !sel.Distinct {
  123. t.Error("expected DISTINCT")
  124. }
  125. }
  126. func TestParseSelectWhere(t *testing.T) {
  127. stmt := parse(t, "SELECT * FROM users WHERE id = 1")
  128. sel := stmt.(*SelectStmt)
  129. if sel.Where == nil {
  130. t.Fatal("expected WHERE clause")
  131. }
  132. binary, ok := sel.Where.(*BinaryExpr)
  133. if !ok {
  134. t.Fatalf("expected BinaryExpr, got %T", sel.Where)
  135. }
  136. if binary.Op != lexer.TokenEq {
  137. t.Errorf("expected =, got %v", binary.Op)
  138. }
  139. }
  140. func TestParseSelectWhereComplex(t *testing.T) {
  141. stmt := parse(t, "SELECT * FROM users WHERE id = 1 AND name = 'John' OR active = TRUE")
  142. sel := stmt.(*SelectStmt)
  143. if sel.Where == nil {
  144. t.Fatal("expected WHERE clause")
  145. }
  146. // Should be: (id = 1 AND name = 'John') OR active = TRUE
  147. or, ok := sel.Where.(*BinaryExpr)
  148. if !ok || or.Op != lexer.TokenOR {
  149. t.Fatal("expected OR at top level")
  150. }
  151. }
  152. func TestParseSelectOrderBy(t *testing.T) {
  153. stmt := parse(t, "SELECT * FROM users ORDER BY name ASC, id DESC")
  154. sel := stmt.(*SelectStmt)
  155. if len(sel.OrderBy) != 2 {
  156. t.Fatalf("expected 2 ORDER BY items, got %d", len(sel.OrderBy))
  157. }
  158. if sel.OrderBy[0].Desc {
  159. t.Error("first item should be ASC")
  160. }
  161. if !sel.OrderBy[1].Desc {
  162. t.Error("second item should be DESC")
  163. }
  164. }
  165. func TestParseSelectLimitOffset(t *testing.T) {
  166. stmt := parse(t, "SELECT * FROM users LIMIT 10 OFFSET 20")
  167. sel := stmt.(*SelectStmt)
  168. if sel.Limit == nil {
  169. t.Error("expected LIMIT")
  170. }
  171. if sel.Offset == nil {
  172. t.Error("expected OFFSET")
  173. }
  174. limit := sel.Limit.(*LiteralExpr)
  175. if limit.Value != "10" {
  176. t.Errorf("expected LIMIT 10, got %s", limit.Value)
  177. }
  178. offset := sel.Offset.(*LiteralExpr)
  179. if offset.Value != "20" {
  180. t.Errorf("expected OFFSET 20, got %s", offset.Value)
  181. }
  182. }
  183. func TestParseSelectGroupBy(t *testing.T) {
  184. stmt := parse(t, "SELECT name, COUNT(*) FROM users GROUP BY name")
  185. sel := stmt.(*SelectStmt)
  186. if len(sel.GroupBy) != 1 {
  187. t.Fatalf("expected 1 GROUP BY column, got %d", len(sel.GroupBy))
  188. }
  189. }
  190. func TestParseSelectHaving(t *testing.T) {
  191. stmt := parse(t, "SELECT name, COUNT(*) as cnt FROM users GROUP BY name HAVING COUNT(*) > 5")
  192. sel := stmt.(*SelectStmt)
  193. if sel.Having == nil {
  194. t.Fatal("expected HAVING clause")
  195. }
  196. }
  197. func TestParseSelectJoin(t *testing.T) {
  198. tests := []struct {
  199. input string
  200. joinType JoinType
  201. }{
  202. {"SELECT * FROM a JOIN b ON a.id = b.id", JoinInner},
  203. {"SELECT * FROM a INNER JOIN b ON a.id = b.id", JoinInner},
  204. {"SELECT * FROM a LEFT JOIN b ON a.id = b.id", JoinLeft},
  205. {"SELECT * FROM a LEFT OUTER JOIN b ON a.id = b.id", JoinLeft},
  206. {"SELECT * FROM a RIGHT JOIN b ON a.id = b.id", JoinRight},
  207. {"SELECT * FROM a CROSS JOIN b", JoinCross},
  208. }
  209. for _, tt := range tests {
  210. t.Run(tt.input, func(t *testing.T) {
  211. stmt := parse(t, tt.input)
  212. sel := stmt.(*SelectStmt)
  213. if sel.From[0].Join == nil {
  214. t.Fatal("expected JOIN")
  215. }
  216. if sel.From[0].Join.Type != tt.joinType {
  217. t.Errorf("expected join type %v, got %v", tt.joinType, sel.From[0].Join.Type)
  218. }
  219. })
  220. }
  221. }
  222. // INSERT statement tests
  223. func TestParseInsertValues(t *testing.T) {
  224. stmt := parse(t, "INSERT INTO users (name, age) VALUES ('John', 30)")
  225. ins, ok := stmt.(*InsertStmt)
  226. if !ok {
  227. t.Fatalf("expected InsertStmt, got %T", stmt)
  228. }
  229. if ins.Table.Name != "users" {
  230. t.Errorf("expected table users, got %s", ins.Table.Name)
  231. }
  232. if len(ins.Columns) != 2 {
  233. t.Fatalf("expected 2 columns, got %d", len(ins.Columns))
  234. }
  235. if len(ins.Values) != 1 || len(ins.Values[0]) != 2 {
  236. t.Error("expected 1 row with 2 values")
  237. }
  238. }
  239. func TestParseJoinUsingMultipleColumns(t *testing.T) {
  240. stmt := parse(t, "SELECT * FROM hit_counts JOIN paths USING (site_id, path_id)")
  241. selectStmt, ok := stmt.(*SelectStmt)
  242. if !ok || len(selectStmt.From) != 1 || selectStmt.From[0].Join == nil {
  243. t.Fatalf("unexpected statement %#v", stmt)
  244. }
  245. using := selectStmt.From[0].Join.Using
  246. if len(using) != 2 || using[0] != "site_id" || using[1] != "path_id" {
  247. t.Fatalf("USING columns = %v", using)
  248. }
  249. }
  250. func TestParseInsertMultipleRows(t *testing.T) {
  251. stmt := parse(t, "INSERT INTO users VALUES (1, 'John'), (2, 'Jane')")
  252. ins := stmt.(*InsertStmt)
  253. if len(ins.Values) != 2 {
  254. t.Fatalf("expected 2 rows, got %d", len(ins.Values))
  255. }
  256. }
  257. func TestParseInsertDefaultValues(t *testing.T) {
  258. stmt := parse(t, "INSERT INTO users DEFAULT VALUES")
  259. ins, ok := stmt.(*InsertStmt)
  260. if !ok {
  261. t.Fatalf("expected InsertStmt, got %T", stmt)
  262. }
  263. if !ins.DefaultValues {
  264. t.Fatal("expected DefaultValues to be set")
  265. }
  266. if len(ins.Values) != 1 || len(ins.Values[0]) != 0 {
  267. t.Fatalf("values = %v, want one empty row", ins.Values)
  268. }
  269. }
  270. func TestParseInsertOrReplace(t *testing.T) {
  271. stmt := parse(t, "INSERT OR REPLACE INTO users (id, name) VALUES (1, 'John')")
  272. ins := stmt.(*InsertStmt)
  273. if ins.OnConflict != ConflictReplace {
  274. t.Errorf("expected ConflictReplace, got %v", ins.OnConflict)
  275. }
  276. if ins.Table.Name != "users" {
  277. t.Errorf("expected table users, got %s", ins.Table.Name)
  278. }
  279. }
  280. func TestParseInsertOrIgnore(t *testing.T) {
  281. stmt := parse(t, "INSERT OR IGNORE INTO users (id, name) VALUES (1, 'John')")
  282. ins := stmt.(*InsertStmt)
  283. if ins.OnConflict != ConflictIgnore {
  284. t.Errorf("expected ConflictIgnore, got %v", ins.OnConflict)
  285. }
  286. }
  287. func TestParseInsertOrFail(t *testing.T) {
  288. stmt := parse(t, "INSERT OR FAIL INTO users (id, name) VALUES (1, 'John')")
  289. ins := stmt.(*InsertStmt)
  290. if ins.OnConflict != ConflictFail {
  291. t.Errorf("expected ConflictFail, got %v", ins.OnConflict)
  292. }
  293. }
  294. func TestParseInsertOrAbort(t *testing.T) {
  295. stmt := parse(t, "INSERT OR ABORT INTO users (id, name) VALUES (1, 'John')")
  296. ins := stmt.(*InsertStmt)
  297. if ins.OnConflict != ConflictAbort {
  298. t.Errorf("expected ConflictAbort, got %v", ins.OnConflict)
  299. }
  300. }
  301. // UPDATE statement tests
  302. func TestParseUpdate(t *testing.T) {
  303. stmt := parse(t, "UPDATE users SET name = 'John', age = 30 WHERE id = 1")
  304. upd, ok := stmt.(*UpdateStmt)
  305. if !ok {
  306. t.Fatalf("expected UpdateStmt, got %T", stmt)
  307. }
  308. if upd.Table.Name != "users" {
  309. t.Errorf("expected table users, got %s", upd.Table.Name)
  310. }
  311. if len(upd.Set) != 2 {
  312. t.Fatalf("expected 2 assignments, got %d", len(upd.Set))
  313. }
  314. if upd.Where == nil {
  315. t.Error("expected WHERE clause")
  316. }
  317. }
  318. // DELETE statement tests
  319. func TestParseDelete(t *testing.T) {
  320. stmt := parse(t, "DELETE FROM users WHERE id = 1")
  321. del, ok := stmt.(*DeleteStmt)
  322. if !ok {
  323. t.Fatalf("expected DeleteStmt, got %T", stmt)
  324. }
  325. if del.Table.Name != "users" {
  326. t.Errorf("expected table users, got %s", del.Table.Name)
  327. }
  328. if del.Where == nil {
  329. t.Error("expected WHERE clause")
  330. }
  331. }
  332. func TestParseDeleteAll(t *testing.T) {
  333. stmt := parse(t, "DELETE FROM users")
  334. del := stmt.(*DeleteStmt)
  335. if del.Where != nil {
  336. t.Error("expected no WHERE clause")
  337. }
  338. }
  339. // CREATE TABLE tests
  340. func TestParseCreateTable(t *testing.T) {
  341. stmt := parse(t, `CREATE TABLE users (
  342. id INTEGER PRIMARY KEY,
  343. name TEXT NOT NULL,
  344. email VARCHAR(255) UNIQUE,
  345. age INTEGER DEFAULT 0
  346. )`)
  347. create, ok := stmt.(*CreateTableStmt)
  348. if !ok {
  349. t.Fatalf("expected CreateTableStmt, got %T", stmt)
  350. }
  351. if create.Table.Name != "users" {
  352. t.Errorf("expected table users, got %s", create.Table.Name)
  353. }
  354. if len(create.Columns) != 4 {
  355. t.Fatalf("expected 4 columns, got %d", len(create.Columns))
  356. }
  357. // Check id column
  358. if create.Columns[0].Name != "id" {
  359. t.Error("expected first column to be id")
  360. }
  361. if create.Columns[0].Type.Name != "INTEGER" {
  362. t.Error("expected INTEGER type")
  363. }
  364. // Check name column has NOT NULL
  365. found := false
  366. for _, c := range create.Columns[1].Constraints {
  367. if c.Type == ConstraintNotNull {
  368. found = true
  369. }
  370. }
  371. if !found {
  372. t.Error("expected NOT NULL constraint on name")
  373. }
  374. // Check email has VARCHAR(255)
  375. if create.Columns[2].Type.Name != "VARCHAR" || create.Columns[2].Type.Precision != 255 {
  376. t.Error("expected VARCHAR(255) for email")
  377. }
  378. }
  379. func TestParseCreateTableIfNotExists(t *testing.T) {
  380. stmt := parse(t, "CREATE TABLE IF NOT EXISTS users (id INTEGER)")
  381. create := stmt.(*CreateTableStmt)
  382. if !create.IfNotExists {
  383. t.Error("expected IF NOT EXISTS")
  384. }
  385. }
  386. func TestParseCreateTableWithConstraints(t *testing.T) {
  387. stmt := parse(t, `CREATE TABLE orders (
  388. id INTEGER,
  389. user_id INTEGER,
  390. PRIMARY KEY (id),
  391. FOREIGN KEY (user_id) REFERENCES users(id)
  392. )`)
  393. create := stmt.(*CreateTableStmt)
  394. if len(create.Constraints) != 2 {
  395. t.Fatalf("expected 2 table constraints, got %d", len(create.Constraints))
  396. }
  397. // Check PRIMARY KEY
  398. if create.Constraints[0].Type != ConstraintPrimaryKey {
  399. t.Error("expected PRIMARY KEY constraint")
  400. }
  401. // Check FOREIGN KEY
  402. if create.Constraints[1].Type != ConstraintForeignKey {
  403. t.Error("expected FOREIGN KEY constraint")
  404. }
  405. if create.Constraints[1].RefTable != "users" {
  406. t.Errorf("expected reference to users, got %s", create.Constraints[1].RefTable)
  407. }
  408. }
  409. func TestParseCreateTableExplicitNullable(t *testing.T) {
  410. stmt := parse(t, `CREATE TABLE users (
  411. id INTEGER,
  412. full_name TEXT NULL,
  413. nickname TEXT NOT NULL,
  414. created_at TIMESTAMP NULL NOT NULL
  415. )`)
  416. create, ok := stmt.(*CreateTableStmt)
  417. if !ok {
  418. t.Fatalf("expected CreateTableStmt, got %T", stmt)
  419. }
  420. if len(create.Columns) != 4 {
  421. t.Fatalf("expected 4 columns, got %d", len(create.Columns))
  422. }
  423. // full_name TEXT NULL: explicit NULL is a no-op, so no constraint is added.
  424. fullName := create.Columns[1]
  425. if fullName.Name != "full_name" || fullName.Type.Name != "TEXT" {
  426. t.Fatalf("unexpected full_name column: %+v", fullName)
  427. }
  428. if len(fullName.Constraints) != 0 {
  429. t.Errorf("explicit NULL should not produce a constraint, got %d", len(fullName.Constraints))
  430. }
  431. // nickname TEXT NOT NULL still records NOT NULL.
  432. nickname := create.Columns[2]
  433. if len(nickname.Constraints) != 1 || nickname.Constraints[0].Type != ConstraintNotNull {
  434. t.Errorf("expected NOT NULL on nickname, got %+v", nickname.Constraints)
  435. }
  436. // created_at TIMESTAMP NULL NOT NULL: NOT NULL wins regardless of ordering.
  437. created := create.Columns[3]
  438. if len(created.Constraints) != 1 || created.Constraints[0].Type != ConstraintNotNull {
  439. t.Errorf("expected NOT NULL on created_at, got %+v", created.Constraints)
  440. }
  441. }
  442. // DROP TABLE tests
  443. func TestParseDropTable(t *testing.T) {
  444. stmt := parse(t, "DROP TABLE users")
  445. drop, ok := stmt.(*DropTableStmt)
  446. if !ok {
  447. t.Fatalf("expected DropTableStmt, got %T", stmt)
  448. }
  449. if len(drop.Tables) != 1 || drop.Tables[0].Name != "users" {
  450. t.Error("expected DROP TABLE users")
  451. }
  452. }
  453. func TestParseCreateTableDefaultSignedNumeric(t *testing.T) {
  454. stmt := parse(t, `CREATE TABLE repo (
  455. id INTEGER PRIMARY KEY,
  456. max_repo_creation INTEGER DEFAULT -1 NOT NULL,
  457. delta INTEGER DEFAULT +5,
  458. tally INTEGER DEFAULT (-7)
  459. )`)
  460. create, ok := stmt.(*CreateTableStmt)
  461. if !ok {
  462. t.Fatalf("expected CreateTableStmt, got %T", stmt)
  463. }
  464. if len(create.Columns) != 4 {
  465. t.Fatalf("expected 4 columns, got %d", len(create.Columns))
  466. }
  467. // xorm real shape: DEFAULT -1 followed by NOT NULL.
  468. col := create.Columns[1]
  469. if len(col.Constraints) != 2 {
  470. t.Fatalf("expected DEFAULT + NOT NULL, got %d constraints", len(col.Constraints))
  471. }
  472. var defaultExpr Expr
  473. var notNull bool
  474. for _, c := range col.Constraints {
  475. switch c.Type {
  476. case ConstraintDefault:
  477. defaultExpr = c.Default
  478. case ConstraintNotNull:
  479. notNull = true
  480. }
  481. }
  482. if !notNull {
  483. t.Error("expected NOT NULL constraint on max_repo_creation")
  484. }
  485. unary, ok := defaultExpr.(*UnaryExpr)
  486. if !ok || unary.Op != lexer.TokenMinus {
  487. t.Fatalf("expected unary minus default, got %T %+v", defaultExpr, defaultExpr)
  488. }
  489. lit, ok := unary.Operand.(*LiteralExpr)
  490. if !ok || lit.Value != "1" {
  491. t.Fatalf("expected -1 literal, got %+v", unary.Operand)
  492. }
  493. // Positive signed default: DEFAULT +5.
  494. plus, ok := create.Columns[2].Constraints[0].Default.(*UnaryExpr)
  495. if !ok || plus.Op != lexer.TokenPlus {
  496. t.Fatalf("expected unary plus default, got %+v", create.Columns[2].Constraints[0].Default)
  497. }
  498. // Parenthesized signed default: DEFAULT (-7).
  499. paren, ok := create.Columns[3].Constraints[0].Default.(*ParenExpr)
  500. if !ok {
  501. t.Fatalf("expected parenthesized default, got %T", create.Columns[3].Constraints[0].Default)
  502. }
  503. inner, ok := paren.Expr.(*UnaryExpr)
  504. if !ok || inner.Op != lexer.TokenMinus {
  505. t.Fatalf("expected unary minus inside parens, got %T %+v", paren.Expr, paren.Expr)
  506. }
  507. }
  508. func TestParseCreateTableUUIDType(t *testing.T) {
  509. stmt := parse(t, `CREATE TABLE upload (
  510. id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
  511. uuid UUID NULL,
  512. name TEXT NULL
  513. )`)
  514. create, ok := stmt.(*CreateTableStmt)
  515. if !ok {
  516. t.Fatalf("expected CreateTableStmt, got %T", stmt)
  517. }
  518. if len(create.Columns) != 3 {
  519. t.Fatalf("expected 3 columns, got %d", len(create.Columns))
  520. }
  521. uuidCol := create.Columns[1]
  522. if uuidCol.Name != "uuid" {
  523. t.Errorf("column name = %q, want %q", uuidCol.Name, "uuid")
  524. }
  525. if uuidCol.Type.Name != "UUID" {
  526. t.Errorf("column type = %q, want %q", uuidCol.Type.Name, "UUID")
  527. }
  528. if len(uuidCol.Constraints) != 0 {
  529. t.Errorf("explicit NULL should produce no constraints, got %d", len(uuidCol.Constraints))
  530. }
  531. }
  532. func TestParseDropTableIfExists(t *testing.T) {
  533. stmt := parse(t, "DROP TABLE IF EXISTS users")
  534. drop := stmt.(*DropTableStmt)
  535. if !drop.IfExists {
  536. t.Error("expected IF EXISTS")
  537. }
  538. }
  539. // Expression tests
  540. func TestParseExprArithmetic(t *testing.T) {
  541. expr := parseExpr(t, "1 + 2 * 3")
  542. // Should be: 1 + (2 * 3) due to precedence
  543. add, ok := expr.(*BinaryExpr)
  544. if !ok || add.Op != lexer.TokenPlus {
  545. t.Fatal("expected + at top level")
  546. }
  547. mul, ok := add.Right.(*BinaryExpr)
  548. if !ok || mul.Op != lexer.TokenStar {
  549. t.Fatal("expected * on right side")
  550. }
  551. }
  552. func TestParseExprParens(t *testing.T) {
  553. expr := parseExpr(t, "(1 + 2) * 3")
  554. // Should be: (1 + 2) * 3
  555. mul, ok := expr.(*BinaryExpr)
  556. if !ok || mul.Op != lexer.TokenStar {
  557. t.Fatal("expected * at top level")
  558. }
  559. paren, ok := mul.Left.(*ParenExpr)
  560. if !ok {
  561. t.Fatal("expected ParenExpr on left")
  562. }
  563. add, ok := paren.Expr.(*BinaryExpr)
  564. if !ok || add.Op != lexer.TokenPlus {
  565. t.Fatal("expected + inside parens")
  566. }
  567. }
  568. func TestParseExprComparison(t *testing.T) {
  569. tests := []struct {
  570. input string
  571. op lexer.TokenType
  572. }{
  573. {"a = b", lexer.TokenEq},
  574. {"a <> b", lexer.TokenNeq},
  575. {"a != b", lexer.TokenNeq},
  576. {"a < b", lexer.TokenLt},
  577. {"a <= b", lexer.TokenLte},
  578. {"a > b", lexer.TokenGt},
  579. {"a >= b", lexer.TokenGte},
  580. }
  581. for _, tt := range tests {
  582. t.Run(tt.input, func(t *testing.T) {
  583. expr := parseExpr(t, tt.input)
  584. binary, ok := expr.(*BinaryExpr)
  585. if !ok {
  586. t.Fatalf("expected BinaryExpr, got %T", expr)
  587. }
  588. if binary.Op != tt.op {
  589. t.Errorf("expected %v, got %v", tt.op, binary.Op)
  590. }
  591. })
  592. }
  593. }
  594. func TestParseExprIsNull(t *testing.T) {
  595. tests := []struct {
  596. input string
  597. not bool
  598. }{
  599. {"a IS NULL", false},
  600. {"a IS NOT NULL", true},
  601. }
  602. for _, tt := range tests {
  603. t.Run(tt.input, func(t *testing.T) {
  604. expr := parseExpr(t, tt.input)
  605. isNull, ok := expr.(*IsNullExpr)
  606. if !ok {
  607. t.Fatalf("expected IsNullExpr, got %T", expr)
  608. }
  609. if isNull.Not != tt.not {
  610. t.Errorf("expected Not=%v, got %v", tt.not, isNull.Not)
  611. }
  612. })
  613. }
  614. }
  615. func TestParseExprIn(t *testing.T) {
  616. tests := []struct {
  617. input string
  618. not bool
  619. }{
  620. {"a IN (1, 2, 3)", false},
  621. {"a NOT IN (1, 2, 3)", true},
  622. }
  623. for _, tt := range tests {
  624. t.Run(tt.input, func(t *testing.T) {
  625. expr := parseExpr(t, tt.input)
  626. in, ok := expr.(*InExpr)
  627. if !ok {
  628. t.Fatalf("expected InExpr, got %T", expr)
  629. }
  630. if in.Not != tt.not {
  631. t.Errorf("expected Not=%v, got %v", tt.not, in.Not)
  632. }
  633. if len(in.Values) != 3 {
  634. t.Errorf("expected 3 values, got %d", len(in.Values))
  635. }
  636. })
  637. }
  638. }
  639. func TestParseExprBetween(t *testing.T) {
  640. tests := []struct {
  641. input string
  642. not bool
  643. }{
  644. {"a BETWEEN 1 AND 10", false},
  645. {"a NOT BETWEEN 1 AND 10", true},
  646. }
  647. for _, tt := range tests {
  648. t.Run(tt.input, func(t *testing.T) {
  649. expr := parseExpr(t, tt.input)
  650. between, ok := expr.(*BetweenExpr)
  651. if !ok {
  652. t.Fatalf("expected BetweenExpr, got %T", expr)
  653. }
  654. if between.Not != tt.not {
  655. t.Errorf("expected Not=%v, got %v", tt.not, between.Not)
  656. }
  657. })
  658. }
  659. }
  660. func TestParseExprLike(t *testing.T) {
  661. tests := []struct {
  662. input string
  663. not bool
  664. }{
  665. {"name LIKE '%test%'", false},
  666. {"name NOT LIKE '%test%'", true},
  667. }
  668. for _, tt := range tests {
  669. t.Run(tt.input, func(t *testing.T) {
  670. expr := parseExpr(t, tt.input)
  671. like, ok := expr.(*LikeExpr)
  672. if !ok {
  673. t.Fatalf("expected LikeExpr, got %T", expr)
  674. }
  675. if like.Not != tt.not {
  676. t.Errorf("expected Not=%v, got %v", tt.not, like.Not)
  677. }
  678. })
  679. }
  680. }
  681. func TestParseExprCase(t *testing.T) {
  682. expr := parseExpr(t, "CASE WHEN x = 1 THEN 'one' WHEN x = 2 THEN 'two' ELSE 'other' END")
  683. caseExpr, ok := expr.(*CaseExpr)
  684. if !ok {
  685. t.Fatalf("expected CaseExpr, got %T", expr)
  686. }
  687. if len(caseExpr.Whens) != 2 {
  688. t.Errorf("expected 2 WHEN clauses, got %d", len(caseExpr.Whens))
  689. }
  690. if caseExpr.Else == nil {
  691. t.Error("expected ELSE clause")
  692. }
  693. }
  694. func TestParseExprCast(t *testing.T) {
  695. expr := parseExpr(t, "CAST(x AS INTEGER)")
  696. cast, ok := expr.(*CastExpr)
  697. if !ok {
  698. t.Fatalf("expected CastExpr, got %T", expr)
  699. }
  700. if cast.Type.Name != "INTEGER" {
  701. t.Errorf("expected INTEGER type, got %s", cast.Type.Name)
  702. }
  703. }
  704. func TestParseExprFunction(t *testing.T) {
  705. tests := []struct {
  706. input string
  707. name string
  708. argCount int
  709. star bool
  710. distinct bool
  711. }{
  712. {"COUNT(*)", "COUNT", 0, true, false},
  713. {"COUNT(id)", "COUNT", 1, false, false},
  714. {"COUNT(DISTINCT id)", "COUNT", 1, false, true},
  715. {"SUM(amount)", "SUM", 1, false, false},
  716. {"UPPER(name)", "UPPER", 1, false, false},
  717. {"COALESCE(a, b, c)", "COALESCE", 3, false, false},
  718. }
  719. for _, tt := range tests {
  720. t.Run(tt.input, func(t *testing.T) {
  721. expr := parseExpr(t, tt.input)
  722. fn, ok := expr.(*FunctionCall)
  723. if !ok {
  724. t.Fatalf("expected FunctionCall, got %T", expr)
  725. }
  726. if fn.Name != tt.name {
  727. t.Errorf("expected name %s, got %s", tt.name, fn.Name)
  728. }
  729. if len(fn.Args) != tt.argCount {
  730. t.Errorf("expected %d args, got %d", tt.argCount, len(fn.Args))
  731. }
  732. if fn.Star != tt.star {
  733. t.Errorf("expected Star=%v, got %v", tt.star, fn.Star)
  734. }
  735. if fn.Distinct != tt.distinct {
  736. t.Errorf("expected Distinct=%v, got %v", tt.distinct, fn.Distinct)
  737. }
  738. })
  739. }
  740. }
  741. func TestParseExprSubquery(t *testing.T) {
  742. expr := parseExpr(t, "id IN (SELECT user_id FROM orders)")
  743. in, ok := expr.(*InExpr)
  744. if !ok {
  745. t.Fatalf("expected InExpr, got %T", expr)
  746. }
  747. if in.Subquery == nil {
  748. t.Error("expected subquery")
  749. }
  750. }
  751. func TestParseExprExists(t *testing.T) {
  752. expr := parseExpr(t, "EXISTS (SELECT 1 FROM users WHERE id = 1)")
  753. exists, ok := expr.(*ExistsExpr)
  754. if !ok {
  755. t.Fatalf("expected ExistsExpr, got %T", expr)
  756. }
  757. if exists.Subquery == nil {
  758. t.Error("expected subquery")
  759. }
  760. }
  761. func TestParseExprColumnRef(t *testing.T) {
  762. tests := []struct {
  763. input string
  764. table string
  765. column string
  766. }{
  767. {"id", "", "id"},
  768. {"users.id", "users", "id"},
  769. {"u.name", "u", "name"},
  770. }
  771. for _, tt := range tests {
  772. t.Run(tt.input, func(t *testing.T) {
  773. expr := parseExpr(t, tt.input)
  774. ref, ok := expr.(*ColumnRef)
  775. if !ok {
  776. t.Fatalf("expected ColumnRef, got %T", expr)
  777. }
  778. if ref.Table != tt.table {
  779. t.Errorf("expected table %q, got %q", tt.table, ref.Table)
  780. }
  781. if ref.Column != tt.column {
  782. t.Errorf("expected column %q, got %q", tt.column, ref.Column)
  783. }
  784. })
  785. }
  786. }
  787. // Error cases
  788. func TestParseErrors(t *testing.T) {
  789. tests := []struct {
  790. name string
  791. input string
  792. }{
  793. {"missing columns", "SELECT FROM users"},
  794. {"missing VALUES", "INSERT INTO users"},
  795. {"missing SET", "UPDATE users WHERE id = 1"},
  796. {"missing table name", "DELETE FROM WHERE id = 1"},
  797. {"unclosed paren", "SELECT * FROM users WHERE (id = 1"},
  798. {"invalid token", "SELECT @ FROM users"},
  799. }
  800. for _, tt := range tests {
  801. t.Run(tt.name, func(t *testing.T) {
  802. l := lexer.New(tt.input)
  803. p := New(l)
  804. _, err := p.Parse()
  805. if err == nil {
  806. t.Error("expected parse error")
  807. }
  808. })
  809. }
  810. }
  811. // Multiple statements
  812. func TestParseMultiple(t *testing.T) {
  813. input := `
  814. SELECT * FROM users;
  815. INSERT INTO users VALUES (1, 'John');
  816. DELETE FROM users WHERE id = 1
  817. `
  818. l := lexer.New(input)
  819. p := New(l)
  820. stmts, err := p.ParseMultiple()
  821. if err != nil {
  822. t.Fatalf("parse error: %v", err)
  823. }
  824. if len(stmts) != 3 {
  825. t.Errorf("expected 3 statements, got %d", len(stmts))
  826. }
  827. }
  828. func TestParseInsertReturning(t *testing.T) {
  829. stmt := parse(t, "INSERT INTO users (id, name) VALUES (1, 'a') RETURNING id, name AS n, id + 1")
  830. ins, ok := stmt.(*InsertStmt)
  831. if !ok {
  832. t.Fatalf("expected InsertStmt, got %T", stmt)
  833. }
  834. if len(ins.Returning) != 3 {
  835. t.Fatalf("expected 3 returning columns, got %d", len(ins.Returning))
  836. }
  837. if ref, ok := ins.Returning[0].Expr.(*ColumnRef); !ok || ref.Column != "id" {
  838. t.Fatalf("unexpected first returning column: %#v", ins.Returning[0])
  839. }
  840. if ins.Returning[1].Alias != "n" {
  841. t.Fatalf("expected alias n, got %q", ins.Returning[1].Alias)
  842. }
  843. if _, ok := ins.Returning[2].Expr.(*BinaryExpr); !ok {
  844. t.Fatalf("expected expression in third returning column, got %T", ins.Returning[2].Expr)
  845. }
  846. }
  847. func TestParseUpdateAndDeleteReturning(t *testing.T) {
  848. upd := parse(t, "UPDATE users SET name = 'b' WHERE id = 1 RETURNING id, name")
  849. if len(upd.(*UpdateStmt).Returning) != 2 {
  850. t.Fatalf("expected 2 returning columns on UPDATE")
  851. }
  852. del := parse(t, "DELETE FROM users WHERE id = 1 RETURNING *")
  853. if len(del.(*DeleteStmt).Returning) != 1 || !del.(*DeleteStmt).Returning[0].Star {
  854. t.Fatalf("expected RETURNING * on DELETE")
  855. }
  856. }
  857. func TestParseGeneratedColumn(t *testing.T) {
  858. stmt := parse(t, `CREATE TABLE t (
  859. a INTEGER,
  860. b INTEGER,
  861. total INTEGER GENERATED ALWAYS AS (a + b) STORED,
  862. vit TEXT AS (a || '-') VIRTUAL
  863. )`)
  864. ct := stmt.(*CreateTableStmt)
  865. if len(ct.Columns) != 4 {
  866. t.Fatalf("expected 4 columns, got %d", len(ct.Columns))
  867. }
  868. if ct.Columns[2].GeneratedExpr == nil || !ct.Columns[2].GeneratedStored {
  869. t.Fatalf("expected stored generated column, got %#v", ct.Columns[2])
  870. }
  871. if ct.Columns[3].GeneratedExpr == nil || ct.Columns[3].GeneratedStored {
  872. t.Fatalf("expected virtual generated column, got %#v", ct.Columns[3])
  873. }
  874. }
  875. func TestParseTableConstraintOnConflictReplace(t *testing.T) {
  876. stmt := parse(t, `CREATE TABLE t (
  877. a INTEGER,
  878. b INTEGER,
  879. CONSTRAINT "t#a#b" UNIQUE(a, b) ON CONFLICT REPLACE
  880. )`)
  881. ct := stmt.(*CreateTableStmt)
  882. if len(ct.Constraints) != 1 {
  883. t.Fatalf("expected 1 constraint, got %d", len(ct.Constraints))
  884. }
  885. c := ct.Constraints[0]
  886. if !c.HasOnConflict || c.OnConflict != ConflictReplace {
  887. t.Fatalf("expected ON CONFLICT REPLACE, got %#v", c)
  888. }
  889. }
  890. func TestParseExpressionIndex(t *testing.T) {
  891. stmt := parse(t, "CREATE UNIQUE INDEX users_email ON users (lower(email))")
  892. ci := stmt.(*CreateIndexStmt)
  893. if len(ci.Columns) != 1 {
  894. t.Fatalf("expected 1 index column, got %d", len(ci.Columns))
  895. }
  896. if ci.Columns[0].Expr == nil {
  897. t.Fatalf("expected expression index column, got %#v", ci.Columns[0])
  898. }
  899. if ci.Columns[0].Name != "lower(email)" {
  900. t.Fatalf("expected name lower(email), got %q", ci.Columns[0].Name)
  901. }
  902. }
  903. func TestParseBitwisePrecedence(t *testing.T) {
  904. // 1 + 2 | 4 must parse as (1 + 2) | 4 because + binds tighter than |.
  905. expr := parseExpr(t, "1 + 2 | 4")
  906. bin, ok := expr.(*BinaryExpr)
  907. if !ok || bin.Op != lexer.TokenBitOr {
  908. t.Fatalf("expected top-level bit-or, got %#v", expr)
  909. }
  910. if left, ok := bin.Left.(*BinaryExpr); !ok || left.Op != lexer.TokenPlus {
  911. t.Fatalf("expected (1+2) on the left, got %#v", bin.Left)
  912. }
  913. }
  914. func TestParseBlobLiteral(t *testing.T) {
  915. expr := parseExpr(t, "X'00FF'")
  916. lit, ok := expr.(*LiteralExpr)
  917. if !ok || lit.Type != lexer.TokenBlob {
  918. t.Fatalf("expected blob literal, got %#v", expr)
  919. }
  920. if []byte(lit.Value)[0] != 0x00 || []byte(lit.Value)[1] != 0xFF {
  921. t.Fatalf("unexpected blob bytes: %v", []byte(lit.Value))
  922. }
  923. }
  924. func TestParseAnalyze(t *testing.T) {
  925. if _, ok := parse(t, "ANALYZE").(*AnalyzeStmt); !ok {
  926. t.Fatalf("ANALYZE did not parse as AnalyzeStmt")
  927. }
  928. stmt := parse(t, "ANALYZE main.users")
  929. if got := stmt.(*AnalyzeStmt).Name; got != "users" {
  930. t.Fatalf("ANALYZE name = %q, want users", got)
  931. }
  932. }
  933. func TestParseIsDistinctFrom(t *testing.T) {
  934. expr := parseExpr(t, "a IS DISTINCT FROM b")
  935. d, ok := expr.(*IsDistinctExpr)
  936. if !ok {
  937. t.Fatalf("expected IsDistinctExpr, got %T", expr)
  938. }
  939. if d.Not {
  940. t.Fatalf("IS DISTINCT FROM should not set Not")
  941. }
  942. expr = parseExpr(t, "a IS NOT DISTINCT FROM b")
  943. if d, ok := expr.(*IsDistinctExpr); !ok || !d.Not {
  944. t.Fatalf("expected IsDistinctExpr with Not=true, got %#v", expr)
  945. }
  946. }
  947. func TestParseUpdateFrom(t *testing.T) {
  948. stmt := parse(t, "UPDATE users SET access = 'x' FROM other WHERE other.id = users.id RETURNING users.id")
  949. upd, ok := stmt.(*UpdateStmt)
  950. if !ok {
  951. t.Fatalf("expected UpdateStmt, got %T", stmt)
  952. }
  953. if len(upd.From) != 1 || upd.From[0].Name != "other" {
  954. t.Fatalf("unexpected FROM: %#v", upd.From)
  955. }
  956. if len(upd.Returning) != 1 {
  957. t.Fatalf("expected 1 RETURNING column, got %d", len(upd.Returning))
  958. }
  959. }
  960. func TestParseWithUpdate(t *testing.T) {
  961. stmt := parse(t, `WITH x AS (SELECT count(*) AS c, site_id FROM users GROUP BY site_id)
  962. UPDATE users SET access = 'y' FROM x WHERE x.c = 1 AND users.site_id = x.site_id`)
  963. upd, ok := stmt.(*UpdateStmt)
  964. if !ok {
  965. t.Fatalf("expected UpdateStmt, got %T", stmt)
  966. }
  967. if len(upd.From) != 1 || upd.From[0].Subquery == nil {
  968. t.Fatalf("CTE was not desugared into the FROM clause: %#v", upd.From)
  969. }
  970. }
  971. func TestParseInsertSelectReturning(t *testing.T) {
  972. // RETURNING after INSERT ... SELECT must not be swallowed as a table alias.
  973. stmt := parse(t, "INSERT INTO dst (a, b) SELECT a, b FROM src RETURNING a")
  974. ins, ok := stmt.(*InsertStmt)
  975. if !ok {
  976. t.Fatalf("expected InsertStmt, got %T", stmt)
  977. }
  978. if ins.Select == nil || len(ins.Select.From) != 1 {
  979. t.Fatalf("unexpected SELECT: %#v", ins.Select)
  980. }
  981. if ins.Select.From[0].Alias != "" {
  982. t.Fatalf("RETURNING was parsed as a table alias: %q", ins.Select.From[0].Alias)
  983. }
  984. if len(ins.Returning) != 1 {
  985. t.Fatalf("expected 1 RETURNING column, got %d", len(ins.Returning))
  986. }
  987. }
  988. func TestParseInsertWithSelect(t *testing.T) {
  989. stmt := parse(t, `INSERT INTO dst (id, value)
  990. WITH source AS (SELECT id, value FROM src WHERE id > 1)
  991. SELECT id, value FROM source`)
  992. insert, ok := stmt.(*InsertStmt)
  993. if !ok {
  994. t.Fatalf("expected InsertStmt, got %T", stmt)
  995. }
  996. if insert.Select == nil || len(insert.Select.From) != 1 || insert.Select.From[0].Subquery == nil {
  997. t.Fatalf("WITH SELECT was not attached to INSERT: %#v", insert.Select)
  998. }
  999. }
  1000. func TestParsePostgresCompatibilityClauses(t *testing.T) {
  1001. t.Run("alter add column if not exists", func(t *testing.T) {
  1002. stmt := parse(t, "ALTER TABLE users ADD COLUMN IF NOT EXISTS revision INTEGER DEFAULT 0")
  1003. action := stmt.(*AlterTableStmt).Action.(*AddColumnAction)
  1004. if !action.IfNotExists || action.Column.Name != "revision" {
  1005. t.Fatalf("unexpected action: %#v", action)
  1006. }
  1007. })
  1008. t.Run("on conflict do update", func(t *testing.T) {
  1009. stmt := parse(t, "INSERT INTO users (id, count) VALUES (1, 1) ON CONFLICT (id) DO UPDATE SET count = users.count + 1")
  1010. insert := stmt.(*InsertStmt)
  1011. if len(insert.ConflictTarget) != 1 || insert.ConflictTarget[0] != "id" || len(insert.ConflictUpdate) != 1 {
  1012. t.Fatalf("unexpected conflict clause: %#v", insert)
  1013. }
  1014. })
  1015. t.Run("jsonb cast", func(t *testing.T) {
  1016. parse(t, "SELECT CAST('{}' AS JSONB)")
  1017. })
  1018. }
  1019. // Phase 4: PRAGMA and EXPLAIN tests
  1020. func TestParsePragmaTableInfo(t *testing.T) {
  1021. stmt := parse(t, "PRAGMA table_info(users)")
  1022. pragma, ok := stmt.(*PragmaStmt)
  1023. if !ok {
  1024. t.Fatalf("expected PragmaStmt, got %T", stmt)
  1025. }
  1026. if pragma.Name != "table_info" {
  1027. t.Errorf("expected pragma name 'table_info', got %s", pragma.Name)
  1028. }
  1029. if pragma.Arg != "users" {
  1030. t.Errorf("expected arg 'users', got %s", pragma.Arg)
  1031. }
  1032. }
  1033. func TestParsePragmaTableList(t *testing.T) {
  1034. stmt := parse(t, "PRAGMA table_list")
  1035. pragma, ok := stmt.(*PragmaStmt)
  1036. if !ok {
  1037. t.Fatalf("expected PragmaStmt, got %T", stmt)
  1038. }
  1039. if pragma.Name != "table_list" {
  1040. t.Errorf("expected pragma name 'table_list', got %s", pragma.Name)
  1041. }
  1042. }
  1043. func TestParsePragmaDatabaseList(t *testing.T) {
  1044. stmt := parse(t, "PRAGMA database_list")
  1045. pragma := stmt.(*PragmaStmt)
  1046. if pragma.Name != "database_list" {
  1047. t.Errorf("expected pragma name 'database_list', got %s", pragma.Name)
  1048. }
  1049. }
  1050. func TestParsePragmaVersion(t *testing.T) {
  1051. stmt := parse(t, "PRAGMA version")
  1052. pragma := stmt.(*PragmaStmt)
  1053. if pragma.Name != "version" {
  1054. t.Errorf("expected pragma name 'version', got %s", pragma.Name)
  1055. }
  1056. }
  1057. func TestParseExplain(t *testing.T) {
  1058. stmt := parse(t, "EXPLAIN SELECT * FROM users")
  1059. explain, ok := stmt.(*ExplainStmt)
  1060. if !ok {
  1061. t.Fatalf("expected ExplainStmt, got %T", stmt)
  1062. }
  1063. if explain.QueryPlan {
  1064. t.Error("expected QueryPlan to be false")
  1065. }
  1066. _, ok = explain.Statement.(*SelectStmt)
  1067. if !ok {
  1068. t.Errorf("expected SelectStmt inside EXPLAIN, got %T", explain.Statement)
  1069. }
  1070. }
  1071. func TestParseExplainQueryPlan(t *testing.T) {
  1072. stmt := parse(t, "EXPLAIN QUERY PLAN SELECT * FROM users WHERE id = 1")
  1073. explain, ok := stmt.(*ExplainStmt)
  1074. if !ok {
  1075. t.Fatalf("expected ExplainStmt, got %T", stmt)
  1076. }
  1077. if !explain.QueryPlan {
  1078. t.Error("expected QueryPlan to be true")
  1079. }
  1080. sel, ok := explain.Statement.(*SelectStmt)
  1081. if !ok {
  1082. t.Errorf("expected SelectStmt inside EXPLAIN, got %T", explain.Statement)
  1083. }
  1084. if sel.Where == nil {
  1085. t.Error("expected WHERE clause in explained statement")
  1086. }
  1087. }
  1088. func TestParseExplainInsert(t *testing.T) {
  1089. stmt := parse(t, "EXPLAIN INSERT INTO users (name) VALUES ('John')")
  1090. explain := stmt.(*ExplainStmt)
  1091. _, ok := explain.Statement.(*InsertStmt)
  1092. if !ok {
  1093. t.Errorf("expected InsertStmt inside EXPLAIN, got %T", explain.Statement)
  1094. }
  1095. }
  1096. // Phase 5: Transaction statement tests
  1097. func TestParseBegin(t *testing.T) {
  1098. stmt := parse(t, "BEGIN")
  1099. _, ok := stmt.(*BeginStmt)
  1100. if !ok {
  1101. t.Fatalf("expected BeginStmt, got %T", stmt)
  1102. }
  1103. }
  1104. func TestParseBeginTransaction(t *testing.T) {
  1105. stmt := parse(t, "BEGIN TRANSACTION")
  1106. _, ok := stmt.(*BeginStmt)
  1107. if !ok {
  1108. t.Fatalf("expected BeginStmt, got %T", stmt)
  1109. }
  1110. }
  1111. func TestParseCommit(t *testing.T) {
  1112. stmt := parse(t, "COMMIT")
  1113. _, ok := stmt.(*CommitStmt)
  1114. if !ok {
  1115. t.Fatalf("expected CommitStmt, got %T", stmt)
  1116. }
  1117. }
  1118. func TestParseCommitTransaction(t *testing.T) {
  1119. stmt := parse(t, "COMMIT TRANSACTION")
  1120. _, ok := stmt.(*CommitStmt)
  1121. if !ok {
  1122. t.Fatalf("expected CommitStmt, got %T", stmt)
  1123. }
  1124. }
  1125. func TestParseRollback(t *testing.T) {
  1126. stmt := parse(t, "ROLLBACK")
  1127. rollback, ok := stmt.(*RollbackStmt)
  1128. if !ok {
  1129. t.Fatalf("expected RollbackStmt, got %T", stmt)
  1130. }
  1131. if rollback.Savepoint != "" {
  1132. t.Errorf("expected empty savepoint, got %s", rollback.Savepoint)
  1133. }
  1134. }
  1135. func TestParseRollbackToSavepoint(t *testing.T) {
  1136. stmt := parse(t, "ROLLBACK TO SAVEPOINT sp1")
  1137. rollback, ok := stmt.(*RollbackStmt)
  1138. if !ok {
  1139. t.Fatalf("expected RollbackStmt, got %T", stmt)
  1140. }
  1141. if rollback.Savepoint != "sp1" {
  1142. t.Errorf("expected savepoint 'sp1', got %s", rollback.Savepoint)
  1143. }
  1144. }
  1145. func TestParseRollbackTo(t *testing.T) {
  1146. stmt := parse(t, "ROLLBACK TO sp1")
  1147. rollback := stmt.(*RollbackStmt)
  1148. if rollback.Savepoint != "sp1" {
  1149. t.Errorf("expected savepoint 'sp1', got %s", rollback.Savepoint)
  1150. }
  1151. }
  1152. func TestParseSavepoint(t *testing.T) {
  1153. stmt := parse(t, "SAVEPOINT my_savepoint")
  1154. sp, ok := stmt.(*SavepointStmt)
  1155. if !ok {
  1156. t.Fatalf("expected SavepointStmt, got %T", stmt)
  1157. }
  1158. if sp.Name != "my_savepoint" {
  1159. t.Errorf("expected savepoint name 'my_savepoint', got %s", sp.Name)
  1160. }
  1161. }
  1162. func TestParseReleaseSavepoint(t *testing.T) {
  1163. stmt := parse(t, "RELEASE SAVEPOINT sp1")
  1164. rel, ok := stmt.(*ReleaseStmt)
  1165. if !ok {
  1166. t.Fatalf("expected ReleaseStmt, got %T", stmt)
  1167. }
  1168. if rel.Name != "sp1" {
  1169. t.Errorf("expected savepoint name 'sp1', got %s", rel.Name)
  1170. }
  1171. }
  1172. func TestParseRelease(t *testing.T) {
  1173. stmt := parse(t, "RELEASE sp1")
  1174. rel := stmt.(*ReleaseStmt)
  1175. if rel.Name != "sp1" {
  1176. t.Errorf("expected savepoint name 'sp1', got %s", rel.Name)
  1177. }
  1178. }
  1179. // Benchmark
  1180. func BenchmarkParseSelect(b *testing.B) {
  1181. input := `SELECT u.id, u.name, u.email, COUNT(o.id) as order_count
  1182. FROM users u
  1183. LEFT JOIN orders o ON u.id = o.user_id
  1184. WHERE u.active = TRUE AND u.created_at >= '2024-01-01'
  1185. GROUP BY u.id, u.name, u.email
  1186. HAVING COUNT(o.id) > 5
  1187. ORDER BY order_count DESC
  1188. LIMIT 100 OFFSET 0`
  1189. b.ResetTimer()
  1190. for i := 0; i < b.N; i++ {
  1191. l := lexer.New(input)
  1192. p := New(l)
  1193. _, _ = p.Parse()
  1194. }
  1195. }
  1196. func BenchmarkParseCreateTable(b *testing.B) {
  1197. input := `CREATE TABLE users (
  1198. id INTEGER PRIMARY KEY AUTOINCREMENT,
  1199. name TEXT NOT NULL,
  1200. email VARCHAR(255) UNIQUE,
  1201. age INTEGER DEFAULT 0,
  1202. active BOOLEAN DEFAULT TRUE,
  1203. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  1204. )`
  1205. b.ResetTimer()
  1206. for i := 0; i < b.N; i++ {
  1207. l := lexer.New(input)
  1208. p := New(l)
  1209. _, _ = p.Parse()
  1210. }
  1211. }
  1212. // CREATE INDEX tests
  1213. func TestParseCreateIndex(t *testing.T) {
  1214. stmt := parse(t, "CREATE INDEX idx_email ON users (email)")
  1215. idx, ok := stmt.(*CreateIndexStmt)
  1216. if !ok {
  1217. t.Fatalf("expected CreateIndexStmt, got %T", stmt)
  1218. }
  1219. if idx.Name != "idx_email" {
  1220. t.Errorf("expected index name idx_email, got %s", idx.Name)
  1221. }
  1222. if idx.Table != "users" {
  1223. t.Errorf("expected table users, got %s", idx.Table)
  1224. }
  1225. if len(idx.Columns) != 1 || idx.Columns[0].Name != "email" {
  1226. t.Error("expected column email")
  1227. }
  1228. if idx.Unique {
  1229. t.Error("expected non-unique index")
  1230. }
  1231. if idx.IfNotExists {
  1232. t.Error("expected IfNotExists to be false")
  1233. }
  1234. }
  1235. func TestParseCreateUniqueIndex(t *testing.T) {
  1236. stmt := parse(t, "CREATE UNIQUE INDEX idx_email ON users (email)")
  1237. idx, ok := stmt.(*CreateIndexStmt)
  1238. if !ok {
  1239. t.Fatalf("expected CreateIndexStmt, got %T", stmt)
  1240. }
  1241. if !idx.Unique {
  1242. t.Error("expected unique index")
  1243. }
  1244. }
  1245. func TestParseCreateIndexIfNotExists(t *testing.T) {
  1246. stmt := parse(t, "CREATE INDEX IF NOT EXISTS idx_email ON users (email)")
  1247. idx, ok := stmt.(*CreateIndexStmt)
  1248. if !ok {
  1249. t.Fatalf("expected CreateIndexStmt, got %T", stmt)
  1250. }
  1251. if !idx.IfNotExists {
  1252. t.Error("expected IfNotExists to be true")
  1253. }
  1254. }
  1255. func TestParseCreateIndexMultiColumn(t *testing.T) {
  1256. stmt := parse(t, "CREATE INDEX idx_name_email ON users (name, email)")
  1257. idx, ok := stmt.(*CreateIndexStmt)
  1258. if !ok {
  1259. t.Fatalf("expected CreateIndexStmt, got %T", stmt)
  1260. }
  1261. if len(idx.Columns) != 2 {
  1262. t.Fatalf("expected 2 columns, got %d", len(idx.Columns))
  1263. }
  1264. if idx.Columns[0].Name != "name" {
  1265. t.Errorf("expected first column name, got %s", idx.Columns[0].Name)
  1266. }
  1267. if idx.Columns[1].Name != "email" {
  1268. t.Errorf("expected second column email, got %s", idx.Columns[1].Name)
  1269. }
  1270. }
  1271. func TestParseCreateIndexWithDesc(t *testing.T) {
  1272. stmt := parse(t, "CREATE INDEX idx_created ON users (created_at DESC)")
  1273. idx, ok := stmt.(*CreateIndexStmt)
  1274. if !ok {
  1275. t.Fatalf("expected CreateIndexStmt, got %T", stmt)
  1276. }
  1277. if len(idx.Columns) != 1 {
  1278. t.Fatalf("expected 1 column, got %d", len(idx.Columns))
  1279. }
  1280. if !idx.Columns[0].Desc {
  1281. t.Error("expected DESC ordering")
  1282. }
  1283. }
  1284. // DROP INDEX tests
  1285. func TestParseDropIndex(t *testing.T) {
  1286. stmt := parse(t, "DROP INDEX idx_email")
  1287. drop, ok := stmt.(*DropIndexStmt)
  1288. if !ok {
  1289. t.Fatalf("expected DropIndexStmt, got %T", stmt)
  1290. }
  1291. if drop.Name != "idx_email" {
  1292. t.Errorf("expected index name idx_email, got %s", drop.Name)
  1293. }
  1294. if drop.IfExists {
  1295. t.Error("expected IfExists to be false")
  1296. }
  1297. }
  1298. func TestParseDropIndexIfExists(t *testing.T) {
  1299. stmt := parse(t, "DROP INDEX IF EXISTS idx_email")
  1300. drop, ok := stmt.(*DropIndexStmt)
  1301. if !ok {
  1302. t.Fatalf("expected DropIndexStmt, got %T", stmt)
  1303. }
  1304. if !drop.IfExists {
  1305. t.Error("expected IfExists to be true")
  1306. }
  1307. }
  1308. // Subquery in FROM clause tests
  1309. func TestParseSelectFromSubquery(t *testing.T) {
  1310. stmt := parse(t, "SELECT * FROM (SELECT id, name FROM users) AS u")
  1311. sel, ok := stmt.(*SelectStmt)
  1312. if !ok {
  1313. t.Fatalf("expected SelectStmt, got %T", stmt)
  1314. }
  1315. if len(sel.From) != 1 {
  1316. t.Fatalf("expected 1 FROM item, got %d", len(sel.From))
  1317. }
  1318. if sel.From[0].Subquery == nil {
  1319. t.Fatal("expected subquery in FROM")
  1320. }
  1321. if sel.From[0].Alias != "u" {
  1322. t.Errorf("expected alias 'u', got '%s'", sel.From[0].Alias)
  1323. }
  1324. // Check subquery
  1325. subquery := sel.From[0].Subquery
  1326. if len(subquery.Columns) != 2 {
  1327. t.Errorf("expected 2 columns in subquery, got %d", len(subquery.Columns))
  1328. }
  1329. if len(subquery.From) != 1 || subquery.From[0].Name != "users" {
  1330. t.Error("expected subquery FROM users")
  1331. }
  1332. }
  1333. func TestParseSelectFromSubqueryWithWhere(t *testing.T) {
  1334. stmt := parse(t, "SELECT name FROM (SELECT id, name FROM users WHERE active = TRUE) AS active_users WHERE id > 10")
  1335. sel, ok := stmt.(*SelectStmt)
  1336. if !ok {
  1337. t.Fatalf("expected SelectStmt, got %T", stmt)
  1338. }
  1339. if sel.From[0].Subquery == nil {
  1340. t.Fatal("expected subquery in FROM")
  1341. }
  1342. // Check outer WHERE clause
  1343. if sel.Where == nil {
  1344. t.Error("expected outer WHERE clause")
  1345. }
  1346. // Check subquery WHERE clause
  1347. if sel.From[0].Subquery.Where == nil {
  1348. t.Error("expected subquery WHERE clause")
  1349. }
  1350. }
  1351. func TestParseSelectFromSubqueryComplex(t *testing.T) {
  1352. stmt := parse(t, "SELECT u.name, u.total FROM (SELECT user_id, SUM(amount) AS total FROM orders GROUP BY user_id) AS u")
  1353. sel, ok := stmt.(*SelectStmt)
  1354. if !ok {
  1355. t.Fatalf("expected SelectStmt, got %T", stmt)
  1356. }
  1357. if sel.From[0].Subquery == nil {
  1358. t.Fatal("expected subquery in FROM")
  1359. }
  1360. subquery := sel.From[0].Subquery
  1361. if len(subquery.GroupBy) == 0 {
  1362. t.Error("expected GROUP BY in subquery")
  1363. }
  1364. // Check that columns reference the alias
  1365. if len(sel.Columns) != 2 {
  1366. t.Fatalf("expected 2 columns, got %d", len(sel.Columns))
  1367. }
  1368. }
  1369. func TestParseSelectFromNestedSubquery(t *testing.T) {
  1370. stmt := parse(t, "SELECT * FROM (SELECT * FROM (SELECT id FROM users) AS inner_q) AS outer_q")
  1371. sel, ok := stmt.(*SelectStmt)
  1372. if !ok {
  1373. t.Fatalf("expected SelectStmt, got %T", stmt)
  1374. }
  1375. if sel.From[0].Subquery == nil {
  1376. t.Fatal("expected subquery in FROM")
  1377. }
  1378. // Check nested subquery
  1379. outerSubquery := sel.From[0].Subquery
  1380. if len(outerSubquery.From) == 0 || outerSubquery.From[0].Subquery == nil {
  1381. t.Error("expected nested subquery")
  1382. }
  1383. }
  1384. // ALTER TABLE tests
  1385. func TestParseAlterTableAddColumn(t *testing.T) {
  1386. stmt := parse(t, "ALTER TABLE users ADD COLUMN age INTEGER")
  1387. alter, ok := stmt.(*AlterTableStmt)
  1388. if !ok {
  1389. t.Fatalf("expected AlterTableStmt, got %T", stmt)
  1390. }
  1391. if alter.Table != "users" {
  1392. t.Errorf("expected table users, got %s", alter.Table)
  1393. }
  1394. action, ok := alter.Action.(*AddColumnAction)
  1395. if !ok {
  1396. t.Fatalf("expected AddColumnAction, got %T", alter.Action)
  1397. }
  1398. if action.Column.Name != "age" {
  1399. t.Errorf("expected column name age, got %s", action.Column.Name)
  1400. }
  1401. if action.Column.Type.Name != "INTEGER" {
  1402. t.Errorf("expected column type INTEGER, got %s", action.Column.Type.Name)
  1403. }
  1404. }
  1405. func TestParseAlterTableAddColumnOptional(t *testing.T) {
  1406. stmt := parse(t, "ALTER TABLE users ADD age INTEGER")
  1407. alter, ok := stmt.(*AlterTableStmt)
  1408. if !ok {
  1409. t.Fatalf("expected AlterTableStmt, got %T", stmt)
  1410. }
  1411. action, ok := alter.Action.(*AddColumnAction)
  1412. if !ok {
  1413. t.Fatalf("expected AddColumnAction, got %T", alter.Action)
  1414. }
  1415. if action.Column.Name != "age" {
  1416. t.Errorf("expected column name age, got %s", action.Column.Name)
  1417. }
  1418. }
  1419. func TestParseAlterTableDropColumn(t *testing.T) {
  1420. stmt := parse(t, "ALTER TABLE users DROP COLUMN email")
  1421. alter, ok := stmt.(*AlterTableStmt)
  1422. if !ok {
  1423. t.Fatalf("expected AlterTableStmt, got %T", stmt)
  1424. }
  1425. action, ok := alter.Action.(*DropColumnAction)
  1426. if !ok {
  1427. t.Fatalf("expected DropColumnAction, got %T", alter.Action)
  1428. }
  1429. if action.Column != "email" {
  1430. t.Errorf("expected column email, got %s", action.Column)
  1431. }
  1432. }
  1433. func TestParseAlterTableRename(t *testing.T) {
  1434. stmt := parse(t, "ALTER TABLE users RENAME TO customers")
  1435. alter, ok := stmt.(*AlterTableStmt)
  1436. if !ok {
  1437. t.Fatalf("expected AlterTableStmt, got %T", stmt)
  1438. }
  1439. action, ok := alter.Action.(*RenameTableAction)
  1440. if !ok {
  1441. t.Fatalf("expected RenameTableAction, got %T", alter.Action)
  1442. }
  1443. if action.NewName != "customers" {
  1444. t.Errorf("expected new name customers, got %s", action.NewName)
  1445. }
  1446. }
  1447. func TestParseAlterTableRenameColumn(t *testing.T) {
  1448. stmt := parse(t, "ALTER TABLE users RENAME COLUMN name TO full_name")
  1449. alter, ok := stmt.(*AlterTableStmt)
  1450. if !ok {
  1451. t.Fatalf("expected AlterTableStmt, got %T", stmt)
  1452. }
  1453. action, ok := alter.Action.(*RenameColumnAction)
  1454. if !ok {
  1455. t.Fatalf("expected RenameColumnAction, got %T", alter.Action)
  1456. }
  1457. if action.OldName != "name" {
  1458. t.Errorf("expected old name 'name', got %s", action.OldName)
  1459. }
  1460. if action.NewName != "full_name" {
  1461. t.Errorf("expected new name 'full_name', got %s", action.NewName)
  1462. }
  1463. }
  1464. // ATTACH/DETACH DATABASE tests
  1465. func TestParseAttach(t *testing.T) {
  1466. stmt := parse(t, "ATTACH DATABASE 'test.db' AS testdb")
  1467. attach, ok := stmt.(*AttachStmt)
  1468. if !ok {
  1469. t.Fatalf("expected AttachStmt, got %T", stmt)
  1470. }
  1471. if attach.FilePath != "test.db" {
  1472. t.Errorf("expected file path 'test.db', got '%s'", attach.FilePath)
  1473. }
  1474. if attach.Alias != "testdb" {
  1475. t.Errorf("expected alias 'testdb', got '%s'", attach.Alias)
  1476. }
  1477. }
  1478. func TestParseAttachOptional(t *testing.T) {
  1479. stmt := parse(t, "ATTACH 'another.db' AS other")
  1480. attach, ok := stmt.(*AttachStmt)
  1481. if !ok {
  1482. t.Fatalf("expected AttachStmt, got %T", stmt)
  1483. }
  1484. if attach.FilePath != "another.db" {
  1485. t.Errorf("expected file path 'another.db', got '%s'", attach.FilePath)
  1486. }
  1487. if attach.Alias != "other" {
  1488. t.Errorf("expected alias 'other', got '%s'", attach.Alias)
  1489. }
  1490. }
  1491. func TestParseDetach(t *testing.T) {
  1492. stmt := parse(t, "DETACH DATABASE testdb")
  1493. detach, ok := stmt.(*DetachStmt)
  1494. if !ok {
  1495. t.Fatalf("expected DetachStmt, got %T", stmt)
  1496. }
  1497. if detach.Alias != "testdb" {
  1498. t.Errorf("expected alias 'testdb', got '%s'", detach.Alias)
  1499. }
  1500. }
  1501. func TestParseDetachOptional(t *testing.T) {
  1502. stmt := parse(t, "DETACH other")
  1503. detach, ok := stmt.(*DetachStmt)
  1504. if !ok {
  1505. t.Fatalf("expected DetachStmt, got %T", stmt)
  1506. }
  1507. if detach.Alias != "other" {
  1508. t.Errorf("expected alias 'other', got '%s'", detach.Alias)
  1509. }
  1510. }
  1511. // The foreign-key clause parser must not swallow a following column constraint:
  1512. // NOT NULL after REFERENCES belongs to the column, and NOT DEFERRABLE is the
  1513. // default that is accepted and recorded as immediate enforcement.
  1514. func TestParseInlineForeignKeyClauseBoundaries(t *testing.T) {
  1515. stmt := parse(t, "CREATE TABLE t (id INTEGER PRIMARY KEY, pid INTEGER REFERENCES p(id) NOT NULL UNIQUE)")
  1516. create := stmt.(*CreateTableStmt)
  1517. column := create.Columns[1]
  1518. if len(column.Constraints) != 3 {
  1519. t.Fatalf("constraints = %+v, want REFERENCES, NOT NULL, and UNIQUE", column.Constraints)
  1520. }
  1521. if column.Constraints[0].Type != ConstraintForeignKey || column.Constraints[0].RefTable != "p" {
  1522. t.Fatalf("foreign key = %+v", column.Constraints[0])
  1523. }
  1524. if len(column.Constraints[0].RefColumns) != 1 || column.Constraints[0].RefColumns[0] != "id" {
  1525. t.Fatalf("ref columns = %v, want [id]", column.Constraints[0].RefColumns)
  1526. }
  1527. if column.Constraints[1].Type != ConstraintNotNull || column.Constraints[2].Type != ConstraintUnique {
  1528. t.Fatalf("following constraints = %+v, want NOT NULL then UNIQUE", column.Constraints[1:])
  1529. }
  1530. stmt = parse(t, "CREATE TABLE t2 (pid INTEGER REFERENCES p(id) NOT DEFERRABLE)")
  1531. column = stmt.(*CreateTableStmt).Columns[0]
  1532. if len(column.Constraints) != 1 || column.Constraints[0].Type != ConstraintForeignKey {
  1533. t.Fatalf("constraints = %+v, want one foreign key", column.Constraints)
  1534. }
  1535. if column.Constraints[0].Deferrable {
  1536. t.Fatal("NOT DEFERRABLE was recorded as deferrable")
  1537. }
  1538. stmt = parse(t, "CREATE TABLE t3 (pid INTEGER REFERENCES p(id) ON DELETE RESTRICT ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED)")
  1539. constraint := stmt.(*CreateTableStmt).Columns[0].Constraints[0]
  1540. if constraint.OnDelete != RefActionRestrict || constraint.OnUpdate != RefActionNoAction {
  1541. t.Fatalf("actions = %v/%v, want RESTRICT/NO ACTION", constraint.OnDelete, constraint.OnUpdate)
  1542. }
  1543. if !constraint.Deferrable {
  1544. t.Fatal("DEFERRABLE INITIALLY DEFERRED was not recorded")
  1545. }
  1546. }