/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.server.test.it.keyupdate; import com.foundationdb.qp.rowtype.RowType; import com.foundationdb.server.error.ErrorCode; import com.foundationdb.server.error.InvalidOperationException; import com.foundationdb.server.rowdata.RowDef; import org.junit.Test; import java.util.List; import static com.foundationdb.server.test.it.keyupdate.Schema.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; // Like KeyUpdateIT, but with cascading keys public class KeyUpdateCascadingKeysIT extends KeyUpdateBase { @Test public void testItemFKUpdate() throws Exception { // Set item.oid = o for item 1222 KeyUpdateRow originalItem = testStore.find(new HKey(vendorRT, 1L, customerRT, 12L, orderRT, 122L, itemRT, 1222L)); KeyUpdateRow updatedItem = updateRow(originalItem, i_oid, 0L, null); startMonitoringHKeyPropagation(); dbUpdate(originalItem, updatedItem); checkHKeyPropagation(0, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedItem, originalItem); checkHKeyPropagation(0, 0); checkDB(); checkInitialState(); } @Test public void testItemPKUpdate() throws Exception { // Set item.iid = 0 for item 1222 KeyUpdateRow originalItem = testStore.find(new HKey(vendorRT, 1L, customerRT, 12L, orderRT, 122L, itemRT, 1222L)); KeyUpdateRow newItem = updateRow(originalItem, i_iid, 0L); startMonitoringHKeyPropagation(); dbUpdate(originalItem, newItem); checkHKeyPropagation(0, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(newItem, originalItem); checkHKeyPropagation(0, 0); checkDB(); checkInitialState(); } @Test public void testItemPKUpdateCreatingDuplicate() throws Exception { // Set item.iid = 1223 for item 1222 KeyUpdateRow originalItem = testStore.find(new HKey(vendorRT, 1L, customerRT, 12L, orderRT, 122L, itemRT, 1222L)); KeyUpdateRow updatedItem = updateRow(originalItem, i_iid, 1223L); try { dbUpdate(originalItem, updatedItem); fail(); } catch (InvalidOperationException e) { assertEquals(e.getCode(), ErrorCode.DUPLICATE_KEY); } checkDB(); } @Test public void testOrderFKUpdate() throws Exception { // Set order.cid = 0 for order 222 KeyUpdateRow originalOrder = testStore.find(new HKey(vendorRT, 2L, customerRT, 22L, orderRT, 222L)); KeyUpdateRow updatedOrder = updateRow(originalOrder, o_cid, 0L); startMonitoringHKeyPropagation(); dbUpdate(originalOrder, updatedOrder); checkHKeyPropagation(2, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedOrder, originalOrder); checkHKeyPropagation(2, 0); checkDB(); checkInitialState(); } @Test public void testOrderPKUpdate() throws Exception { // Set order.oid = 0 for order 222 KeyUpdateRow originalOrder = testStore.find(new HKey(vendorRT, 2L, customerRT, 22L, orderRT, 222L)); KeyUpdateRow updatedOrder = updateRow(originalOrder, o_oid, 0L); startMonitoringHKeyPropagation(); dbUpdate(originalOrder, updatedOrder); checkHKeyPropagation(2, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedOrder, originalOrder); checkHKeyPropagation(2, 0); checkDB(); checkInitialState(); } @Test public void testOrderPKUpdateCreatingDuplicate() throws Exception { // Set order.oid = 221 for order 222 KeyUpdateRow originalOrder = testStore.find(new HKey(vendorRT, 2L, customerRT, 22L, orderRT, 222L)); KeyUpdateRow updatedOrder = updateRow(originalOrder, o_oid, 221L); try { dbUpdate(originalOrder, updatedOrder); fail(); } catch (InvalidOperationException e) { assertEquals(e.getCode(), ErrorCode.DUPLICATE_KEY); } checkDB(); } @Test public void testCustomerFKUpdate() throws Exception { // Set order.vid = 0 for customer 13 KeyUpdateRow originalCustomer = testStore.find(new HKey(vendorRT, 1L, customerRT, 13L)); KeyUpdateRow updatedCustomer = updateRow(originalCustomer, c_vid, 0L); startMonitoringHKeyPropagation(); dbUpdate(originalCustomer, updatedCustomer); checkHKeyPropagation(2, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedCustomer, originalCustomer); checkHKeyPropagation(2, 0); checkDB(); checkInitialState(); } @Test public void testCustomerPKUpdate() throws Exception { // Set customer.cid = 0 for customer 22 KeyUpdateRow originalCustomer = testStore.find(new HKey(vendorRT, 2L, customerRT, 22L)); KeyUpdateRow updatedCustomer = updateRow(originalCustomer, c_cid, 0L); startMonitoringHKeyPropagation(); dbUpdate(originalCustomer, updatedCustomer); checkHKeyPropagation(2, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedCustomer, originalCustomer); checkHKeyPropagation(2, 0); checkDB(); checkInitialState(); } @Test public void testCustomerPKUpdateCreatingDuplicate() throws Exception { // Set customer.vid = 11 for customer 23 KeyUpdateRow oldCustomerRow = testStore.find(new HKey(vendorRT, 2L, customerRT, 23L)); KeyUpdateRow newCustomerRow = updateRow(oldCustomerRow, c_vid, 1L, c_cid, 11L); try { dbUpdate(oldCustomerRow, newCustomerRow); fail(); } catch (InvalidOperationException e) { assertEquals(e.getCode(), ErrorCode.DUPLICATE_KEY); } checkDB(); } @Test public void testVendorPKUpdate() throws Exception { // Set vendor.vid = 0 for vendor 1 KeyUpdateRow originalVendor = testStore.find(new HKey(vendorRT, 1L)); KeyUpdateRow updatedVendor = updateRow(originalVendor, v_vid, 0L, null); startMonitoringHKeyPropagation(); dbUpdate(originalVendor, updatedVendor); checkHKeyPropagation(2, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedVendor, originalVendor); checkHKeyPropagation(2, 0); checkDB(); checkInitialState(); } @Test public void testVendorPKUpdateCreatingDuplicate() throws Exception { // Set vendor.vid = 2 for vendor 1 KeyUpdateRow originalVendorRow = testStore.find(new HKey(vendorRT, 1L)); KeyUpdateRow updatedVendorRow = updateRow(originalVendorRow, v_vid, 2L, null); try { dbUpdate(originalVendorRow, updatedVendorRow); fail(); } catch (InvalidOperationException e) { assertEquals(ErrorCode.DUPLICATE_KEY, e.getCode()); } checkDB(); } @Test public void testItemDelete() throws Exception { KeyUpdateRow itemRow = testStore.find(new HKey(vendorRT, 2L, customerRT, 22L, orderRT, 222L, itemRT, 2222L)); startMonitoringHKeyPropagation(); dbDelete(itemRow); checkHKeyPropagation(0, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbInsert(itemRow); checkHKeyPropagation(0, 0); checkDB(); checkInitialState(); } @Test public void testOrderDelete() throws Exception { KeyUpdateRow orderRow = testStore.find(new HKey(vendorRT, 2L, customerRT, 22L, orderRT, 222L)); startMonitoringHKeyPropagation(); dbDelete(orderRow); checkHKeyPropagation(1, 3); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbInsert(orderRow); checkHKeyPropagation(1, 3); checkDB(); checkInitialState(); } @Test public void testCustomerDelete() throws Exception { KeyUpdateRow customerRow = testStore.find(new HKey(vendorRT, 2L, customerRT, 22L)); startMonitoringHKeyPropagation(); dbDelete(customerRow); checkHKeyPropagation(1, 12); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbInsert(customerRow); checkHKeyPropagation(1, 12); checkDB(); checkInitialState(); } @Test public void testVendorDelete() throws Exception { KeyUpdateRow vendorRow = testStore.find(new HKey(vendorRT, 2L)); startMonitoringHKeyPropagation(); dbDelete(vendorRow); checkHKeyPropagation(1, 39); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbInsert(vendorRow); checkHKeyPropagation(1, 39); checkDB(); checkInitialState(); } @Override protected void createSchema() throws InvalidOperationException { // vendor vendorId = createTable("coi", "vendor", "vid bigint not null", "vx bigint", "primary key(vid)"); v_vid = 0; v_vx = 1; // customer customerId = createTable("coi", "customer", "vid bigint not null", "cid bigint not null", "cx bigint", "primary key(vid, cid)", "grouping foreign key (vid) references vendor(vid)"); c_vid = 0; c_cid = 1; c_cx = 2; // order orderId = createTable("coi", "order", "vid bigint not null", "cid bigint not null", "oid bigint not null", "ox bigint", "priority bigint", "when bigint", "primary key(vid, cid, oid)", "unique(when)", "grouping foreign key (vid, cid) references customer(vid, cid)"); createIndex("coi", "order", "priority", "priority"); o_vid = 0; o_cid = 1; o_oid = 2; o_ox = 3; o_priority = 4; o_when = 5; // item itemId = createTable("coi", "item", "vid bigint not null", "cid bigint not null", "oid bigint not null", "iid bigint not null", "ix bigint", "primary key(vid, cid, oid, iid)", "grouping foreign key (vid, cid, oid) references \"order\"(vid, cid, oid)"); i_vid = 0; i_cid = 1; i_oid = 2; i_iid = 3; i_ix = 4; vendorRT = getRowType(vendorId); customerRT = getRowType(customerId); orderRT = getRowType(orderId); itemRT = getRowType(itemId); // group group = customerRT.table().getGroup(); } @Override protected List<List<Object>> customerPKIndex(List<TreeRecord> records) { throw new UnsupportedOperationException(); } @Override protected List<List<Object>> vendorPKIndex(List<TreeRecord> records) { throw new UnsupportedOperationException(); } @Override protected List<List<Object>> orderPKIndex(List<TreeRecord> records) { throw new UnsupportedOperationException(); } @Override protected List<List<Object>> itemPKIndex(List<TreeRecord> records) { throw new UnsupportedOperationException(); } @Override protected List<List<Object>> orderPriorityIndex(List<TreeRecord> records) { return indexFromRecords(records, orderRT, o_priority, o_vid, o_cid, o_oid); } @Override protected List<List<Object>> orderWhenIndex(List<TreeRecord> records) { return indexFromRecords(records, orderRT, o_when, o_vid, o_cid, o_oid); } @Override protected void populateTables() throws Exception { // Vendor 1 dbInsert(kurow(vendorRT, 1, 100)); dbInsert(kurow(customerRT, 1, 11, 1100)); dbInsert(kurow(orderRT, 1, 11, 111, 11100, 81, 9001)); dbInsert(kurow(itemRT, 1, 11, 111, 1111, 111100)); dbInsert(kurow(itemRT, 1, 11, 111, 1112, 111200)); dbInsert(kurow(itemRT, 1, 11, 111, 1113, 111300)); dbInsert(kurow(orderRT, 1, 11, 112, 11200, 83, 9002)); dbInsert(kurow(itemRT, 1, 11, 112, 1121, 112100)); dbInsert(kurow(itemRT, 1, 11, 112, 1122, 112200)); dbInsert(kurow(itemRT, 1, 11, 112, 1123, 112300)); dbInsert(kurow(orderRT, 1, 11, 113, 11300, 81, 9003)); dbInsert(kurow(itemRT, 1, 11, 113, 1131, 113100)); dbInsert(kurow(itemRT, 1, 11, 113, 1132, 113200)); dbInsert(kurow(itemRT, 1, 11, 113, 1133, 113300)); dbInsert(kurow(customerRT, 1, 12, 1200)); dbInsert(kurow(orderRT, 1, 12, 121, 12100, 83, 9004)); dbInsert(kurow(itemRT, 1, 12, 121, 1211, 121100)); dbInsert(kurow(itemRT, 1, 12, 121, 1212, 121200)); dbInsert(kurow(itemRT, 1, 12, 121, 1213, 121300)); dbInsert(kurow(orderRT, 1, 12, 122, 12200, 81, 9005)); dbInsert(kurow(itemRT, 1, 12, 122, 1221, 122100)); dbInsert(kurow(itemRT, 1, 12, 122, 1222, 122200)); dbInsert(kurow(itemRT, 1, 12, 122, 1223, 122300)); dbInsert(kurow(orderRT, 1, 12, 123, 12300, 82, 9006)); dbInsert(kurow(itemRT, 1, 12, 123, 1231, 123100)); dbInsert(kurow(itemRT, 1, 12, 123, 1232, 123200)); dbInsert(kurow(itemRT, 1, 12, 123, 1233, 123300)); dbInsert(kurow(customerRT, 1, 13, 1300)); dbInsert(kurow(orderRT, 1, 13, 131, 13100, 81, 9007)); dbInsert(kurow(itemRT, 1, 13, 131, 1311, 131100)); dbInsert(kurow(itemRT, 1, 13, 131, 1312, 131200)); dbInsert(kurow(itemRT, 1, 13, 131, 1313, 131300)); dbInsert(kurow(orderRT, 1, 13, 132, 13200, 82, 9008)); dbInsert(kurow(itemRT, 1, 13, 132, 1321, 132100)); dbInsert(kurow(itemRT, 1, 13, 132, 1322, 132200)); dbInsert(kurow(itemRT, 1, 13, 132, 1323, 132300)); dbInsert(kurow(orderRT, 1, 13, 133, 13300, 83, 9009)); dbInsert(kurow(itemRT, 1, 13, 133, 1331, 133100)); dbInsert(kurow(itemRT, 1, 13, 133, 1332, 133200)); dbInsert(kurow(itemRT, 1, 13, 133, 1333, 133300)); // Vendor 2 dbInsert(kurow(vendorRT, 2, 200)); dbInsert(kurow(customerRT, 2, 21, 2100)); dbInsert(kurow(orderRT, 2, 21, 211, 21100, 81, 9010)); dbInsert(kurow(itemRT, 2, 21, 211, 2111, 211100)); dbInsert(kurow(itemRT, 2, 21, 211, 2112, 211200)); dbInsert(kurow(itemRT, 2, 21, 211, 2113, 211300)); dbInsert(kurow(orderRT, 2, 21, 212, 21200, 83, 9011)); dbInsert(kurow(itemRT, 2, 21, 212, 2121, 212100)); dbInsert(kurow(itemRT, 2, 21, 212, 2122, 212200)); dbInsert(kurow(itemRT, 2, 21, 212, 2123, 212300)); dbInsert(kurow(orderRT, 2, 21, 213, 21300, 81, 9012)); dbInsert(kurow(itemRT, 2, 21, 213, 2131, 213100)); dbInsert(kurow(itemRT, 2, 21, 213, 2132, 213200)); dbInsert(kurow(itemRT, 2, 21, 213, 2133, 213300)); dbInsert(kurow(customerRT, 2, 22, 2200)); dbInsert(kurow(orderRT, 2, 22, 221, 22100, 83, 9013)); dbInsert(kurow(itemRT, 2, 22, 221, 2211, 221100)); dbInsert(kurow(itemRT, 2, 22, 221, 2212, 221200)); dbInsert(kurow(itemRT, 2, 22, 221, 2213, 221300)); dbInsert(kurow(orderRT, 2, 22, 222, 22200, 81, 9014)); dbInsert(kurow(itemRT, 2, 22, 222, 2221, 222100)); dbInsert(kurow(itemRT, 2, 22, 222, 2222, 222200)); dbInsert(kurow(itemRT, 2, 22, 222, 2223, 222300)); dbInsert(kurow(orderRT, 2, 22, 223, 22300, 82, 9015)); dbInsert(kurow(itemRT, 2, 22, 223, 2231, 223100)); dbInsert(kurow(itemRT, 2, 22, 223, 2232, 223200)); dbInsert(kurow(itemRT, 2, 22, 223, 2233, 223300)); dbInsert(kurow(customerRT, 2, 23, 2300)); dbInsert(kurow(orderRT, 2, 23, 231, 23100, 81, 9016)); dbInsert(kurow(itemRT, 2, 23, 231, 2311, 231100)); dbInsert(kurow(itemRT, 2, 23, 231, 2312, 231200)); dbInsert(kurow(itemRT, 2, 23, 231, 2313, 231300)); dbInsert(kurow(orderRT, 2, 23, 232, 23200, 82, 9017)); dbInsert(kurow(itemRT, 2, 23, 232, 2321, 232100)); dbInsert(kurow(itemRT, 2, 23, 232, 2322, 232200)); dbInsert(kurow(itemRT, 2, 23, 232, 2323, 232300)); dbInsert(kurow(orderRT, 2, 23, 233, 23300, 83, 9018)); dbInsert(kurow(itemRT, 2, 23, 233, 2331, 233100)); dbInsert(kurow(itemRT, 2, 23, 233, 2332, 233200)); dbInsert(kurow(itemRT, 2, 23, 233, 2333, 233300)); } @Override protected HKey hKey(KeyUpdateRow row) { HKey hKey = null; RowType rowType = row.rowType(); if (rowType == vendorRT) { hKey = new HKey(vendorRT, row.value(v_vid).getInt64()); } else if (rowType == customerRT) { hKey = new HKey(vendorRT, row.value(c_vid).getInt64(), customerRT, row.value(c_cid).getInt64()); } else if (rowType == orderRT) { hKey = new HKey(vendorRT, row.value(o_vid).getInt64(), customerRT, row.value(o_cid).getInt64(), orderRT, row.value(o_oid).getInt64()); } else if (rowType == itemRT) { hKey = new HKey(vendorRT, row.value(i_vid).getInt64(), customerRT, row.value(i_cid).getInt64(), orderRT, row.value(i_oid).getInt64(), itemRT, row.value(i_iid).getInt64()); } else { fail(); } return hKey; } @Override protected HKey hKey(KeyUpdateRow row, KeyUpdateRow parent) { return hKey(row); } @Override protected HKey hKey(KeyUpdateRow row, KeyUpdateRow parent, KeyUpdateRow grandparent) { return hKey(row); } @Override protected boolean checkChildPKs() { return false; } protected void confirmColumns() { confirmColumn(vendorRT, v_vid, "vid"); confirmColumn(vendorRT, v_vx, "vx"); confirmColumn(customerRT, c_vid, "vid"); confirmColumn(customerRT, c_cid, "cid"); confirmColumn(customerRT, c_cx, "cx"); confirmColumn(orderRT, o_vid, "vid"); confirmColumn(orderRT, o_cid, "cid"); confirmColumn(orderRT, o_oid, "oid"); confirmColumn(orderRT, o_ox, "ox"); confirmColumn(orderRT, o_priority, "priority"); confirmColumn(orderRT, o_when, "when"); confirmColumn(itemRT, i_vid, "vid"); confirmColumn(itemRT, i_cid, "cid"); confirmColumn(itemRT, i_oid, "oid"); confirmColumn(itemRT, i_iid, "iid"); confirmColumn(itemRT, i_ix, "ix"); } }