package main.expressions; import java.util.ArrayList; import java.util.HashMap; //Plan: //cases: //all appropriate join keywords are contained -> do nothing //no join keywords and valid implicit join //semi-implicit, and explicit join? (explore this) //implicit join exists if there is a where condition and the variables are coming from two different groupings // Case 1. if join keyword is encountered skip over (already made explicit) // Case 2a. if where condition is encountered, and some or all the variables come from different groupings -> proceed to rewrite // Case 2b. if where condition is encountered, and all the variables come from the same grouping -> do not rewrite //internal data structures filled regardless of Case -> rewrite will only happen if Case 2a occurs //internal data structures will clear if Case 1. or 2b. occurs //For Clause: //HashMap of ArrayLists of vars (e.g. (0, [$b, $tb]), (1, [$a, $ta])) //HashMap of ArrayLists of for statement (e.g. ([0, $b in doc("input")/book, 1, $tb in $b/title], [$a in doc("input")/entry, $ta in $a/title]) //the index of the grouping is the groupId (e.g. 0 id is for the b variables, 1 id is for the a variables //hash map of vars to groupId for faster lookup //Where Clause (how to handle multi-join case?) -> push selection for any conditions that apply to only one group //Singular Conditions -> HashMap<GroupingID, ArrayList<String>{VAR eq STRINGCONST, VAR2 eq STRINGCONST, etc.} //any singular conditions encountered should be pushed here //Double Conditions -> HashMap<[GroupingID1, GroupingID2], ArrayList<String{VAR1G1 eq VAR1G2, etc.} //key is an ArrayList of two group IDs //any conditions from two groups should be pushed here //final return condition //save outside return tagname //save the variables to return //ArrayList<String> toReturn //after going through a singular pass //construct -< rewrite with the data //Number of joins = size of the hashmap for double conditions //base case is just two joins -> simple construct //if size > 2 -> pick first two -> remove from double condition hash map -> modify new grouping in Arraylists of ArrayLists to contain a grouping of joined variables //for each group -> convert to a for-return string e.g. group 0 would convert to //(for $b in doc("input")/book, // $tb in $b/title // return <tuple> <b> {$b} </b> <tb> {$tb} </tb> </tuple> public class JoinContainer { //Groupings represents a "forest" of roots, non-leaf, leafs -> each are mapped to a key representing a unique index identifier //FOR CLAUSE public HashMap<Integer, ArrayList<String>> varVarGroupings; //contains arraylists of vars in separate groups (in order of nested level) (key is the group id) public HashMap<Integer, ArrayList<String>> varForGroupings; //contains arraylists of for statements in separate groups (key is the group id) //ArrayList<ArrayList<String>> varVarGroupings; //ArrayList<ArrayList<String>> varForGroupings; public HashMap<String, Integer> varGroupIds; //maps the variable name to groupID //WHERE CLAUSE public HashMap<Integer, ArrayList<String>> singleConditions; //maps the single groupId to single variable condition (pushing the where cond early) //note that the [1, 0] should appear as [0, 1] in the hashmap (least to greatest) public HashMap<ArrayList<Integer>, ArrayList<String>> doubleVarConditions; //maps a pair of group of ids to an ArrayList of all vars to bind to //HashMap<ArrayList<Integer>, ArrayList<String>> doubleFullConditions; //maps a pair of group ids to the full string conditions with two variables public HashMap<ArrayList<Integer>, ArrayList<String>> doubleVarsOnly; //maps a pair of group of ids to be joined to a list of all variables or stringconsts encountered for this join //RETURN CLAUSE public ArrayList<String> nodesToReturn; //convert to $tuple/all/nodes/in/path/* (add descendant and self at the end) public String finalTagName; //for the return statement (tag name in the final return clause) public Integer lastGroupId; public boolean firstReturn; //indicator for the return clause (is set to true when doing the final return), and indicates xq var, tag, concat, and path methods to construct the return path public String tupleName; //tuple variable name (the variable name to refer to built tuples in joins - e.g. $tuple) JoinContainer(String tupleName){ //base the name of the outer tuple name for rewritten join rule finalTagName = ""; nodesToReturn = new ArrayList<>(); singleConditions = new HashMap<>(); doubleVarConditions = new HashMap<>(); doubleVarsOnly = new HashMap<>(); varGroupIds = new HashMap<>(); varForGroupings = new HashMap<>(); varVarGroupings = new HashMap<>(); lastGroupId = -1; firstReturn = false; this.tupleName = tupleName; } int getNumGroupings(){ return varVarGroupings.size(); } int getNumJoinsRemaining(){ return doubleVarConditions.size(); } //[0, 1] is equal to [1, 0] //boolean checkGroupPairEq(){ //} }