org.apache.hadoop.hive.ql.parse.QBJoinTree Maven / Gradle / Ivy
/**
* 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;
import java.util.Map.Entry;
import org.apache.hadoop.hive.ql.exec.Operator;
import org.apache.hadoop.hive.ql.plan.OperatorDesc;
/**
* 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;
private Map> aliasToOpInfo;
// The subquery identifier from QB.
// It is of the form topSubQuery:innerSubQuery:....:innerMostSubQuery
private String id;
// keeps track of the right-hand-side table name of the left-semi-join, and
// its list of join keys
private transient final HashMap> rhsSemijoin;
// join conditions
private transient ArrayList> expressions;
// key index to nullsafe join flag
private ArrayList nullsafes;
// filters
private transient ArrayList> filters;
// outerjoin-pos = other-pos:filter-len, other-pos:filter-len, ...
private int[][] filterMap;
// filters for pushing
private transient ArrayList> filtersForPushing;
// user asked for map-side join
private boolean mapSideJoin;
private List mapAliases;
// big tables that should be streamed
private List streamAliases;
/*
* when a QBJoinTree is merged into this one, its left(pos =0) filters can
* refer to any of the srces in this QBJoinTree. If a particular filterForPushing refers
* to multiple srces in this QBJoinTree, we collect them into 'postJoinFilters'
* We then add a Filter Operator after the Join Operator for this QBJoinTree.
*/
private final List postJoinFilters;
/**
* constructor.
*/
public QBJoinTree() {
nextTag = 0;
noOuterJoin = true;
noSemiJoin = true;
rhsSemijoin = new HashMap>();
aliasToOpInfo = new HashMap>();
postJoinFilters = new ArrayList();
}
/**
* 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) {
if ( this.leftAlias != null && !this.leftAlias.equals(leftAlias) ) {
this.leftAlias = null;
} else {
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> getExpressions() {
return expressions;
}
public void setExpressions(ArrayList> 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 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> getFilters() {
return filters;
}
/**
* @param filters
* the filters to set
*/
public void setFilters(ArrayList> filters) {
this.filters = filters;
}
/**
* @return the filters for pushing
*/
public ArrayList> getFiltersForPushing() {
return filtersForPushing;
}
/**
* @param filters for pushing
* the filters to set
*/
public void setFiltersForPushing(ArrayList> 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 getMapAliases() {
return mapAliases;
}
/**
* @param mapAliases
* the mapAliases to set
*/
public void setMapAliases(List mapAliases) {
this.mapAliases = mapAliases;
}
public List getStreamAliases() {
return streamAliases;
}
public void setStreamAliases(List 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 columns) {
ArrayList 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 cols = rhsSemijoin.get(alias);
if (cols == null) {
cols = new ArrayList();
cols.add(column);
rhsSemijoin.put(alias, cols);
} else {
cols.add(column);
}
}
public ArrayList 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> e : src.rhsSemijoin.entrySet()) {
String key = e.getKey();
ArrayList value = rhsSemijoin.get(key);
if (value == null) {
rhsSemijoin.put(key, e.getValue());
} else {
value.addAll(e.getValue());
}
}
}
public ArrayList getNullSafes() {
return nullsafes;
}
public void setNullSafes(ArrayList nullSafes) {
this.nullsafes = nullSafes;
}
public void addFilterMapping(int outer, int target, int length) {
filterMap[outer] = new int[] { target, length };
}
public int[][] getFilterMap() {
return filterMap;
}
public void setFilterMap(int[][] filterMap) {
this.filterMap = filterMap;
}
public Map> getAliasToOpInfo() {
return aliasToOpInfo;
}
public void setAliasToOpInfo(Map> aliasToOpInfo) {
this.aliasToOpInfo = aliasToOpInfo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void addPostJoinFilter(ASTNode filter) {
postJoinFilters.add(filter);
}
public List getPostJoinFilters() {
return postJoinFilters;
}
}