/* This file is part of VoltDB. * Copyright (C) 2008-2017 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.regressionsuites; import java.io.IOException; import org.voltdb.BackendTarget; import org.voltdb.VoltTable; import org.voltdb.client.Client; import org.voltdb.client.ClientResponse; import org.voltdb.compiler.VoltProjectBuilder; public class TestMaxSuite extends RegressionSuite { static final Class<?>[] PROCEDURES = {}; private static int SQL_TEXT_MAX_LENGTH = 100000; private static int SQL_LITERAL_MAX_ELEMENT = Short.MAX_VALUE; // literal element limit to 65535 private static int SQL_LITERAL_MAX_LENGTH = 1024*1024; // literal length limit to 1MB private static String LONG_STRING_TEMPLATE = "This is a long string to test. It will make the client easier " + "to generate very long long string."; private static int APPEND_TIMES = SQL_TEXT_MAX_LENGTH / LONG_STRING_TEMPLATE.length(); private static int PARAMETERS_MAX_JOIN = 100; private static int PARAMETERS_MAX_COLUMN = 1024; private static int PARAMETERS_MAX_IN = 6000; public TestMaxSuite(String name) { super(name); } public void testMaxSQLLength() throws Exception { Client client = this.getClient(); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < APPEND_TIMES; i++) { stringBuilder.append(LONG_STRING_TEMPLATE); } client.callProcedure("max_sql_proc"); client.callProcedure("max_parameter_proc", stringBuilder.toString()); } public void testAdHocMaxSQLText() throws Exception { if (isValgrind()) { return; } Client client = this.getClient(); StringBuilder stringBuilder = new StringBuilder( "select * from max_in_table where column0 in("); for (int i = 0; i < SQL_LITERAL_MAX_ELEMENT; i++) { stringBuilder.append(i); if (i != SQL_LITERAL_MAX_ELEMENT - 1) { stringBuilder.append(", "); } } stringBuilder.append(") order by column0;"); assert(stringBuilder.length() > Short.MAX_VALUE); // previous limit assert(stringBuilder.length() < SQL_LITERAL_MAX_LENGTH); // new limit due to ENG-10059 try { VoltTable result = client.callProcedure("@AdHoc", stringBuilder.toString()).getResults()[0]; assertEquals(0, result.getRowCount()); } catch(Exception ex) { fail(); } } public void testMaxIn() throws Exception { final Client client = this.getClient(); ClientResponse resp = null; for (int i = 0; i < 10; i++) { resp = client.callProcedure("MAX_IN_TABLE.insert", i, i); assertEquals(ClientResponse.SUCCESS, resp.getStatus()); } StringBuilder stringBuilder = new StringBuilder( "select * from max_in_table where column0 in("); for (int i = 0; i < PARAMETERS_MAX_IN; i++) { stringBuilder.append(i); if (i != PARAMETERS_MAX_IN - 1) { stringBuilder.append(","); } } stringBuilder.append(") order by column0;"); resp = client.callProcedure("@AdHoc", stringBuilder.toString()); assertEquals(ClientResponse.SUCCESS, resp.getStatus()); assertEquals(1, resp.getResults().length); VoltTable results = resp.getResults()[0]; int rowCount = results.getRowCount(); assertEquals(10, rowCount); assertEquals(2, results.getColumnCount()); for (int i = 0; i < rowCount; i++) { assertEquals(i, results.fetchRow(i).getLong(0)); } } public void testMaxColumn() throws Exception { final Client client = this.getClient(); ClientResponse resp = null; StringBuilder sb = new StringBuilder( "insert into max_column_table values("); for (int i = 0; i < PARAMETERS_MAX_COLUMN; i++) { sb.append(i); if (i != PARAMETERS_MAX_COLUMN - 1) { sb.append(","); } } sb.append(");"); resp = client.callProcedure("@AdHoc", sb.toString()); sb = new StringBuilder("select "); for (int i = 0; i < PARAMETERS_MAX_COLUMN; i++) { sb.append("column"); sb.append(i); if (i != PARAMETERS_MAX_COLUMN - 1) { sb.append(","); } } sb.append(" from max_column_table order by column0;"); resp = client.callProcedure("@AdHoc", sb.toString()); assertEquals(ClientResponse.SUCCESS, resp.getStatus()); assertEquals(1, resp.getResults().length); VoltTable results = resp.getResults()[0]; assertEquals(1, results.getRowCount()); assertEquals(PARAMETERS_MAX_COLUMN, results.getColumnCount()); assertEquals(0, results.fetchRow(0).getLong(0)); } public void testMaxJoin() throws Exception { final Client client = this.getClient(); ClientResponse resp = null; StringBuilder sb = new StringBuilder(); for (int i = 0; i < PARAMETERS_MAX_JOIN; i++) { resp = client.callProcedure("MAX_JOIN_TABLE" + i + ".insert", 1, 1); assertEquals(ClientResponse.SUCCESS, resp.getStatus()); } sb = new StringBuilder("select * from "); for (int i = 0; i < PARAMETERS_MAX_JOIN; i++) { sb.append("max_join_table"); sb.append(i); if (i != PARAMETERS_MAX_JOIN - 1) { sb.append(","); } } resp = client.callProcedure("@AdHoc", sb.toString()); assertEquals(ClientResponse.SUCCESS, resp.getStatus()); assertEquals(1, resp.getResults().length); VoltTable results = resp.getResults()[0]; assertEquals(1, results.getRowCount()); assertEquals(PARAMETERS_MAX_JOIN * 2, results.getColumnCount()); assertEquals(1, results.fetchRow(0).getLong(0)); } static public junit.framework.Test suite() { VoltServerConfig config = null; final MultiConfigSuiteBuilder builder = new MultiConfigSuiteBuilder( TestMaxSuite.class); final VoltProjectBuilder project = new VoltProjectBuilder(); try { StringBuilder sb; /** for max parameter or SQL text */ sb = new StringBuilder( "CREATE TABLE max_sql_table(column0 VARCHAR(1048576) NOT NULL," + "PRIMARY KEY(column0)); "); sb.append("CREATE PROCEDURE max_sql_proc AS " + "SELECT column0 as c1 from max_sql_table where column0 = ' "); for (int i = 0; i < APPEND_TIMES; i++) { sb.append(LONG_STRING_TEMPLATE); } sb.append("';"); sb.append("CREATE PROCEDURE max_parameter_proc AS " + "SELECT column0 as c2 from max_sql_table where column0 = ?;"); project.addLiteralSchema(sb.toString()); /** for max column */ sb = new StringBuilder( "CREATE TABLE max_column_table("); for (int i = 0; i < PARAMETERS_MAX_COLUMN; i++) { sb.append("column"); sb.append(i); sb.append(" INTEGER NOT NULL,"); } sb.append("PRIMARY KEY(column0));"); project.addLiteralSchema(sb.toString()); project.addPartitionInfo("max_column_table", "column0"); /** for max join */ sb = new StringBuilder(); for (int i = 0; i < PARAMETERS_MAX_JOIN; i++) { sb.append("create table max_join_table"); sb.append(i); sb.append("(column0 INTEGER NOT NULL, column1 INTEGER NOT NULL, PRIMARY KEY (column0));"); project.addLiteralSchema(sb.toString()); // project.addPartitionInfo("p1", "b1"); sb.setLength(0); } /** for max in */ project.addLiteralSchema("CREATE TABLE max_in_table(column0 INTEGER NOT NULL, column1 INTEGER NOT NULL, PRIMARY KEY (column0));"); project.addPartitionInfo("max_in_table", "column0"); } catch (IOException error) { fail(error.getMessage()); } // JNI config = new LocalCluster("testMax-onesite.jar", 1, 1, 0, BackendTarget.NATIVE_EE_JNI); boolean t1 = config.compile(project); assertTrue(t1); builder.addServerConfig(config); config = new LocalCluster("testMax-hsql.jar", 1, 1, 0, BackendTarget.HSQLDB_BACKEND); boolean success = config.compile(project); assertTrue(success); builder.addServerConfig(config); // CLUSTER config = new LocalCluster("testMax-cluster.jar", 2, 3, 1, BackendTarget.NATIVE_EE_JNI); boolean t2 = config.compile(project); assertTrue(t2); builder.addServerConfig(config); return builder; } }