All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.voltdb.sysprocs.ExplainProc Maven / Gradle / Ivy

There is a newer version: 10.1.1
Show newest version
/* This file is part of VoltDB.
 * Copyright (C) 2008-2018 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 .
 */

package org.voltdb.sysprocs;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.voltdb.CatalogContext;
import org.voltdb.ClientInterface.ExplainMode;
import org.voltdb.ClientResponseImpl;
import org.voltdb.DefaultProcedureManager;
import org.voltdb.VoltDB;
import org.voltdb.VoltTable;
import org.voltdb.VoltType;
import org.voltdb.catalog.Procedure;
import org.voltdb.catalog.Statement;
import org.voltdb.client.ClientResponse;
import org.voltdb.parser.SQLLexer;
import org.voltdb.utils.Encoder;

public class ExplainProc extends AdHocNTBase {

    public CompletableFuture run(String procedureNames) {
        // Go to the catalog and fetch all the "explain plan" strings of the queries in the procedure.

        CatalogContext context = VoltDB.instance().getCatalogContext();

        /*
         * TODO: We don't actually support multiple proc names in an ExplainProc call,
         * so I THINK that the string is always a single procname symbol and all this
         * splitting and iterating is a no-op.
         */
        List procNames = SQLLexer.splitStatements(procedureNames).getCompletelyParsedStmts();
        int size = procNames.size();
        VoltTable[] vt = new VoltTable[size];

        for (int i = 0; i < size; i++) {
            String procName = procNames.get(i);

            // look in the catalog
            Procedure proc = context.procedures.get(procName);
            if (proc == null) {
                // check default procs and send them off to be explained using the regular
                // adhoc explain process
                proc = context.m_defaultProcs.checkForDefaultProcedure(procName);
                if (proc == null) {
                    return makeQuickResponse(ClientResponse.GRACEFUL_FAILURE,
                            "Procedure " + procName + " not in catalog");
                }
                String nibbledelete = procName.split("\\.")[1];
                if (!nibbledelete.equals(DefaultProcedureManager.NIBBLE_DELETE_PROC)) {
                    String sql = DefaultProcedureManager.sqlForDefaultProc(proc);
                    List sqlStatements = new ArrayList<>(1);
                    sqlStatements.add(sql);
                    return runNonDDLAdHoc(context,
                            sqlStatements,
                            true, // infer partitioning
                            null, // no partition key
                            ExplainMode.EXPLAIN_DEFAULT_PROC,
                            false, // not a large query
                            false, // not swap tables
                            new Object[0]);
                }

            }

            vt[i] = new VoltTable(new VoltTable.ColumnInfo("STATEMENT_NAME", VoltType.STRING),
                                  new VoltTable.ColumnInfo("SQL_STATEMENT", VoltType.STRING),
                                  new VoltTable.ColumnInfo("EXECUTION_PLAN", VoltType.STRING));

            for(Statement stmt : proc.getStatements()) {
                vt[i].addRow(stmt.getTypeName(), stmt.getSqltext(), Encoder.hexDecodeToString(stmt.getExplainplan()));
            }
        }

        ClientResponseImpl response = new ClientResponseImpl(ClientResponseImpl.SUCCESS,
                                                             ClientResponse.UNINITIALIZED_APP_STATUS_CODE,
                                                             null,
                                                             vt,
                                                             null);

        CompletableFuture fut = new CompletableFuture<>();
        fut.complete(response);
        return fut;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy