package com.tesora.dve.sql.transform.strategy.join;
/*
* #%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.sql.expression.ExpressionUtils;
import com.tesora.dve.sql.expression.TableKey;
import com.tesora.dve.sql.node.expression.ColumnInstance;
import com.tesora.dve.sql.node.expression.ExpressionNode;
import com.tesora.dve.sql.node.expression.FunctionCall;
import com.tesora.dve.sql.node.expression.Wildcard;
import com.tesora.dve.sql.node.test.EngineConstant;
import com.tesora.dve.sql.schema.Column;
import com.tesora.dve.sql.schema.SchemaContext;
import com.tesora.dve.sql.statement.dml.SelectStatement;
import com.tesora.dve.sql.transform.ColumnInstanceCollector;
import com.tesora.dve.sql.util.ListSet;
class P1ProjectionBuffer extends Buffer {
public P1ProjectionBuffer(Buffer prev) {
super(BufferKind.P1, prev);
}
private void analyze(SchemaContext sc, SelectStatement stmt, boolean forceExpansion) {
for(BufferEntry be : getPreviousBuffer().getEntries()) {
be.setAfterOffsetBegin(size());
List<ExpressionNode> nexts = be.getNext();
for(ExpressionNode en : nexts) {
ListSet<ColumnInstance> cols = ColumnInstanceCollector.getColumnInstances(en);
BufferEntry nbe = null;
if (cols.isEmpty()) {
if (!forceExpansion)
continue;
ExpressionNode targ = ExpressionUtils.getTarget(en);
if (EngineConstant.FUNCTION.has(targ, EngineConstant.COUNT)) {
FunctionCall fc = (FunctionCall)targ;
if (fc.getParametersEdge().get(0) instanceof Wildcard) {
ListSet<TableKey> tabs = EngineConstant.TABLES.getValue(stmt,sc);
cols = new ListSet<ColumnInstance>();
for(TableKey tk : tabs) {
for(Column<?> c : tk.getTable().getColumns(sc)) {
cols.add(new ColumnInstance(c,tk.toInstance()));
}
}
}
}
if (cols.isEmpty())
continue;
nbe = new SubstitutingBufferEntry(en, cols);
} else if (!(en instanceof ColumnInstance)) {
ListSet<ExpressionNode> ugh = new ListSet<ExpressionNode>();
for(ColumnInstance ci : cols)
ugh.add(ci);
nbe = new ExplodingBufferEntry(en,ugh);
} else {
nbe = new BufferEntry(en);
}
be.addDependency(nbe);
add(nbe);
}
be.setAfterOffsetEnd(size());
}
}
@Override
public void adapt(SchemaContext sc, SelectStatement stmt) {
analyze(sc, stmt, false);
if (size() == 0)
analyze(sc, stmt, true);
}
}