/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 VoltDB. If not, see <http://www.gnu.org/licenses/>. */ package org.voltdb.planner; import java.util.ArrayList; import java.util.List; import org.voltdb.catalog.Index; import org.voltdb.expressions.AbstractExpression; import org.voltdb.types.IndexLookupType; import org.voltdb.types.SortDirectionType; /** * We may may have several ways to access data in tables. We * may use a simple table scan or an index scan. Index scans may * have sort orders. There are also other data we may want to * attach to a particular plan. This is a convenient place to * organize everything associated with accessing tables or indexes. */ public class AccessPath { Index index = null; IndexUseType use = IndexUseType.COVERING_UNIQUE_EQUALITY; boolean nestLoopIndexJoin = false; boolean requiresSendReceive = false; boolean keyIterate = false; IndexLookupType lookupType = IndexLookupType.EQ; SortDirectionType sortDirection = SortDirectionType.INVALID; // The initial expression is needed to adjust (forward) the start of the reverse // iteration when it had to initially settle for starting at // "greater than a prefix key". final List<AbstractExpression> initialExpr = new ArrayList<>(); final List<AbstractExpression> indexExprs = new ArrayList<>(); final List<AbstractExpression> endExprs = new ArrayList<>(); final List<AbstractExpression> otherExprs = new ArrayList<>(); final List<AbstractExpression> joinExprs = new ArrayList<>(); final List<AbstractExpression> bindings = new ArrayList<>(); final List<AbstractExpression> eliminatedPostExprs = new ArrayList<>(); // // If a window function uses the index, then this will be set // to the number of the window function which uses this index. // If it is set to SubPlanAssembler.STATEMENT_LEVEL_ORDER_BY_INDEX // then no window function uses the index, but // the window function ordering is compatible with the statement // level ordering, and the statement level order does not need // an order by node. If it is set to SubPlanAssembler.NO_INDEX_USE, // then nothing uses the index. // int m_windowFunctionUsesIndex = SubPlanAssembler.NO_INDEX_USE; // // This is true iff there is a window function which // uses an index for order, but the statement level // order by can use the same index. In this case we // may not use any sorts at all. // boolean m_stmtOrderByIsCompatible = false; // // This is the final expression ordering. We need this // to remember the order an index imposes on a WindowFunction, // since the partition by expressions are not ordered among // themselves. Note that this will never be null, but may be empty // if there is no index in this access path. // final List<AbstractExpression> m_finalExpressionOrder = new ArrayList<>(); @Override public String toString() { String retval = ""; retval += "INDEX: " + ((index == null) ? "NULL" : (index.getParent().getTypeName() + "." + index.getTypeName())) + "\n"; retval += "USE: " + use.toString() + "\n"; retval += "FOR: " + indexPurposeString() + "\n"; retval += "TYPE: " + lookupType.toString() + "\n"; retval += "DIR: " + sortDirection.toString() + "\n"; retval += "ITER?: " + String.valueOf(keyIterate) + "\n"; retval += "NLIJ?: " + String.valueOf(nestLoopIndexJoin) + "\n"; retval += "IDX EXPRS:\n"; int i = 0; for (AbstractExpression expr : indexExprs) retval += "\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n"; retval += "END EXPRS:\n"; i = 0; for (AbstractExpression expr : endExprs) retval += "\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n"; retval += "OTHER EXPRS:\n"; i = 0; for (AbstractExpression expr : otherExprs) retval += "\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n"; retval += "JOIN EXPRS:\n"; i = 0; for (AbstractExpression expr : joinExprs) retval += "\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n"; retval += "ELIMINATED POST FILTER EXPRS:\n"; i = 0; for (AbstractExpression expr : eliminatedPostExprs) retval += "\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n"; return retval; } private String indexPurposeString() { switch (m_windowFunctionUsesIndex) { case SubPlanAssembler.STATEMENT_LEVEL_ORDER_BY_INDEX: return "Statement Level Order By"; case SubPlanAssembler.NO_INDEX_USE: return "No Indexing Used"; default: if (0 <= m_windowFunctionUsesIndex) { return "Window function plan node " + m_windowFunctionUsesIndex; } } /* * This should never happen. */ assert(false); return ""; } }