Package org.voltdb.regressionsuites

Source Code of org.voltdb.regressionsuites.TestSqlAggregateSuite

/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* 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.regressionsuites;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.voltdb.BackendTarget;
import org.voltdb.VoltProcedure;
import org.voltdb.VoltTable;
import org.voltdb.VoltTableRow;
import org.voltdb.VoltType;
import org.voltdb.client.Client;
import org.voltdb.client.ProcCallException;
import org.voltdb.compiler.VoltProjectBuilder;
import org.voltdb.regressionsuites.aggregates.*;

import edu.brown.utils.MathUtil;

/**
* System tests for basic aggregate and DISTINCT functionality
*/

public class TestSqlAggregateSuite extends RegressionSuite {
   
    private static final String PREFIX = "sqlaggregate";

    /** Procedures used by this suite */
    @SuppressWarnings("unchecked")
    public static final Class<? extends VoltProcedure> PROCEDURES[] = (Class<? extends VoltProcedure>[])new Class<?>[] {
        Insert.class
    };

    static final int ROWS = 10;

    public void testDistinct() throws IOException, ProcCallException {
        String[] tables = {"P1", "R1"};
        for (String table : tables)
        {
            Client client = getClient();
            for (int i = 0; i < ROWS; ++i)
            {
                client.callProcedure("Insert", table, i, "desc",
                                     new BigDecimal(10.0), i / 2, 14.5);
            }
            String query = String.format("select distinct %s.NUM from %s",
                                         table, table);
            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
            // lazy check that we get 5 rows back, put off checking contents
            assertEquals(5, results[0].getRowCount());
        }
    }
   
    public void testMultipleAverages() throws IOException, ProcCallException {
        String[] tables = {"P1", "R1"};
       
        Random rand = this.getRandom();
        for (String table : tables) {
            Client client = getClient();
            List<Long> val_nums = new ArrayList<Long>();
            List<Double> val_ratios = new ArrayList<Double>();
           
            for (int i = 0; i < ROWS; ++i) {
                BigDecimal cash = new BigDecimal(10.0);
                long num = i / 2;
                double ratio = rand.nextDouble();
                client.callProcedure("Insert", table, i, "desc", cash, num, ratio);
                val_nums.add(num);
                val_ratios.add(ratio);
            } // FOR
           
            double expected_results[] = {
                MathUtil.arithmeticMean(val_nums),
                MathUtil.arithmeticMean(val_ratios),
            };
            String query = String.format("SELECT AVG(NUM), AVG(RATIO) FROM %s", table);
            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
            assertEquals(1, results.length);
            assertEquals(1, results[0].getRowCount());
            assertTrue(results[0].advanceRow());
            for (int i = 0; i < expected_results.length; ++i) {
                double val = ((Number)results[0].get(i, results[0].getColumnType(i))).doubleValue();
                assertEquals(table+"."+i, expected_results[i], val, 0.00001);
            } // FOR
        } // FOR
    }
   
    public void testMixedAggregates() throws IOException, ProcCallException {
        String[] aggs = {"count", "sum", "min", "max", "avg"};
        Object[] expected_results = {ROWS,
                                     (0 + 1 + 2 + 3 + 4) * 2,
                                     0,
                                     4,
                                     2.0};
        String[] tables = {"P1", "R1"};
       
        for (String table : tables) {
            Client client = getClient();
            for (int i = 0; i < ROWS; ++i) {
                client.callProcedure("Insert", table, i, "desc",
                                     new BigDecimal(10.0), i / 2, 14.5);
            } // FOR
       
            String query = "SELECT ";
            for (int i = 0; i < aggs.length; ++i) {
                if (i > 0) query += ", ";
                query += String.format("%s(%s.NUM)", aggs[i], table);
            } // FOR
            query += "FROM " + table;
           
            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
            assertEquals(1, results.length);
            assertEquals(1, results[0].getRowCount());
            assertTrue(results[0].advanceRow());
            for (int i = 0; i < aggs.length; ++i) {
                // Do avg separately since the column is a float
                if (aggs[i] == "avg") {
                    double val = ((Number)results[0].get(i, results[0].getColumnType(i))).doubleValue();
                    assertEquals(table+"."+aggs[i], expected_results[i], val);
                } else {
                    int val = (int)results[0].getLong(i);
                    int expected = (int)(Integer)expected_results[i];
                    assertEquals(table+"."+aggs[i], expected, val);
                }
            } // FOR
        } // FOR
    }

