/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.phoenix.compile;

import static org.apache.phoenix.util.TestUtil.PHOENIX_JDBC_URL;
import static org.junit.Assert.assertEquals;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;

import org.apache.phoenix.query.BaseConnectionlessQueryTest;
import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.TestUtil;
import org.junit.Test;



/**
 * 
 * Tests for getting PreparedStatement meta data
 *
 * 
 * @since 0.1
 */
public class QueryMetaDataTest extends BaseConnectionlessQueryTest {

    @Test
    public void testNoParameterMetaData() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE organization_id='000000000000000'";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(0, pmd.getParameterCount());
    }

    @Test
    public void testCaseInsensitive() throws Exception {
        String query = "SELECT A_string, b_striNG FROM ataBle WHERE ORGANIZATION_ID='000000000000000'";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(0, pmd.getParameterCount());
    }

    @Test
    public void testParameterMetaData() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE organization_id=? and (a_integer = ? or a_date = ? or b_string = ? or a_string = 'foo')";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(4, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(2));
        assertEquals(Date.class.getName(), pmd.getParameterClassName(3));
        assertEquals(String.class.getName(), pmd.getParameterClassName(4));
    }

    @Test
    public void testUpsertParameterMetaData() throws Exception {
        String query = "UPSERT INTO atable VALUES (?, ?, ?, ?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(5, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
        assertEquals(String.class.getName(), pmd.getParameterClassName(2));
        assertEquals(String.class.getName(), pmd.getParameterClassName(3));
        assertEquals(String.class.getName(), pmd.getParameterClassName(4));
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(5));
    }

    @Test
    public void testToDateFunctionMetaData() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE a_date > to_date(?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
    }

    @Test
    public void testLimitParameterMetaData() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE organization_id=? and a_string = 'foo' LIMIT ?";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(2));
    }

    @Test
    public void testRoundParameterMetaData() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE round(a_date,'day', ?) = ?";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Date.class.getName(), pmd.getParameterClassName(2));
    }

    @Test
    public void testInListParameterMetaData1() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE a_string IN (?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
        assertEquals(String.class.getName(), pmd.getParameterClassName(2));
    }

    @Test
    public void testInListParameterMetaData2() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE ? IN (2.2, 3)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(BigDecimal.class.getName(), pmd.getParameterClassName(1));
    }

    @Test
    public void testInListParameterMetaData3() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE ? IN ('foo')";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
    }

    @Test
    public void testInListParameterMetaData4() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE ? IN (?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(3, pmd.getParameterCount());
        assertEquals(null, pmd.getParameterClassName(1));
        assertEquals(null, pmd.getParameterClassName(2));
        assertEquals(null, pmd.getParameterClassName(3));
    }

    @Test
    public void testCaseMetaData() throws Exception {
        String query1 = "SELECT a_string, b_string FROM atable WHERE case when a_integer = 1 then ? when a_integer > 2 then 2 end > 3";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query1);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(BigDecimal.class.getName(), pmd.getParameterClassName(1));
        assertEquals(ParameterMetaData.parameterNullable, pmd.isNullable(1));
        
        String query2 = "SELECT a_string, b_string FROM atable WHERE case when a_integer = 1 then 1 when a_integer > 2 then 2 end > ?";
        PreparedStatement statement2 = conn.prepareStatement(query2);
        ParameterMetaData pmd2 = statement2.getParameterMetaData();
        assertEquals(1, pmd2.getParameterCount());
        assertEquals(Integer.class.getName(), pmd2.getParameterClassName(1));
        assertEquals(ParameterMetaData.parameterNullable, pmd2.isNullable(1));
    }

    @Test
    public void testSubstrParameterMetaData() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE substr(a_string,?,?) = ?";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(3, pmd.getParameterCount());
        assertEquals(Long.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Long.class.getName(), pmd.getParameterClassName(2));
        assertEquals(String.class.getName(), pmd.getParameterClassName(3));
    }

    @Test
    public void testKeyPrefixParameterMetaData() throws Exception {
        String query = "SELECT a_string, b_string FROM atable WHERE organization_id='000000000000000' and substr(entity_id,1,3)=? and a_string = 'foo'";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
    }
    
    @Test
    public void testDateSubstractExpressionMetaData1() throws Exception {
        String query = "SELECT entity_id,a_string FROM atable where a_date-2.5-?=a_date";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(BigDecimal.class.getName(), pmd.getParameterClassName(1));
    }

    @Test
    public void testDateSubstractExpressionMetaData2() throws Exception {
        String query = "SELECT entity_id,a_string FROM atable where a_date-?=a_date";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        // FIXME: Should really be Date, but we currently don't know if we're 
        // comparing to a date or a number where this is being calculated 
        // (which would disambiguate it).
        assertEquals(null, pmd.getParameterClassName(1));
    }

    @Test
    public void testDateSubstractExpressionMetaData3() throws Exception {
        String query = "SELECT entity_id,a_string FROM atable where a_date-?=a_integer";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        // FIXME: Should really be Integer, but we currently don't know if we're 
        // comparing to a date or a number where this is being calculated 
        // (which would disambiguate it).
        assertEquals(null, pmd.getParameterClassName(1));
    }

    @Test
    public void testTwoDateSubstractExpressionMetaData() throws Exception {
        String query = "SELECT entity_id,a_string FROM atable where ?-a_date=1";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        // We know this must be date - anything else would be an error
        assertEquals(Date.class.getName(), pmd.getParameterClassName(1));
    }

    @Test
    public void testDateAdditionExpressionMetaData1() throws Exception {
        String query = "SELECT entity_id,a_string FROM atable where 1+a_date+?>a_date";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(BigDecimal.class.getName(), pmd.getParameterClassName(1));
    }

    @Test
    public void testDateAdditionExpressionMetaData2() throws Exception {
        String query = "SELECT entity_id,a_string FROM atable where ?+a_date>a_date";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(1, pmd.getParameterCount());
        assertEquals(BigDecimal.class.getName(), pmd.getParameterClassName(1));
    }

    @Test
    public void testCoerceToDecimalArithmeticMetaData() throws Exception {
        String[] ops = { "+", "-", "*", "/" };
        for (String op : ops) {
            String query = "SELECT entity_id,a_string FROM atable where a_integer" + op + "2.5" + op + "?=0";
            Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
            PreparedStatement statement = conn.prepareStatement(query);
            statement.setInt(1, 4);
            ParameterMetaData pmd = statement.getParameterMetaData();
            assertEquals(1, pmd.getParameterCount());
            assertEquals(BigDecimal.class.getName(), pmd.getParameterClassName(1));
        }
    }

    @Test
    public void testLongArithmeticMetaData() throws Exception {
        String[] ops = { "+", "-", "*", "/" };
        for (String op : ops) {
            String query = "SELECT entity_id,a_string FROM atable where a_integer" + op + "2" + op + "?=0";
            Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
            PreparedStatement statement = conn.prepareStatement(query);
            statement.setInt(1, 4);
            ParameterMetaData pmd = statement.getParameterMetaData();
            assertEquals(1, pmd.getParameterCount());
            assertEquals(Long.class.getName(), pmd.getParameterClassName(1));
        }
    }

    @Test
    public void testBasicResultSetMetaData() throws Exception {
        String query = "SELECT organization_id, a_string, b_string, a_integer i, a_date FROM atable WHERE organization_id='000000000000000' and substr(entity_id,1,3)=? and a_string = 'foo'";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ResultSetMetaData md = statement.getMetaData();
        assertEquals(5, md.getColumnCount());
        
        assertEquals("organization_id".toUpperCase(),md.getColumnName(1));
        assertEquals("a_string".toUpperCase(),md.getColumnName(2));
        assertEquals("b_string".toUpperCase(),md.getColumnName(3));
        assertEquals("i".toUpperCase(),md.getColumnName(4));
        assertEquals("a_date".toUpperCase(),md.getColumnName(5));
        
        assertEquals(String.class.getName(),md.getColumnClassName(1));
        assertEquals(String.class.getName(),md.getColumnClassName(2));
        assertEquals(String.class.getName(),md.getColumnClassName(3));
        assertEquals(Integer.class.getName(),md.getColumnClassName(4));
        assertEquals(Date.class.getName(),md.getColumnClassName(5));
        
        assertEquals("atable".toUpperCase(),md.getTableName(1));
        assertEquals(java.sql.Types.INTEGER,md.getColumnType(4));
        assertEquals(true,md.isReadOnly(1));
        assertEquals(false,md.isDefinitelyWritable(1));
        assertEquals("i".toUpperCase(),md.getColumnLabel(4));
        assertEquals("a_date".toUpperCase(),md.getColumnLabel(5));
        assertEquals(ResultSetMetaData.columnNoNulls,md.isNullable(1));
        assertEquals(ResultSetMetaData.columnNullable,md.isNullable(5));
    }
    @Test
    public void testStringConcatMetaData() throws Exception {
    	String query = "SELECT entity_id,a_string FROM atable where 2 || a_integer || ? like '2%'";
    	Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
    	PreparedStatement statement = conn.prepareStatement(query);
    	statement.setString(1, "foo");
    	ParameterMetaData pmd = statement.getParameterMetaData();
    	assertEquals(1, pmd.getParameterCount());
    	assertEquals(String.class.getName(), pmd.getParameterClassName(1));

    }
    
    @Test
    public void testRowValueConstructorBindParamMetaData() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE (a_integer, x_integer, a_string) = (?, ?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(3, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(2));
        assertEquals(String.class.getName(), pmd.getParameterClassName(3));
    }
    
    @Test
    public void testRowValueConstructorBindParamMetaDataWithMoreNumberOfBindArgs() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE (a_integer, x_integer) = (?, ?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(3, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(2));
        assertEquals(null, pmd.getParameterClassName(3));
    }
    
    @Test
    public void testRowValueConstructorBindParamMetaDataWithLessNumberOfBindArgs() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE (a_integer, x_integer, a_string) = (?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(2));
    }
    
    @Test
    public void testRowValueConstructorBindParamMetaDataWithBindArgsAtSamePlacesOnLHSRHS() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE (a_integer, ?) = (a_integer, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(null, pmd.getParameterClassName(1));
        assertEquals(null, pmd.getParameterClassName(2));
    }
    
    @Test
    public void testRowValueConstructorBindParamMetaDataWithBindArgsAtDiffPlacesOnLHSRHS() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE (a_integer, ?) = (?, a_integer)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(2));
    }
    
    // @Test broken currently, as we'll end up with null = 7 which is never true
    public void testRowValueConstructorBindParamMetaDataWithBindArgsOnLHSAndLiteralExprOnRHS() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE (?, ?) = 7";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(null, pmd.getParameterClassName(2));
    }
    
    @Test
    public void testRowValueConstructorBindParamMetaDataWithBindArgsOnRHSAndLiteralExprOnLHS() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE 7 = (?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(null, pmd.getParameterClassName(2));
    }
    
    @Test
    public void testNonEqualityRowValueConstructorBindParamMetaDataWithBindArgsOnRHSAndLiteralExprOnLHS() throws Exception {
        String query = "SELECT a_integer, x_integer FROM aTable WHERE 7 >= (?, ?)";
        Connection conn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(2, pmd.getParameterCount());
        assertEquals(Integer.class.getName(), pmd.getParameterClassName(1));
        assertEquals(null, pmd.getParameterClassName(2));
    }
    
    @Test
    public void testBindParamMetaDataForNestedRVC() throws Exception {
        String query = "SELECT organization_id, entity_id, a_string FROM aTable WHERE (organization_id, (entity_id, a_string)) >= (?, (?, ?))";
        Connection conn = DriverManager.getConnection(PHOENIX_JDBC_URL, PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES));
        PreparedStatement statement = conn.prepareStatement(query);
        ParameterMetaData pmd = statement.getParameterMetaData();
        assertEquals(3, pmd.getParameterCount());
        assertEquals(String.class.getName(), pmd.getParameterClassName(1));
        assertEquals(String.class.getName(), pmd.getParameterClassName(2));
        assertEquals(String.class.getName(), pmd.getParameterClassName(3));
    }
}
