package com.tesora.dve.sql.transform.execution;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.queryplan.QueryStepOperation;
import com.tesora.dve.resultset.ProjectionInfo;
import com.tesora.dve.server.connectionmanager.SSConnection;
import com.tesora.dve.sql.ParserException.Pass;
import com.tesora.dve.sql.SchemaException;
import com.tesora.dve.sql.parser.ExtractedLiteral;
import com.tesora.dve.sql.schema.SchemaContext;
import com.tesora.dve.sql.schema.ValueManager;
import com.tesora.dve.sql.schema.cache.CachedPlan;
import com.tesora.dve.sql.statement.StatementType;
import com.tesora.dve.sql.util.UnaryProcedure;
public class RootExecutionPlan extends ExecutionPlan {
private ProjectionInfo projection;
// cacheable only if true
private Boolean cacheable;
@SuppressWarnings("unused")
private CachedPlan owner;
// com_* stats are populated via this when there is a plan cache hit
private final StatementType originalStatementType;
private boolean isEmptyPlan = false;
public RootExecutionPlan(ProjectionInfo pi, ValueManager vm, StatementType stmtType) {
super(vm);
projection = pi;
originalStatementType = stmtType;
}
public List<QueryStepOperation> schedule(ExecutionPlanOptions opts, SSConnection connection, SchemaContext sc, ConnectionValuesMap cv) throws PEException {
List<QueryStepOperation> buf = new ArrayList<QueryStepOperation>();
schedule(opts, buf,projection,sc, cv, (ExecutionPlan)this);
Long lastInsertId = steps.getlastInsertId(values,sc,cv.getValues(this));
if (lastInsertId != null)
connection.setLastInsertedId(lastInsertId.longValue());
else
connection.setLastInsertedId(0);
return buf;
}
@Override
public void setCacheable(boolean v) {
// i.e. peg not cacheable
if (Boolean.FALSE.equals(cacheable)) return;
else if (!v) cacheable = false;
else cacheable = v;
}
@Override
public boolean isCacheable() {
return Boolean.TRUE.equals(cacheable);
}
public void setOwningCache(CachedPlan cp) {
owner = cp;
values.setFrozen();
prepareForCache();
}
public ProjectionInfo getProjectionInfo() {
return projection;
}
public StatementType getStatementType() {
return originalStatementType;
}
public boolean isEmptyPlan() {
return isEmptyPlan;
}
public void setIsEmptyPlan(boolean isEmptyPlan) {
this.isEmptyPlan = isEmptyPlan;
}
@Override
public boolean isRoot() {
return true;
}
// this does planning time resets
public ConnectionValuesMap resetForNewPlan(final SchemaContext sc, final List<ExtractedLiteral> literalValues) throws PEException {
final ConnectionValuesMap cvm = new ConnectionValuesMap();
traverseExecutionPlans(new UnaryProcedure<ExecutionPlan>() {
@Override
public void execute(ExecutionPlan object) {
try {
if (object.isRoot()) {
cvm.addValues(object, object.getValueManager().resetForNewPlan(sc, literalValues));
} else {
cvm.addValues(object, object.getValueManager().resetForNewNestedPlan(sc));
}
} catch (PEException pe) {
throw new SchemaException(Pass.PLANNER, pe);
}
}
});
return cvm;
}
public ConnectionValuesMap resetForNewPStmtExec(final SchemaContext sc, final List<Object> params) throws PEException {
final ConnectionValuesMap cvm = new ConnectionValuesMap();
traverseExecutionPlans(new UnaryProcedure<ExecutionPlan>() {
@Override
public void execute(ExecutionPlan object) {
try {
if (object.isRoot()) {
cvm.addValues(object, object.getValueManager().resetForNewPStmtExec(sc, params));
} else {
cvm.addValues(object, object.getValueManager().resetForNewNestedPlan(sc));
}
} catch (PEException pe) {
throw new SchemaException(Pass.PLANNER,pe);
}
}
});
return cvm;
}
public void collectNonRootValueTemplates(final SchemaContext sc, final ConnectionValuesMap cvm) {
traverseExecutionPlans(new UnaryProcedure<ExecutionPlan>() {
@Override
public void execute(ExecutionPlan object) {
if (object.isRoot()) return;
try {
cvm.addValues(object, object.getValueManager().resetForNewNestedPlan(sc));
} catch (PEException pe) {
throw new SchemaException(Pass.PLANNER,pe);
}
}
});
}
}