    public void testAggregates() throws IOException, ProcCallException {
        String[] aggs = {"count", "sum", "min", "max"};
        long[] expected_results = {10,
                                   (0 + 1 + 2 + 3 + 4) * 2,
                                   0,
                                   4};
        String[] tables = {"P1", "R1"};
        for (String table : tables)
        {
            Client client = getClient();
            for (int i = 0; i < ROWS; ++i)
            {
                client.callProcedure("Insert", table, i, "desc",
                                     new BigDecimal(10.0), i / 2, 14.5);
            }
            for (int i = 0; i < aggs.length; ++i)
            {
                String query = String.format("select %s(%s.NUM) from %s",
                                             aggs[i], table, table);
                VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
                assertEquals(expected_results[i], results[0].asScalarLong());
            }
            // Do avg separately since the column is a float and makes
            // asScalarLong() unhappy
            String query = String.format("select avg(%s.NUM) from %s",
                                         table, table);
            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
            results[0].advanceRow();
            assertEquals(2.0,
                         ((Number)results[0].get(0, results[0].getColumnType(0))).doubleValue());
        }
    }

    public void testAggregatesOnEmptyTable() throws IOException, ProcCallException {
        String[] aggs = {"count", "sum", "min", "max"};
        String[] tables = {"P1", "R1"};
        for (String table : tables)
        {
            Client client = getClient();
            for (int i = 0; i < aggs.length; ++i)
            {
                String query = String.format("select %s(%s.NUM) from %s",
                                             aggs[i], table, table);
                VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
                if (aggs[i].equals("count")) {
                    assertEquals(0, results[0].asScalarLong());
                } else {
                    final VoltTableRow row = results[0].fetchRow(0);
                    row.get(0, results[0].getColumnType(0));
                    if (!isHSQL()) {
                        assertTrue(row.wasNull());
                    }
                }
            }
            // Do avg separately since the column is a float and makes
            // asScalarLong() unhappy
            String query = String.format("select avg(%s.NUM) from %s",
                                         table, table);
            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
            results[0].advanceRow();
            @SuppressWarnings("unused")
            final double value = ((Number)results[0].get(0, results[0].getColumnType(0))).doubleValue();
            if (!isHSQL()) {
                assertTrue(results[0].wasNull());
            }
        }
    }

    // This test case includes all of the broken cases of sum, min, max, and avg
    // which didn't actually do DISTINCT.
    // This is only visible for sum and avg, of course
//    public void testAggregatesWithDistinct()
//    throws IOException, ProcCallException
//    {
//        String[] aggs = {"count", "sum", "min", "max"};
//        long[] expected_results = {5,
//                                   (0 + 1 + 2 + 3 + 4),
//                                   0,
//                                   4};
//        String[] tables = {"P1", "R1"};
//        for (String table : tables)
//        {
//            Client client = getClient();
//            for (int i = 0; i < ROWS; ++i)
//            {
//                client.callProcedure("Insert", table, i, "desc",
//                                     new BigDecimal(10.0), i / 2, 14.5);
//            }
//            for (int i = 0; i < aggs.length; ++i)
//            {
//                String query = String.format("select %s(distinct(%s.NUM)) from %s",
//                                             aggs[i], table, table);
//                VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
//                assertEquals(expected_results[i], results[0].asScalarLong());
//            }
//            // Do avg separately since the column is a float and makes
//            // asScalarLong() unhappy
//            String query = String.format("select avg(distinct(%s.NUM)) from %s",
//                                         table, table);
//            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
//            results[0].advanceRow();
//            assertEquals(2.0,
//                         ((Number)results[0].get(0, results[0].getColumnType(0))).doubleValue());
//        }
//    }

