package org.wonderdb.parser.jtree;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.wonderdb.expression.BasicExpression;
import org.wonderdb.expression.Expression;
import org.wonderdb.expression.Operand;
import org.wonderdb.expression.TreeOperand;
import org.wonderdb.expression.VariableOperand;
import org.wonderdb.parser.TableDef;
import org.wonderdb.parser.UpdateSetExpression;
import org.wonderdb.query.parse.CollectionAlias;
import org.wonderdb.query.parse.StaticOperand;
import org.wonderdb.schema.CollectionMetadata;
import org.wonderdb.schema.SchemaMetadata;
import org.wonderdb.types.DBType;
import org.wonderdb.types.StringType;
public class SimpleNodeHelper {
private static SimpleNodeHelper instance = new SimpleNodeHelper();
private SimpleNodeHelper() {
}
public static SimpleNodeHelper getInstance() {
return instance;
}
public SimpleNode getFirstNode(SimpleNode node, int nodeId) {
if (node == null) {
return null;
}
if (node.id == nodeId) {
return node;
}
Node[] children = node.children;
if (children == null) {
return null;
}
for (int i = 0; i < children.length; i++) {
SimpleNode n = (SimpleNode) children[i];
if (n.id == nodeId) {
return n;
}
n = getFirstNode(n, nodeId);
if (n != null && n.id == nodeId) {
return n;
}
}
return null;
}
public Map<String, CollectionAlias> getFromMap(SimpleNode root) {
Map<String, CollectionAlias> map = new HashMap<String, CollectionAlias>();
List<SimpleNode> list = new ArrayList<SimpleNode>();
traverse(root, UQLParserTreeConstants.JJTTABLEDEF, list);
for (int i = 0; i < list.size(); i++) {
TableDef tableDef = getTableDef(list.get(i));
CollectionAlias ca = new CollectionAlias(tableDef.table, tableDef.alias);
map.put(tableDef.alias, ca);
}
return map;
}
public void traverse(SimpleNode root, int nodeId, List<SimpleNode> nodeList) {
if (root == null) {
return;
}
if (root.id == nodeId) {
nodeList.add(root);
}
Node[] children = root.children;
if (children != null) {
for (int i = 0; i < children.length; i++) {
traverse((SimpleNode) children[i], nodeId, nodeList);
}
}
}
public TableDef getTableDef(SimpleNode node) {
Token f = node.jjtGetFirstToken();
Token l = node.jjtGetLastToken();
TableDef tableDef = new TableDef();
tableDef.table = f.image;
tableDef.alias = "";
if (f != l) {
tableDef.alias = l.image;
}
return tableDef;
}
public void getNodes(SimpleNode root, int nodeId, List<SimpleNode> nodeList) {
if (root == null) {
return;
}
if (root.id == nodeId) {
nodeList.add(root);
}
Node[] children = root.children;
if (children != null) {
for (int i = 0; i < children.length; i++) {
SimpleNode node = (SimpleNode) children[i];
getNodes(node, nodeId, nodeList);
}
}
}
public List<TableDef> getTables(SimpleNode selectNode) {
List<TableDef> retList = new ArrayList<TableDef>();
List<SimpleNode> tableDefNodes = new ArrayList<SimpleNode>();
getNodes(selectNode, UQLParserTreeConstants.JJTTABLEDEF, tableDefNodes);
for (int i = 0; i < tableDefNodes.size(); i++) {
SimpleNode node = tableDefNodes.get(i);
retList.add(getTableDef(node));
}
return retList;
}
public SimpleNode copyTree(SimpleNode node) {
SimpleNode n = new SimpleNode(node.id);
n.jjtSetFirstToken(node.jjtGetFirstToken());
n.jjtSetLastToken(node.jjtGetLastToken());
n.jjtSetParent(node.jjtGetParent());
n.jjtSetValue(node.jjtGetValue());
if (node.children != null) {
for (int i = 0; i < node.children.length; i++) {
SimpleNode n1 = copyTree((SimpleNode) node.children[i]);
n.jjtAddChild(n1, i);
}
}
return n;
}
public void makeGrandParentAsParent(SimpleNode node) {
if (node == null) {
return;
}
SimpleNode parent = (SimpleNode) node.jjtGetParent();
if (parent == null) {
return;
}
parent = (SimpleNode) parent.jjtGetParent();
if (parent == null) {
return;
}
parent.jjtAddChild(node, parent.children.length);
}
// public ExpressionNode shouldQueryRewriteStartNode(SimpleNode start) {
// SimpleNode selectNode = (SimpleNode) start.children[0];
// SimpleNode compareNode = null;
// for (int i = 0; i < selectNode.children.length; i++) {
// compareNode = (SimpleNode) selectNode.children[i];
// if (compareNode.id == UQLParserTreeConstants.JJTFILTEREXPRESSION) {
// break;
// }
// }
//
// if (compareNode.id != UQLParserTreeConstants.JJTFILTEREXPRESSION) {
// return null;
// }
// if (compareNode.children != null && compareNode.children.length > 0) {
// return convertToExpressionNode((SimpleNode) compareNode.children[0]);
// }
// return new ExpressionNode(start, new ArrayList<>(), new ArrayList<>());
// }
public void orderAndOr(SimpleNode start) {
if (andOrOutofOrder(start)) {
order(start);
}
if (start.children != null) {
for (int i = 0; i < start.children.length; i++) {
orderAndOr((SimpleNode) start.children[i]);
}
}
}
public void order(SimpleNode start) {
List<List<SimpleNode>> orNodes = new ArrayList<List<SimpleNode>>();
List<List<SimpleNode>> andNodes = new ArrayList<List<SimpleNode>>();
List<SimpleNode> temp = new ArrayList<SimpleNode>();
for (int i = 0; i < start.children.length; i++) {
SimpleNode n = (SimpleNode) start.children[i];
if (n.id != UQLParserTreeConstants.JJTAND || n.id != UQLParserTreeConstants.JJTOR) {
temp.add(n);
} else if (n.id == UQLParserTreeConstants.JJTAND) {
andNodes.add(temp);
temp = new ArrayList<SimpleNode>();
} else if (n.id == UQLParserTreeConstants.JJTOR) {
orNodes.add(temp);
temp = new ArrayList<SimpleNode>();
}
}
List<SimpleNode> finalList = new ArrayList<SimpleNode>();
for (int i = 0; i < andNodes.size(); i++) {
temp = andNodes.get(i);
finalList.addAll(temp);
if (i < andNodes.size()-1) {
finalList.add(new SimpleNode(UQLParserTreeConstants.JJTAND));
}
}
if (finalList.size() > 0) {
finalList.add(new SimpleNode(UQLParserTreeConstants.JJTOR));
}
for (int i = 0; i < orNodes.size(); i++) {
temp = orNodes.get(i);
finalList.addAll(temp);
if (i < orNodes.size()-1) {
finalList.add(new SimpleNode(UQLParserTreeConstants.JJTOR));
}
}
}
public boolean andOrOutofOrder(SimpleNode node) {
boolean foundOr = false;
if (node.children != null) {
for (int i = 0; i < node.children.length; i++) {
SimpleNode n = (SimpleNode) node.children[i];
if (n.id != UQLParserTreeConstants.JJTAND && n.id != UQLParserTreeConstants.JJTOR) {
continue;
}
if (n.id == UQLParserTreeConstants.JJTAND && foundOr) {
return true;
} else {
foundOr = true;
}
}
}
return false;
}
// public ExpressionNode convertToExpressionNode(SimpleNode start) {
// List<ExpressionNode> andList = new ArrayList<>();
// List<ExpressionNode> orList = new ArrayList<>();
//
// ExpressionNode currentNode = null;
// int currentOp = -1;
// if (start.children != null) {
// for (int i = 0; i < start.children.length; i++) {
// SimpleNode child = (SimpleNode) start.children[i];
// if (child.id == UQLParserTreeConstants.JJTAND && currentNode != null) {
// andList.add(currentNode);
// currentOp = child.id;
// } else if (child.id == UQLParserTreeConstants.JJTOR && currentNode != null) {
// orList.add(currentNode);
// currentOp = child.id;
// }
// currentNode = convertToExpressionNode((SimpleNode) start.children[i]);
// }
// }
// if (currentOp == UQLParserTreeConstants.JJTAND) {
// andList.add(currentNode);
// } else if (currentOp == UQLParserTreeConstants.JJTOR) {
// orList.add(currentNode);
// }
// return new ExpressionNode(start, andList, orList);
// }
// public ExpressionNode shouldQueryRewrite(SimpleNode start) {
// Set<SimpleNode> andList = new HashSet<SimpleNode>();
// Set<SimpleNode> orList = new HashSet<SimpleNode>();
//
// List<ExpressionNode> aList = new ArrayList<ExpressionNode>(andList.size());
// List<ExpressionNode> oList = new ArrayList<ExpressionNode>(orList.size());
//
// SimpleNode node = start;
// if (node.children == null) {
// return new ExpressionNode(node, aList, oList);
// }
//
// int posn = 1;
// node = (SimpleNode) node.children[0];
// if (node.id != UQLParserTreeConstants.JJTCOMPAREEQUATION) {
// return new ExpressionNode((SimpleNode) node.parent, aList, oList);
// }
//
// int currentId = UQLParserTreeConstants.JJTAND;
//
// while (true) {
// if (node.children.length == 1) {
// andList.add((SimpleNode) node.children[0]);
// break;
// }
//
// if (posn < node.children.length) {
// currentId = ((SimpleNode) node.children[posn]).id;
// }
//
// SimpleNode current = (SimpleNode) node.children[posn-1];
// if (currentId == UQLParserTreeConstants.JJTAND) {
// andList.add(current);
// } else {
// orList.add(current);
// }
// if (posn >= node.children.length) {
// break;
// }
// posn = posn + 2;
// }
//
// Iterator<SimpleNode> iter = andList.iterator();
// while (iter.hasNext()) {
// ExpressionNode n = shouldQueryRewrite(iter.next());
// aList.add(n);
// }
//
// iter = orList.iterator();
// while (iter.hasNext()) {
// ExpressionNode n = shouldQueryRewrite(iter.next());
// oList.add(n);
// }
//
// return new ExpressionNode(node, aList, oList);
// }
// public void flattenNode(ExpressionNode node) {
// while (node != null && (flatenParentAndChildSameType(node) || flattenParentAndChildOr(node)));
// }
// public boolean flattenParentAndChildOr(ExpressionNode node) {
//
// boolean retVal = false;
//
// for (int i = 0; i < node.andList.size(); i++) {
// ExpressionNode en = node.andList.get(i);
// retVal = retVal || flattenParentAndChildOr(en);
// }
//
// for (int i = 0; i < node.orList.size(); i++) {
// ExpressionNode en = node.orList.get(i);
// retVal = retVal || flattenParentAndChildOr(en);
// }
// List<ExpressionNode> newOrList = new ArrayList<ExpressionNode>(node.orList);
//
// for (int i = 0; i < node.andList.size(); i++) {
// ExpressionNode en = node.andList.get(i);
// if (isOrOr(en)) {
// List<ExpressionNode> al = null;
// ExpressionNode n = null;
//
// for (int j = 0; j < en.orList.size(); j++) {
// al = new ArrayList<ExpressionNode>(node.andList);
// al.add(en.orList.get(j));
// n = new ExpressionNode(node.currentNode, al, new ArrayList<ExpressionNode>());
// newOrList.add(n);
// }
// retVal = true;
// }
// }
//
// if (retVal) {
// node.andList = new ArrayList<ExpressionNode>();
// node.orList = newOrList;
// }
// return retVal;
// }
// public boolean flatenParentAndChildSameType(ExpressionNode node) {
//// if (true) {
//// return false;
//// }
// // case I and-and/ or - or -> Just move children to parent.
// for (int i = 0; i < node.andList.size(); i++) {
// ExpressionNode en = node.andList.get(i);
// flatenParentAndChildSameType(en);
// }
//
// for (int i = 0; i < node.orList.size(); i++) {
// ExpressionNode en = node.orList.get(i);
// flatenParentAndChildSameType(en);
// }
//
// List<ExpressionNode> removeAndList = new ArrayList<ExpressionNode>();
// List<ExpressionNode> removeOrList = new ArrayList<ExpressionNode>();
//
// for (int i = 0; i < node.andList.size(); i++) {
// ExpressionNode en = node.andList.get(i);
// if (isAndAnd(en) && en.andList.size() > 0) {
// node.andList.addAll(en.andList);
// removeAndList.add(en);
// }
// }
//
// for (int i = 0; i < node.orList.size(); i++) {
// ExpressionNode en = node.orList.get(i);
// if (isOrOr(en) && node.orList.size() > 0) {
// node.orList.addAll(en.orList);
// node.orList.addAll(en.andList);
// removeOrList.add(en);
// }
// }
//
// node.andList.removeAll(removeAndList);
// node.orList.removeAll(removeOrList);
//
// return removeAndList.size() > 0 || removeOrList.size() > 0;
// }
// private boolean isAndAnd(ExpressionNode node) {
// if (node.orList.size() != 0) {
// return false;
// }
//
// return true;
// }
//
// private boolean isOrOr(ExpressionNode node) {
// if (node.orList.size() > 0 && node.andList.size() == 0) {
// return true;
// } else if (node.andList.size() == 1) {
// return true;
// }
//
// return false;
// }
public List<SimpleNode> breakAnds(SimpleNode compareNode) {
List<SimpleNode> retList = new ArrayList<SimpleNode>();
if (compareNode == null) {
return retList;
}
Node[] children = compareNode.children;
for (int i = 0; i < children.length; i++) {
SimpleNode node = (SimpleNode) children[i];
if (node.id == UQLParserTreeConstants.JJTOR) {
return new ArrayList<SimpleNode>();
}
if (node.id == UQLParserTreeConstants.JJTEQUALITYEQUATION) {
retList.add(node);
}
}
return retList;
}
public List<BasicExpression> buildAndExpressionList(SimpleNode filterNode, List<CollectionAlias> caList) {
List<SimpleNode> list = breakAnds(filterNode);
List<BasicExpression> retList = new ArrayList<BasicExpression>();
for (int i = 0; i < list.size(); i++) {
SimpleNode node = list.get(i);
Node[] children = node.children;
if (children == null || children.length != 3) {
continue;
}
SimpleNode left = (SimpleNode) children[0];
SimpleNode op = (SimpleNode) children[1];
SimpleNode right = (SimpleNode) children[2];
if (left == null || op == null || right == null) {
continue;
}
if (op.id != UQLParserTreeConstants.JJTEQ &&
op.id != UQLParserTreeConstants.JJTLE &&
op.id != UQLParserTreeConstants.JJTLT &&
op.id != UQLParserTreeConstants.JJTGE &&
op.id != UQLParserTreeConstants.JJTGT) {
continue;
}
Operand leftOperand = getOperand(left, caList);
Operand rightOperand = getOperand(right, caList);
int operator = convertToExpOp(op.id);
BasicExpression exp = new BasicExpression(leftOperand, rightOperand, operator);
retList.add(exp);
}
return retList;
}
private Operand getOperand(SimpleNode node, List<CollectionAlias> caList) {
Operand operand = null;
if (getColumnAliasNode(node) != null) {
operand = getColumnId(node, caList);
} else if (isStaticNode(node)) {
QueryEvaluator qe = new QueryEvaluator(null, null);
qe.processMultiplicativeExpression(node);
Object val = node.jjtGetValue();
if (val instanceof DBType) {
operand = new StaticOperand((DBType) val);
} else {
operand = new StaticOperand(new StringType(val != null ? val.toString() : null));
}
} else {
operand = new TreeOperand();
}
return operand;
}
private SimpleNode getColumnAliasNode(SimpleNode node) {
Node[] children = node.children;
if (children == null || node.children == null || node.children.length == 0) {
if (node.id == UQLParserTreeConstants.JJTCOLUMNANDALIAS) {
return node;
} else {
return null;
}
}
if (node.children.length > 1) {
return null;
}
return getColumnAliasNode((SimpleNode) node.children[0]);
}
int convertToExpOp(int nodeOp) {
switch (nodeOp) {
case UQLParserTreeConstants.JJTEQ:
return Expression.EQ;
case UQLParserTreeConstants.JJTLE:
return Expression.LE;
case UQLParserTreeConstants.JJTGE:
return Expression.GE;
case UQLParserTreeConstants.JJTGT:
return Expression.GT;
case UQLParserTreeConstants.JJTLT:
return Expression.LT;
// case UQLParserTreeConstants.LIKE:
// return Expression..LIKE;
}
return -1;
}
public boolean isStaticNode(SimpleNode node) {
List<SimpleNode> nodeList = new ArrayList<SimpleNode>();
getNodes(node, UQLParserTreeConstants.JJTCOLUMNANDALIAS, nodeList);
return nodeList.size() == 0 ? true : false;
}
public VariableOperand getColumnId(SimpleNode columnAliasNode, List<CollectionAlias> caList) {
String alias = columnAliasNode.firstToken.image;
String columnName = columnAliasNode.lastToken.image;
if (alias == columnName) {
alias = "";
}
CollectionAlias ca = getCollectionAlias(alias, caList);
CollectionMetadata colMeta = SchemaMetadata.getInstance().getCollectionMetadata(ca.getCollectionName());
int colId = colMeta.getColumnId(columnName);
return new VariableOperand(ca, colId, null);
}
public CollectionAlias getCollectionAlias(String alias, List<CollectionAlias> caList) {
for (int i = 0; i < caList.size(); i++) {
CollectionAlias ca = caList.get(i);
if (ca.getAlias().equals(alias)) {
return ca;
}
}
return null;
}
public List<UpdateSetExpression> getUpdateSet(List<SimpleNode> updateSetNodes, List<CollectionAlias> caList) {
List<UpdateSetExpression> retList = new ArrayList<UpdateSetExpression>();
for (int i = 0; i < updateSetNodes.size(); i++) {
SimpleNode node = updateSetNodes.get(i);
if (node.children == null || node.children.length != 2) {
continue;
}
UpdateSetExpression exp = new UpdateSetExpression();
SimpleNode leftChild = (SimpleNode) node.children[0];
if (leftChild.id == UQLParserTreeConstants.JJTCOLUMNANDALIAS) {
VariableOperand vo = getColumnId(leftChild, caList);
exp.column = vo;
} else {
throw new RuntimeException("Invalid update set value");
}
SimpleNode rightChild = (SimpleNode) node.children[1];
exp.value = rightChild;
retList.add(exp);
}
return retList;
}
public int getConstCount(SimpleNode node, int constId) {
int count = 0;
if (node == null) {
return 0;
}
if (node.firstToken.kind == constId) {
count = 1;
}
Node[] children = node.children;
if (children == null) {
return count;
}
for (int i = 0; i < children.length; i++) {
SimpleNode n = (SimpleNode) children[i];
count = count + getConstCount(n, constId);
}
return count;
}
}