From 58e4295ff55f42a7ec82cb387bfc3b65dff3e68d Mon Sep 17 00:00:00 2001 From: Nathan VanBenschoten Date: Fri, 24 Mar 2023 21:13:40 -0400 Subject: [PATCH] workload/tpcc: implement remaining consistency checks This commit adds consistency check 3.3.2.10, 3.3.2.11, and 3.3.2.12 from the TPC-C spec. We'll be using these consistency checks as part of the testing coverage for upcoming changes to transaction isolation. Epic: None Release notes: None --- pkg/workload/tpcc/checks.go | 180 +++++++++++++++++++++--------------- 1 file changed, 103 insertions(+), 77 deletions(-) diff --git a/pkg/workload/tpcc/checks.go b/pkg/workload/tpcc/checks.go index a4d99f612b3c..0fdb7b13002e 100644 --- a/pkg/workload/tpcc/checks.go +++ b/pkg/workload/tpcc/checks.go @@ -38,18 +38,16 @@ func AllChecks() []Check { {"3.3.2.7", check3327, false}, {"3.3.2.8", check3328, false}, {"3.3.2.9", check3329, false}, + {"3.3.2.10", check33210, true}, + {"3.3.2.11", check33211, false}, + {"3.3.2.12", check33212, true}, } } func check3321(db *gosql.DB, asOfSystemTime string) error { // 3.3.2.1 Entries in the WAREHOUSE and DISTRICT tables must satisfy the relationship: // W_YTD = sum (D_YTD) - txn, err := beginAsOfSystemTime(db, asOfSystemTime) - if err != nil { - return err - } - defer func() { _ = txn.Rollback() }() - row := txn.QueryRow(` + return checkNoRows(db, asOfSystemTime, ` SELECT count(*) FROM @@ -65,16 +63,6 @@ FROM WHERE w_ytd != sum_d_ytd `) - var i int - if err := row.Scan(&i); err != nil { - return err - } - - if i != 0 { - return errors.Errorf("%d rows returned, expected zero", i) - } - - return nil } func check3322(db *gosql.DB, asOfSystemTime string) (retErr error) { @@ -160,12 +148,7 @@ ORDER BY func check3323(db *gosql.DB, asOfSystemTime string) error { // max(NO_O_ID) - min(NO_O_ID) + 1 = # of rows in new_order for each warehouse/district - txn, err := beginAsOfSystemTime(db, asOfSystemTime) - if err != nil { - return err - } - defer func() { _ = txn.Rollback() }() - row := txn.QueryRow(` + return checkNoRows(db, asOfSystemTime, ` SELECT count(*) FROM @@ -178,18 +161,8 @@ FROM no_w_id, no_d_id ) WHERE - nod != -1`) - - var i int - if err := row.Scan(&i); err != nil { - return err - } - - if i != 0 { - return errors.Errorf("%d rows returned, expected zero", i) - } - - return nil + nod != -1 +`) } func check3324(db *gosql.DB, asOfSystemTime string) (retErr error) { @@ -330,12 +303,7 @@ func check3327(db *gosql.DB, asOfSystemTime string) error { // date/time if and only if the corresponding row in the ORDER table defined // by (O_W_ID, O_D_ID, O_ID) = (OL_W_ID, OL_D_ID, OL_O_ID) has // O_CARRIER_ID set to a null value. - txn, err := beginAsOfSystemTime(db, asOfSystemTime) - if err != nil { - return err - } - defer func() { _ = txn.Rollback() }() - row := txn.QueryRow(` + return checkNoRows(db, asOfSystemTime, ` SELECT count(*) FROM (SELECT o_w_id, o_d_id, o_id FROM "order" WHERE o_carrier_id IS NULL) FULL OUTER JOIN @@ -343,28 +311,12 @@ FULL OUTER JOIN ON (ol_w_id = o_w_id AND ol_d_id = o_d_id AND ol_o_id = o_id) WHERE ol_o_id IS NULL OR o_id IS NULL `) - - var i int - if err := row.Scan(&i); err != nil { - return err - } - - if i != 0 { - return errors.Errorf("%d rows returned, expected zero", i) - } - - return nil } func check3328(db *gosql.DB, asOfSystemTime string) error { // Entries in the WAREHOUSE and HISTORY tables must satisfy the relationship: // W_YTD = SUM(H_AMOUNT) for each warehouse defined by (W_ID = H _W_ID). - txn, err := beginAsOfSystemTime(db, asOfSystemTime) - if err != nil { - return err - } - defer func() { _ = txn.Rollback() }() - row := txn.QueryRow(` + return checkNoRows(db, asOfSystemTime, ` SELECT count(*) FROM (SELECT w_id, w_ytd, sum FROM warehouse JOIN @@ -373,28 +325,12 @@ SELECT count(*) FROM WHERE w_ytd != sum ) `) - - var i int - if err := row.Scan(&i); err != nil { - return err - } - - if i != 0 { - return errors.Errorf("%d rows returned, expected zero", i) - } - - return nil } func check3329(db *gosql.DB, asOfSystemTime string) error { // Entries in the DISTRICT and HISTORY tables must satisfy the relationship: // D_YTD=SUM(H_AMOUNT) for each district defined by (D_W_ID,D_ID)=(H_W_ID,H_D_ID) - txn, err := beginAsOfSystemTime(db, asOfSystemTime) - if err != nil { - return err - } - defer func() { _ = txn.Rollback() }() - row := txn.QueryRow(` + return checkNoRows(db, asOfSystemTime, ` SELECT count(*) FROM (SELECT d_id, d_ytd, sum FROM district JOIN @@ -403,16 +339,106 @@ SELECT count(*) FROM WHERE d_ytd != sum ) `) +} - var i int - if err := row.Scan(&i); err != nil { +func check33210(db *gosql.DB, asOfSystemTime string) error { + // Entries in the CUSTOMER, HISTORY, ORDER, and ORDER-LINE tables must satisfy + // the relationship: + // + // C_BALANCE = sum(OL_AMOUNT) - sum(H_AMOUNT) + // + // where: + // + // H_AMOUNT is selected by (C_W_ID, C_D_ID, C_ID) = (H_C_W_ID, H_C_D_ID, H_C_ID) + // + // and + // + // OL_AMOUNT is selected by: + // (OL_W_ID, OL_D_ID, OL_O_ID) = (O_W_ID, O_D_ID, O_ID) and + // (O_W_ID, O_D_ID, O_C_ID) = (C_W_ID, C_D_ID, C_ID) and + // (OL_DELIVERY_D is not a null value) + // + return checkNoRows(db, asOfSystemTime, ` +SELECT count(*) FROM + (SELECT c_balance, + (SELECT coalesce(sum(ol_amount), 0) FROM "order", order_line + WHERE ol_w_id = o_w_id + AND ol_d_id = o_d_id + AND ol_o_id = o_id + AND o_w_id = c_w_id + AND o_d_id = c_d_id + AND o_c_id = c_id + AND ol_delivery_d IS NOT NULL) sum_ol_amount, + (SELECT coalesce(sum(h_amount), 0) FROM history + WHERE h_c_w_id = c_w_id + AND h_c_d_id = c_d_id + AND h_c_id = c_id) sum_h_amount + FROM customer) +WHERE c_balance != sum_ol_amount - sum_h_amount +`) +} + +func check33211(db *gosql.DB, asOfSystemTime string) error { + // Entries in the CUSTOMER, ORDER and NEW-ORDER tables must satisfy the + // relationship: + // + // (count(*) from ORDER) - (count(*) from NEW-ORDER) = 2100 + // + // for each district defined by: + // + // (O_W_ID, O_D_ID) = (NO_W_ID, NO_D_ID) = (C_W_ID, C_D_ID) + // + return checkNoRows(db, asOfSystemTime, ` +SELECT count(*) FROM + (SELECT order_count, new_order_count FROM + (SELECT o_w_id, o_d_id, count(*) order_count FROM "order" GROUP BY o_w_id, o_d_id), + (SELECT no_w_id, no_d_id, count(*) new_order_count FROM new_order GROUP BY no_w_id, no_d_id), + (SELECT c_w_id, c_d_id FROM customer GROUP BY c_w_id, c_d_id) + WHERE (o_w_id, o_d_id) = (no_w_id, no_d_id) + AND (no_w_id, no_d_id) = (c_w_id, c_d_id)) +WHERE order_count - new_order_count != 2100 +`) +} + +func check33212(db *gosql.DB, asOfSystemTime string) error { + // Entries in the CUSTOMER and ORDER-LINE tables must satisfy the + // relationship: + // + // C_BALANCE + C_YTD_PAYMENT = sum(OL_AMOUNT) + // + // for any randomly selected customers and where OL_DELIVERY_D is + // not set to a null date / time. + return checkNoRows(db, asOfSystemTime, ` +SELECT count(*) FROM + (SELECT c_balance, + c_ytd_payment, + (SELECT coalesce(sum(ol_amount), 0) FROM "order", order_line + WHERE ol_w_id = o_w_id + AND ol_d_id = o_d_id + AND ol_o_id = o_id + AND o_w_id = c_w_id + AND o_d_id = c_d_id + AND o_c_id = c_id + AND ol_delivery_d IS NOT NULL) sum_ol_amount + FROM customer) +WHERE c_balance + c_ytd_payment != sum_ol_amount +`) +} + +func checkNoRows(db *gosql.DB, asOfSystemTime string, q string) error { + txn, err := beginAsOfSystemTime(db, asOfSystemTime) + if err != nil { return err } + defer func() { _ = txn.Rollback() }() + var i int + if err := txn.QueryRow(q).Scan(&i); err != nil { + return err + } if i != 0 { return errors.Errorf("%d rows returned, expected zero", i) } - return nil }