Package org.teiid.query.processor.relational

Source Code of org.teiid.query.processor.relational.JoinNode$BatchAvailableException

/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/

package org.teiid.query.processor.relational;

import static org.teiid.query.analysis.AnalysisRecord.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.teiid.api.exception.query.ExpressionEvaluationException;
import org.teiid.client.plan.PlanNode;
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.TupleBatch;
import org.teiid.common.buffer.TupleBuffer;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.query.processor.ProcessorDataManager;
import org.teiid.query.processor.relational.SourceState.ImplicitBuffer;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.util.CommandContext;


/**
* @since 4.2
*/
public class JoinNode extends SubqueryAwareRelationalNode {
 
  static class BatchAvailableException extends RuntimeException {}
 
  static BatchAvailableException BATCH_AVILABLE = new BatchAvailableException();
 
  public enum JoinStrategyType {   
      MERGE,
      ENHANCED_SORT,
      NESTED_LOOP,
      NESTED_TABLE
  }
       
    private enum State { LOAD_LEFT, LOAD_RIGHT, EXECUTE }   
    private State state = State.LOAD_LEFT;
   
    private JoinStrategy joinStrategy;
    private JoinType joinType;
    private String dependentValueSource;
  
    private List leftExpressions;
    private List rightExpressions;
    private boolean leftDistinct;
    private boolean rightDistinct;
    private Criteria joinCriteria;
   
    private Map combinedElementMap;
    private int[] projectionIndexes;
   
    public JoinNode(int nodeID) {
        super(nodeID);
    }
   
    public void setJoinType(JoinType type) {
        this.joinType = type;
    }
   
    public JoinStrategy getJoinStrategy() {
        return this.joinStrategy;
    }

    public void setJoinStrategy(JoinStrategy joinStrategy) {
        this.joinStrategy = joinStrategy;
    }

    public void setJoinExpressions(List leftExpressions, List rightExpressions) {
        this.leftExpressions = leftExpressions;
        this.rightExpressions = rightExpressions;
    }
   
    public boolean isLeftDistinct() {
    return leftDistinct;
  }
   
    public void setLeftDistinct(boolean leftDistinct) {
    this.leftDistinct = leftDistinct;
  }
   
    public boolean isRightDistinct() {
    return rightDistinct;
  }
   
    public void setRightDistinct(boolean rightDistinct) {
    this.rightDistinct = rightDistinct;
  }
   
    public void setJoinCriteria(Criteria joinCriteria) {
        this.joinCriteria = joinCriteria;
    }
   
    @Override
    public void initialize(CommandContext context, BufferManager bufferManager,
        ProcessorDataManager dataMgr) {
      super.initialize(context, bufferManager, dataMgr);
     
      if (this.combinedElementMap == null) {
          // Create element lookup map for evaluating project expressions
          List combinedElements = new ArrayList(getChildren()[0].getElements());
          combinedElements.addAll(getChildren()[1].getElements());
          this.combinedElementMap = createLookupMap(combinedElements);
          this.projectionIndexes = getProjectionIndexes(combinedElementMap, getElements());
      }
    }
   
    public void open()
        throws TeiidComponentException, TeiidProcessingException {
        // Set Up Join Strategy
        this.joinStrategy.initialize(this);
       
        joinStrategy.openLeft();
       
        if(!isDependent()) {
          joinStrategy.openRight();
        }
           
        this.state = State.LOAD_LEFT;
    }

    /**
     * @see org.teiid.query.processor.relational.RelationalNode#clone()
     * @since 4.2
     */
    public Object clone() {
        JoinNode clonedNode = new JoinNode(super.getID());
        super.copy(this, clonedNode);
       
        clonedNode.joinType = this.joinType;
        clonedNode.joinStrategy = this.joinStrategy.clone();
       
        clonedNode.joinCriteria = this.joinCriteria;
       
        clonedNode.leftExpressions = leftExpressions;
       
        clonedNode.rightExpressions = rightExpressions;
        clonedNode.dependentValueSource = this.dependentValueSource;
        clonedNode.rightDistinct = rightDistinct;
        clonedNode.leftDistinct = leftDistinct;
       
        return clonedNode;
    }

