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.List;
import com.tesora.dve.common.catalog.StorageGroup;
import com.tesora.dve.db.Emitter.EmitOptions;
import com.tesora.dve.db.GenericSQLCommand;
import com.tesora.dve.distribution.IKeyValue;
import com.tesora.dve.distribution.StaticDistributionModel;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.queryplan.QueryStepDMLOperation;
import com.tesora.dve.queryplan.QueryStepOperation;
import com.tesora.dve.queryplan.QueryStepResultsOperation;
import com.tesora.dve.queryplan.QueryStepSelectAllOperation;
import com.tesora.dve.queryplan.QueryStepSelectByKeyOperation;
import com.tesora.dve.resultset.ProjectionInfo;
import com.tesora.dve.resultset.ResultRow;
import com.tesora.dve.server.messaging.SQLCommand;
import com.tesora.dve.sql.node.expression.LiteralExpression;
import com.tesora.dve.sql.schema.ConnectionValues;
import com.tesora.dve.sql.schema.Database;
import com.tesora.dve.sql.schema.DistributionKey;
import com.tesora.dve.sql.schema.DistributionVector;
import com.tesora.dve.sql.schema.ExplainOptions;
import com.tesora.dve.sql.schema.PEStorageGroup;
import com.tesora.dve.sql.schema.SchemaContext;
import com.tesora.dve.sql.statement.dml.DMLStatement;
public final class ProjectingExecutionStep extends AbstractProjectingExecutionStep {
protected LiteralExpression inMemLimit = null;
protected ProjectionInfo projectionOverride = null;
private ProjectingExecutionStep(SchemaContext sc, Database<?> db, PEStorageGroup storageGroup, DistributionVector vect, DistributionKey distKey,
DMLStatement command, DMLExplainRecord splain) throws PEException {
super(sc,db,storageGroup,vect,distKey,command,splain);
}
public static ProjectingExecutionStep build(SchemaContext sc, Database<?> db, PEStorageGroup storageGroup, DistributionVector vect, DistributionKey distKey,
DMLStatement command, DMLExplainRecord splain) throws PEException {
maybeApplyMultitenant(sc, command);
return new ProjectingExecutionStep(sc, db, storageGroup, vect, distKey, command, splain);
}
private ProjectingExecutionStep(final SchemaContext sc, Database<?> db, PEStorageGroup storageGroup, String sql) throws PEException {
super(db, storageGroup, null, null, new GenericSQLCommand(sc, sql), DMLExplainReason.ADHOC.makeRecord());
}
public static ProjectingExecutionStep build(final SchemaContext sc, Database<?> db, PEStorageGroup storageGroup, String sql) throws PEException {
return new ProjectingExecutionStep(sc, db, storageGroup, sql);
}
private ProjectingExecutionStep(Database<?> db, PEStorageGroup storageGroup, GenericSQLCommand gsql) throws PEException {
super(db, storageGroup, null, null, gsql, DMLExplainReason.ADHOC.makeRecord());
}
public static ProjectingExecutionStep build(Database<?> db, PEStorageGroup storageGroup, GenericSQLCommand gsql) throws PEException {
return new ProjectingExecutionStep(db, storageGroup, gsql);
}
@Override
public void display(SchemaContext sc, ConnectionValuesMap cv, ExecutionPlan containing, List<String> buf, String indent, EmitOptions opts) {
super.display(sc, cv, containing, buf, indent, opts);
long lim = getInMemLimit(cv.getValues(containing));
if (lim > -1)
buf.add(indent + " limit " + lim);
}
@Override
public boolean useRowCount() {
if (useRowCount != null) return useRowCount.booleanValue();
return super.useRowCount();
}
@Override
public void schedule(ExecutionPlanOptions opts, List<QueryStepOperation> qsteps, ProjectionInfo projection, SchemaContext sc,
ConnectionValuesMap cvm, ExecutionPlan containing)
throws PEException {
QueryStepDMLOperation qso = null;
ConnectionValues cv = cvm.getValues(containing);
long inMem = getInMemLimit(cv);
IKeyValue ikv = getKeyValue(sc,cv);
SQLCommand sqlCommand = getCommand(sc,cv)
.withProjection((projectionOverride == null ? projection : projectionOverride))
.withReferenceTime(cv.getCurrentTimestamp());
QueryStepResultsOperation qsro = null;
StorageGroup sg = getStorageGroup(sc,cv);
if (ikv != null) {
qsro = new QueryStepSelectByKeyOperation(sg, getPersistentDatabase(), ikv, sqlCommand);
} else {
qsro = new QueryStepSelectAllOperation(sg, getPersistentDatabase(), StaticDistributionModel.SINGLETON, sqlCommand);
}
if (inMem > -1)
qsro.setResultsLimit(inMem);
qso = qsro;
qso.setStatistics(getStepStatistics(sc));
qsteps.add(qso);
}
@Override
public void prepareForCache() {
if (inMemLimit != null)
inMemLimit.setParent(null);
super.prepareForCache();
}
public void setInMemoryLimit(LiteralExpression litex) {
inMemLimit = litex;
}
public boolean usesInMemoryLimit() {
return inMemLimit != null;
}
private long getInMemLimit(ConnectionValues cv) {
if (inMemLimit == null) return -1;
Object value = inMemLimit.getValue(cv);
long lim = -1;
if (value instanceof Number) {
lim = ((Number)value).longValue();
}
return lim;
}
public void setProjectionOverride(ProjectionInfo pi) {
projectionOverride = pi;
}
@Override
protected void addStepExplainColumns(SchemaContext sc, ConnectionValues cv, ResultRow rr, ExplainOptions opts) {
super.addStepExplainColumns(sc, cv, rr, opts);
addStringResult(rr,null); // target group
addStringResult(rr,null); // target table
addStringResult(rr,""); // target dist
addStringResult(rr,null); // target hints
addStringResult(rr,explainExplainHint(sc));
}
}