github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/migration/build_events_bigint_test.go (about) 1 package migration_test 2 3 import ( 4 "database/sql" 5 "fmt" 6 "strings" 7 8 . "github.com/onsi/ginkgo" 9 . "github.com/onsi/gomega" 10 ) 11 12 var _ = Describe("build_events bigint indexes", func() { 13 const preMigrationVersion = 1602860421 14 const postMigrationVersion = 1606068653 15 const downMigrationVersion = 1603405319 16 17 var db *sql.DB 18 var teamID int 19 var pipelineID int 20 21 explain := func(query string, params ...interface{}) string { 22 rows, err := db.Query("SET enable_seqscan = OFF; EXPLAIN "+query, params...) 23 Expect(err).ToNot(HaveOccurred()) 24 25 lines := []string{} 26 for rows.Next() { 27 var line string 28 Expect(rows.Scan(&line)).To(Succeed()) 29 lines = append(lines, line) 30 } 31 32 return strings.Join(lines, "\n") 33 } 34 35 BeforeEach(func() { 36 db = postgresRunner.OpenDBAtVersion(preMigrationVersion) 37 38 err := db.QueryRow(` 39 INSERT INTO teams (name, auth) 40 VALUES ('some-team', '{}') 41 RETURNING id 42 `).Scan(&teamID) 43 Expect(err).ToNot(HaveOccurred()) 44 45 err = db.QueryRow(` 46 INSERT INTO pipelines (name, team_id) 47 VALUES ('some-pipeline', $1) 48 RETURNING id 49 `, teamID).Scan(&pipelineID) 50 Expect(err).ToNot(HaveOccurred()) 51 52 postgresRunner.MigrateToVersion(postMigrationVersion) 53 }) 54 55 AfterEach(func() { 56 Expect(db.Close()).To(Succeed()) 57 }) 58 59 Describe("Up", func() { 60 It("has indexes for both build_id_old and build_id in parent table", func() { 61 plan := explain(`SELECT * FROM build_events WHERE build_id = 1`) 62 Expect(plan).To(ContainSubstring("Index Scan")) 63 64 plan = explain(`SELECT * FROM build_events WHERE build_id_old = 1`) 65 Expect(plan).To(ContainSubstring("Index Scan")) 66 }) 67 68 It("has indexes for both build_id_old and build_id in pipeline partitions", func() { 69 plan := explain(fmt.Sprintf( 70 `SELECT * FROM pipeline_build_events_%d WHERE build_id = 1`, 71 pipelineID, 72 )) 73 Expect(plan).To(ContainSubstring("Index Scan")) 74 75 plan = explain(fmt.Sprintf( 76 `SELECT * FROM pipeline_build_events_%d WHERE build_id_old = 1`, 77 pipelineID, 78 )) 79 Expect(plan).To(ContainSubstring("Index Scan")) 80 }) 81 82 It("has indexes for only build_id in team partitions", func() { 83 plan := explain(fmt.Sprintf( 84 `SELECT * FROM team_build_events_%d WHERE build_id = 1`, 85 teamID, 86 )) 87 Expect(plan).To(ContainSubstring("Index Scan")) 88 89 plan = explain(fmt.Sprintf( 90 `SELECT * FROM team_build_events_%d WHERE build_id_old = 1`, 91 pipelineID, 92 )) 93 Expect(plan).To(ContainSubstring("Seq Scan")) 94 }) 95 96 It("has indexes for newly created team partitions", func() { 97 var newTeamID int 98 err := db.QueryRow(` 99 INSERT INTO teams (name, auth) 100 VALUES ('some-other-team', '{}') 101 RETURNING id 102 `).Scan(&newTeamID) 103 Expect(err).ToNot(HaveOccurred()) 104 105 plan := explain(fmt.Sprintf( 106 `SELECT * FROM team_build_events_%d WHERE build_id = 1`, 107 newTeamID, 108 )) 109 Expect(plan).To(ContainSubstring("Index Scan")) 110 }) 111 112 It("has indexes for both build_id and build_id_old in newly created pipeline partitions", func() { 113 var newPipelineID int 114 err := db.QueryRow(` 115 INSERT INTO pipelines (name, team_id) 116 VALUES ('some-other-pipeline', $1) 117 RETURNING id 118 `, teamID).Scan(&newPipelineID) 119 Expect(err).ToNot(HaveOccurred()) 120 121 plan := explain(fmt.Sprintf( 122 `SELECT * FROM pipeline_build_events_%d WHERE build_id = 1`, 123 newPipelineID, 124 )) 125 Expect(plan).To(ContainSubstring("Index Scan")) 126 127 plan = explain(fmt.Sprintf( 128 `SELECT * FROM pipeline_build_events_%d WHERE build_id_old = 1`, 129 newPipelineID, 130 )) 131 Expect(plan).To(ContainSubstring("Index Scan")) 132 }) 133 }) 134 135 Describe("Down", func() { 136 BeforeEach(func() { 137 postgresRunner.MigrateToVersion(downMigrationVersion) 138 }) 139 140 It("has index for build_id", func() { 141 plan := explain(`SELECT * FROM build_events WHERE build_id = 1`) 142 Expect(plan).To(ContainSubstring("Index Scan")) 143 Expect(plan).ToNot(ContainSubstring("build_id_old")) 144 }) 145 146 It("has index for build_id_old in pipeline partitions", func() { 147 plan := explain(fmt.Sprintf( 148 `SELECT * FROM pipeline_build_events_%d WHERE build_id_old = 1`, 149 pipelineID, 150 )) 151 Expect(plan).To(ContainSubstring("Index Scan")) 152 }) 153 154 It("does not have index for build_id in pipeline partitions", func() { 155 plan := explain(fmt.Sprintf( 156 `SELECT * FROM pipeline_build_events_%d WHERE build_id = 1`, 157 pipelineID, 158 )) 159 Expect(plan).To(ContainSubstring("Seq Scan")) 160 }) 161 162 It("does not have index for build_id in team partitions", func() { 163 plan := explain(fmt.Sprintf( 164 `SELECT * FROM team_build_events_%d WHERE build_id = 1`, 165 teamID, 166 )) 167 Expect(plan).To(ContainSubstring("Seq Scan")) 168 }) 169 170 It("does not have index for build_id in newly created team partitions", func() { 171 var newTeamID int 172 err := db.QueryRow(` 173 INSERT INTO teams (name, auth) 174 VALUES ('some-other-team', '{}') 175 RETURNING id 176 `).Scan(&newTeamID) 177 Expect(err).ToNot(HaveOccurred()) 178 179 plan := explain(fmt.Sprintf( 180 `SELECT * FROM team_build_events_%d WHERE build_id = 1`, 181 newTeamID, 182 )) 183 Expect(plan).To(ContainSubstring("Seq Scan")) 184 }) 185 186 It("has index for build_id in newly created pipeline partitions", func() { 187 var newPipelineID int 188 err := db.QueryRow(` 189 INSERT INTO pipelines (name, team_id) 190 VALUES ('some-other-pipeline', $1) 191 RETURNING id 192 `, teamID).Scan(&newPipelineID) 193 Expect(err).ToNot(HaveOccurred()) 194 195 plan := explain(fmt.Sprintf( 196 `SELECT * FROM pipeline_build_events_%d WHERE build_id = 1`, 197 newPipelineID, 198 )) 199 Expect(plan).To(ContainSubstring("Index Scan")) 200 }) 201 }) 202 })