/**
* 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.qp.operator;
import com.foundationdb.ais.model.AkibanInformationSchema;
import com.foundationdb.ais.model.Index;
import com.foundationdb.ais.model.Join;
import com.foundationdb.ais.model.Table;
import com.foundationdb.ais.model.aisb2.AISBBasedBuilder;
import com.foundationdb.server.types.common.types.TypesTranslator;
import com.foundationdb.server.types.mcompat.mtypes.MTypesTranslator;
import com.foundationdb.junit.NamedParameterizedRunner;
import com.foundationdb.junit.OnlyIf;
import com.foundationdb.junit.OnlyIfNot;
import com.foundationdb.junit.Parameterization;
import com.foundationdb.junit.ParameterizationBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(NamedParameterizedRunner.class)
public final class IndexScanSelectorTest {
@NamedParameterizedRunner.TestParameters
public static Collection<Parameterization> params() {
ParameterizationBuilder builder = new ParameterizationBuilder();
builder.add("ONCE", null, null);
// bitmap descriptors are leaf to root
param(builder, IndexScanSelector.leftJoinAfter(ais.oiGroupIndex, ais.o), "010");
param(builder, IndexScanSelector.leftJoinAfter(ais.oiGroupIndex, ais.i), "110");
param(builder, IndexScanSelector.rightJoinUntil(ais.oiGroupIndex, ais.o), "110");
param(builder, IndexScanSelector.rightJoinUntil(ais.oiGroupIndex, ais.i), "100");
param(builder, IndexScanSelector.inner(ais.oiGroupIndex), "110");
return builder.asList();
}
private static void param(ParameterizationBuilder builder, IndexScanSelector selector, String bitmap) {
bitmap = bitmap.substring(bitmap.indexOf('1'));
for(char c : bitmap.toCharArray())
assert c == '1' || c == '0' : c;
builder.add(builder.asList().size() + " " + selector.describe() + " -> " + bitmap, selector, bitmap);
}
@OnlyIf("parameterized()")
@Test
public void testBitMap() {
String actual = Long.toBinaryString(selector.getBitMask());
assertEquals(expectedMap, actual);
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void leftAboveGI() {
IndexScanSelector.leftJoinAfter(ais.oiGroupIndex, ais.c);
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void leftBelowGI() {
IndexScanSelector.leftJoinAfter(ais.oiGroupIndex, ais.h);
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void rightAboveGI() {
IndexScanSelector.leftJoinAfter(ais.oiGroupIndex, ais.c);
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void rightBelowGI() {
IndexScanSelector.leftJoinAfter(ais.oiGroupIndex, ais.h);
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void leftBelowTI() {
IndexScanSelector.leftJoinAfter(ais.oTableIndex, ais.i);
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void leftAboveTI() {
IndexScanSelector.leftJoinAfter(ais.oTableIndex, ais.c);
}
@OnlyIfNot("parameterized()")
@Test()
public void leftAtTI() {
assertTrue("doesn't match all", IndexScanSelector.leftJoinAfter(ais.oTableIndex, ais.o).matchesAll());
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void rightBelowTI() {
IndexScanSelector.rightJoinUntil(ais.oTableIndex, ais.i);
}
@OnlyIfNot("parameterized()")
@Test(expected = IllegalArgumentException.class)
public void rightAboveTI() {
IndexScanSelector.rightJoinUntil(ais.oTableIndex, ais.c);
}
@OnlyIfNot("parameterized()")
@Test()
public void rightAtTI() {
assertTrue("doesn't match all", IndexScanSelector.rightJoinUntil(ais.oTableIndex, ais.o).matchesAll());
}
public boolean parameterized() {
return selector != null;
}
public IndexScanSelectorTest(IndexScanSelector selector, String expectedMap) {
this.selector = selector;
this.expectedMap = expectedMap;
}
private final IndexScanSelector selector;
private final String expectedMap;
private static final AisStruct ais = new AisStruct();
private static class AisStruct {
public AisStruct() {
TypesTranslator typesTranslator = MTypesTranslator.INSTANCE;
AkibanInformationSchema ais = AISBBasedBuilder.create("coih", typesTranslator)
.table("customers").colInt("cid").colString("name", 32).pk("cid")
.table("orders").colInt("oid").colInt("c_id").colInt("priority").pk("oid")
.key("o_index", "priority")
.joinTo("customers").on("c_id", "cid")
.table("items").colInt("iid").colInt("o_id").colInt("sku").pk("iid")
.joinTo("orders").on("o_id", "oid")
.table("handling").colInt("hid").colInt("i_id").colString("description", 32)
.joinTo("items").on("i_id", "iid")
.groupIndex("sku_priority_gi", Index.JoinType.LEFT).on("items", "sku").and("orders", "priority")
.ais();
c = ais.getTable("coih", "customers");
o = ais.getTable("coih", "orders");
i = ais.getTable("coih", "items");
h = ais.getTable("coih", "handling");
oTableIndex = o.getIndex("o_index");
oiGroupIndex = i.getGroup().getIndex("sku_priority_gi");
}
private final Table c;
private final Table o;
private final Table i;
private final Table h;
private final Index oiGroupIndex;
private final Index oTableIndex;
}
}