Package org.voltdb

Source Code of org.voltdb.TestLikeQueries$LikeTest

/* This file is part of VoltDB.
* Copyright (C) 2008-2014 VoltDB Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package org.voltdb;

import java.io.IOException;

import junit.framework.TestCase;

import org.voltdb.VoltDB.Configuration;
import org.voltdb.client.Client;
import org.voltdb.client.ClientFactory;
import org.voltdb.client.NoConnectionsException;
import org.voltdb.client.ProcCallException;
import org.voltdb.compiler.VoltProjectBuilder;
import org.voltdb.utils.MiscUtils;

public class TestLikeQueries extends TestCase {

    static class LikeTest
    {
        String pattern;
        int matches;
        boolean crashes;
        boolean addNot = false;
        String escape  = null;

        public LikeTest(String pattern, int matches) {
            this.pattern = pattern;
            this.matches = matches;
            this.crashes = false;
        }

        public LikeTest(String pattern, int matches, boolean crashes, boolean addNot, String escape) {
            this.pattern = pattern;
            this.matches = matches;
            this.crashes = crashes;
            this.addNot  = addNot;
            this.escape  = escape;
        }

        public String getClause() {
            String not = (this.addNot ? "NOT " : "");
            String escape = (this.escape != null ? String.format(" ESCAPE '%s'", this.escape) : "");
            String clause = String.format("%sLIKE '%s'%s", not, this.pattern, escape);
            return clause;
        }
    }

    static class NotLikeTest extends LikeTest {
        public NotLikeTest(String pattern, int matches) {
            super(pattern, matches, false, true, null);
        }
    }

    static class EscapeLikeTest extends LikeTest {
        public EscapeLikeTest(String pattern, int matches, String escape) {
            super(pattern, matches, false, false, escape);
        }
    }

    static class UnsupportedLikeTest extends LikeTest {
        public UnsupportedLikeTest(String pattern, int matches) {
            super(pattern, matches, true, false, null);
        }
    }

    static class UnsupportedEscapeLikeTest extends LikeTest {
        public UnsupportedEscapeLikeTest(String pattern, int matches, String escape) {
            super(pattern, matches, true, false, escape);
        }
    }

    static class LikeTestData {
        public final String val;
        public final String pat;
        public LikeTestData(String val, String pat) {
            this.val = val;
            this.pat = pat;
        }
    }

    public static final String schema =
            "create table STRINGS (" +
            "ID int default 0 not null, " +
            "VAL varchar(32) default null," +
            "PAT varchar(32) default null," +
            "PRIMARY KEY(ID));";

    static final LikeTestData[] rowData = {
            new LikeTestData("aaaaaaa", "aaa%"),
            new LikeTestData("abcccc%", "abc%"),
            new LikeTestData("abcdefg", "abcdefg"),
            new LikeTestData("âxxxéyy", "âxxx%"),
            new LikeTestData("â🀲x一xxéyyÔ±", "â🀲x一%"),
            new LikeTestData("â🀲x", "â🀲%"),
        };

    static final LikeTest[] tests = new LikeTest[] {
            // Patterns that pass (currently supported)
            new LikeTest("aaa%", 1),
            new LikeTest("abc%", 2),
            new LikeTest("AbC%", 0),
            new LikeTest("zzz%", 0),
            new LikeTest("%", rowData.length),
            new LikeTest("_%", rowData.length),
            new LikeTest("a%", 3),
            new LikeTest("âxxx%", 1),
            new LikeTest("aaaaaaa", 1),
            new LikeTest("aaa", 0),
            new LikeTest("abcdef_", 1),
            new LikeTest("ab_d_fg", 1),
            new LikeTest("%defg", 1),
            new LikeTest("%de%", 1),
            new LikeTest("â🀲x", 1),
            new LikeTest("â🀲x一xxéyyÔ±", 1),
            new LikeTest("â🀲x_xxéyyÔ±", 1),
            new LikeTest("â🀲x一xxéyy_", 1),
            new LikeTest("â🀲x一xéyyÔ±", 0),
            new NotLikeTest("aaa%", rowData.length - 1),
            new EscapeLikeTest("ââ🀲x一xxéyyÔ±", 1, "â"),
            new EscapeLikeTest("abccccâ%", 1, "â"),
            new EscapeLikeTest("abcccc|%", 1, "|"),
            new EscapeLikeTest("abc%", 2, "|"),
            new EscapeLikeTest("aaa", 0, "|")
    };

    static final LikeTest[] hsqlDiscrepencies = new LikeTest[] {
            // Patterns that fail on hsql (unsupported until someone fixes unicode handling).
            // We don't bother to run these in the head-to-head regression suite
            new LikeTest("â_x一xxéyyÔ±", 1),
            // Patterns that fail (unsupported until we fix the parser)
            new UnsupportedEscapeLikeTest("abcd!%%", 0, "!"),
    };

    public static class LikeSuite {
        public void doTests(Client client, boolean forHSQLcomparison) throws IOException, NoConnectionsException, ProcCallException {
            loadForTests(client);
            if (forHSQLcomparison == false) {
                doViaStoredProc(client);
            }
            doViaAdHoc(client, forHSQLcomparison);
        }

        private void loadForTests(Client client) throws IOException, NoConnectionsException, ProcCallException {
            int id = 0;
            for (LikeTestData data : rowData) {
                id++;
                String query = String.format("insert into strings values (%d,'%s','%s');", id, data.val, data.pat);
                VoltTable modCount = client.callProcedure("@AdHoc", query).getResults()[0];
                assertEquals("Bad insert row count:", 1, modCount.getRowCount());
                assertEquals("Bad insert modification count:", 1, modCount.asScalarLong());
            }
        }

        protected void doViaStoredProc(Client client) throws IOException, NoConnectionsException {
            // Tests based on LikeTest list
            for (LikeTest test : tests) {
                doTestViaStoredProc(client, test);
            }
            for (LikeTest nonHsqlTest : hsqlDiscrepencies) {
                doTestViaStoredProc(client, nonHsqlTest);
            }
        }

        private void doViaAdHoc(Client client, boolean forHSQLcomparison) throws IOException, NoConnectionsException, ProcCallException {
            // Test parameter values used as like expression
            for (LikeTest test : tests) {
                doTestViaAdHoc(client, test);
            }
            if ( ! forHSQLcomparison) {
                for (LikeTest otherTest : hsqlDiscrepencies) {
                    doTestViaAdHoc(client, otherTest);
                }
            }

            // Tests using PAT column for pattern data
            {
                //Without an escape this works
                String query = "select * from strings where val like pat";
                VoltTable result = client.callProcedure("@AdHoc", query).getResults()[0];
                assertEquals(String.format("LIKE column test: bad row count:"),
                            rowData.length, result.getRowCount());

                //With an escape there is no way for the escape to propagate to the expression in EE
                //So HSQL should reject it due to our modifications
                query = "select * from strings where val like pat ESCAPE '?'";
                try {
                    result = client.callProcedure("@AdHoc", query).getResults()[0];
                    assertEquals(String.format("LIKE column test: bad row count:"),
                            rowData.length, result.getRowCount());
                } catch (ProcCallException e) {
                    System.out.println("LIKE column test failed (expected for now)");
                }
            }
        }

        private void doTestViaStoredProc(Client client, LikeTest test) throws IOException, NoConnectionsException {
            String procName = null;
            if (test.getClass() == LikeTest.class) {
                procName = "SelectLike";
            } else if (test instanceof NotLikeTest) {
                procName = "NotLike";
            } else if (test instanceof EscapeLikeTest) {
                return;
            }
            if (test.getClass() == LikeTest.class) {
                System.out.printf("SelectLike pattern \"%s\"\n", test.pattern);
                try {
                    VoltTable result = client.callProcedure(procName, test.pattern).getResults()[0];
                    assertEquals(String.format("\"%s\": bad row count:", test.pattern),
                                 test.matches, result.getRowCount());
                    System.out.println(result.toString());
                    assertFalse(String.format("Expected to crash on \"%s\", but didn't", test.pattern), test.crashes);
                } catch (ProcCallException e) {
                    System.out.printf("LIKE pattern \"%s\" failed\n", test.pattern);
                    System.out.println(e.toString());
                    assertTrue("This failure was unexpected", test.crashes);
                    System.out.println("(This failure was expected)");
                }
            }
        }

        private void doTestViaAdHoc(Client client, LikeTest test) throws IOException, NoConnectionsException {
            String clause = test.getClause();
            String query = String.format("select * from strings where val %s", clause);
            System.out.printf("LIKE clause \"%s\"\n", clause);
            try {
                VoltTable result = client.callProcedure("@AdHoc", query).getResults()[0];
                assertEquals(String.format("\"%s\": bad row count:", clause),
                        test.matches, result.getRowCount());
                System.out.println(result.toString());
                assertFalse(String.format("Expected to crash on \"%s\", but didn't", clause), test.crashes);
            } catch (ProcCallException e) {
                System.out.printf("LIKE clause \"%s\" failed\n", clause);
                System.out.println(e.toString());
                assertTrue("This failure was unexpected", test.crashes);
                System.out.println("(This failure was expected)");
            }
        }
    }

    public void testLikeClause() throws Exception {

        String pathToCatalog = Configuration.getPathToCatalogForTest("adhoc_like.jar");
        String pathToDeployment = Configuration.getPathToCatalogForTest("adhoc_like.xml");

        VoltProjectBuilder builder = new VoltProjectBuilder();
        builder.addLiteralSchema(schema);
        builder.addPartitionInfo("STRINGS", "ID");
        builder.addStmtProcedure("Insert", "insert into strings values (?, ?, ?);", null);
        builder.addStmtProcedure("SelectLike", "select * from strings where  val like ?;");
        builder.addStmtProcedure("SelectNotLike", "select * from strings where  val not like ?;");
        boolean success = builder.compile(pathToCatalog, 2, 1, 0);
        assertTrue("Insert compilation failed", success);
        MiscUtils.copyFile(builder.getPathToDeployment(), pathToDeployment);

        VoltDB.Configuration config = new VoltDB.Configuration();
        config.m_pathToCatalog = pathToCatalog;
        config.m_pathToDeployment = pathToDeployment;
        ServerThread localServer = new ServerThread(config);

        Client client = null;

        try {
            localServer.start();
            localServer.waitForInitialization();

            client = ClientFactory.createClient();
            client.createConnection("localhost");

            LikeSuite tests = new LikeSuite();
            tests.doTests(client, false);
        }
        finally {
            if (client != null) client.close();
            client = null;

            if (localServer != null) {
                localServer.shutdown();
                localServer.join();
            }
            localServer = null;

            // no clue how helpful this is
            System.gc();
        }
    }
}
TOP

Related Classes of org.voltdb.TestLikeQueries$LikeTest

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.