package edu.brown.plannodes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.voltdb.catalog.Column;
import org.voltdb.catalog.PlanFragment;
import org.voltdb.catalog.Procedure;
import org.voltdb.catalog.Statement;
import org.voltdb.catalog.Table;
import org.voltdb.expressions.AbstractExpression;
import org.voltdb.planner.PlannerContext;
import org.voltdb.plannodes.AbstractPlanNode;
import org.voltdb.plannodes.AbstractScanPlanNode;
import org.voltdb.plannodes.IndexScanPlanNode;
import org.voltdb.plannodes.PlanNodeList;
import org.voltdb.plannodes.ProjectionPlanNode;
import org.voltdb.plannodes.SeqScanPlanNode;
import org.voltdb.types.ExpressionType;
import edu.brown.BaseTestCase;
import edu.brown.benchmark.tm1.TM1Constants;
import edu.brown.benchmark.tm1.procedures.GetNewDestination;
import edu.brown.benchmark.tm1.procedures.GetTableCounts;
import edu.brown.benchmark.tm1.procedures.UpdateLocation;
import edu.brown.catalog.CatalogUtil;
import edu.brown.expressions.ExpressionUtil;
import edu.brown.utils.CollectionUtil;
import edu.brown.utils.ProjectType;
import edu.brown.utils.StringUtil;
public class TestPlanNodeUtil extends BaseTestCase {
protected Procedure catalog_proc;
protected Statement catalog_stmt;
protected Table catalog_tbl;
@Override
protected void setUp() throws Exception {
super.setUp(ProjectType.TM1);
catalog_proc = this.getProcedure(GetTableCounts.class);
catalog_stmt = catalog_proc.getStatements().get("AccessInfoCount");
assertNotNull(catalog_stmt);
catalog_tbl = catalog_db.getTables().get(TM1Constants.TABLENAME_ACCESS_INFO);
assertNotNull(catalog_tbl);
}
/**
* testClone
*/
@Test
public void testClone() throws Exception {
Procedure catalog_proc = this.getProcedure(GetNewDestination.class);
Statement catalog_stmt = this.getStatement(catalog_proc, "GetData");
AbstractPlanNode root = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, true);
assertNotNull(root);
AbstractPlanNode clone = (AbstractPlanNode)root.clone();
assertNotNull(clone);
// assertEquals(root, clone);
assertFalse(root == clone);
List<AbstractPlanNode> list0 = new PlanNodeList(root).getExecutionList();
List<AbstractPlanNode> list1 = new PlanNodeList(clone).getExecutionList();
assertEquals(list0.size(), list1.size());
for (int i = 0, cnt = list0.size(); i < cnt; i++) {
AbstractPlanNode node0 = list0.get(i);
assertNotNull(node0);
AbstractPlanNode node1 = list1.get(i);
assertNotNull(node1);
// Compare!
assertFalse(node0 == node1);
assertEquals(node0.getChildPlanNodeCount(), node1.getChildPlanNodeCount());
assertEquals(node0.getInlinePlanNodeCount(), node1.getInlinePlanNodeCount());
assertEquals(node0.getOutputColumnGUIDCount(), node1.getOutputColumnGUIDCount());
List<AbstractExpression> exps0 = new ArrayList<AbstractExpression>(PlanNodeUtil.getExpressionsForPlanNode(node0));
List<AbstractExpression> exps1 = new ArrayList<AbstractExpression>(PlanNodeUtil.getExpressionsForPlanNode(node1));
assertEquals(exps0.size(), exps1.size());
for (int j = 0; j < exps0.size(); j++) {
AbstractExpression exp0 = exps0.get(j);
assertNotNull(exp0);
AbstractExpression exp1 = exps1.get(j);
assertNotNull(exp1);
// assertFalse(exp0 == exp1);
if (exp0.equals(exp1) == false) {
System.err.println("Failed to clone " + node0);
String col0 = "";
for (AbstractExpression exp : exps0)
col0 += "\n" + ExpressionUtil.debug(exp);
String col1 = "";
for (AbstractExpression exp : exps1)
col1 += "\n" + ExpressionUtil.debug(exp);
System.err.println(StringUtil.columns(col0, col1));
}
assertEquals(exp0, exp1);
} // FOR (exps)
// Make sure that they don't have the same reference!
node0.setOutputColumns(Collections.singleton(Integer.MIN_VALUE));
assertFalse(node0.getOutputColumnGUIDs().equals(node1.getOutputColumnGUIDs()));
} // FOR (nodes)
}
/**
* testGetScanExpressionTypes
*/
@Test
public void testGetScanExpressionTypes() throws Exception {
ExpressionType expected[] = {
ExpressionType.COMPARE_EQUAL,
ExpressionType.VALUE_PARAMETER,
ExpressionType.VALUE_TUPLE,
};
Procedure catalog_proc = this.getProcedure(UpdateLocation.class);
Statement catalog_stmt = this.getStatement(catalog_proc, "update");
AbstractPlanNode root = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, true);
assertNotNull(root);
Collection<ExpressionType> result = PlanNodeUtil.getScanExpressionTypes(root);
assertNotNull(result);
assertFalse(result.isEmpty());
for (ExpressionType e : expected) {
assert(result.contains(e)) : "Missing " + e;
}
}
/**
* testGetOutputColumns
*/
@Test
public void testGetOutputColumns() throws Exception {
Procedure catalog_proc = this.getProcedure(GetTableCounts.class);
Statement catalog_stmt = this.getStatement(catalog_proc, "CallForwardingCount");
Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_CALL_FORWARDING);
Column expected[] = {
this.getColumn(catalog_tbl, "S_ID")
};
AbstractPlanNode root = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, true);
assertNotNull(root);
Collection<Column> columns = PlanNodeUtil.getOutputColumnsForPlanNode(catalog_db, root.getChild(0));
assertNotNull(columns);
// System.err.print(catalog_stmt.fullName() + ": " + CatalogUtil.debug(columns));
// System.err.println(PlanNodeUtil.debug(root));
assertEquals(catalog_stmt.fullName(), expected.length, columns.size());
for (int i = 0; i < expected.length; i++) {
assert(columns.contains(expected[i])) : "Missing column " + CatalogUtil.getDisplayName(expected[i]);
} // FOR
}
/**
* testGetOutputColumns
*/
@Test
public void testGetUpdatedColumns() throws Exception {
Procedure catalog_proc = this.getProcedure(UpdateLocation.class);
Statement catalog_stmt = this.getStatement(catalog_proc, "update");
Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_SUBSCRIBER);
Column expected[] = {
this.getColumn(catalog_tbl, "VLR_LOCATION")
};
AbstractPlanNode root = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, false);
assertNotNull(root);
IndexScanPlanNode idx_node = CollectionUtil.first(PlanNodeUtil.getPlanNodes(root, IndexScanPlanNode.class));
assertNotNull(idx_node);
Collection<Column> columns = PlanNodeUtil.getUpdatedColumnsForPlanNode(catalog_db, idx_node);
assertNotNull(columns);
// System.err.print(catalog_stmt.fullName() + ": " + CatalogUtil.debug(columns));
// System.err.println(PlanNodeUtil.debug(root));
assertEquals(catalog_stmt.fullName(), expected.length, columns.size());
for (int i = 0; i < expected.length; i++) {
assert(columns.contains(expected[i])) : "Missing column " + CatalogUtil.getDisplayName(expected[i]);
} // FOR
}
/**
* testGetPlanNodes
*/
public void testGetPlanNodes() throws Exception {
PlannerContext cntxt = new PlannerContext();
AbstractPlanNode root_node = new ProjectionPlanNode(cntxt, 1);
root_node.addAndLinkChild(new SeqScanPlanNode(cntxt, 2));
Collection<SeqScanPlanNode> found0 = PlanNodeUtil.getPlanNodes(root_node, SeqScanPlanNode.class);
assertFalse(found0.isEmpty());
Collection<AbstractScanPlanNode> found1 = PlanNodeUtil.getPlanNodes(root_node, AbstractScanPlanNode.class);
assertFalse(found1.isEmpty());
}
/**
* testGetTableReferences
*/
public void testGetTableReferences() throws Exception {
AbstractPlanNode root_node = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, true);
assertNotNull(root_node);
Collection<AbstractPlanNode> found = PlanNodeUtil.getPlanNodesReferencingTable(root_node, catalog_tbl);
assertEquals(1, found.size());
AbstractPlanNode node = CollectionUtil.first(found);
assertNotNull(node);
assertTrue(node instanceof AbstractScanPlanNode);
}
/**
* testContainsPlanNode
*/
public void testContainsPlanNode() throws Exception {
assertTrue(catalog_stmt.getHas_multisited());
Collection<PlanFragment> fragments = catalog_stmt.getMs_fragments();
assertFalse(fragments.isEmpty());
Map<PlanFragment, Set<AbstractPlanNode>> fragment_nodes = new HashMap<PlanFragment, Set<AbstractPlanNode>>();
Set<AbstractPlanNode> all_nodes = new HashSet<AbstractPlanNode>();
for (PlanFragment catalog_frag : fragments) {
assertNotNull(catalog_frag);
final Set<AbstractPlanNode> nodes = new HashSet<AbstractPlanNode>();
AbstractPlanNode root = PlanNodeUtil.getPlanNodeTreeForPlanFragment(catalog_frag);
assertNotNull(nodes);
new PlanNodeTreeWalker(true) {
@Override
protected void callback(AbstractPlanNode element) {
nodes.add(element);
}
}.traverse(root);
assertFalse(nodes.isEmpty());
fragment_nodes.put(catalog_frag, nodes);
all_nodes.addAll(nodes);
} // FOR
for (PlanFragment catalog_frag : fragments) {
Set<AbstractPlanNode> nodes = fragment_nodes.get(catalog_frag);
assertNotNull(nodes);
for (AbstractPlanNode node : all_nodes) {
boolean expected = nodes.contains(node);
boolean actual = PlanNodeUtil.containsPlanNode(catalog_frag, node);
assertEquals(catalog_frag + "=>" + node, expected, actual);
} // FOR
} // FOR
System.err.println(StringUtil.formatMaps(fragment_nodes));
}
// public void testX() throws Exception {
// AbstractPlanNode root = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, false);
// PlanTreeCatalogNode p = new PlanTreeCatalogNode("XXX", catalog_stmt.getMs_fragments(), root);
//
// JFrame ret = new JFrame("XXXXX");
// ret.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// ret.setLayout(new BorderLayout());
// ret.setContentPane(p.getPanel());
// ret.setSize(650, 650);
// ret.setVisible(true);
// ThreadUtil.sleep(11000000);
//
// }
}