Package org.voltdb.plannodes

Examples of org.voltdb.plannodes.AbstractPlanNode


    @SuppressWarnings("unchecked")
    public static <T extends AbstractPlanNode> Collection<T> getChildren(AbstractPlanNode node, Class<T> search_class) {
        final Set<T> found = new HashSet<T>();
        for (int i = 0, cnt = node.getChildPlanNodeCount(); i < cnt; i++) {
            AbstractPlanNode child = node.getChild(i);
            Class<? extends AbstractPlanNode> child_class = child.getClass();
            if (ClassUtil.getSuperClasses(child_class).contains(search_class)) {
                found.add((T) child);
            }
        } // FOR
        return (found);
View Full Code Here


            }
        });
        sorted_nodes.addAll(nodes);
        if (debug.val)
            LOG.debug("SORTED NODES: " + sorted_nodes);
        AbstractPlanNode last_node = null;
        for (AbstractPlanNode node : sorted_nodes) {
            final AbstractPlanNode walker_last_node = last_node;
            final List<AbstractPlanNode> next_last_node = new ArrayList<AbstractPlanNode>();
            new PlanNodeTreeWalker() {
                @Override
                protected void callback(AbstractPlanNode element) {
                    if (element instanceof SendPlanNode && walker_last_node != null) {
                        walker_last_node.addAndLinkChild(element);
                    } else if (element instanceof ReceivePlanNode) {
                        assert (next_last_node.isEmpty());
                        next_last_node.add(element);
                    }
                }
View Full Code Here

        // Check whether we have this cached already
        // This is probably not thread-safe because the AbstractPlanNode tree
        // has pointers to specific table catalog objects
        String cache_key = CatalogKey.createKey(catalog_stmt);
        Map<String, AbstractPlanNode> cache = (singlePartition ? PlanNodeUtil.CACHE_DESERIALIZE_SP_STATEMENT : PlanNodeUtil.CACHE_DESERIALIZE_MP_STATEMENT);
        AbstractPlanNode ret = cache.get(cache_key);
        if (ret != null)
            return (ret);

        // Otherwise construct the AbstractPlanNode tree
        Database catalog_db = CatalogUtil.getDatabase(catalog_stmt);
View Full Code Here

     * @param catalog_frag
     * @return
     */
    public static AbstractPlanNode getPlanNodeTreeForPlanFragment(PlanFragment catalog_frag) {
        String id = catalog_frag.getName();
        AbstractPlanNode ret = PlanNodeUtil.CACHE_DESERIALIZE_FRAGMENT.get(id);
        if (ret == null) {
            if (debug.val)
                LOG.warn("No cached object for " + catalog_frag.fullName());
            Database catalog_db = CatalogUtil.getDatabase(catalog_frag);
            String jsonString = Encoder.hexDecodeToString(catalog_frag.getPlannodetree());
View Full Code Here

     * @param catalog_frag
     * @param node
     * @return
     */
    public static boolean containsPlanNode(final PlanFragment catalog_frag, final AbstractPlanNode node) {
        final AbstractPlanNode root = getPlanNodeTreeForPlanFragment(catalog_frag);
        final boolean found[] = { false };
        new PlanNodeTreeWalker(true) {
            @Override
            protected void callback(AbstractPlanNode element) {
                if (element.equals(node)) {
View Full Code Here

            return (bytes);

        // Otherwise, we have to calculate things.
        // Then pluck out all the MaterializePlanNodes so that we inspect the
        // tuples
        AbstractPlanNode node = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, true);
        Collection<MaterializePlanNode> matched_nodes = PlanNodeUtil.getPlanNodes(node, MaterializePlanNode.class);
        if (matched_nodes.isEmpty()) {
            LOG.fatal("Failed to retrieve any MaterializePlanNodes from " + catalog_stmt);
            return 0l;
        } else if (matched_nodes.size() > 1) {
View Full Code Here

                } else if (frag_cache.isValid()) {
                    assert (!frag_cache.isValid()) : "Cache entry for " + CatalogUtil.getDisplayName(catalog_frag) + " is marked as valid when we were expecting to be invalid\n" + this.toString();
                    frag_cache.setValid();
                }

                AbstractPlanNode root = PlanNodeUtil.getPlanNodeTreeForPlanFragment(catalog_frag);
                Collection<Table> frag_tables = CatalogUtil.getReferencedTablesForTree(catalogContext.database, root);
                // Table tables_arr[] = new Table[frag_tables.size()];
                // tables_arr = frag_tables.toArray(tables_arr);
                // assert (tables_arr.length == frag_tables.size());
                if (trace.val)
                    LOG.trace("Analyzing " + catalog_frag.fullName());

                // Check whether the predicate expression in this PlanFragment contains an OR
                // We need to know this if we get hit with Multi-Column Partitioning
                // XXX: Why does this matter??
                Collection<ExpressionType> exp_types = PlanNodeUtil.getScanExpressionTypes(root);
                if (exp_types.contains(ExpressionType.CONJUNCTION_OR)) {
                    if (debug.val)
                        LOG.warn(String.format("%s contains %s. Cannot be used with multi-column partitioning",
                                 catalog_frag.fullName(), ExpressionType.CONJUNCTION_OR));
                    stmt_cache.markContainsOR(true);
                    frag_cache.markContainsOR(true);
                }

                // If there are no tables, then we need to double check that the "non-transactional"
                // flag is set for the fragment. This means that this fragment does not operate directly
                // on a persistent table in the database. We'll add an entry in the cache using our
                // special "no tables" flag. This means that the fragment needs to be executed locally.
                if (frag_tables.isEmpty()) {
                    String msg = catalog_frag.fullName() + " does not reference any tables";
                    if (!catalog_frag.getNontransactional()) {
                        LOG.warn(catalog_stmt.fullName() + "\n" + PlanNodeUtil.debug(PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, false)));
                        for (PlanFragment f : fragments) {
                            LOG.warn("singlePartiton=" + singlesited + " - " + f.fullName() + "\n" + PlanNodeUtil.debug(PlanNodeUtil.getPlanNodeTreeForPlanFragment(f)));
                        }
                        throw new Exception(msg + " but the non-transactional flag is not set");
                    }
                    if (trace.val)
                        LOG.trace(msg);
                }
                if (trace.val && frag_tables.isEmpty() == false )
                    LOG.trace("Fragment Tables: " + frag_tables);

                // We only need to find where the partition column is referenced
                // If it's not in there, then this query has to be broadcasted to all nodes
                // Note that we pass all the tables that are part of the fragment, since
                // we need to be able to handle joins
                PredicatePairs predicates = CatalogUtil.extractFragmentPredicates(catalog_frag, false, frag_tables);
                assert (predicates != null);
                Map<Column, Set<Column>> column_joins = new TreeMap<Column, Set<Column>>();
                if (trace.val)
                    LOG.trace("Extracted PredicatePairs for " + frag_tables + ":\n" + predicates.debug());

                // -------------------------------
                // If there are no columns, then this fragment is doing a full table scan
                // -------------------------------
                if (predicates.isEmpty() && frag_tables.size() > 0) {
                    if (trace.val)
                        LOG.trace("No columns accessed in " + catalog_frag + " despite reading " + frag_tables.size() + " tables");
                    stmt_cache.markAsBroadcast(frag_tables);
                    frag_cache.markAsBroadcast(frag_tables);
                }
                // -------------------------------
                // Fragment references the columns for our tables. Pick them apart!
                // -------------------------------
                else {
                    // First go through all the entries and add any mappings from
                    // Columns to StmtParameters to our stmt_cache
                    for (CatalogPair pair : predicates) {
                        if (trace.val)
                            LOG.trace(String.format("Examining extracted %s: %s",
                                      pair.getClass().getSimpleName(), pair));

                        // Column = Column
                        if (pair.getFirst() instanceof Column && pair.getSecond() instanceof Column) {
                            Column col0 = (Column) pair.getFirst();
                            Column col1 = (Column) pair.getSecond();
                           
                            // If this table is a view, then we need to check whether
                            // we have to point the column down to the origin column
                            if (col0.getMatviewsource() != null) {
                                col0 = col0.getMatviewsource();
                            }
                            if (col1.getMatviewsource() != null) {
                                col1 = col1.getMatviewsource();
                            }

                            if (!pair.getComparisonExp().equals(ExpressionType.COMPARE_EQUAL)) {
                                if (debug.val)
                                    LOG.warn(String.format("Unsupported non-equality join in %s: %s",
                                             catalog_stmt.fullName(), pair));
                            } else {
                                if (!column_joins.containsKey(col0))
                                    column_joins.put(col0, new TreeSet<Column>());
                                if (!column_joins.containsKey(col1))
                                    column_joins.put(col1, new TreeSet<Column>());
                                column_joins.get(col0).add(col1);
                                column_joins.get(col1).add(col0);
                            }
                            continue;
                        }
                       
                        // Look for predicates with StmtParameters or ConstantValues
                        for (Table catalog_tbl : frag_tables) {
                            Column catalog_col = null;
                            CatalogType catalog_param = null;
                           
                            // *********************************** DEBUG ***********************************
                            if (trace.val) {
                                LOG.trace("Current Table: " + catalog_tbl.hashCode());
                                if (pair.getFirst() != null) {
                                    LOG.trace("entry.getFirst().getParent(): " + (pair.getFirst().getParent() != null ?
                                                    pair.getFirst().getParent().hashCode() :
                                                    pair.getFirst() + " parent is null?"));
                           
                                    if (pair.getFirst().getParent() instanceof Table) {
                                        Table parent = pair.getFirst().getParent();
                                        if (parent.getName().equals(catalog_tbl.getName())) {
                                            assert(parent.equals(catalog_tbl)) :
                                                "Mismatch on " + parent.getName() + "???";
                                        }
                                    }
                                } else {
                                    LOG.trace("entry.getFirst():             " + null);
                                }
                                if (pair.getSecond() != null) {
                                    LOG.trace("entry.getSecond().getParent(): " + (pair.getSecond().getParent() != null ?
                                                  pair.getSecond().getParent().hashCode() :
                                                  pair.getSecond() + " parent is null?"));
                                } else {
                                    LOG.trace("entry.getSecond():             " + null);
                                }
                            }
                            // *********************************** DEBUG ***********************************

                            // Column = (StmtParameter or ConstantValue)
                            if (pair.getFirst().getParent() != null && pair.getFirst().getParent().equals(catalog_tbl) &&
                                    (pair.getSecond() instanceof StmtParameter || pair.getSecond() instanceof ConstantValue) ) {
                                catalog_col = (Column) pair.getFirst();
                                catalog_param = pair.getSecond();
                           
                            }
                            // (StmtParameter or ConstantValue) = Column
                            else if (pair.getSecond().getParent() != null && pair.getSecond().getParent().equals(catalog_tbl) &&
                                    (pair.getFirst() instanceof StmtParameter || pair.getFirst() instanceof ConstantValue)) {
                                catalog_col = (Column) pair.getSecond();
                                catalog_param = pair.getFirst();
                            }
                            if (catalog_col != null && catalog_param != null) {
                                // If this table is a view, then we need to check whether
                                // we have to point the column down to the origin column
                                if (catalog_col.getMatviewsource() != null) {
                                    if (debug.val)
                                        LOG.debug("Found View Column: " + catalog_col.fullName() + " -> " + catalog_col.getMatviewsource().fullName());
                                    catalog_col = catalog_col.getMatviewsource();
                                }
                                if (trace.val)
                                    LOG.trace(String.format("[%s] Adding cache entry for %s: %s -> %s",
                                                            CatalogUtil.getDisplayName(catalog_tbl),
                                                            CatalogUtil.getDisplayName(catalog_frag),
                                                            CatalogUtil.getDisplayName(catalog_col),
                                                            CatalogUtil.getDisplayName(catalog_param)));
                                stmt_cache.put(catalog_col, catalog_param, pair.getComparisonExp(), catalog_tbl);
                                frag_cache.put(catalog_col, catalog_param, pair.getComparisonExp(), catalog_tbl);
                            }
                        } // FOR (tables)
                        if (trace.val)
                            LOG.trace("-------------------");
                    } // FOR (entry)

                    // We now have to take a second pass through the column mappings
                    // This will pick-up those columns that are joined together where one of them
                    // is also referenced with an input parameter. So we will map the input
                    // parameter to the second column as well
                    PartitionEstimator.populateColumnJoinSets(column_joins);

                    for (Column catalog_col : column_joins.keySet()) {
                        // Otherwise, we have to examine the the ColumnSet and
                        // look for any reference to this column
                        if (trace.val)
                            LOG.trace("Trying to find all references to " + CatalogUtil.getDisplayName(catalog_col));
                        for (Column other_col : column_joins.get(catalog_col)) {
                            // IMPORTANT: If the other entry is a column from another table and we don't
                            // have a reference in stmt_cache for ourselves, then we can look to see if
                            // this guy was used against a StmtParameter some where else in the Statement
                            // If this is the case, then we can substitute that mofo in it's place
                            if (stmt_cache.predicates.containsKey(catalog_col)) {
                                for (Pair<ExpressionType, CatalogType> pair : stmt_cache.predicates.get(catalog_col)) {
                                    if (trace.val)
                                        LOG.trace(String.format("Linking %s to predicate %s because of %s",
                                                  other_col.fullName(), pair, catalog_col.fullName()));
                                   
                                    ExpressionType expType = pair.getFirst();
                                    CatalogType param = pair.getSecond();
                                    stmt_cache.put(other_col, param, expType, (Table)other_col.getParent());
                                    frag_cache.put(other_col, param, expType, (Table)other_col.getParent());
                                } // FOR (StmtParameter.Index)
                            }
                        } // FOR (Column)
                    } // FOR (Column)
                }
                if (trace.val)
                    LOG.trace(frag_cache.toString());

                // Loop through all of our tables and make sure that there is an entry in the PlanFragment CacheEntrry
                // If there isn't, then that means there was no predicate on the table and therefore the PlanFragment
                // must be broadcast to all partitions (unless it is replicated)
                for (Table catalog_tbl : frag_tables) {
                    if (!frag_cache.hasTable(catalog_tbl)) {
                        if (trace.val)
                            LOG.trace(String.format("No column predicate for %s. Marking as broadcast for %s: %s",
                                      catalog_tbl.fullName(), catalog_frag.fullName(), frag_cache.getTables()));
                        frag_cache.markAsBroadcast(catalog_tbl);
                        stmt_cache.markAsBroadcast(catalog_tbl);
                    }
                } // FOR

                // Store the Fragment cache and update the Table xref mapping
                this.cache_fragmentEntries.put(frag_key, frag_cache);
                this.addTableCacheXref(frag_cache, frag_tables);
            } // FOR (fragment)

            // Then for updates we need to look to see whether they are updating an attribute
            // that they are partitioned on. If so, then it gets dicey because we need to
            // know the value...
            if (stmt_type == QueryType.UPDATE) {
                List<Table> tables = new ArrayList<Table>();
                PredicatePairs update_cset = new PredicatePairs();
                for (Table catalog_tbl : CatalogUtil.getReferencedTables(catalog_stmt)) {
                    update_cset.clear();
                    tables.clear();
                    tables.add(catalog_tbl);
                    AbstractPlanNode root_node = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, true);
                    CatalogUtil.extractUpdatePredicates(catalog_stmt, catalogContext.database, update_cset, root_node, true, tables);

                    boolean found = false;
                    for (CatalogPair pair : update_cset) {
                        Column catalog_col = null;
View Full Code Here

            return (Pair.of(false, rootNode));
        }
       
        // Check if this is COUNT(DISTINCT) query
        // If it is then we can only pushdown the DISTINCT
        AbstractPlanNode clone_node = null;
        if (node.getAggregateTypes().contains(ExpressionType.AGGREGATE_COUNT)) {
            for (AbstractPlanNode child : node.getChildren()) {
                if (child.getClass().equals(DistinctPlanNode.class)) {
                    try {
                        clone_node = (AbstractPlanNode) child.clone(false, true);
                    } catch (CloneNotSupportedException ex) {
                        throw new RuntimeException(ex);
                    }
                    state.markDirty(clone_node);
                    break;
                }
            } // FOR
        }
       
        // Note that we don't want actually move the existing aggregate. We just
        // want to clone it and then attach it down below the SEND/RECIEVE so
        // that we calculate the aggregates in parallel
        if (clone_node == null) {
            clone_node = this.cloneAggregatePlanNode(node);
        }
        assert (clone_node != null);
       
        // But this means we have to also update the RECEIVE to only expect the
        // columns that the AggregateNode will be sending along
        ReceivePlanNode recv_node = null;
        if (clone_node instanceof DistinctPlanNode) {
            recv_node = (ReceivePlanNode) node.getChild(0).getChild(0);
        } else {
            recv_node = (ReceivePlanNode) node.getChild(0);
        }
        recv_node.getOutputColumnGUIDs().clear();
        recv_node.getOutputColumnGUIDs().addAll(clone_node.getOutputColumnGUIDs());
        state.markDirty(recv_node);

        assert (recv_node.getChild(0) instanceof SendPlanNode);
        SendPlanNode send_node = (SendPlanNode) recv_node.getChild(0);
        send_node.getOutputColumnGUIDs().clear();
        send_node.getOutputColumnGUIDs().addAll(clone_node.getOutputColumnGUIDs());
        send_node.addIntermediary(clone_node);
        state.markDirty(send_node);

        // 2011-12-08: We now need to correct the aggregate columns for the
        // original plan node
        if ((clone_node instanceof DistinctPlanNode) == false) {
            // If we have a AGGREGATE_WEIGHTED_AVG in our node, then we know that
            // we can skip the last column because that's the COUNT from the remote partition
            boolean has_weightedAvg = node.getAggregateTypes().contains(ExpressionType.AGGREGATE_WEIGHTED_AVG);
            node.getAggregateColumnGuids().clear();
            int num_cols = clone_node.getOutputColumnGUIDCount() - (has_weightedAvg ? 1 : 0);
            for (int i = 0; i < num_cols; i++) {
                Integer aggOutput = clone_node.getOutputColumnGUID(i);
                PlanColumn planCol = state.plannerContext.get(aggOutput);
                assert (planCol != null);
                AbstractExpression exp = planCol.getExpression();
                assert (exp != null);
                Collection<String> refTables = ExpressionUtil.getReferencedTableNames(exp);
View Full Code Here

    private void init() {
        new PlanNodeTreeWalker() {
            @Override
            protected void callback(AbstractPlanNode element) {
                AbstractPlanNode parent = this.getPrevious();
                if (parent == null) {
                    PlanNodeGraph.this.addVertex(element);
                } else {
                    PlanNodeGraph.this.addEdge(new Edge(), parent, element);
                }
View Full Code Here

        assert (catalog_proc != null) : "Invalid Procedure Name: " + proc_name;

        Statement catalog_stmt = catalog_proc.getStatements().getIgnoreCase(stmt_name);
        assert (catalog_stmt != null) : "Invalid Statement Name: " + proc_name + "." + stmt_name;

        AbstractPlanNode root = PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, false);
        PlanNodeGraph graph = new PlanNodeGraph(root);

        GraphVisualizationPanel.createFrame(graph).setVisible(true);
    }
View Full Code Here

TOP

Related Classes of org.voltdb.plannodes.AbstractPlanNode

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.