Package com.foundationdb.sql.test

Source Code of com.foundationdb.sql.test.Tester

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.sql.test;

import com.foundationdb.server.rowdata.SchemaFactory;
import com.foundationdb.sql.StandardException;
import com.foundationdb.sql.compiler.BooleanNormalizer;
import com.foundationdb.sql.optimizer.AISBinder;
import com.foundationdb.sql.optimizer.AISTypeComputer;
import com.foundationdb.sql.optimizer.BindingNodeFactory;
import com.foundationdb.sql.optimizer.BoundNodeToString;
import com.foundationdb.sql.optimizer.DistinctEliminator;
import com.foundationdb.sql.optimizer.OperatorCompiler;
import com.foundationdb.sql.optimizer.OperatorCompilerTest;
import com.foundationdb.sql.optimizer.SubqueryFlattener;
import com.foundationdb.sql.optimizer.plan.AST;
import com.foundationdb.sql.optimizer.plan.PlanToString;
import com.foundationdb.sql.optimizer.rule.BaseRule;
import static com.foundationdb.sql.optimizer.rule.DefaultRules.*;
import com.foundationdb.sql.optimizer.rule.PlanContext;
import com.foundationdb.sql.optimizer.rule.RulesContext;
import com.foundationdb.sql.optimizer.rule.RulesTestContext;
import com.foundationdb.sql.optimizer.rule.RulesTestHelper;
import com.foundationdb.sql.parser.DMLStatementNode;
import com.foundationdb.sql.parser.SQLParser;
import com.foundationdb.sql.parser.StatementNode;
import com.foundationdb.sql.views.ViewDefinition;

import com.foundationdb.ais.model.AkibanInformationSchema;

import java.util.*;
import java.io.*;

/** Standalone testing. */
public class Tester
{
    enum Action {
        ECHO, PARSE, CLONE,
        PRINT_TREE, PRINT_SQL, PRINT_BOUND_SQL,
        BIND, COMPUTE_TYPES,
        BOOLEAN_NORMALIZE, FLATTEN_SUBQUERIES, ELIMINATE_DISTINCTS,
        PLAN, OPERATORS
    }

    List<Action> actions;
    SQLParser parser;
    Properties compilerProperties;
    BoundNodeToString unparser;
    AkibanInformationSchema ais;
    AISBinder binder;
    AISTypeComputer typeComputer;
    BooleanNormalizer booleanNormalizer;
    SubqueryFlattener subqueryFlattener;
    DistinctEliminator distinctEliminator;
    OperatorCompiler operatorCompiler;
    List<BaseRule> planRules;
    RulesContext rulesContext;
    File statsFile;
    int repeat;

    public Tester() {
        actions = new ArrayList<>();
        parser = new SQLParser();
        parser.setNodeFactory(new BindingNodeFactory(parser.getNodeFactory()));
        compilerProperties = new Properties();
        unparser = new BoundNodeToString();
        typeComputer = new AISTypeComputer();
        booleanNormalizer = new BooleanNormalizer(parser);
        subqueryFlattener = new SubqueryFlattener(parser);
        distinctEliminator = new DistinctEliminator(parser);
    }

    public void addAction(Action action) {
        actions.add(action);
    }

    public int getRepeat() {
        return repeat;
    }
    public void setRepeat(int repeat) {
        this.repeat = repeat;
    }

    public void process(String sql) throws Exception {
        process(sql, false);
        if (repeat > 0) {
            long start = System.currentTimeMillis();
            for (int i = 0; i < repeat; i++) {
                process(sql, true);
            }
            long end =  System.currentTimeMillis();
            System.out.println((end - start) + " ms.");
        }
    }

    public void process(String sql, boolean silent) throws Exception {
        StatementNode stmt = null;
        for (Action action : actions) {
            switch (action) {
            case ECHO:
                if (!silent) {
                    System.out.println("=====");
                    System.out.println(sql);
                }
                break;
            case PARSE:
                stmt = parser.parseStatement(sql);
                break;
            case CLONE:
                stmt = (StatementNode)parser.getNodeFactory().copyNode(stmt, parser);
                break;
            case PRINT_TREE:
                stmt.treePrint();
                break;
            case PRINT_SQL:
            case PRINT_BOUND_SQL:
                {
                    unparser.setUseBindings(action == Action.PRINT_BOUND_SQL);
                    String usql = unparser.toString(stmt);
                    if (!silent)
                        System.out.println(usql);
                }
                break;
            case BIND:
                binder.bind(stmt);
                break;
            case COMPUTE_TYPES:
                typeComputer.compute(stmt);
                break;
            case BOOLEAN_NORMALIZE:
                stmt = booleanNormalizer.normalize(stmt);
                break;
            case FLATTEN_SUBQUERIES:
                stmt = subqueryFlattener.flatten((DMLStatementNode)stmt);
                break;
            case ELIMINATE_DISTINCTS:
                stmt = distinctEliminator.eliminate((DMLStatementNode)stmt);
                break;
            case PLAN:
                {
                    PlanContext plan =
                        new PlanContext(rulesContext,
                                        new AST((DMLStatementNode)stmt,
                                                parser.getParameterList()));
                    rulesContext.applyRules(plan);
                    System.out.println(PlanToString.of(plan.getPlan()));
                }
                break;
            case OPERATORS:
                {
                    Object compiled = operatorCompiler.compile((DMLStatementNode)stmt,
                                                                   parser.getParameterList());
                    if (!silent)
                        System.out.println(compiled);
                }
                break;
            }
        }
    }

    static final String DEFAULT_SCHEMA = "test";

