/** * 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.rowdata; import static org.junit.Assert.assertSame; import static org.junit.Assert.*; import com.foundationdb.ais.model.*; import org.junit.Assert; import org.junit.Test; public class RowDefBuilderTest { @Test public void testMultipleBadlyOrderedColumns() throws Exception { String[] ddl = { "create table b(", " b0 int,", " b1 int not null,", " b2 int not null,", " b3 int not null,", " b4 int not null,", " b5 int,", " primary key(b3, b2, b4, b1)", ");", "create table bb(", " bb0 int not null,", " bb1 int,", " bb2 int not null,", " bb3 int not null,", " bb4 int not null,", " bb5 int not null,", " primary key (bb0, bb5, bb3, bb2, bb4), ", " GROUPING FOREIGN KEY (bb0,bb2,bb1,bb3) REFERENCES b (b3,b2,b4,b1)", ");", }; AkibanInformationSchema ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); RowDef b = ais.getTable(tableName("b")).rowDef(); Table bTable = b.table(); checkHKey(bTable.hKey(), bTable, bTable, "b3", bTable, "b2", bTable, "b4", bTable, "b1"); assertEquals(5, b.getHKeyDepth()); // b ordinal, b3, b2, b4, b1 RowDef bb = ais.getTable(tableName("bb")).rowDef(); Table bbTable = bb.table(); checkHKey(bbTable.hKey(), bTable, bbTable, "bb0", bbTable, "bb2", bbTable, "bb1", bbTable, "bb3", bbTable, bbTable, "bb5", bbTable, "bb4"); assertEquals(8, bb.getHKeyDepth()); // b ordinal, b3, b2, b4, b1, bb ordinal, b5, b4 assertEquals(6, b.getFieldDefs().length); checkField("b0", b, 0); checkField("b1", b, 1); checkField("b2", b, 2); checkField("b3", b, 3); checkField("b4", b, 4); checkField("b5", b, 5); assertEquals(6, bb.getFieldDefs().length); checkField("bb0", bb, 0); checkField("bb1", bb, 1); checkField("bb2", bb, 2); checkField("bb3", bb, 3); checkField("bb4", bb, 4); checkField("bb5", bb, 5); assertArrayEquals(new int[]{}, b.getParentJoinFields()); assertArrayEquals(new int[]{0, 2, 1, 3}, bb.getParentJoinFields()); } @Test public void childDoesNotContributeToHKey() throws Exception { String[] ddl = { "create table parent (", " id int not null,", " primary key(id)", ");", "create table child (", " id int not null,", " primary key(id),", " GROUPING FOREIGN KEY (id) references parent(id)", ");" }; AkibanInformationSchema ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); RowDef parent = ais.getTable(tableName("parent")).rowDef(); Table p = parent.table(); checkHKey(p.hKey(), p, p, "id"); assertEquals(2, parent.getHKeyDepth()); // parent ordinal, id RowDef child = ais.getTable(tableName("child")).rowDef(); Table c = child.table(); checkHKey(c.hKey(), p, c, "id", c); assertEquals(3, child.getHKeyDepth()); // parent ordinal, id, child ordinal assertArrayEquals("parent joins", new int[]{}, parent.getParentJoinFields()); assertArrayEquals("child joins", new int[]{0}, child.getParentJoinFields()); } @Test public void testUserIndexDefs() throws Exception { String[] ddl = { "create table t (", " a int not null, ", " b int, ", " c int not null, ", " d int, ", " e int, ", " primary key(c, a), ", " constraint d_b unique(d, b)", ");", "create index e_d on t(e, d);" }; AkibanInformationSchema ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); RowDef t = ais.getTable(tableName("t")).rowDef(); assertEquals(3, t.getHKeyDepth()); // t ordinal, c, a Index index; index = t.getPKIndex(); assertTrue(index.isPrimaryKey()); assertTrue(index.isUnique()); index = t.table().getIndex("e_d"); assertTrue(!index.isPrimaryKey()); assertTrue(!index.isUnique()); index = t.table().getIndex("d_b"); assertTrue(!index.isPrimaryKey()); assertTrue(index.isUnique()); } @Test public void testNonCascadingPKs() throws Exception { String[] ddl = { "create table customer(", " cid int not null, ", " cx int not null, ", " primary key(cid), ", " constraint cid_cx unique(cid, cx) ", "); ", "create table orders(", " oid int not null, ", " cid int not null, ", " ox int not null, ", " primary key(oid), ", " constraint cid_oid unique(cid, oid), ", " constraint oid_cid unique(oid, cid), ", " constraint cid_oid_ox unique(cid, oid, ox), ", " grouping foreign key(cid) references customer(cid)", "); ", "create index \"__akiban_oc\" on orders(cid);", "create table item(", " iid int not null, ", " oid int not null, ", " ix int not null, ", " primary key(iid), ", " grouping foreign key(oid) references orders(oid)", "); ", "create index \"__akiban_io\" on item(oid);", "create index oid_iid on item(oid, iid);", "create index iid_oid on item(iid, oid);", "create index oid_iid_ix on item(oid, iid, ix);", }; AkibanInformationSchema ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); TableIndex index; int[] fields; IndexRowComposition rowComp; IndexToHKey indexToHKey; // ------------------------- Customer ------------------------------------------ Table customer = ais.getTable(tableName("customer")); checkFields(customer, "cid", "cx"); assertEquals(2, customer.rowDef().getHKeyDepth()); // customer ordinal, cid assertArrayEquals(new int[]{}, customer.rowDef().getParentJoinFields()); // index on cid index = customer.rowDef().getPKIndex(); assertNotNull(index); assertTrue(index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // c.cid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // c.cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(0, indexToHKey.getIndexRowPosition(1)); // index cid // index on cid, cx index = customer.getIndex("cid_cx"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // c.cid assertEquals(1, fields[1]); // c.cx rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // c.cid assertEquals(1, rowComp.getFieldPosition(1)); // c.cx indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(0, indexToHKey.getIndexRowPosition(1)); // index cid // ------------------------- Orders ------------------------------------------ Table orders = ais.getTable(tableName("orders")); checkFields(orders, "oid", "cid", "ox"); assertEquals(4, orders.rowDef().getHKeyDepth()); // customer ordinal, cid, orders ordinal, oid assertArrayEquals(new int[]{1}, orders.rowDef().getParentJoinFields()); // index on oid index = orders.rowDef().getPKIndex(); assertNotNull(index); assertTrue(index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // o.oid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // o.oid assertEquals(1, rowComp.getFieldPosition(1)); // o.cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(1, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(0, indexToHKey.getIndexRowPosition(3)); // index oid // index on cid, oid index = orders.getIndex("cid_oid"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(1, fields[0]); // o.cid assertEquals(0, fields[1]); // o.oid rowComp = index.indexRowComposition(); assertEquals(1, rowComp.getFieldPosition(0)); // o.cid assertEquals(0, rowComp.getFieldPosition(1)); // o.oid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(0, indexToHKey.getIndexRowPosition(1)); assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(1, indexToHKey.getIndexRowPosition(3)); // index oid // index on oid, cid index = orders.getIndex("oid_cid"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // o.oid assertEquals(1, fields[1]); // o.cid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // o.oid assertEquals(1, rowComp.getFieldPosition(1)); // o.cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(1, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(0, indexToHKey.getIndexRowPosition(3)); // index oid // index on cid, oid, ox index = orders.getIndex("cid_oid_ox"); assertNotNull(index); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(1, fields[0]); // o.cid assertEquals(0, fields[1]); // o.oid assertEquals(2, fields[2]); // o.ox rowComp = index.indexRowComposition(); assertEquals(1, rowComp.getFieldPosition(0)); // o.cid assertEquals(0, rowComp.getFieldPosition(1)); // o.oid assertEquals(2, rowComp.getFieldPosition(2)); // o.ox indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(0, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(1, indexToHKey.getIndexRowPosition(3)); // index oid // ------------------------- Item ------------------------------------------ Table item = ais.getTable(tableName("item")); checkFields(item, "iid", "oid", "ix"); assertEquals(6, item.rowDef().getHKeyDepth()); // customer ordinal, cid, orders ordinal, oid, item ordinal, iid assertArrayEquals(new int[]{1}, item.rowDef().getParentJoinFields()); // Index on iid index = item.rowDef().getPKIndex(); assertNotNull(index); assertTrue(index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // i.iid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // i.iid assertEquals(1, rowComp.getHKeyPosition(1)); // hkey cid assertEquals(1, rowComp.getFieldPosition(2)); // i.oid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(1, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(2, indexToHKey.getIndexRowPosition(3)); // index oid assertEquals(item.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(0, indexToHKey.getIndexRowPosition(5)); // index oid // Index on oid, iid index = item.getIndex("oid_iid"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(!index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(1, fields[0]); // i.oid assertEquals(0, fields[1]); // i.iid rowComp = index.indexRowComposition(); assertEquals(1, rowComp.getFieldPosition(0)); // i.oid assertEquals(0, rowComp.getFieldPosition(1)); // i.iid assertEquals(1, rowComp.getHKeyPosition(2)); // hkey cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(2, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(0, indexToHKey.getIndexRowPosition(3)); // index oid assertEquals(item.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(1, indexToHKey.getIndexRowPosition(5)); // index iid // Index on iid, oid index = item.getIndex("iid_oid"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(!index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // i.iid assertEquals(1, fields[1]); // i.oid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // i.iid assertEquals(1, rowComp.getFieldPosition(1)); // i.oid assertEquals(1, rowComp.getHKeyPosition(2)); // hkey cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(2, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(1, indexToHKey.getIndexRowPosition(3)); // index oid assertEquals(item.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(0, indexToHKey.getIndexRowPosition(5)); // index iid // Index on oid, iid, ix index = item.getIndex("oid_iid_ix"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(!index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(1, fields[0]); // i.oid assertEquals(0, fields[1]); // i.iid assertEquals(2, fields[2]); // i.ix rowComp = index.indexRowComposition(); assertEquals(1, rowComp.getFieldPosition(0)); // i.oid assertEquals(0, rowComp.getFieldPosition(1)); // i.iid assertEquals(2, rowComp.getFieldPosition(2)); // i.ix assertEquals(1, rowComp.getHKeyPosition(3)); // hkey cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(3, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(0, indexToHKey.getIndexRowPosition(3)); // index oid assertEquals(item.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(1, indexToHKey.getIndexRowPosition(5)); // index iid } @Test public void testCascadingPKs() throws Exception { String[] ddl = { "create table customer(", " cid int not null, ", " cx int not null, ", " primary key(cid) ", "); ", "create index cx on customer(cx);", "create table orders(", " cid int not null, ", " oid int not null, ", " ox int not null, ", " primary key(cid, oid), ", " grouping foreign key (cid) references customer(cid)", "); ", "create index \"__akiban_oc\" on orders(cid);", "create index ox_cid on orders(ox, cid);", "create table item(", " cid int not null, ", " oid int not null, ", " iid int not null, ", " ix int not null, ", " primary key(cid, oid, iid), ", " grouping foreign key (cid, oid) references orders(cid, oid)", "); ", "create index \"__akiban_io\" on item(cid, oid);", "create index ix_iid_oid_cid on item(ix, iid, oid, cid);", }; AkibanInformationSchema ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); TableIndex index; int[] fields; IndexRowComposition rowComp; IndexToHKey indexToHKey; // ------------------------- Customer ------------------------------------------ Table customer = ais.getTable(tableName("customer")); checkFields(customer, "cid", "cx"); assertEquals(2, customer.rowDef().getHKeyDepth()); // customer ordinal, cid assertArrayEquals(new int[]{}, customer.rowDef().getParentJoinFields()); // index on cid index = customer.rowDef().getPKIndex(); assertNotNull(index); assertTrue(index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // c.cid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // c.cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(0, indexToHKey.getIndexRowPosition(1)); // index cid // index on cx index = customer.getIndex("cx"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(!index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(1, fields[0]); // c.cx rowComp = index.indexRowComposition(); assertEquals(1, rowComp.getFieldPosition(0)); // c.cx assertEquals(0, rowComp.getFieldPosition(1)); // c.cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(1, indexToHKey.getIndexRowPosition(1)); // index cid // ------------------------- Orders ------------------------------------------ Table orders = ais.getTable(tableName("orders")); checkFields(orders, "cid", "oid", "ox"); assertEquals(4, orders.rowDef().getHKeyDepth()); // customer ordinal, cid, orders ordinal, oid assertArrayEquals(new int[]{0}, orders.rowDef().getParentJoinFields()); // index on cid, oid index = orders.rowDef().getPKIndex(); assertNotNull(index); assertTrue(index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // o.cid assertEquals(1, fields[1]); // o.oid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // o.cid assertEquals(1, rowComp.getFieldPosition(1)); // o.oid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(0, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(1, indexToHKey.getIndexRowPosition(3)); // index oid // index on ox, cid index = orders.getIndex("ox_cid"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(!index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(2, fields[0]); // o.ox assertEquals(0, fields[1]); // o.cid rowComp = index.indexRowComposition(); assertEquals(2, rowComp.getFieldPosition(0)); // o.ox assertEquals(0, rowComp.getFieldPosition(1)); // o.cid assertEquals(1, rowComp.getFieldPosition(2)); // o.oid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(1, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(2, indexToHKey.getIndexRowPosition(3)); // index oid // ------------------------- Item ------------------------------------------ Table item = ais.getTable(tableName("item")); checkFields(item, "cid", "oid", "iid", "ix"); assertEquals(6, item.rowDef().getHKeyDepth()); // customer ordinal, cid, orders ordinal, oid, item ordinal iid assertArrayEquals(new int[]{0, 1}, item.rowDef().getParentJoinFields()); // index on cid, oid, iid index = item.rowDef().getPKIndex(); assertNotNull(index); assertTrue(index.isPrimaryKey()); assertTrue(index.isUnique()); // assertTrue(index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(0, fields[0]); // i.cid assertEquals(1, fields[1]); // i.oid assertEquals(2, fields[2]); // i.iid rowComp = index.indexRowComposition(); assertEquals(0, rowComp.getFieldPosition(0)); // i.cid assertEquals(1, rowComp.getFieldPosition(1)); // i.oid assertEquals(2, rowComp.getFieldPosition(2)); // i.iid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(0, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(1, indexToHKey.getIndexRowPosition(3)); // index oid assertEquals(item.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(2, indexToHKey.getIndexRowPosition(5)); // index oid // index on ix, iid, oid, cid index = item.getIndex("ix_iid_oid_cid"); assertNotNull(index); assertTrue(!index.isPrimaryKey()); assertTrue(!index.isUnique()); // assertTrue(!index.isHKeyEquivalent()); fields = indexFields(index); assertEquals(3, fields[0]); // i.ix assertEquals(2, fields[1]); // i.iid assertEquals(1, fields[2]); // i.oid assertEquals(0, fields[3]); // i.cid rowComp = index.indexRowComposition(); assertEquals(3, rowComp.getFieldPosition(0)); // i.ix assertEquals(2, rowComp.getFieldPosition(1)); // i.iid assertEquals(1, rowComp.getFieldPosition(2)); // i.oid assertEquals(0, rowComp.getFieldPosition(3)); // i.cid indexToHKey = index.indexToHKey(); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(3, indexToHKey.getIndexRowPosition(1)); // index cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(2, indexToHKey.getIndexRowPosition(3)); // index oid assertEquals(item.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(1, indexToHKey.getIndexRowPosition(5)); // index oid } @Test public void checkCOGroupIndex() throws Exception { String[] ddl = { "create table customer(cid int not null, name varchar(32), primary key(cid));", "create table orders(oid int not null, cid int, date date, primary key(oid), "+ "grouping foreign key(cid) references customer(cid));", "create index \"cName_oDate\" on orders(customer.name, orders.date) using left join;" }; final AkibanInformationSchema ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); GroupIndex index; IndexRowComposition rowComp; IndexToHKey indexToHKey; Table customer = ais.getTable(tableName("customer")); Table orders = ais.getTable(tableName("orders")); // left join group index on (c.name,o.date): // declared: c.name o.date // hkey: o.cid c.oid index = orders.getGroup().getIndex("cName_oDate"); assertNotNull(index); assertFalse(index.isPrimaryKey()); assertFalse(index.isUnique()); rowComp = index.indexRowComposition(); // Flattened: (c.cid, c.name, o.oid, o.cid, o.date) assertEquals(1, rowComp.getFieldPosition(0)); // c.name assertEquals(4, rowComp.getFieldPosition(1)); // o.date // order hkey assertEquals(0, rowComp.getFieldPosition(2)); // c.cid assertEquals(2, rowComp.getFieldPosition(3)); // o.oid assertEquals(4, rowComp.getLength()); // group index row: c.name, o.date, o.cid, o.oid, c.cid // group index -> order hkey indexToHKey = index.indexToHKey(orders.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(2, indexToHKey.getIndexRowPosition(1)); // c.cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(3, indexToHKey.getIndexRowPosition(3)); // o.oid // group index -> customer hkey indexToHKey = index.indexToHKey(customer.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(2, indexToHKey.getIndexRowPosition(1)); // c.cid } @Test public void checkCOIGroupIndex() throws Exception { String[] ddl = { "create table customer(cid int not null, name varchar(32), primary key(cid));", "create table orders(oid int not null, cid int, date date, primary key(oid), "+ "grouping foreign key(cid) references customer(cid));", "create table items(iid int not null, oid int, sku int, primary key(iid), "+ "grouping foreign key(oid) references orders(oid));", "create index \"cName_oDate_iSku\" on items(customer.name, orders.date, items.sku) using left join;" }; final AkibanInformationSchema ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); GroupIndex index; IndexRowComposition rowComp; IndexToHKey indexToHKey; Table customer = ais.getTable(tableName("customer")); Table orders = ais.getTable(tableName("orders")); Table items = ais.getTable(tableName("items")); // left join group index on (c.name,o.date,i.sku): // declared: c.name o.date i.sku // hkey: c.cid o.oid i.iid index = items.getGroup().getIndex("cName_oDate_iSku"); assertNotNull(index); assertFalse(index.isPrimaryKey()); assertFalse(index.isUnique()); rowComp = index.indexRowComposition(); // Flattened: (c.cid, c.name, o.oid, o.cid, o.date, i.iid, i.oid, i.sku) assertEquals(1, rowComp.getFieldPosition(0)); // c.name assertEquals(4, rowComp.getFieldPosition(1)); // o.date assertEquals(7, rowComp.getFieldPosition(2)); // i.sku // item hkey assertEquals(0, rowComp.getFieldPosition(3)); // c.cid assertEquals(2, rowComp.getFieldPosition(4)); // o.oid assertEquals(5, rowComp.getFieldPosition(5)); // i.iid assertEquals(6, rowComp.getLength()); // group index -> i hkey indexToHKey = index.indexToHKey(items.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(3, indexToHKey.getIndexRowPosition(1)); // c.cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(4, indexToHKey.getIndexRowPosition(3)); // o.oid assertEquals(items.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(5, indexToHKey.getIndexRowPosition(5)); // i.iid // group index -> o hkey indexToHKey = index.indexToHKey(orders.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(3, indexToHKey.getIndexRowPosition(1)); // c.cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(4, indexToHKey.getIndexRowPosition(3)); // o.oid // group index -> c hkey indexToHKey = index.indexToHKey(customer.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(3, indexToHKey.getIndexRowPosition(1)); // c.cid } @Test public void checkOIGroupIndex() throws Exception { String[] ddl = { "create table customer(cid int not null, name varchar(32), primary key(cid));", "create table orders(oid int not null, cid int, date date, primary key(oid), "+ "grouping foreign key(cid) references customer(cid));", "create table items(iid int not null, oid int, sku int, primary key(iid), "+ "grouping foreign key(oid) references orders(oid));", "create index \"oDate_iSku\" on items(orders.date, items.sku) using left join;" }; final AkibanInformationSchema ais; { ais = SCHEMA_FACTORY.aisWithRowDefs(ddl); } GroupIndex index; IndexRowComposition rowComp; IndexToHKey indexToHKey; Table customer = ais.getTable(tableName("customer")); Table orders = ais.getTable(tableName("orders")); Table items = ais.getTable(tableName("items")); // left join group index on o.date,i.sku // declared: o.date i.sku // hkey: o.cid o.oid i.iid index = items.getGroup().getIndex("oDate_iSku"); assertNotNull(index); assertFalse(index.isPrimaryKey()); assertFalse(index.isUnique()); rowComp = index.indexRowComposition(); // Flattened: (c.cid, c.name, o.oid, o.cid, o.date, i.iid, i.oid, i.sku) assertEquals(4, rowComp.getFieldPosition(0)); // o.date assertEquals(7, rowComp.getFieldPosition(1)); // i.sku // item hkey assertEquals(3, rowComp.getFieldPosition(2)); // o.cid assertEquals(2, rowComp.getFieldPosition(3)); // o.oid assertEquals(5, rowComp.getFieldPosition(4)); // i.iid assertEquals(5, rowComp.getLength()); // group index -> i hkey indexToHKey = index.indexToHKey(items.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(2, indexToHKey.getIndexRowPosition(1)); // o.cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(3, indexToHKey.getIndexRowPosition(3)); // o.oid assertEquals(items.getOrdinal().intValue(), indexToHKey.getOrdinal(4)); // i ordinal assertEquals(4, indexToHKey.getIndexRowPosition(5)); // i.iid // group index -> o hkey indexToHKey = index.indexToHKey(orders.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(2, indexToHKey.getIndexRowPosition(1)); // o.cid assertEquals(orders.getOrdinal().intValue(), indexToHKey.getOrdinal(2)); // o ordinal assertEquals(3, indexToHKey.getIndexRowPosition(3)); // o.oid // group index -> c hkey indexToHKey = index.indexToHKey(customer.getDepth()); assertEquals(customer.getOrdinal().intValue(), indexToHKey.getOrdinal(0)); // c ordinal assertEquals(2, indexToHKey.getIndexRowPosition(1)); // o.cid } private void checkFields(Table table, String... expectedFields) { checkFields(table.rowDef(), expectedFields); } private void checkFields(RowDef rowdef, String... expectedFields) { FieldDef[] fields = rowdef.getFieldDefs(); Assert.assertEquals(expectedFields.length, fields.length); for (int i = 0; i < fields.length; i++) { assertEquals(expectedFields[i], fields[i].getName()); } } private TableName tableName(String name) { return new TableName(SCHEMA, name); } private void checkField(String name, RowDef rowDef, int fieldNumber) { FieldDef field = rowDef.getFieldDefs()[fieldNumber]; assertEquals(name, field.getName()); } // Copied from AISTest private void checkHKey(HKey hKey, Object... elements) { int e = 0; int position = 0; for (HKeySegment segment : hKey.segments()) { Assert.assertEquals(position++, segment.positionInHKey()); assertSame(elements[e++], segment.table()); for (HKeyColumn column : segment.columns()) { Assert.assertEquals(position++, column.positionInHKey()); Assert.assertEquals(elements[e++], column.column().getTable()); Assert.assertEquals(elements[e++], column.column().getName()); } } Assert.assertEquals(elements.length, e); } private int[] indexFields(Index index) { int[] fields = new int[index.getKeyColumns().size()]; IndexRowComposition indexRowComposition = index.indexRowComposition(); for (int i = 0; i < fields.length; i++) { fields[i] = indexRowComposition.getFieldPosition(i); } return fields; } private static final String SCHEMA = "schema"; private static final SchemaFactory SCHEMA_FACTORY = new SchemaFactory(SCHEMA); }