Last active
August 29, 2015 14:01
-
-
Save nathanlws/3d6d546697810805edc6 to your computer and use it in GitHub Desktop.
Query Splitter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ java -cp fdb-sql-parser-1.2.0.jar:. QuerySplitter "select * from a,b where (a.name='xyz' or a.id>5 ) and (b.name='abc' or b.id=5)" | |
original: select * from a,b where (a.name='xyz' or a.id>5 ) and (b.name='abc' or b.id=5) | |
unparsed: SELECT * FROM a, b WHERE ((a.name = 'xyz') OR (a.id > 5)) AND ((b.name = 'abc') OR (b.id = 5)) | |
table a: SELECT * FROM a WHERE ((a.name = 'xyz') OR (a.id > 5)) AND (TRUE OR TRUE) | |
table b: SELECT * FROM b WHERE (TRUE OR TRUE) AND ((b.name = 'abc') OR (b.id = 5)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.foundationdb.sql.*; | |
import com.foundationdb.sql.parser.*; | |
import com.foundationdb.sql.unparser.*; | |
import java.util.*; | |
public class QuerySplitter | |
{ | |
public static void main(String[] args) throws Exception { | |
SQLParser parser = new SQLParser(); | |
NodeToString nodeToString = new NodeToString(); | |
for(String s : args) { | |
StatementNode stmt = parser.parseStatement(s); | |
System.out.println("original: " + s); | |
System.out.println("unparsed: " + nodeToString.toString(stmt)); | |
TableFinder finder = new TableFinder(); | |
stmt.accept(finder); | |
for(TableName tn : finder.tableNames) { | |
QueryTreeNode copy = parser.getNodeFactory().copyNode(stmt, parser); | |
copy.accept(new TableKeeper(tn)); | |
System.out.println("table " + tn + ": " + nodeToString.toString(copy)); | |
} | |
} | |
} | |
private static class TableFinder implements Visitor | |
{ | |
public List<TableName> tableNames = new ArrayList<>(); | |
public Visitable visit(Visitable node) throws StandardException { | |
if(node instanceof FromList) { | |
FromList fl = (FromList)node; | |
for(int i = 0; i < fl.size(); ++i) { | |
tableNames.add(fl.get(i).getTableName()); | |
} | |
} | |
return node; | |
} | |
public boolean visitChildrenFirst(Visitable node) { | |
return false; | |
} | |
public boolean stopTraversal() { | |
return false; | |
} | |
public boolean skipChildren(Visitable node) throws StandardException { | |
return false; | |
} | |
} | |
private static class TableKeeper implements Visitor | |
{ | |
private final TableName keepTable; | |
public TableKeeper(TableName keepTable) { | |
this.keepTable = keepTable; | |
} | |
private boolean eliminate(ValueNode valueNode) { | |
if(valueNode instanceof ColumnReference) { | |
return !keepTable.equals(((ColumnReference)valueNode).getTableNameNode()); | |
} | |
return false; | |
} | |
private ValueNode newTrueNode() throws StandardException { | |
BooleanConstantNode boolNode = new BooleanConstantNode(); | |
boolNode.setNodeType(NodeTypes.BOOLEAN_CONSTANT_NODE); | |
boolNode.init(Boolean.TRUE); | |
return boolNode; | |
} | |
public Visitable visit(Visitable node) throws StandardException { | |
if(node instanceof FromList) { | |
FromList fl = (FromList)node; | |
Iterator<FromTable> it = fl.iterator(); | |
while(it.hasNext()) { | |
FromTable ft = it.next(); | |
if(!keepTable.equals(ft.getTableName())) { | |
it.remove(); | |
} | |
} | |
} | |
else if(node instanceof BinaryRelationalOperatorNode) { | |
BinaryRelationalOperatorNode relNode = (BinaryRelationalOperatorNode)node; | |
if(eliminate(relNode.getLeftOperand()) || eliminate(relNode.getRightOperand())) { | |
node = newTrueNode(); | |
} | |
} | |
return node; | |
} | |
public boolean visitChildrenFirst(Visitable node) { | |
return false; | |
} | |
public boolean stopTraversal() { | |
return false; | |
} | |
public boolean skipChildren(Visitable node) throws StandardException { | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment