package com.alvazan.orm.parser.antlr; import java.util.HashSet; import java.util.Set; public class JoinMeta { private JoinInfo primaryJoinInfo; private Set<JoinInfo> infos = new HashSet<JoinInfo>(); private Set<ViewInfoImpl> views = new HashSet<ViewInfoImpl>(); private JoinType joinType; public JoinMeta(JoinInfo info, JoinType type, Set<JoinInfo> set1, Set<JoinInfo> set2) { this(info, type); addInfos(set1); addInfos(set2); } public JoinMeta(JoinInfo info, JoinType type) { this.primaryJoinInfo = info; this.infos.add(info); views.addAll(info.getViews()); this.joinType = type; } @Override public String toString() { return "["+joinType+",views="+views+", primary="+primaryJoinInfo+"]"; } public JoinInfo getPrimaryJoinInfo() { return primaryJoinInfo; } public JoinMeta fetchJoinMeta(JoinMeta rightSide) { Set<ViewInfoImpl> views1 = this.getViews(); Set<ViewInfoImpl> views2 = rightSide.getViews(); //View matches are MUCH less costly than join matches so find view match first!! for(ViewInfoImpl infoL : views1) { for(ViewInfoImpl infoR : views2) { if(infoL == infoR) { JoinInfo joinInfo = new JoinInfo(infoL, null, null, null, JoinType.NONE); Set<JoinInfo> set1 = this.getJoinInfoSet(); Set<JoinInfo> set2 = rightSide.getJoinInfoSet(); JoinMeta meta = new JoinMeta(joinInfo, JoinType.NONE, set1, set2); return meta; } } } for(ViewInfoImpl infoL : views1) { for(ViewInfoImpl infoR : views2) { JoinInfo joinInfo = infoL.getJoinInfo(infoR); if(joinInfo != null) { Set<JoinInfo> set1 = this.getJoinInfoSet(); Set<JoinInfo> set2 = rightSide.getJoinInfoSet(); JoinMeta meta = new JoinMeta(joinInfo, joinInfo.getJoinType(), set1, set2); return meta; } } } throw new IllegalArgumentException("Sorry, if you got here, you have a complex query that is not optimized. " + "We were trying to find a direct join between infos="+views1+" and infos="+views2+" but could not find a direct" + " join so either 1. optimize the query, 2. send us the query so we can send you the optimized version" + " or 3. wait for us to implement the optimizer"); } public JoinType getJoinType() { return joinType; } protected Set<JoinInfo> getJoinInfoSet() { return infos; } private void addInfos(Set<JoinInfo> set) { infos.addAll(set); for(JoinInfo info : set) { views.addAll(info.getViews()); } } protected Set<ViewInfoImpl> getViews() { return views; } public boolean contains(ViewInfoImpl primaryTable) { return views.contains(primaryTable); } }