gt:         JenaConnection conn = this.getConnection();
context: /**
   * 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.jena.jdbc.connections;
  
  import java.net.MalformedURLException ;
  import java.net.URL ;
  import java.sql.* ;
  import java.sql.ResultSet ;
  import java.util.HashMap ;
  import java.util.Properties ;
  
  import org.apache.jena.jdbc.JdbcCompatibility ;
  import org.apache.jena.jdbc.postprocessing.ResultsEcho ;
  import org.apache.jena.jdbc.preprocessing.Echo ;
  import org.apache.jena.jdbc.results.AskResults ;
  import org.apache.jena.jdbc.results.SelectResults ;
  import org.apache.jena.jdbc.results.TripleIteratorResults ;
  import org.apache.jena.jdbc.results.metadata.AskResultsMetadata ;
  import org.apache.jena.jdbc.results.metadata.TripleResultsMetadata ;
  import org.apache.jena.jdbc.utils.TestUtils ;
  import org.junit.Assert ;
  import org.junit.Assume ;
  import org.junit.Test ;
  
  import com.hp.hpl.jena.graph.Node ;
  import com.hp.hpl.jena.graph.NodeFactory ;
  import com.hp.hpl.jena.query.* ;
  import com.hp.hpl.jena.sparql.core.Quad ;
  import com.hp.hpl.jena.update.UpdateFactory ;
  import com.hp.hpl.jena.update.UpdateRequest ;
  
  /**
   * Abstract tests for {@link JenaConnection} implementations
   * 
   */
  public abstract class AbstractJenaConnectionTests {
  
      static {
          ARQ.init();
      }
  
      /**
       * Method which derived test classes must implement to provide a connection
       * to an empty database for testing
       * 
       * @return Connection
       * @throws SQLException
       */
      protected abstract JenaConnection getConnection() throws SQLException;
  
      /**
       * Method which derived test classes must implement to provide a connection
       * to a database constructed from the given dataset for testing
       * 
       * @return Connection
       * @throws SQLException
       */
      protected abstract JenaConnection getConnection(Dataset ds) throws SQLException;
  
      /**
       * Method which indicates whether a named graph is being used as the default
       * graph since some tests need to know this in order to adjust SPARQL
       * Updates issued appropriately
       * <p>
       * By default assumed to be false, override if you need to make it true for
       * your connection
       * </p>
       * 
       * @return Whether a named graph is used as the default graph
       */
      protected boolean usesNamedGraphAsDefault() {
          return false;
      }
  
      /**
       * Method which indicates whether the connection being tested supports query
       * timeouts
       * 
       * @return True if query timeouts are supported
       */
      protected boolean supportsTimeouts() {
          return true;
      }
  
      /**
       * Method which returns the name of the default graph when a named graph is
       * being used as the default graph
       * 
       * @return Named Graph being used as the default graph
       * @throws SQLException
       *             Thrown if this feature is not being used
       */
      protected String getDefaultGraphName() throws SQLException {
          throw new SQLException(
                  "Named Default Graph not used by these tests, please override getDefaultGraphName() if your connection uses this feature");
      }
  
      /**
       * Create and close a connection to an empty database
       * 
       * @throws SQLException
       */
      @Test
      public void connection_create_close_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Create and close a connection to an explicitly provided empty database
       * 
       * @throws SQLException
       */
      @Test
      public void connection_create_close_02() throws SQLException {
          JenaConnection conn = this.getConnection(DatasetFactory.createMem());
          Assert.assertFalse(conn.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Retrieve and close a statement
       * 
       * @throws SQLException
       */
      @Test
      public void connection_get_statement_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Statement stmt = conn.createStatement();
          Assert.assertNotNull(stmt);
          Assert.assertFalse(stmt.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Trying to retrieve a statement from a closed connection is an error
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_get_statement_02() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
          Assert.assertTrue(conn.isClosed());
  
          // Trying to create a statement after the connection is closed is an
          // error
          conn.createStatement();
      }
  
      /**
       * Trying to use a statement from a closed connection is an error
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_get_statement_03() throws SQLException {
          JenaConnection conn = this.getConnection();
          Statement stmt = conn.createStatement();
          Assert.assertNotNull(stmt);
          Assert.assertFalse(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
  
          // Trying to use a statement after the connection is closed is an error
          stmt.execute("SELECT * { ?s ?p ?o }");
      }
  
      /**
       * Runs a SELECT query on an empty database and checks it returns empty
       * results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_select_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(stmt.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a SELECT query on a non-empty database and checks it returns
       * non-empty results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_select_02() throws SQLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createURI("http://example/object")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 4);
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a SELECT query on a non-empty database and checks it returns
       * non-empty results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_select_03() throws SQLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createURI("http://example/object")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("SELECT DISTINCT ?g WHERE { GRAPH ?g { ?s ?p ?o } }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 1);
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a SELECT query on a non-empty database and checks it returns
       * non-empty results. Uses high compatibility level to ensure that column
       * type detection doesn't consume the first row.
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_select_04() throws SQLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createURI("http://example/object")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          conn.setJdbcCompatibilityLevel(JdbcCompatibility.HIGH);
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 4);
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Tests use of prepared statements
       * 
       * @throws SQLException
       * @throws MalformedURLException
       */
      @Test
      public void connection_prepared_statement_select_01() throws SQLException, MalformedURLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createURI("http://example/object")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          conn.setJdbcCompatibilityLevel(JdbcCompatibility.HIGH);
          PreparedStatement stmt = conn.prepareStatement("SELECT * WHERE { GRAPH ? { ?s ?p ?o } }");
          ParameterMetaData metadata = stmt.getParameterMetaData();
          Assert.assertEquals(1, metadata.getParameterCount());
          stmt.setURL(1, new URL("http://example/graph"));
  
          ResultSet rset = stmt.executeQuery();
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Tests use of prepared statements
       * 
       * @throws SQLException
       * @throws MalformedURLException
       */
      @Test
      public void connection_prepared_statement_select_02() throws SQLException, MalformedURLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createLiteral("value")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          conn.setJdbcCompatibilityLevel(JdbcCompatibility.HIGH);
          PreparedStatement stmt = conn.prepareStatement("SELECT * WHERE { GRAPH ?g { ?s ?p ? } }");
          ParameterMetaData metadata = stmt.getParameterMetaData();
          Assert.assertEquals(1, metadata.getParameterCount());
          stmt.setString(1, "value");
  
          ResultSet rset = stmt.executeQuery();
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Tests use of prepared statements
       * 
       * @throws SQLException
       * @throws MalformedURLException
       */
      @Test
      public void connection_prepared_statement_select_03() throws SQLException, MalformedURLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createLiteral("value")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          conn.setJdbcCompatibilityLevel(JdbcCompatibility.HIGH);
          PreparedStatement stmt = conn.prepareStatement("SELECT * WHERE { GRAPH ?g { ?s ?p ? } }");
          ParameterMetaData metadata = stmt.getParameterMetaData();
          Assert.assertEquals(1, metadata.getParameterCount());
          stmt.setNString(1, "value");
  
          ResultSet rset = stmt.executeQuery();
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
     
  
      /**
       * Runs a SELECT query on a non-empty database with max rows set and checks
       * that the appropriate number of rows are returned
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_select_max_rows_01() throws SQLException {
          // Prepare a dataset
          Dataset ds = TestUtils.generateDataset(3, 10, false);
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
          stmt.setMaxRows(10);
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 4);
  
          // Check expected number of rows
          int count = 0;
          while (rset.next()) {
              count++;
          }
          Assert.assertEquals(10, count);
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a SELECT query on a non-empty database with max rows set and checks
       * that the appropriate number of rows are returned
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_select_max_rows_02() throws SQLException {
          // Prepare a dataset
          Dataset ds = TestUtils.generateDataset(3, 10, false);
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
  
          // Set max rows to 10, note that if the query specifies a lower limit
          // then that is respected
          stmt.setMaxRows(10);
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } } LIMIT 1");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 4);
  
          // Check expected number of rows
          int count = 0;
          while (rset.next()) {
              count++;
          }
          Assert.assertEquals(1, count);
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a SELECT query on a non-empty database with max rows set and checks
       * that the appropriate number of rows are returned
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_select_max_rows_03() throws SQLException {
          // Prepare a dataset
          Dataset ds = TestUtils.generateDataset(3, 10, false);
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
  
          // Set max rows to 20, note that if the query specifies a higher limit
          // then the max rows are still enforced
          stmt.setMaxRows(10);
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } } LIMIT 50");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Check result set metadata
          checkSelectMetadata(rset, 4);
  
          // Check expected number of rows
          int count = 0;
          while (rset.next()) {
              count++;
          }
          Assert.assertEquals(10, count);
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a SELECT query on a non-empty database with timeout
       * 
       * @throws SQLException
       * @throws InterruptedException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_query_select_timeout_01() throws SQLException, InterruptedException {
          Assume.assumeTrue(this.supportsTimeouts());
  
          // Prepare a dataset
          Dataset ds = TestUtils.generateDataset(1, 1000, true);
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
  
          // Set timeout to 1 second
          stmt.setQueryTimeout(1);
          try {
              ResultSet rset = stmt.executeQuery("SELECT * WHERE { "
                      + (this.usesNamedGraphAsDefault() ? "GRAPH <" + this.getDefaultGraphName() + "> {" : "")
                      + " ?a ?b ?c . ?d ?e ?f . ?g ?h ?i " + (this.usesNamedGraphAsDefault() ? "}" : "") + "}");
  
              // Note that we have to start iterating otherwise the query doesn't
              // get executed and the timeout will never apply
              while (rset.next()) {
                  Thread.sleep(100);
              }
  
              rset.close();
              Assert.fail("Expected a query timeout");
          } finally {
              // Close things
              stmt.close();
              conn.close();
          }
      }
  
      /**
       * Runs a SELECT query on a non-empty database with timeout
       * 
       * @throws SQLException
       * @throws InterruptedException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_query_select_timeout_02() throws SQLException, InterruptedException {
          Assume.assumeTrue(this.supportsTimeouts());
  
          // Prepare a dataset
          Dataset ds = TestUtils.generateDataset(1, 1000, true);
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  
          // Set timeout to 1 second
          stmt.setQueryTimeout(1);
          try {
              ResultSet rset = stmt.executeQuery("SELECT * WHERE { "
                      + (this.usesNamedGraphAsDefault() ? "GRAPH <" + this.getDefaultGraphName() + "> {" : "")
                      + " ?a ?b ?c . ?d ?e ?f . ?g ?h ?i . " + (this.usesNamedGraphAsDefault() ? "}" : "") + "}");
  
              // Note that we have to start iterating otherwise the query doesn't
              // get executed and the timeout will never apply
              while (rset.next()) {
                  Thread.sleep(100);
              }
  
              rset.close();
              Assert.fail("Expected a query timeout");
          } finally {
              // Close things
              stmt.close();
              conn.close();
          }
      }
  
      /**
       * Runs a SELECT query on a non-empty database with timeout
       * 
       * @throws SQLException
       * @throws InterruptedException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_query_construct_timeout_01() throws SQLException, InterruptedException {
          Assume.assumeTrue(this.supportsTimeouts());
  
          // Prepare a dataset
          Dataset ds = TestUtils.generateDataset(1, 1000, true);
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
  
          // Set timeout to 1 second
          stmt.setQueryTimeout(1);
          try {
              ResultSet rset = stmt.executeQuery("CONSTRUCT { ?s ?p ?o } WHERE { "
                      + (this.usesNamedGraphAsDefault() ? "GRAPH <" + this.getDefaultGraphName() + "> {" : "")
                      + " ?a ?b ?c . ?s ?p ?o . " + (this.usesNamedGraphAsDefault() ? "}" : "") + "}");
  
              // Note that we have to start iterating otherwise the query doesn't
              // get executed and the timeout will never apply
              while (rset.next()) {
                  Thread.sleep(100);
              }
  
              rset.close();
              Assert.fail("Expected a query timeout");
          } finally {
              // Close things
              stmt.close();
              conn.close();
          }
      }
  
      /**
       * Runs a SELECT query on a non-empty database with timeout
       * 
       * @throws SQLException
       * @throws InterruptedException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_query_construct_timeout_02() throws SQLException, InterruptedException {
          Assume.assumeTrue(this.supportsTimeouts());
  
          // Prepare a dataset
          Dataset ds = TestUtils.generateDataset(1, 1000, true);
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  
          // Set timeout to 1 second
          stmt.setQueryTimeout(1);
          try {
              ResultSet rset = stmt.executeQuery("CONSTRUCT { ?s ?p ?o } WHERE { "
                      + (this.usesNamedGraphAsDefault() ? "GRAPH <" + this.getDefaultGraphName() + "> {" : "")
                      + " ?a ?b ?c . ?s ?p ?o . " + (this.usesNamedGraphAsDefault() ? "}" : "") + "}");
  
              // Note that we have to start iterating otherwise the query doesn't
              // get executed and the timeout will never apply
              while (rset.next()) {
                  Thread.sleep(100);
              }
  
              rset.close();
              Assert.fail("Expected a query timeout");
          } finally {
              // Close things
              stmt.close();
              conn.close();
          }
      }
  
      protected void checkSelectMetadata(ResultSet results, int numColumns) throws SQLException {
          ResultSetMetaData metadata = results.getMetaData();
          Assert.assertEquals(numColumns, metadata.getColumnCount());
          for (int i = 1; i <= numColumns; i++) {
              Assert.assertEquals(String.class.getCanonicalName(), metadata.getColumnClassName(i));
              Assert.assertEquals(Node.class.getCanonicalName(), metadata.getColumnTypeName(i));
              Assert.assertEquals(Types.NVARCHAR, metadata.getColumnType(i));
          }
      }
  
      /**
       * Runs an ASK query on an empty database and checks it returns true
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_ask_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("ASK WHERE { }");
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkAskMetadata(rset);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.getBoolean(1));
  
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      protected void checkAskMetadata(ResultSet results) throws SQLException {
          ResultSetMetaData metadata = results.getMetaData();
          Assert.assertEquals(1, metadata.getColumnCount());
          Assert.assertEquals(Boolean.class.getCanonicalName(), metadata.getColumnClassName(1));
          Assert.assertEquals(Node.class.getCanonicalName(), metadata.getColumnTypeName(1));
          Assert.assertEquals(Types.BOOLEAN, metadata.getColumnType(1));
      }
  
      /**
       * Runs a CONSTRUCT query on an empty database and checks it returns empty
       * results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_construct_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("CONSTRUCT WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkConstructDescribeMetadata(rset);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a CONSTRUCT query on a non-empty database and checks it returns
       * non-empty results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_construct_02() throws SQLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createURI("http://example/object")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("CONSTRUCT { ?s ?p ?o } WHERE { GRAPH ?g { ?s ?p ?o } }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a CONSTRUCT query on an empty database and checks it returns empty
       * results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_describe_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("DESCRIBE <http://subject>");
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkConstructDescribeMetadata(rset);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a CONSTRUCT query on a non-empty database and checks it returns
       * non-empty results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_query_describe_02() throws SQLException {
          // Prepare a dataset
          Dataset ds = DatasetFactory.createMem();
          ds.asDatasetGraph().add(
                  new Quad(NodeFactory.createURI("http://example/graph"), NodeFactory.createURI("http://example/subject"),
                          NodeFactory.createURI("http://example/predicate"), NodeFactory.createURI("http://example/object")));
  
          // Work with the connection
          JenaConnection conn = this.getConnection(ds);
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("DESCRIBE ?s WHERE { GRAPH ?g { ?s ?p ?o } }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have a row
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.isFirst());
          Assert.assertEquals(1, rset.getRow());
  
          // Should be no further rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(rset.isClosed());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      protected void checkConstructDescribeMetadata(ResultSet results) throws SQLException {
          // Check result set metadata
          ResultSetMetaData metadata = results.getMetaData();
          Assert.assertEquals(3, metadata.getColumnCount());
          for (int i = 1; i <= TripleResultsMetadata.NUM_COLUMNS; i++) {
              Assert.assertEquals(String.class.getCanonicalName(), metadata.getColumnClassName(i));
              Assert.assertEquals(Node.class.getCanonicalName(), metadata.getColumnTypeName(i));
              Assert.assertEquals(Types.NVARCHAR, metadata.getColumnType(i));
          }
      }
  
      /**
       * Does a basic read transaction
       * 
       * @throws SQLException
       */
      @Test
      public void connection_transactions_01() throws SQLException {
          // Set up connection
          JenaConnection conn = this.getConnection(DatasetFactory.createMem());
          Assume.assumeNotNull(conn.getMetaData());
          Assume.assumeTrue(conn.getMetaData().supportsTransactions());
          conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
          conn.setAutoCommit(true);
  
          // Make a read operation
          Statement stmt = conn.createStatement();
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have no rows
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Does a basic write transaction
       * 
       * @throws SQLException
       */
      @Test
      public void connection_transactions_02() throws SQLException {
          // Set up connection
          JenaConnection conn = this.getConnection(DatasetFactory.createMem());
          Assume.assumeNotNull(conn.getMetaData());
          Assume.assumeTrue(conn.getMetaData().supportsTransactions());
          conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
          conn.setAutoCommit(true);
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
  
          // Make a write operation
          Statement stmt = conn.createStatement();
          stmt.executeUpdate("INSERT DATA { <http://x> <http://y> <http://z> }");
  
          // Make a subsequent read, with auto-commit we should see some data
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have one row
          Assert.assertTrue(rset.next());
          Assert.assertFalse(rset.next());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Does a basic write transaction without auto-commit and then commits it
       * 
       * @throws SQLException
       */
      @Test
      public void connection_transactions_03() throws SQLException {
          // Set up connection
          JenaConnection conn = this.getConnection(DatasetFactory.createMem());
          Assume.assumeNotNull(conn.getMetaData());
          Assume.assumeTrue(conn.getMetaData().supportsTransactions());
          conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
          conn.setAutoCommit(false);
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
  
          // Make a write operation
          Statement stmt = conn.createStatement();
          stmt.executeUpdate("INSERT DATA { <http://x> <http://y> <http://z> }");
  
          // Make a subsequent read, with auto-commit we should see some data
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have one row
          Assert.assertTrue(rset.next());
          Assert.assertFalse(rset.next());
          rset.close();
          Assert.assertTrue(rset.isClosed());
  
          // Commit the transaction
          conn.commit();
  
          // Check we still can read the data
          rset = stmt.executeQuery("SELECT * WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have one row
          Assert.assertTrue(rset.next());
          Assert.assertFalse(rset.next());
          rset.close();
          Assert.assertTrue(rset.isClosed());
  
          // Close things
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Does a basic write transaction without auto-commit and then rolls it back
       * 
       * @throws SQLException
       */
      @Test
      public void connection_transactions_04() throws SQLException {
          // Set up connection
          JenaConnection conn = this.getConnection(DatasetFactory.createMem());
          Assume.assumeNotNull(conn.getMetaData());
          Assume.assumeTrue(conn.getMetaData().supportsTransactions());
          conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
          conn.setAutoCommit(false);
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
  
          // Make a write operation
          Statement stmt = conn.createStatement();
          stmt.executeUpdate("INSERT DATA { <http://x> <http://y> <http://z> }");
  
          // Make a subsequent read, with auto-commit we should see some data
          ResultSet rset = stmt.executeQuery("SELECT * WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have one row
          Assert.assertTrue(rset.next());
          Assert.assertFalse(rset.next());
          rset.close();
          Assert.assertTrue(rset.isClosed());
  
          // Rollback the transaction
          conn.rollback();
  
          // Check we can no longer read the data
          rset = stmt.executeQuery("SELECT * WHERE { ?s ?p ?o }");
          Assert.assertNotNull(rset);
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
  
          // Should have no rows
          Assert.assertFalse(rset.next());
          rset.close();
          Assert.assertTrue(rset.isClosed());
  
          // Close things
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Tests error cases for transactions
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_transaction_bad_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Trying to commit a transaction on a closed connection should be an
          // error
          conn.commit();
      }
  
      /**
       * Tests error cases for transactions
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_transaction_bad_02() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Trying to commit a transaction on a closed connection should be an
          // error
          conn.rollback();
      }
  
      /**
       * Test error cases for creating statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_bad_creation_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.createStatement();
      }
  
      /**
       * Test error cases for creating statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_bad_creation_02() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
      }
  
      /**
       * Test error cases for creating statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_bad_creation_03() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
      }
  
      /**
       * Test error cases for creating statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLFeatureNotSupportedException.class)
      public void connection_statement_bad_creation_04() throws SQLException {
          JenaConnection conn = this.getConnection();
  
          try {
              // Creating a SCOLL_SENSITIVE statement is not supported
              conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
          } finally {
              conn.close();
          }
      }
  
      /**
       * Test error cases for creating statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLFeatureNotSupportedException.class)
      public void connection_statement_bad_creation_05() throws SQLException {
          JenaConnection conn = this.getConnection();
  
          try {
              // Creating a CONCUR_UPDATABLE statement is not supported
              conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
          } finally {
              conn.close();
          }
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_prepared_statement_bad_creation_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }");
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_prepared_statement_bad_creation_02() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }", 1);
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_prepared_statement_bad_creation_03() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }", new int[0]);
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_prepared_statement_bad_creation_04() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }", new String[0]);
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_prepared_statement_bad_creation_05() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_prepared_statement_bad_creation_06() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.close();
  
          // Creating a statement after closing should be an error
          conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
                  ResultSet.CLOSE_CURSORS_AT_COMMIT);
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLFeatureNotSupportedException.class)
      public void connection_prepared_statement_bad_creation_07() throws SQLException {
          JenaConnection conn = this.getConnection();
  
          try {
              // Creating a statement with SCROLL_SENSITIVE is not supported
              conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
          } finally {
              conn.close();
          }
      }
  
      /**
       * Test error cases for creating prepared statements
       * 
       * @throws SQLException
       */
      @Test(expected = SQLFeatureNotSupportedException.class)
      public void connection_prepared_statement_bad_creation_08() throws SQLException {
          JenaConnection conn = this.getConnection();
  
          try {
              // Creating a statement with CONCUR_UPDATABLE is not supported
              conn.prepareStatement("SELECT * WHERE { ?s ?p ?o }", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
          } finally {
              conn.close();
          }
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(1, batchResults.length);
  
          // Expect first result set returned to be SELECT results
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          ResultSet rset = stmt.getResultSet();
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(stmt.isClosed());
  
          // Expect there to be no further results
          Assert.assertFalse(stmt.getMoreResults());
          Assert.assertTrue(rset.isClosed()); // Should cause previous result set
                                              // to be closed
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_02() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          stmt.addBatch("ASK WHERE { }");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(2, batchResults.length);
  
          // Expect first result set returned to be SELECT results
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          ResultSet rset = stmt.getResultSet();
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(stmt.isClosed());
  
          // Expect there to be a further ASK result set
          Assert.assertEquals(batchResults[1], Statement.SUCCESS_NO_INFO);
          Assert.assertTrue(stmt.getMoreResults());
          Assert.assertTrue(rset.isClosed()); // Should close the previous result
                                              // set
          rset = stmt.getResultSet();
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkAskMetadata(rset);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertTrue(rset.next());
          Assert.assertTrue(rset.getBoolean(AskResultsMetadata.COLUMN_LABEL_ASK));
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_03() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
  
          // This test needs scroll insensitive result sets as otherwise the first
          // SELECT may see data from the update if the underlying connection does
          // not have suitable transaction isolation
          Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          if (this.usesNamedGraphAsDefault()) {
              stmt.addBatch("INSERT DATA { GRAPH <" + this.getDefaultGraphName() + "> { <http://x> <http://y> <http://z> } }");
          } else {
              stmt.addBatch("INSERT DATA { <http://x> <http://y> <http://z> }");
          }
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(3, batchResults.length);
  
          // Expect first result set returned to be SELECT results
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          ResultSet rset = stmt.getResultSet();
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
          Assert.assertFalse(stmt.isClosed());
  
          // Next results should be for the update so should return null for the
          // result set
          Assert.assertTrue(batchResults[1] >= 0);
          Assert.assertTrue(stmt.getMoreResults());
          rset = stmt.getResultSet();
          Assert.assertNull(rset);
  
          // Expect there to be a further SELECT result set
          Assert.assertEquals(batchResults[2], Statement.SUCCESS_NO_INFO);
          Assert.assertTrue(stmt.getMoreResults());
          rset = stmt.getResultSet();
          Assert.assertNotNull(rset);
  
          // Check result set metadata
          checkSelectMetadata(rset, 3);
  
          // Check result set
          Assert.assertFalse(rset.isClosed());
          Assert.assertTrue(rset.isBeforeFirst());
          Assert.assertTrue(rset.next()); // Should now be a row because previous
                                          // command in batch inserted data
          Assert.assertFalse(rset.next());
          Assert.assertTrue(rset.isAfterLast());
  
          // Close things
          rset.close();
          Assert.assertTrue(rset.isClosed());
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_04() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          stmt.addBatch("ASK WHERE { }");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(2, batchResults.length);
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[1], Statement.SUCCESS_NO_INFO);
  
          // Closing the statement should clean up any open result sets even if we
          // haven't retrieved them yet
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
  
          // Clean up
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_05() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          stmt.addBatch("ASK WHERE { }");
          stmt.addBatch("CONSTRUCT WHERE { ?s ?p ?o }");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(3, batchResults.length);
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[1], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[2], Statement.SUCCESS_NO_INFO);
  
          // Get first result set
          ResultSet rset = stmt.getResultSet();
          Assert.assertTrue(rset instanceof SelectResults);
          checkSelectMetadata(rset, 3);
  
          // Grab the next result set leaving this one open
          Assert.assertTrue(stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT));
          Assert.assertFalse(rset.isClosed());
          ResultSet rset2 = stmt.getResultSet();
          Assert.assertTrue(rset2 instanceof AskResults);
          checkAskMetadata(rset2);
  
          // Closing the statement should clean up any open result sets even if we
          // haven't retrieved them yet or have previously moved past them but
          // left them open
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          Assert.assertTrue(rset.isClosed());
          Assert.assertTrue(rset2.isClosed());
  
          // Clean up
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_06() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          stmt.addBatch("ASK WHERE { }");
          stmt.addBatch("CONSTRUCT WHERE { ?s ?p ?o }");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(3, batchResults.length);
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[1], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[2], Statement.SUCCESS_NO_INFO);
  
          // Get first result set
          ResultSet rset = stmt.getResultSet();
          Assert.assertTrue(rset instanceof SelectResults);
          checkSelectMetadata(rset, 3);
  
          // Close this and grab the next result set
          Assert.assertTrue(stmt.getMoreResults(Statement.CLOSE_CURRENT_RESULT));
          Assert.assertTrue(rset.isClosed());
          ResultSet rset2 = stmt.getResultSet();
          Assert.assertTrue(rset2 instanceof AskResults);
          checkAskMetadata(rset2);
  
          // Closing the statement should clean up any open result sets even if we
          // haven't retrieved them yet or have previously moved past them but
          // left them open
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          Assert.assertTrue(rset2.isClosed());
  
          // Clean up
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_07() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          stmt.addBatch("ASK WHERE { }");
          stmt.addBatch("CONSTRUCT WHERE { ?s ?p ?o }");
          stmt.addBatch("DESCRIBE <http://example>");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(4, batchResults.length);
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[1], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[2], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[3], Statement.SUCCESS_NO_INFO);
  
          // Get first result set
          ResultSet rset = stmt.getResultSet();
          Assert.assertTrue(rset instanceof SelectResults);
          checkSelectMetadata(rset, 3);
  
          // Leave open and grab the next result set
          Assert.assertTrue(stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT));
          Assert.assertFalse(rset.isClosed());
          ResultSet rset2 = stmt.getResultSet();
          Assert.assertTrue(rset2 instanceof AskResults);
          checkAskMetadata(rset2);
  
          // Leave open and grab the next result set
          Assert.assertTrue(stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT));
          Assert.assertFalse(rset.isClosed());
          Assert.assertFalse(rset2.isClosed());
          ResultSet rset3 = stmt.getResultSet();
          Assert.assertTrue(rset3 instanceof TripleIteratorResults);
          checkConstructDescribeMetadata(rset3);
  
          // Grab next result set closing all previous
          Assert.assertTrue(stmt.getMoreResults(Statement.CLOSE_ALL_RESULTS));
          Assert.assertTrue(rset.isClosed());
          Assert.assertTrue(rset2.isClosed());
          Assert.assertTrue(rset3.isClosed());
          ResultSet rset4 = stmt.getResultSet();
          Assert.assertFalse(rset4.isClosed());
          checkConstructDescribeMetadata(rset4);
  
          // Closing the statement should clean up any open result sets even if we
          // haven't retrieved them yet or have previously moved past them but
          // left them open
          stmt.close();
          Assert.assertTrue(stmt.isClosed());
          Assert.assertTrue(rset.isClosed());
          Assert.assertTrue(rset2.isClosed());
  
          // Clean up
          conn.close();
          Assert.assertTrue(conn.isClosed());
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_08() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create a a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          stmt.addBatch("ASK WHERE { }");
          stmt.addBatch("CONSTRUCT WHERE { ?s ?p ?o }");
          stmt.addBatch("DESCRIBE <http://example>");
  
          // Clear the batch
          stmt.clearBatch();
  
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(0, batchResults.length);
  
          stmt.close();
          conn.close();
      }
  
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test(expected = SQLException.class)
      public void connection_statement_batch_09() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          // Create and execute a batch
          stmt.addBatch("SELECT * WHERE { ?s ?p ?o }");
          stmt.addBatch("ASK WHERE { }");
          stmt.addBatch("CONSTRUCT WHERE { ?s ?p ?o }");
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(3, batchResults.length);
          Assert.assertEquals(batchResults[0], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[1], Statement.SUCCESS_NO_INFO);
          Assert.assertEquals(batchResults[2], Statement.SUCCESS_NO_INFO);
  
          // Get first result set
          ResultSet rset = stmt.getResultSet();
          Assert.assertTrue(rset instanceof SelectResults);
          checkSelectMetadata(rset, 3);
  
          try {
              // Not a valid option for what to do with previous results
              stmt.getMoreResults(-1);
          } finally {
              stmt.close();
              conn.close();
          }
      }
      
      /**
       * Runs a batch of operations and checks the results results
       * 
       * @throws SQLException
       */
      @Test
      public void connection_statement_batch_10() throws SQLException {
          JenaConnection conn = this.getConnection();
          conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
          Statement stmt = conn.createStatement();
  
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(0, batchResults.length);
          Assert.assertFalse(stmt.getMoreResults());
  
          stmt.close();
          conn.close();
      }
      
      /**
       * Tests using batches with prepared statements
       * @throws SQLException
       * @throws MalformedURLException 
       */
      @Test
      public void connection_prepared_statement_batch_01() throws SQLException, MalformedURLException {
          JenaConnection conn = this.getConnection();
          PreparedStatement stmt = conn.prepareStatement("SELECT * WHERE { ? ?p ?o }");
          
          for (int i = 1; i <= 5; i++) {
              stmt.setURL(1, new URL("http://example/" + i));
              stmt.addBatch();
          }
          
          int[] batchResults = stmt.executeBatch();
          Assert.assertEquals(5, batchResults.length);
          
          // Expect all to be SELECT results
          ResultSet rset = stmt.getResultSet();
          checkSelectMetadata(rset, 2);
          while (stmt.getMoreResults()) {
              rset = stmt.getResultSet();
              checkSelectMetadata(rset, 2);
          }
          
          stmt.close();
          conn.close();
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_pre_processors_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Adding a null pre-processor has no effect
          conn.addPreProcessor(null);
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Similarly so does removing a null pre-processor
          conn.removePreProcessor(null);
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Inserting a null pre-processor also has no effect
          conn.insertPreProcessor(0, null);
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test(expected = IndexOutOfBoundsException.class)
      public void connection_pre_processors_02() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          Echo echo = new Echo();
  
          // Inserting at zero index should be safe
          conn.insertPreProcessor(0, echo);
          Assert.assertTrue(conn.getPreProcessors().hasNext());
  
          // Inserting at some random index will cause an error
          try {
              conn.insertPreProcessor(50, echo);
          } finally {
              conn.close();
          }
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_pre_processors_03() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Add a pre-processor
          Echo echo = new Echo();
          conn.addPreProcessor(echo);
          Assert.assertTrue(conn.getPreProcessors().hasNext());
  
          // Remove it
          conn.removePreProcessor(echo);
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_pre_processors_04() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Add a pre-processor
          Echo echo = new Echo();
          conn.addPreProcessor(echo);
          Assert.assertTrue(conn.getPreProcessors().hasNext());
  
          // Remove it
          conn.removePreProcessor(0);
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_pre_processors_05() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Add a pre-processor
          Echo echo = new Echo();
          conn.addPreProcessor(echo);
          Assert.assertTrue(conn.getPreProcessors().hasNext());
  
          // Remove all
          conn.clearPreProcessors();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_pre_processors_06() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Add a pre-processor
          Echo echo = new Echo();
          conn.addPreProcessor(echo);
          Assert.assertTrue(conn.getPreProcessors().hasNext());
  
          // Apply the pre-processor
          String input = "SELECT * WHERE { ?s ?p ?o }";
          String output = conn.applyPreProcessors(input);
          Assert.assertEquals(input, output);
  
          conn.close();
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_pre_processors_07() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Add a pre-processor
          Echo echo = new Echo();
          conn.addPreProcessor(echo);
          Assert.assertTrue(conn.getPreProcessors().hasNext());
  
          // Apply the pre-processor
          Query input = QueryFactory.create("SELECT * WHERE { ?s ?p ?o }");
          Query output = conn.applyPreProcessors(input);
          Assert.assertEquals(input, output);
  
          conn.close();
      }
  
      /**
       * Tests pre-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_pre_processors_08() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPreProcessors().hasNext());
  
          // Add a pre-processor
          Echo echo = new Echo();
          conn.addPreProcessor(echo);
          Assert.assertTrue(conn.getPreProcessors().hasNext());
  
          // Apply the pre-processor
          UpdateRequest input = UpdateFactory.create("DELETE WHERE { ?s ?p ?o }");
          UpdateRequest output = conn.applyPreProcessors(input);
          Assert.assertEquals(input, output);
  
          conn.close();
      }
      
      /**
       * Tests post-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_post_processors_01() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          // Adding a null post-processor has no effect
          conn.addPostProcessor(null);
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          // Similarly so does removing a null post-processor
          conn.removePostProcessor(null);
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          // Inserting a null post-processor also has no effect
          conn.insertPostProcessor(0, null);
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests post-processor management operations
       * 
       * @throws SQLException
       */
      @Test(expected = IndexOutOfBoundsException.class)
      public void connection_post_processors_02() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          ResultsEcho echo = new ResultsEcho();
  
          // Inserting at zero index should be safe
          conn.insertPostProcessor(0, echo);
          Assert.assertTrue(conn.getPostProcessors().hasNext());
  
          // Inserting at some random index will cause an error
          try {
              conn.insertPostProcessor(50, echo);
          } finally {
              conn.close();
          }
      }
  
      /**
       * Tests post-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_post_processors_03() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          // Add a post-processor
          ResultsEcho echo = new ResultsEcho();
          conn.addPostProcessor(echo);
          Assert.assertTrue(conn.getPostProcessors().hasNext());
  
          // Remove it
          conn.removePostProcessor(echo);
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests post-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_post_processors_04() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          // Add a post-processor
          ResultsEcho echo = new ResultsEcho();
          conn.addPostProcessor(echo);
          Assert.assertTrue(conn.getPostProcessors().hasNext());
  
          // Remove it
          conn.removePostProcessor(0);
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests post-processor management operations
       * 
       * @throws SQLException
       */
      @Test
      public void connection_post_processors_05() throws SQLException {
          JenaConnection conn = this.getConnection();
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          // Add a post-processor
          ResultsEcho echo = new ResultsEcho();
          conn.addPostProcessor(echo);
          Assert.assertTrue(conn.getPostProcessors().hasNext());
  
          // Remove all
          conn.clearPostProcessors();
          Assert.assertFalse(conn.getPostProcessors().hasNext());
  
          conn.close();
      }
  
      /**
       * Tests error cases trying to set invalid options
       * 
       * @throws SQLException
       */
      @Test(expected = SQLFeatureNotSupportedException.class)
      public void connection_bad_option_01() throws SQLException {
  