/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.hive.ql.parse; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; /** * Internal representation of the join tree. * */ public class QBJoinTree implements Serializable{ private static final long serialVersionUID = 1L; private String leftAlias; private String[] rightAliases; private String[] leftAliases; private QBJoinTree joinSrc; private String[] baseSrc; private int nextTag; private JoinCond[] joinCond; private boolean noOuterJoin; private boolean noSemiJoin; // keeps track of the right-hand-side table name of the left-semi-join, and // its list of join keys private final HashMap<String, ArrayList<ASTNode>> rhsSemijoin; // join conditions private ArrayList<ArrayList<ASTNode>> expressions; // key index to nullsafe join flag private ArrayList<Boolean> nullsafes; // filters private ArrayList<ArrayList<ASTNode>> filters; // filters for pushing private ArrayList<ArrayList<ASTNode>> filtersForPushing; // user asked for map-side join private boolean mapSideJoin; private List<String> mapAliases; // big tables that should be streamed private List<String> streamAliases; /** * constructor. */ public QBJoinTree() { nextTag = 0; noOuterJoin = true; noSemiJoin = true; rhsSemijoin = new HashMap<String, ArrayList<ASTNode>>(); } /** * returns left alias if any - this is used for merging later on. * * @return left alias if any */ public String getLeftAlias() { return leftAlias; } /** * set left alias for the join expression. * * @param leftAlias * String */ public void setLeftAlias(String leftAlias) { this.leftAlias = leftAlias; } public String[] getRightAliases() { return rightAliases; } public void setRightAliases(String[] rightAliases) { this.rightAliases = rightAliases; } public String[] getLeftAliases() { return leftAliases; } public void setLeftAliases(String[] leftAliases) { this.leftAliases = leftAliases; } public ArrayList<ArrayList<ASTNode>> getExpressions() { return expressions; } public void setExpressions(ArrayList<ArrayList<ASTNode>> expressions) { this.expressions = expressions; } public String[] getBaseSrc() { return baseSrc; } public void setBaseSrc(String[] baseSrc) { this.baseSrc = baseSrc; } public QBJoinTree getJoinSrc() { return joinSrc; } public void setJoinSrc(QBJoinTree joinSrc) { this.joinSrc = joinSrc; } public int getNextTag() { return nextTag++; } public String getJoinStreamDesc() { return "$INTNAME"; } public JoinCond[] getJoinCond() { return joinCond; } public void setJoinCond(JoinCond[] joinCond) { this.joinCond = joinCond; } public boolean getNoOuterJoin() { return noOuterJoin; } public void setNoOuterJoin(boolean noOuterJoin) { this.noOuterJoin = noOuterJoin; } public boolean getNoSemiJoin() { return noSemiJoin; } public void setNoSemiJoin(boolean semi) { noSemiJoin = semi; } /** * @return the filters */ public ArrayList<ArrayList<ASTNode>> getFilters() { return filters; } /** * @param filters * the filters to set */ public void setFilters(ArrayList<ArrayList<ASTNode>> filters) { this.filters = filters; } /** * @return the filters for pushing */ public ArrayList<ArrayList<ASTNode>> getFiltersForPushing() { return filtersForPushing; } /** * @param filters for pushing * the filters to set */ public void setFiltersForPushing(ArrayList<ArrayList<ASTNode>> filters) { this.filtersForPushing = filters; } /** * @return the mapSidejoin */ public boolean isMapSideJoin() { return mapSideJoin; } /** * @param mapSideJoin * the mapSidejoin to set */ public void setMapSideJoin(boolean mapSideJoin) { this.mapSideJoin = mapSideJoin; } /** * @return the mapAliases */ public List<String> getMapAliases() { return mapAliases; } /** * @param mapAliases * the mapAliases to set */ public void setMapAliases(List<String> mapAliases) { this.mapAliases = mapAliases; } public List<String> getStreamAliases() { return streamAliases; } public void setStreamAliases(List<String> streamAliases) { this.streamAliases = streamAliases; } /** * Insert only a key to the semijoin table name to column names map. * * @param alias * table name alias. */ public void addRHSSemijoin(String alias) { if (!rhsSemijoin.containsKey(alias)) { rhsSemijoin.put(alias, null); } } /** * Remeber the mapping of table alias to set of columns. * * @param alias * @param columns */ public void addRHSSemijoinColumns(String alias, ArrayList<ASTNode> columns) { ArrayList<ASTNode> cols = rhsSemijoin.get(alias); if (cols == null) { rhsSemijoin.put(alias, columns); } else { cols.addAll(columns); } } /** * Remeber the mapping of table alias to set of columns. * * @param alias * @param column */ public void addRHSSemijoinColumns(String alias, ASTNode column) { ArrayList<ASTNode> cols = rhsSemijoin.get(alias); if (cols == null) { cols = new ArrayList<ASTNode>(); cols.add(column); rhsSemijoin.put(alias, cols); } else { cols.add(column); } } public ArrayList<ASTNode> getRHSSemijoinColumns(String alias) { return rhsSemijoin.get(alias); } /** * Merge the rhs tables from another join tree. * * @param src * the source join tree */ public void mergeRHSSemijoin(QBJoinTree src) { for (Entry<String, ArrayList<ASTNode>> e : src.rhsSemijoin.entrySet()) { String key = e.getKey(); ArrayList<ASTNode> value = rhsSemijoin.get(key); if (value == null) { rhsSemijoin.put(key, e.getValue()); } else { value.addAll(e.getValue()); } } } public ArrayList<Boolean> getNullSafes() { return nullsafes; } public void setNullSafes(ArrayList<Boolean> nullSafes) { this.nullsafes = nullSafes; } }