@@ -278,7 +278,10 @@ TEST_F(UpdateSQLTests, UpdateSQLCastTest) {
278
278
txn_manager.CommitTransaction (txn);
279
279
}
280
280
281
- TEST_F (UpdateSQLTests, HalloweenTest) {
281
+ TEST_F (UpdateSQLTests, HalloweenProblemTest) {
282
+ // This SQL Test verifies that executor does not cause the Halloween Problem
283
+ // This test checks for tables without Primary Keys
284
+
282
285
LOG_DEBUG (" Bootstrapping..." );
283
286
284
287
auto catalog = catalog::Catalog::GetInstance ();
@@ -289,6 +292,12 @@ TEST_F(UpdateSQLTests, HalloweenTest) {
289
292
290
293
LOG_DEBUG (" Bootstrapping completed!" );
291
294
295
+ // Setting ActiveTileGroupCount to 3 in order to trigger the case where
296
+ // the executor scans TileGroup 0, inserts an empty version in TileGroup 1.
297
+ // It then inserts the updated version of the tuple in TileGroup 2.
298
+ // When it scans TileGroup 2, without the statement level WriteSet,
299
+ // it would have caused a second update on an already updated Tuple.
300
+
292
301
size_t active_tilegroup_count = 3 ;
293
302
storage::DataTable::SetActiveTileGroupCount (active_tilegroup_count);
294
303
@@ -310,9 +319,80 @@ TEST_F(UpdateSQLTests, HalloweenTest) {
310
319
TestingSQLUtil::ExecuteSQLQuery (" INSERT INTO test VALUES (10, 1000);" );
311
320
LOG_DEBUG (" Tuple inserted!" );
312
321
322
+ // Update a tuple in the table
323
+ LOG_DEBUG (" Updating a tuple..." );
324
+ LOG_DEBUG (" Query: UPDATE test SET a = a/2" );
325
+
326
+ std::vector<ResultValue> result;
327
+ std::vector<FieldInfo> tuple_descriptor;
328
+ std::string error_message;
329
+ int rows_affected;
330
+
331
+ TestingSQLUtil::ExecuteSQLQuery (" UPDATE test SET a = a/2;" , result,
332
+ tuple_descriptor, rows_affected,
333
+ error_message);
334
+
335
+ // Check the return value
336
+ EXPECT_EQ (1 , rows_affected);
337
+ LOG_DEBUG (" Tuple Updated!" );
313
338
txn_manager.CommitTransaction (txn);
314
339
315
- // Update a tuple into table
340
+ LOG_DEBUG (" Selecting updated value." );
341
+ txn = txn_manager.BeginTransaction ();
342
+ // Check value of column a after updating
343
+ TestingSQLUtil::ExecuteSQLQuery (" SELECT a from test" , result,
344
+ tuple_descriptor, rows_affected,
345
+ error_message);
346
+ // Check the return value
347
+ txn_manager.CommitTransaction (txn);
348
+
349
+ EXPECT_EQ (TestingSQLUtil::GetResultValueAsString (result, 0 ), " 5" );
350
+ LOG_DEBUG (" Successfully updated tuple." );
351
+
352
+ // free the database just created
353
+ txn = txn_manager.BeginTransaction ();
354
+ catalog::Catalog::GetInstance ()->DropDatabaseWithName (DEFAULT_DB_NAME, txn);
355
+ txn_manager.CommitTransaction (txn);
356
+ }
357
+
358
+ TEST_F (UpdateSQLTests, HalloweenProblemTestWithPK) {
359
+ // This SQL Test verifies that executor does not cause the Halloween Problem
360
+ // This test checks for tables with Primary Keys
361
+ // It checks for updates on both Non-Primary Key column & Primary Key column
362
+
363
+ LOG_DEBUG (" Bootstrapping..." );
364
+
365
+ auto catalog = catalog::Catalog::GetInstance ();
366
+ auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance ();
367
+ auto txn = txn_manager.BeginTransaction ();
368
+ catalog->CreateDatabase (DEFAULT_DB_NAME, txn);
369
+ txn_manager.CommitTransaction (txn);
370
+
371
+ LOG_DEBUG (" Bootstrapping completed!" );
372
+
373
+ // active_tilegroup_count set to 3, [Reason: Refer to HalloweenProblemTest]
374
+ size_t active_tilegroup_count = 3 ;
375
+ storage::DataTable::SetActiveTileGroupCount (active_tilegroup_count);
376
+
377
+ LOG_DEBUG (" Active tile group count = %zu" ,
378
+ storage::DataTable::GetActiveTileGroupCount ());
379
+ // Create a table first
380
+ LOG_DEBUG (" Creating a table..." );
381
+ LOG_DEBUG (" Query: CREATE TABLE test(a INT PRIMARY KEY, b INT)" );
382
+
383
+ TestingSQLUtil::ExecuteSQLQuery (" CREATE TABLE test(a INT PRIMARY KEY, b INT);" );
384
+
385
+ LOG_DEBUG (" Table created!" );
386
+
387
+ txn = txn_manager.BeginTransaction ();
388
+ // Insert a tuple into table
389
+ LOG_DEBUG (" Inserting a tuple..." );
390
+
391
+ LOG_DEBUG (" Query: INSERT INTO test VALUES (10, 100)" );
392
+ TestingSQLUtil::ExecuteSQLQuery (" INSERT INTO test VALUES (10, 1000);" );
393
+ LOG_DEBUG (" Tuple inserted!" );
394
+
395
+ // Update a tuple in table
316
396
LOG_DEBUG (" Updating a tuple..." );
317
397
LOG_DEBUG (" Query: UPDATE test SET a = a/2" );
318
398
@@ -321,19 +401,18 @@ TEST_F(UpdateSQLTests, HalloweenTest) {
321
401
std::string error_message;
322
402
int rows_affected;
323
403
324
- txn = txn_manager.BeginTransaction ();
325
404
TestingSQLUtil::ExecuteSQLQuery (" UPDATE test SET a = a/2;" , result,
326
405
tuple_descriptor, rows_affected,
327
406
error_message);
328
407
329
408
// Check the return value
330
409
EXPECT_EQ (1 , rows_affected);
331
- LOG_DEBUG (" Tuple Updated!" );
410
+ LOG_DEBUG (" Tuple Primary Key column Updated!" );
332
411
txn_manager.CommitTransaction (txn);
333
412
334
413
LOG_DEBUG (" Selecting updated value." );
335
414
txn = txn_manager.BeginTransaction ();
336
- // Check value of column salary after updating
415
+ // Check value of column a after updating
337
416
TestingSQLUtil::ExecuteSQLQuery (" SELECT a from test" , result,
338
417
tuple_descriptor, rows_affected,
339
418
error_message);
@@ -343,6 +422,34 @@ TEST_F(UpdateSQLTests, HalloweenTest) {
343
422
EXPECT_EQ (TestingSQLUtil::GetResultValueAsString (result, 0 ), " 5" );
344
423
LOG_DEBUG (" Successfully updated tuple." );
345
424
425
+ txn = txn_manager.BeginTransaction ();
426
+
427
+ LOG_DEBUG (" Updating a tuple..." );
428
+ LOG_DEBUG (" Query: UPDATE test SET b = b/2" );
429
+
430
+ TestingSQLUtil::ExecuteSQLQuery (" UPDATE test SET b = b/2;" , result,
431
+ tuple_descriptor, rows_affected,
432
+ error_message);
433
+
434
+ EXPECT_EQ (1 , rows_affected);
435
+ LOG_DEBUG (" Tuple Non-Primary Key column Updated!" );
436
+ txn_manager.CommitTransaction (txn);
437
+
438
+ LOG_DEBUG (" Selecting updated value." );
439
+ txn = txn_manager.BeginTransaction ();
440
+ // Check value of column b after updating
441
+ TestingSQLUtil::ExecuteSQLQuery (" SELECT b from test" , result,
442
+ tuple_descriptor, rows_affected,
443
+ error_message);
444
+ // Check the return value
445
+ txn_manager.CommitTransaction (txn);
446
+
447
+ EXPECT_EQ (TestingSQLUtil::GetResultValueAsString (result, 0 ), " 500" );
448
+ LOG_DEBUG (" Successfully updated tuple." );
449
+
450
+
451
+
452
+
346
453
// free the database just created
347
454
txn = txn_manager.BeginTransaction ();
348
455
catalog::Catalog::GetInstance ()->DropDatabaseWithName (DEFAULT_DB_NAME, txn);
@@ -360,6 +467,7 @@ TEST_F(UpdateSQLTests, MultiTileGroupUpdateSQLTest) {
360
467
361
468
LOG_DEBUG (" Bootstrapping completed!" );
362
469
470
+ // active_tilegroup_count set to 3, [Reason: Refer to HalloweenProblemTest]
363
471
size_t active_tilegroup_count = 3 ;
364
472
storage::DataTable::SetActiveTileGroupCount (active_tilegroup_count);
365
473
@@ -382,7 +490,7 @@ TEST_F(UpdateSQLTests, MultiTileGroupUpdateSQLTest) {
382
490
383
491
LOG_DEBUG (" Tuple inserted!" );
384
492
385
- // Update a tuple into table
493
+ // Update a tuple in the table
386
494
LOG_DEBUG (" Updating a tuple..." );
387
495
LOG_DEBUG (" Query: UPDATE test SET a = 10 WHERE b = 100" );
388
496
@@ -398,15 +506,20 @@ TEST_F(UpdateSQLTests, MultiTileGroupUpdateSQLTest) {
398
506
LOG_DEBUG (" Query: UPDATE test SET a = 1 WHERE b = 100" );
399
507
// Check the return value
400
508
EXPECT_EQ (1 , rows_affected);
401
- LOG_DEBUG (" Tuple Updated !" );
509
+ LOG_DEBUG (" Tuple Update successful !" );
402
510
403
511
TestingSQLUtil::ExecuteSQLQuery (" UPDATE test SET a = 1 WHERE b = 100;" ,
404
512
result, tuple_descriptor, rows_affected,
405
513
error_message);
406
514
407
515
// Check the return value
516
+ // Updating the tuple the second time casued the assertion failure
517
+ // on line 641 of timestamp_ordering_transaction_manager.cpp
518
+ // This was because it tried to update an already updated version
519
+ // of the tuple. This was fixed by the statement level WriteSet.
408
520
EXPECT_EQ (1 , rows_affected);
409
- LOG_DEBUG (" Tuple Updated!" );
521
+ LOG_DEBUG (" Tuple Update successful, again!" );
522
+
410
523
411
524
// free the database just created
412
525
txn = txn_manager.BeginTransaction ();
0 commit comments