    public void setSchema(String sql) throws Exception {
        SchemaFactory schemaFactory = new SchemaFactory(DEFAULT_SCHEMA);
        ais = schemaFactory.ais(sql);
        if (actions.contains(Action.BIND))
            binder = new AISBinder(ais, DEFAULT_SCHEMA);
        if (actions.contains(Action.OPERATORS))
            operatorCompiler = OperatorCompilerTest.TestOperatorCompiler.create(parser, ais, statsFile, compilerProperties);
        if (actions.contains(Action.PLAN))
            rulesContext = RulesTestContext.create(ais, statsFile, false, planRules, compilerProperties);
    }

    public void setIndexStatistics(File file) throws Exception {
        statsFile = file;
    }

    public void defaultPlanRules() throws Exception {
        planRules = DEFAULT_RULES;
    }

    public void loadPlanRules(File file) throws Exception {
        planRules = RulesTestHelper.loadRules(file);
    }

    public void parsePlanRules(String rules) throws Exception {
        planRules = RulesTestHelper.parseRules(rules);
    }

    public void loadCompilerProperties(File file) throws Exception {
        FileInputStream fstr = new FileInputStream(file);
        try {
            compilerProperties.load(fstr);
        }
        finally {
            fstr.close();
        }
    }

    public void parseCompilerProperties(String props) throws Exception {
        compilerProperties.load(new StringReader(props));
    }

    public static String maybeFile(String sql) throws Exception {
        if (!sql.startsWith("@"))
            return sql;
        FileReader reader = null;
        try {
            reader = new FileReader(sql.substring(1));
            StringBuilder str = new StringBuilder();
            char[] buf = new char[128];
            while (true) {
                int nc = reader.read(buf);
                if (nc < 0) break;
                str.append(buf, 0, nc);
            }
            return str.toString();
        }
        finally {
            if (reader != null) {
                reader.close();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        if (args.length == 0) {
            System.out.println("Usage: Tester " +
                               "[-clone] [-bind] [-types] [-boolean] [-flatten] [-plan @planfile] [-operators]" +
                               "[-tree] [-print] [-print-bound]" +
                               "[-schema ddl] [-index-stats yamlfile] [-view ddl]..." +
                               "sql...");
            System.out.println("Examples:");
            System.out.println("-tree 'SELECT t1.x+2 FROM t1'");
            System.out.println("-bind -print -tree -schema 'CREATE TABLE t1(x INT NOT NULL, y VARCHAR(7), z DECIMAL); CREATE table t2(w CHAR(1) NOT NULL);' -view 'CREATE VIEW v1(x,y) AS SELECT y,z FROM t1 WHERE y IS NOT NULL' \"SELECT x FROM v1 WHERE y > 'foo'\"");
            System.out.println("-operators -schema 'CREATE TABLE parent(id INT, PRIMARY KEY(id), name VARCHAR(256) NOT NULL, UNIQUE(name), state CHAR(2)); CREATE TABLE child(id INT, PRIMARY KEY(id), pid INT, CONSTRAINT `__akiban_fk0` FOREIGN KEY akibanfk(pid) REFERENCES parent(id), name VARCHAR(256) NOT NULL);' \"SELECT parent.name,child.name FROM parent,child WHERE child.pid = parent.id AND parent.state = 'MA'\"");

        }
        Tester tester = new Tester();
        tester.addAction(Action.ECHO);
        tester.addAction(Action.PARSE);
        int i = 0;
        while (i < args.length) {
            String arg = args[i++];
            if (arg.startsWith("-")) {
                if ("-tree".equals(arg))
                    tester.addAction(Action.PRINT_TREE);
                else if ("-print".equals(arg))
                    tester.addAction(Action.PRINT_SQL);
                else if ("-print-bound".equals(arg))
                    tester.addAction(Action.PRINT_BOUND_SQL);
                else if ("-clone".equals(arg))
                    tester.addAction(Action.CLONE);
                else if ("-bind".equals(arg))
                    tester.addAction(Action.BIND);
                else if ("-schema".equals(arg))
                    tester.setSchema(maybeFile(args[i++]));
                else if ("-index-stats".equals(arg))
                    tester.setIndexStatistics(new File(args[i++]));
                else if ("-types".equals(arg))
                    tester.addAction(Action.COMPUTE_TYPES);
                else if ("-boolean".equals(arg))
                    tester.addAction(Action.BOOLEAN_NORMALIZE);
                else if ("-flatten".equals(arg))
                    tester.addAction(Action.FLATTEN_SUBQUERIES);
                else if ("-distinct".equals(arg))
                    tester.addAction(Action.ELIMINATE_DISTINCTS);
                else if ("-plan".equals(arg)) {
                    String rules = args[i++];
                    if (rules.startsWith("@"))
                        tester.loadPlanRules(new File(rules.substring(1)));
                    else if (rules.equals("default"))
                        tester.defaultPlanRules();
                    else
                        tester.parsePlanRules(rules);
                    tester.addAction(Action.PLAN);
                }
                else if ("-compiler-properties".equals(arg)) {
                    String props = args[i++];
                    if (props.startsWith("@"))
                        tester.loadCompilerProperties(new File(props.substring(1)));
                    else
                        tester.parseCompilerProperties(props);
                }
                else if ("-operators".equals(arg))
                    tester.addAction(Action.OPERATORS);
                else if ("-repeat".equals(arg))
                    tester.setRepeat(Integer.parseInt(args[i++]));
                else
                    throw new Exception("Unknown switch: " + arg);
            }
            else {
                try {
                    tester.process(maybeFile(arg));
                }
                catch (StandardException ex) {
                    System.out.flush();
                    ex.printStackTrace();
                }
            }
        }
    }
}
TOP

Related Classes of com.foundationdb.sql.test.Tester

TOP
Copyright © 2018 www.massapi.com. 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.