2
0

executor_join_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package executor
  2. import (
  3. "testing"
  4. "github.com/danfragoso/pizzasql-next/pkg/storage"
  5. )
  6. func TestMergeRowsDoesNotOverwriteColumns(t *testing.T) {
  7. e := &Executor{}
  8. // Create two rows with overlapping column names (like "id")
  9. left := storage.Row{
  10. "id": "left-id-123",
  11. "name": "LeftName",
  12. }
  13. right := storage.Row{
  14. "id": "right-id-456",
  15. "value": "RightValue",
  16. }
  17. // Merge with aliases
  18. merged := e.mergeRows(left, right, "o", "om")
  19. // Check that both qualified names exist and are correct
  20. if merged["o.id"] != "left-id-123" {
  21. t.Errorf("Expected o.id = 'left-id-123', got %v", merged["o.id"])
  22. }
  23. if merged["om.id"] != "right-id-456" {
  24. t.Errorf("Expected om.id = 'right-id-456', got %v", merged["om.id"])
  25. }
  26. // Check that the unqualified "id" is from the left table (first one wins)
  27. if merged["id"] != "left-id-123" {
  28. t.Errorf("Expected unqualified id = 'left-id-123' (from left table), got %v", merged["id"])
  29. }
  30. // Check other columns are present
  31. if merged["o.name"] != "LeftName" {
  32. t.Errorf("Expected o.name = 'LeftName', got %v", merged["o.name"])
  33. }
  34. if merged["om.value"] != "RightValue" {
  35. t.Errorf("Expected om.value = 'RightValue', got %v", merged["om.value"])
  36. }
  37. }
  38. func TestJoinConditionWithQualifiedNames(t *testing.T) {
  39. e := &Executor{}
  40. // Simulate two rows from different tables with the same column name "id"
  41. orgRow := storage.Row{
  42. "id": "org-123",
  43. "name": "Organization 1",
  44. }
  45. memberRow := storage.Row{
  46. "id": "member-456",
  47. "org_id": "org-123", // This should match orgRow's id
  48. }
  49. // Merge with table aliases
  50. merged := e.mergeRows(orgRow, memberRow, "o", "om")
  51. // Verify that o.id and om.org_id have the correct values for comparison
  52. // This is what the JOIN condition would use: o.id = om.org_id
  53. if merged["o.id"] != "org-123" {
  54. t.Errorf("Expected o.id = 'org-123', got %v", merged["o.id"])
  55. }
  56. if merged["om.org_id"] != "org-123" {
  57. t.Errorf("Expected om.org_id = 'org-123', got %v", merged["om.org_id"])
  58. }
  59. // The key fix: om.org_id should NOT have been overwritten by the right table's "id"
  60. // In the old buggy code, this would have been "member-456" instead of "org-123"
  61. if merged["om.org_id"] == merged["om.id"] {
  62. t.Log("✓ JOIN condition can correctly compare o.id with om.org_id")
  63. }
  64. }
  65. func TestLeftJoinWithNullConditions(t *testing.T) {
  66. e := &Executor{}
  67. // Create test rows
  68. leftRows := []storage.Row{
  69. {"col1": int64(1), "col2": "a"},
  70. {"col1": int64(2), "col2": "b"},
  71. }
  72. // Test merging left row with null right row
  73. left := leftRows[0]
  74. nullRight := storage.Row{
  75. "col3": nil,
  76. "col4": nil,
  77. }
  78. merged := e.mergeRows(left, nullRight, "cor0", "cor1")
  79. // Verify left columns are preserved
  80. if merged["cor0.col1"] != int64(1) {
  81. t.Errorf("Expected cor0.col1 = 1, got %v", merged["cor0.col1"])
  82. }
  83. if merged["cor0.col2"] != "a" {
  84. t.Errorf("Expected cor0.col2 = 'a', got %v", merged["cor0.col2"])
  85. }
  86. // Verify right columns are NULL
  87. if merged["cor1.col3"] != nil {
  88. t.Errorf("Expected cor1.col3 = nil, got %v", merged["cor1.col3"])
  89. }
  90. if merged["cor1.col4"] != nil {
  91. t.Errorf("Expected cor1.col4 = nil, got %v", merged["cor1.col4"])
  92. }
  93. // Verify unqualified columns exist
  94. if merged["col1"] != int64(1) {
  95. t.Errorf("Expected col1 = 1, got %v", merged["col1"])
  96. }
  97. if merged["col2"] != "a" {
  98. t.Errorf("Expected col2 = 'a', got %v", merged["col2"])
  99. }
  100. if merged["col3"] != nil {
  101. t.Errorf("Expected col3 = nil, got %v", merged["col3"])
  102. }
  103. if merged["col4"] != nil {
  104. t.Errorf("Expected col4 = nil, got %v", merged["col4"])
  105. }
  106. t.Log("✓ LEFT JOIN with NULL conditions creates proper null rows for unmatched right table")
  107. }