/*
* 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.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
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.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.processor.ProcessorDataManager;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.util.CommandContext;
public class SelectNode extends SubqueryAwareRelationalNode {
private Criteria criteria;
private List<Expression> projectedExpressions;
// Derived element lookup map
private Map<Expression, Integer> elementMap;
private int[] projectionIndexes;
// State if blocked on evaluating a criteria
private TupleBatch currentBatch;
private int currentRow = 1;
protected SelectNode() {
super();
}
public SelectNode(int nodeID) {
super(nodeID);
}
public void reset() {
super.reset();
currentBatch = null;
currentRow = 1;
}
public void setCriteria(Criteria criteria) {
this.criteria = criteria;
}
public Criteria getCriteria() { // made public to support change in ProcedurePlanner
return this.criteria;
}
public void setProjectedExpressions(List<Expression> projectedExpressions) {
this.projectedExpressions = projectedExpressions;
}
@Override
public void initialize(CommandContext context, BufferManager bufferManager,
ProcessorDataManager dataMgr) {
super.initialize(context, bufferManager, dataMgr);
// Create element lookup map for evaluating project expressions
if(this.elementMap == null) {
this.elementMap = createLookupMap(this.getChildren()[0].getElements());
this.projectionIndexes = getProjectionIndexes(this.elementMap, projectedExpressions!=null?projectedExpressions:getElements());
}
}
/**
* @see org.teiid.query.processor.relational.RelationalNode#nextBatchDirect()
*/
public TupleBatch nextBatchDirect()
throws BlockedException, TeiidComponentException, TeiidProcessingException {
if(currentBatch == null) {
currentBatch = this.getChildren()[0].nextBatch();
}
while (currentRow <= currentBatch.getEndRow() && !isBatchFull()) {
List<?> tuple = currentBatch.getTuple(currentRow);
if(getEvaluator(this.elementMap).evaluate(this.criteria, tuple)) {
addBatchRow(projectTuple(this.projectionIndexes, tuple));
}
currentRow++;
}
if (currentRow > currentBatch.getEndRow()) {
if(currentBatch.getTerminationFlag()) {
terminateBatches();
}
currentBatch = null;
}
return pullBatch();
}
protected void getNodeString(StringBuffer str) {
super.getNodeString(str);
str.append(criteria);
}
public Object clone(){
SelectNode clonedNode = new SelectNode();
this.copyTo(clonedNode);
return clonedNode;
}
protected void copyTo(SelectNode target){
super.copyTo(target);
target.criteria = criteria;
target.elementMap = elementMap;
target.projectionIndexes = projectionIndexes;
target.projectedExpressions = projectedExpressions;
}
public PlanNode getDescriptionProperties() {
PlanNode props = super.getDescriptionProperties();
AnalysisRecord.addLanaguageObjects(props, PROP_CRITERIA, Arrays.asList(this.criteria));
return props;
}
@Override
public Collection<? extends LanguageObject> getObjects() {
return Arrays.asList(this.criteria);
}
}