package com.tesora.dve.sql.jg; /* * #%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.HashSet; import java.util.List; import java.util.Map; import java.util.TreeMap; import com.tesora.dve.sql.SchemaException; import com.tesora.dve.sql.ParserException.Pass; import com.tesora.dve.sql.expression.TableKey; import com.tesora.dve.sql.node.structural.FromTableReference; import com.tesora.dve.sql.schema.SchemaContext; import com.tesora.dve.sql.statement.dml.MultiTableDMLStatement; public abstract class JoinGraph { private static final boolean emitState = Boolean.getBoolean("JOIN_GRAPH"); MultiTableDMLStatement stmt; List<DPart> vertices; List<JoinEdge> edges; protected JoinGraph(MultiTableDMLStatement stmt) { vertices = new ArrayList<DPart>(); edges = new ArrayList<JoinEdge>(); this.stmt = stmt; } public String describe(SchemaContext sc) { StringBuilder buf = new StringBuilder(); for(DPart dp : vertices) dp.describe(sc,"", buf); return buf.toString(); } protected void unhandled(String what) { throw new SchemaException(Pass.PLANNER, "Unhandled in " + this.getClass().getSimpleName() + ": " + what); } public List<JoinEdge> getJoins() { return edges; } public List<DPart> getPartitions() { return vertices; } public MultiTableDMLStatement getStatement() { return stmt; } public boolean isDegenerate() { return true; } public boolean requiresRedistribution() { return true; } public abstract Map<FromTableReference,Integer> getBranches(); // natural order is left to right with informal wc joins at the end public List<DGJoin> getNaturalOrder() { TreeMap<JoinPosition,DGJoin> byPosition = new TreeMap<JoinPosition,DGJoin>(); HashSet<DGJoin> processed = new HashSet<DGJoin>(); List<DGJoin> informal = new ArrayList<DGJoin>(); for(JoinEdge je : edges) { if (!processed.add(je.getJoin())) continue; if (je.getJoin().getPosition().isInformal()) informal.add(je.getJoin()); byPosition.put(je.getJoin().getPosition(),je.getJoin()); } ArrayList<DGJoin> out = new ArrayList<DGJoin>(byPosition.values()); out.addAll(informal); return out; } public DPart getPartitionFor(TableKey tk) { for(DPart dp : vertices) { if (dp.getTables().contains(tk)) return dp; } return null; } protected boolean emitting() { return emitState; } protected void emit(String what) { System.out.println(this.getClass().getSimpleName() + ": " + what); } }