    public void testStringMinMaxAndCount()
    throws IOException, ProcCallException
    {
        String[] tables = {"P1", "R1"};
        for (String table : tables)
        {
            Client client = getClient();
            for (int i = 0; i < ROWS; ++i)
            {
                client.callProcedure("Insert", table, i, String.valueOf(i),
                                     new BigDecimal(10.0), i / 2, 14.5);
            }
            for (int i = ROWS; i < ROWS + 5; ++i)
            {
                client.callProcedure("Insert", table, i, VoltType.NULL_STRING,
                                     new BigDecimal(10.0), i / 2, 14.5);
            }
            String query = String.format("select MIN(%s.DESC) from %s",
                                         table, table);
            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
            results[0].advanceRow();
            assertEquals("0", results[0].getString(0));
            query = String.format("select MAX(%s.DESC) from %s",
                                  table, table);
            results = client.callProcedure("@AdHoc", query).getResults();
            results[0].advanceRow();
            assertEquals("9", results[0].getString(0));
            query = String.format("select COUNT(%s.DESC) from %s",
                                  table, table);
            results = client.callProcedure("@AdHoc", query).getResults();
            assertEquals(ROWS, results[0].asScalarLong());
        }
    }

//    public void testAggregatesWithNulls() throws IOException, ProcCallException
//    {
//        int good_rows = 10;
//        int null_rows = 5;
//
//        String[] aggs = {"sum", "min", "max", "avg"};
//        long[] expected_int_results = {(0 + 1 + 2 + 3 + 4) * 2,
//                                       0,
//                                       4,
//                                       2};
//        double[] expected_float_results = {(0 + 0.5 + 1 + 1.5 + 2 + 2.5 + 3 +
//                                            3.5 + 4 + 4.5),
//                                           0.0,
//                                           4.5,
//                                           2.25};
//        String[] tables = {"P1", "R1"};
//        for (String table : tables)
//        {
//            Client client = getClient();
//            for (int i = 0; i < good_rows; ++i)
//            {
//                client.callProcedure("Insert", table, i, "desc",
//                                     new BigDecimal(i / 2.0), i / 2, i / 2.0);
//            }
//            for (int i = good_rows; i < good_rows + null_rows; ++i)
//            {
//                client.callProcedure("Insert", table, i, VoltType.NULL_STRING,
//                                     VoltType.NULL_DECIMAL,
//                                     VoltType.NULL_INTEGER,
//                                     VoltType.NULL_FLOAT);
//            }
//            // do count separately since it's always integer return type
//            String query = String.format("select count(%s.CASH) from %s",
//                                         table, table);
//            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
//            assertEquals(good_rows, results[0].asScalarLong());
//            query = String.format("select count(%s.NUM) from %s",
//                                         table, table);
//            results = client.callProcedure("@AdHoc", query).getResults();
//            assertEquals(good_rows, results[0].asScalarLong());
//            query = String.format("select count(%s.RATIO) from %s",
//                                         table, table);
//            results = client.callProcedure("@AdHoc", query).getResults();
//            assertEquals(good_rows, results[0].asScalarLong());
//            for (int i = 0; i < aggs.length; ++i)
//            {
//                query = String.format("select %s(%s.CASH) from %s",
//                                      aggs[i], table, table);
//                results = client.callProcedure("@AdHoc", query).getResults();
//                results[0].advanceRow();
//                assertEquals(expected_float_results[i],
//                             results[0].getDecimalAsBigDecimal(0).doubleValue());
//                query = String.format("select %s(%s.NUM) from %s",
//                                             aggs[i], table, table);
//                results = client.callProcedure("@AdHoc", query).getResults();
//                assertEquals(expected_int_results[i], results[0].asScalarLong());
//                query = String.format("select %s(%s.RATIO) from %s",
//                                             aggs[i], table, table);
//                results = client.callProcedure("@AdHoc", query).getResults();
//                results[0].advanceRow();
//                assertEquals(expected_float_results[i], results[0].getDouble(0));
//            }
//            // and finish up with count(*) for good measure
//            query = String.format("select count(*) from %s", table);
//            results = client.callProcedure("@AdHoc", query).getResults();
//            results[0].advanceRow();
//            assertEquals(good_rows + null_rows, results[0].asScalarLong());
//        }
//    }
//
//    public void testAggregatesWithOnlyNulls() throws IOException, ProcCallException
//    {
//        int null_rows = 5;
//
//        String[] aggs = {"sum", "min", "max", "avg"};
//        String[] tables = {"P1", "R1"};
//        for (String table : tables)
//        {
//            Client client = getClient();
//            for (int i = 0; i < null_rows; ++i)
//            {
//                client.callProcedure("Insert", table, i, VoltType.NULL_STRING,
//                                     VoltType.NULL_DECIMAL,
//                                     VoltType.NULL_INTEGER,
//                                     VoltType.NULL_FLOAT);
//            }
//            // do count separately since it's always integer return type
//            String query = String.format("select count(%s.CASH) from %s",
//                                         table, table);
//            VoltTable[] results = client.callProcedure("@AdHoc", query).getResults();
//            assertEquals(0, results[0].asScalarLong());
//            query = String.format("select count(%s.NUM) from %s",
//                                         table, table);
//            results = client.callProcedure("@AdHoc", query).getResults();
//            assertEquals(0, results[0].asScalarLong());
//            query = String.format("select count(%s.RATIO) from %s",
//                                         table, table);
//            results = client.callProcedure("@AdHoc", query).getResults();
//            assertEquals(0, results[0].asScalarLong());
//            for (int i = 0; i < aggs.length; ++i)
//            {
//                query = String.format("select %s(%s.CASH) from %s",
//                                      aggs[i], table, table);
//                results = client.callProcedure("@AdHoc", query).getResults();
//                results[0].advanceRow();
//                @SuppressWarnings("unused")
//                BigDecimal dec_val = results[0].getDecimalAsBigDecimal(0);
//                assert(results[0].wasNull());
//                query = String.format("select %s(%s.NUM) from %s",
//                                             aggs[i], table, table);
//                results = client.callProcedure("@AdHoc", query).getResults();
//                results[0].advanceRow();
//                @SuppressWarnings("unused")
//                long long_val = results[0].getLong(0);
//                assert(results[0].wasNull());
//                query = String.format("select %s(%s.RATIO) from %s",
//                                             aggs[i], table, table);
//                results = client.callProcedure("@AdHoc", query).getResults();
//                results[0].advanceRow();
//                @SuppressWarnings("unused")
//                double doub_val = results[0].getDouble(0);
//                assert(results[0].wasNull());
//            }
//            // and finish up with count(*) for good measure
//            query = String.format("select count(*) from %s", table);
//            results = client.callProcedure("@AdHoc", query).getResults();
//            results[0].advanceRow();
//            assertEquals(null_rows, results[0].asScalarLong());
//        }
//    }