    /**
     * @see org.teiid.query.processor.relational.RelationalNode#nextBatchDirect()
     * @since 4.2
     */
    protected TupleBatch nextBatchDirect() throws BlockedException,
                                          TeiidComponentException,
                                          TeiidProcessingException {
        if (state == State.LOAD_LEFT) {
          if (this.joinType != JoinType.JOIN_FULL_OUTER) {
              this.joinStrategy.leftSource.setImplicitBuffer(ImplicitBuffer.NONE);
            }
          //left child was already opened by the join node
            this.joinStrategy.loadLeft();
            if (isDependent()) {
                TupleBuffer buffer = this.joinStrategy.leftSource.getTupleBuffer();
                this.getContext().getVariableContext().setGlobalValue(this.dependentValueSource, new DependentValueSource(buffer));
            }
            state = State.LOAD_RIGHT;
        }
        if (state == State.LOAD_RIGHT) {
          this.joinStrategy.openRight();
            this.joinStrategy.loadRight();
            state = State.EXECUTE;
        }
        try {
          this.joinStrategy.process();
          this.terminateBatches();
        } catch (BatchAvailableException e) {
          //pull the batch
        }
        return pullBatch();
    }

    /**
     * @see org.teiid.query.processor.relational.RelationalNode#getDescriptionProperties()
     * @since 4.2
     */
    public PlanNode getDescriptionProperties() {
        // Default implementation - should be overridden    
      PlanNode props = super.getDescriptionProperties();
       
        if(isDependent()) {
          props.addProperty(PROP_DEPENDENT, Boolean.TRUE.toString());
        }
        props.addProperty(PROP_JOIN_STRATEGY, this.joinStrategy.toString());
        props.addProperty(PROP_JOIN_TYPE, this.joinType.toString());
        List<String> critList = getCriteriaList();
        props.addProperty(PROP_JOIN_CRITERIA, critList);
        return props;
    }

  private List<String> getCriteriaList() {
    List<String> critList = new ArrayList<String>();
        if (leftExpressions != null) {
            for(int i=0; i < this.leftExpressions.size(); i++) {
                critList.add(this.leftExpressions.get(i).toString() + "=" + this.rightExpressions.get(i).toString())//$NON-NLS-1$
            }
        }
        if (this.joinCriteria != null) {
            for (Criteria crit : (List<Criteria>)Criteria.separateCriteriaByAnd(joinCriteria)) {
                critList.add(crit.toString());
            }
        }
    return critList;
  }

    /**
     * @see org.teiid.query.processor.relational.RelationalNode#getNodeString(java.lang.StringBuffer)
     * @since 4.2
     */
    protected void getNodeString(StringBuffer str) {
        str.append(getClassName());
        str.append("("); //$NON-NLS-1$
        str.append(getID());
        str.append(") [");//$NON-NLS-1$
        if(isDependent()) {
            str.append("Dependent] [");//$NON-NLS-1$
        }
        str.append(this.joinStrategy.toString());
        str.append("] [");//$NON-NLS-1$
        str.append(this.joinType.toString());
        str.append("]"); //$NON-NLS-1$
        if (getJoinType() != JoinType.JOIN_CROSS) {
          str.append(" criteria=").append(getCriteriaList()); //$NON-NLS-1$
        }
        str.append(" output="); //$NON-NLS-1$
        str.append(getElements());
    }

    /**
     * @return Returns the isDependent.
     */
    public boolean isDependent() {
        return this.dependentValueSource != null;
    }
   
    /**
     * @param isDependent The isDependent to set.
     */
    public void setDependentValueSource(String dependentValueSource) {
        this.dependentValueSource = dependentValueSource;
    }
   
    public void closeDirect() {
        super.closeDirect();
        joinStrategy.close();
        if (this.getContext() != null && this.dependentValueSource != null) {
          this.getContext().getVariableContext().setGlobalValue(this.dependentValueSource, null);
        }
    }

    public JoinType getJoinType() {
        return this.joinType;
    }

    Map getCombinedElementMap() {
        return this.combinedElementMap;
    }

    public Criteria getJoinCriteria() {
        return this.joinCriteria;
    }
   
    boolean matchesCriteria(List outputTuple) throws BlockedException, TeiidComponentException, ExpressionEvaluationException {
    return (this.joinCriteria == null || getEvaluator(this.combinedElementMap).evaluate(this.joinCriteria, outputTuple));
    }

    public List getLeftExpressions() {
        return this.leftExpressions;
    }

    public List getRightExpressions() {
        return this.rightExpressions;
    }
   
    @Override
    protected void addBatchRow(List row) {
        List projectTuple = projectTuple(this.projectionIndexes, row);
        super.addBatchRow(projectTuple);
        if (isBatchFull()) {
          throw BATCH_AVILABLE;
        }
    }

}
TOP

Related Classes of org.teiid.query.processor.relational.JoinNode$BatchAvailableException

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.