use of org.voltdb.types.PlanNodeType in project voltdb by VoltDB.
the class testPlannerTester method testWriteAndLoad.
public void testWriteAndLoad() throws Exception {
AbstractPlanNode pn = null;
plannerTester.setUpForTest(m_currentDir + "tests/frontend/org/voltdb/planner/testplans-plannerTester-ddl.sql", "testplans-plannerTester-ddl");
List<AbstractPlanNode> pnList = plannerTester.testCompile("select * from l, t where t.a=l.a limit ?;");
System.out.println(pnList.size());
pn = pnList.get(0);
assert (pnList.get(1) instanceof SendPlanNode);
pn.reattachFragment(pnList.get(1));
System.out.println(pn.toJSONString());
System.out.println(pn.toExplainPlanString());
plannerTester.writePlanToFile(pn, m_homeDir, "prettyJson.txt", "");
ArrayList<String> getsql = new ArrayList<String>();
AbstractPlanNode pn2 = plannerTester.loadPlanFromFile(m_homeDir + "prettyJson.txt", getsql);
System.out.println(pn2.toExplainPlanString());
ArrayList<AbstractPlanNode> list1 = pn.getPlanNodeList();
ArrayList<AbstractPlanNode> list2 = pn2.getPlanNodeList();
assertTrue(list1.size() == list2.size());
for (int i = 0; i < list1.size(); i++) {
Map<PlanNodeType, AbstractPlanNode> inlineNodes1 = list1.get(i).getInlinePlanNodes();
Map<PlanNodeType, AbstractPlanNode> inlineNodes2 = list2.get(i).getInlinePlanNodes();
if (inlineNodes1 != null) {
assertTrue(inlineNodes1.size() == inlineNodes2.size());
}
}
}
use of org.voltdb.types.PlanNodeType in project voltdb by VoltDB.
the class plannerTester method diffInlineAndJoin.
public static boolean diffInlineAndJoin(AbstractPlanNode oldpn1, AbstractPlanNode newpn2) {
m_treeSizeDiff = 0;
boolean noDiff = true;
ArrayList<String> messages = new ArrayList<String>();
ArrayList<AbstractPlanNode> list1 = oldpn1.getPlanNodeList();
ArrayList<AbstractPlanNode> list2 = newpn2.getPlanNodeList();
int size1 = list1.size();
int size2 = list2.size();
m_treeSizeDiff = size1 - size2;
diffPair intdiffPair = new diffPair(0, 0);
diffPair stringdiffPair = new diffPair(null, null);
if (size1 != size2) {
intdiffPair.set(size1, size2);
messages.add("Plan tree size diff: " + intdiffPair.toString());
}
Map<String, ArrayList<Integer>> planNodesPosMap1 = new LinkedHashMap<String, ArrayList<Integer>>();
Map<String, ArrayList<AbstractPlanNode>> inlineNodesPosMap1 = new LinkedHashMap<String, ArrayList<AbstractPlanNode>>();
Map<String, ArrayList<Integer>> planNodesPosMap2 = new LinkedHashMap<String, ArrayList<Integer>>();
Map<String, ArrayList<AbstractPlanNode>> inlineNodesPosMap2 = new LinkedHashMap<String, ArrayList<AbstractPlanNode>>();
fetchPositionInfoFromList(list1, planNodesPosMap1, inlineNodesPosMap1);
fetchPositionInfoFromList(list2, planNodesPosMap2, inlineNodesPosMap2);
planNodePositionDiff(planNodesPosMap1, planNodesPosMap2, messages);
inlineNodePositionDiff(inlineNodesPosMap1, inlineNodesPosMap2, messages);
// join nodes diff
ArrayList<AbstractPlanNode> joinNodes1 = getJoinNodes(list1);
ArrayList<AbstractPlanNode> joinNodes2 = getJoinNodes(list2);
size1 = joinNodes1.size();
size2 = joinNodes2.size();
if (size1 != size2) {
intdiffPair.set(size1, size2);
messages.add("Join Nodes Number diff:\n" + intdiffPair.toString() + "\nSQL statement might be changed.");
m_changedSQL = true;
String str1 = "";
String str2 = "";
for (AbstractPlanNode pn : joinNodes1) {
str1 = str1 + pn.toString() + ", ";
}
for (AbstractPlanNode pn : joinNodes2) {
str2 = str2 + pn.toString() + ", ";
}
if (str1.length() > 1) {
str1 = (str1.subSequence(0, str1.length() - 2)).toString();
}
if (str2.length() > 1) {
str2 = (str2.subSequence(0, str2.length() - 2)).toString();
}
stringdiffPair.set(str1, str2);
messages.add("Join Node List diff: " + "\n" + stringdiffPair.toString() + "\n");
} else {
for (int i = 0; i < size1; i++) {
AbstractPlanNode pn1 = joinNodes1.get(i);
AbstractPlanNode pn2 = joinNodes2.get(i);
PlanNodeType pnt1 = pn1.getPlanNodeType();
PlanNodeType pnt2 = pn2.getPlanNodeType();
if (!pnt1.equals(pnt2)) {
stringdiffPair.set(pn1.toString(), pn2.toString());
messages.add("Join Node Type diff:\n" + stringdiffPair.toString());
}
}
}
for (String msg : messages) {
if (msg.contains("diff") || msg.contains("Diff")) {
noDiff = false;
break;
}
}
m_diffMessages.addAll(messages);
return noDiff;
}
use of org.voltdb.types.PlanNodeType in project voltdb by VoltDB.
the class PlannerTestCase method validatePlan.
/**
* Validate a plan. This is kind of like
* PlannerTestCase.compileToTopDownTree. The differences are
* <ol>
* <li>We can compile MP plans and SP plans, and</li>
* <li>The boundaries between fragments in MP plans
* are marked with PlanNodeType.INVALID.</li>
* <li>We can describe inline nodes pretty easily.</li>
* </ol>
*
* See TestWindowFunctions.testWindowFunctionWithIndex for examples
* of the use of this function.
*
* @param SQL The statement text.
* @param numberOfFragments The number of expected fragments.
* @param types The plan node types of the inline and out-of-line nodes.
* If types[idx] is a PlanNodeType, then the node should
* have no inline children. If types[idx] is an object of
* type PlanWithInlineNode then it has the main node type,
* and node types of the inline children as well.
*/
protected void validatePlan(String SQL, int numberOfFragments, Object... types) {
List<AbstractPlanNode> fragments = compileToFragments(SQL);
assertEquals(String.format("Expected %d fragments, not %d", numberOfFragments, fragments.size()), numberOfFragments, fragments.size());
int idx = 0;
int fragment = 1;
// The index of the last PlanNodeType in types.
int nchildren = types.length;
System.out.printf("Plan for <%s>\n", SQL);
for (AbstractPlanNode plan : fragments) {
printPlanNodes(plan, fragment, numberOfFragments);
// marked with PlanNodeType.INVALID.
if (fragment > 1) {
assertEquals("Expected a fragment to start here", PlanNodeType.INVALID, types[idx]);
idx += 1;
}
fragment += 1;
for (; plan != null; idx += 1) {
if (types.length <= idx) {
fail(String.format("Expected %d plan nodes, but found more.", types.length));
}
if (types[idx] instanceof PlanNodeType) {
assertEquals(String.format("Expected %s plan node but found %s", types[idx], plan.getPlanNodeType()), types[idx], plan.getPlanNodeType());
} else if (types[idx] instanceof PlanWithInlineNodes) {
PlanWithInlineNodes branch = (PlanWithInlineNodes) types[idx];
String error = branch.match(plan);
if (error != null) {
fail(error);
}
} else {
fail("Expected a PlanNodeType or an array of PlanNodeTypes here.");
}
plan = (plan.getChildCount() > 0) ? plan.getChild(0) : null;
}
}
assertEquals(nchildren, idx);
}
use of org.voltdb.types.PlanNodeType in project voltdb by VoltDB.
the class PlanNodeTree method loadPlanNodesFromJSONArrays.
/**
* Load plan nodes from the "PLAN_NODE" array. All the nodes are from
* a substatement with the id = stmtId
* @param stmtId
* @param jArray - PLAN_NODES
* @param db
* @throws JSONException
*/
private void loadPlanNodesFromJSONArrays(int stmtId, JSONArray jArray, Database db) {
List<AbstractPlanNode> planNodes = new ArrayList<AbstractPlanNode>();
int size = jArray.length();
try {
for (int i = 0; i < size; i++) {
JSONObject jobj = jArray.getJSONObject(i);
String nodeTypeStr = jobj.getString("PLAN_NODE_TYPE");
PlanNodeType nodeType = PlanNodeType.get(nodeTypeStr);
AbstractPlanNode apn = nodeType.getPlanNodeClass().newInstance();
apn.loadFromJSONObject(jobj, db);
planNodes.add(apn);
}
//link children and parents
for (int i = 0; i < size; i++) {
JSONObject jobj = jArray.getJSONObject(i);
if (jobj.has("CHILDREN_IDS")) {
AbstractPlanNode parent = planNodes.get(i);
JSONArray children = jobj.getJSONArray("CHILDREN_IDS");
for (int j = 0; j < children.length(); j++) {
AbstractPlanNode child = getNodeofId(children.getInt(j), planNodes);
parent.addAndLinkChild(child);
}
}
}
m_planNodesListMap.put(stmtId, planNodes);
} catch (JSONException | InstantiationException | IllegalAccessException e) {
System.err.println(e);
e.printStackTrace();
}
}
use of org.voltdb.types.PlanNodeType in project voltdb by VoltDB.
the class InlineOrderByIntoMergeReceive method recursivelyApply.
@Override
protected AbstractPlanNode recursivelyApply(AbstractPlanNode planNode) {
assert (planNode != null);
// side effects.
if (m_parsedStmt.topmostParentStatementIsDML()) {
// Do not apply the optimization.
return planNode;
}
Queue<AbstractPlanNode> children = new LinkedList<>();
children.add(planNode);
while (!children.isEmpty()) {
AbstractPlanNode plan = children.remove();
PlanNodeType nodeType = plan.getPlanNodeType();
if (PlanNodeType.RECEIVE == nodeType) {
// continue. We are after the coordinator ORDER BY or WINDOWFUNCTION node.
return planNode;
}
if (PlanNodeType.ORDERBY == nodeType) {
assert (plan instanceof OrderByPlanNode);
AbstractPlanNode newPlan = applyOptimization((OrderByPlanNode) plan);
// the new plan node.
if (newPlan != plan) {
// Only one coordinator ORDER BY node is possible
if (plan == planNode) {
return newPlan;
} else {
// Do not apply the optimization.
return planNode;
}
}
} else if (PlanNodeType.WINDOWFUNCTION == nodeType) {
assert (plan instanceof WindowFunctionPlanNode);
AbstractPlanNode newPlan = applyOptimization((WindowFunctionPlanNode) plan);
// See above for why this is the way it is.
if (newPlan != plan) {
return newPlan;
} else {
return planNode;
}
}
for (int i = 0; i < plan.getChildCount(); i++) {
children.add(plan.getChild(i));
}
}
// Do not apply the optimization.
return planNode;
}
Aggregations