14
14
import org .junit .*;
15
15
import org .junit .rules .ExpectedException ;
16
16
import org .postgresql .util .PSQLException ;
17
+ import static org .junit .Assert .assertEquals ;
17
18
18
19
public class AlterTableTest extends PLTestBase {
19
20
private Connection conn ;
@@ -32,6 +33,8 @@ public class AlterTableTest extends PLTestBase {
32
33
private static final String SQL_RENAME_COLUMN =
33
34
"ALTER TABLE foo RENAME year to month;" ;
34
35
36
+ private static final double EPSILON = 1e-6 ;
37
+
35
38
36
39
@ Rule
37
40
public ExpectedException thrown = ExpectedException .none ();
@@ -193,4 +196,207 @@ public void test_RenameCol_Concurrent() throws SQLException {
193
196
// conn2.commit();
194
197
// }
195
198
199
+ /**
200
+ * Add a column to the table, and do some insertion.
201
+ */
202
+ @ Test
203
+ public void test_AddCol_Basic () throws SQLException {
204
+ String sql = "ALTER TABLE foo ADD month int;" ;
205
+ conn .createStatement ().execute (sql );
206
+ ResultSet rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
207
+ rs .next ();
208
+ checkRow (rs ,
209
+ new String [] {"id" , "year" , "month" },
210
+ new int [] {5 , 400 , 0 });
211
+ assertNoMoreRows (rs );
212
+
213
+ String sql2 = "INSERT INTO foo VALUES (6, 500, 1);" ;
214
+ conn .createStatement ().execute (sql2 );
215
+ rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
216
+ rs .next ();
217
+ checkRow (rs ,
218
+ new String [] {"id" , "year" , "month" },
219
+ new int [] {5 , 400 , 0 });
220
+ rs .next ();
221
+ checkRow (rs ,
222
+ new String [] {"id" , "year" , "month" },
223
+ new int [] {6 , 500 , 1 });
224
+ assertNoMoreRows (rs );
225
+ }
226
+
227
+ /**
228
+ * Add a column to a name that already exists, should throw exception
229
+ */
230
+ @ Test
231
+ public void test_AddCol_Exist () throws SQLException {
232
+ String sql = "ALTER TABLE foo ADD year int;" ;
233
+
234
+ // New column already exists
235
+ thrown .expect (PSQLException .class );
236
+ conn .createStatement ().execute (sql );
237
+ }
238
+
239
+ /**
240
+ * Drop a column from the table.
241
+ */
242
+ @ Test
243
+ public void test_DropCol_Basic () throws SQLException {
244
+ String sql = "ALTER TABLE foo DROP year;" ;
245
+ conn .createStatement ().execute (sql );
246
+ ResultSet rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
247
+ rs .next ();
248
+ checkRow (rs ,
249
+ new String [] {"id" },
250
+ new int [] {5 });
251
+ assertNoMoreRows (rs );
252
+
253
+ String sql2 = "INSERT INTO foo VALUES (6);" ;
254
+ conn .createStatement ().execute (sql2 );
255
+ rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
256
+ rs .next ();
257
+ checkRow (rs ,
258
+ new String [] {"id" },
259
+ new int [] {5 });
260
+ rs .next ();
261
+ checkRow (rs ,
262
+ new String [] {"id" },
263
+ new int [] {6 });
264
+ assertNoMoreRows (rs );
265
+ }
266
+
267
+ /**
268
+ * Drop a column that does not exists, should throw exception
269
+ */
270
+ @ Test
271
+ public void test_DropCol_NotExist () throws SQLException {
272
+ String sql = "ALTER TABLE foo DROP month;" ;
273
+
274
+ // Old column does not exist
275
+ thrown .expect (PSQLException .class );
276
+ conn .createStatement ().execute (sql );
277
+ }
278
+
279
+ /**
280
+ * Alter column type from int to float and then alter to int again.
281
+ */
282
+ @ Test
283
+ public void test_AlterType_Basic () throws SQLException {
284
+ String sql = "ALTER TABLE foo ALTER year TYPE float;" ;
285
+ conn .createStatement ().execute (sql );
286
+ ResultSet rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
287
+ rs .next ();
288
+ assertEquals (rs .getInt ("id" ), 5 );
289
+ assertEquals (rs .getFloat ("year" ), 400 , EPSILON );
290
+ assertNoMoreRows (rs );
291
+
292
+ String sql2 = "INSERT INTO foo VALUES (6, 3.5);" ;
293
+ conn .createStatement ().execute (sql2 );
294
+ rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
295
+ rs .next ();
296
+ assertEquals (rs .getInt ("id" ), 5 );
297
+ assertEquals (rs .getFloat ("year" ), 400 , EPSILON );
298
+ rs .next ();
299
+ assertEquals (rs .getInt ("id" ), 6 );
300
+ assertEquals (rs .getFloat ("year" ), 3.5 , EPSILON );
301
+ assertNoMoreRows (rs );
302
+
303
+ String sql3 = "ALTER TABLE foo ALTER year TYPE int;" ;
304
+ conn .createStatement ().execute (sql3 );
305
+ rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
306
+ rs .next ();
307
+ assertEquals (rs .getInt ("id" ), 5 );
308
+ assertEquals (rs .getInt ("year" ), 400 );
309
+ rs .next ();
310
+ assertEquals (rs .getInt ("id" ), 6 );
311
+ assertEquals (rs .getInt ("year" ), 3 );
312
+ assertNoMoreRows (rs );
313
+ }
314
+
315
+ /**
316
+ * Alter column type from int to varchar and backwards.
317
+ */
318
+ @ Test
319
+ public void test_AlterType_Varchar () throws SQLException {
320
+ String sql = "ALTER TABLE foo ALTER year TYPE varchar;" ;
321
+ conn .createStatement ().execute (sql );
322
+ ResultSet rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
323
+ rs .next ();
324
+ assertEquals (rs .getInt ("id" ), 5 );
325
+ assertEquals (rs .getString ("year" ), Integer .toString (400 ));
326
+ assertNoMoreRows (rs );
327
+
328
+ String sql2 = "ALTER TABLE foo ALTER year TYPE int;" ;
329
+ conn .createStatement ().execute (sql2 );
330
+ rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
331
+ rs .next ();
332
+ assertEquals (rs .getInt ("id" ), 5 );
333
+ assertEquals (rs .getInt ("year" ), 400 );
334
+ assertNoMoreRows (rs );
335
+ }
336
+
337
+ /**
338
+ * Alter type to column that does not exist
339
+ */
340
+ @ Test
341
+ public void test_AlterType_NonExist () throws SQLException {
342
+ String sql = "ALTER TABLE foo ALTER a TYPE int;" ;
343
+
344
+ thrown .expect (PSQLException .class );
345
+ conn .createStatement ().execute (sql );
346
+ }
347
+
348
+ /**
349
+ * Alter to an unsupported column type
350
+ */
351
+ @ Test
352
+ public void test_AlterType_UnSupported () throws SQLException {
353
+ String sql = "ALTER TABLE foo ALTER year TYPE non;" ;
354
+ thrown .expect (PSQLException .class );
355
+ conn .createStatement ().execute (sql );
356
+ }
357
+
358
+ /**
359
+ * Add columns, drop columns, change column type in one sql statement
360
+ */
361
+ @ Test
362
+ public void test_MultiOperation () throws SQLException {
363
+ String sql =
364
+ "ALTER TABLE foo ADD month INT, DROP year, ALTER id TYPE float;" ;
365
+ conn .createStatement ().execute (sql );
366
+ ResultSet rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
367
+ rs .next ();
368
+ assertEquals (rs .getFloat ("id" ), 5 , EPSILON );
369
+ assertEquals (rs .getInt ("month" ), 0 );
370
+ assertNoMoreRows (rs );
371
+
372
+ String sql2 = "INSERT INTO foo VALUES (4.5, 3);" ;
373
+ conn .createStatement ().execute (sql2 );
374
+ rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
375
+ rs .next ();
376
+ assertEquals (rs .getFloat ("id" ), 5 , EPSILON );
377
+ assertEquals (rs .getInt ("month" ), 0 );
378
+ rs .next ();
379
+ assertEquals (rs .getFloat ("id" ), 4.5 , EPSILON );
380
+ assertEquals (rs .getInt ("month" ), 3 );
381
+ assertNoMoreRows (rs );
382
+ }
383
+
384
+ /**
385
+ * If multiple operations in one statement failed, schema will not change
386
+ */
387
+ @ Test
388
+ public void test_MultiOperationFailed () throws SQLException {
389
+ String sql =
390
+ "ALTER TABLE foo ADD month int, DROP month, ALTER year TYPE float;" ;
391
+
392
+ thrown .expect (PSQLException .class );
393
+ conn .createStatement ().execute (sql );
394
+
395
+ ResultSet rs = conn .createStatement ().executeQuery (SQL_SELECT_STAR );
396
+ rs .next ();
397
+ checkRow (rs ,
398
+ new String [] {"id" , "year" },
399
+ new int [] {5 , 400 });
400
+ assertNoMoreRows (rs );
401
+ }
196
402
}
0 commit comments