    //
    // JUnit / RegressionSuite boilerplate
    //
    public TestSqlAggregateSuite(String name) {
        super(name);
    }

    static public junit.framework.Test suite() {

        VoltServerConfig config = null;
        MultiConfigSuiteBuilder builder =
            new MultiConfigSuiteBuilder(TestSqlAggregateSuite.class);

        VoltProjectBuilder project = new VoltProjectBuilder("aggregate");
        project.addSchema(Insert.class.getResource("aggregate-sql-ddl.sql"));
        project.addTablePartitionInfo("P1", "ID");
        project.addProcedures(PROCEDURES);
       
        boolean success;
       
        /////////////////////////////////////////////////////////////
        // CONFIG #1: 1 Local Site/Partition
        /////////////////////////////////////////////////////////////
        config = new LocalSingleProcessServer(PREFIX + "-1part.jar", 1, BackendTarget.NATIVE_EE_JNI);
        success = config.compile(project);
        assert(success);
        builder.addServerConfig(config);
       
        /////////////////////////////////////////////////////////////
        // CONFIG #2: 1 Local Site with 2 Partitions running on JNI backend
        /////////////////////////////////////////////////////////////
        config = new LocalSingleProcessServer(PREFIX + "-2part.jar", 2, BackendTarget.NATIVE_EE_JNI);
        success = config.compile(project);
        assert(success);
        builder.addServerConfig(config);

        ////////////////////////////////////////////////////////////
        // CONFIG #3: cluster of 2 nodes running 2 site each, one replica
        ////////////////////////////////////////////////////////////
        config = new LocalCluster(PREFIX + "-cluster.jar", 2, 2, 1, BackendTarget.NATIVE_EE_JNI);
        success = config.compile(project);
        assert(success);
        builder.addServerConfig(config);

        return builder;
    }

}
TOP

Related Classes of org.voltdb.regressionsuites.TestSqlAggregateSuite

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.