JDK-8188051-branch: Updates to sync with AOJ JDK-8188051-branch
authorlancea
Mon, 23 Apr 2018 13:55:47 -0400
branchJDK-8188051-branch
changeset 56475 e700edfac7ad
parent 56420 a5581ec6884a
child 56479 045b7db933bd
JDK-8188051-branch: Updates to sync with AOJ
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaConnectionProperty.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayCountOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Connection.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ConnectionProperty.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/MultiOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/PrimitiveOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/package-info.java
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaConnectionProperty.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaConnectionProperty.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
    */
   CACHING(Caching.class, 
           v -> v instanceof Caching,
-          Caching.CACHED,
+          Caching.AS_NEW,
           false),
   
   /**
@@ -72,9 +72,9 @@
   /**
    *
    */
-  NETWORK_TIMEOUT(Integer.class, 
-          v -> v instanceof Integer && ((int) v) >= 0,
-          Integer.MAX_VALUE,
+  NETWORK_TIMEOUT(Duration.class, 
+          v -> v instanceof Duration && ! ((Duration)v).isNegative(),
+          Duration.ofSeconds(Long.MAX_VALUE),
           false),
 
   /**
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java	Mon Apr 23 13:55:47 2018 -0400
@@ -83,9 +83,9 @@
      */
     VARCHAR,
     /**
-     * Identifies the generic SQL type {@code LONGVARCHAR}.
+     * Identifies the generic SQL type {@code LONG VARCHAR}.
      */
-    LONGVARCHAR,
+    LONG_VARCHAR,
     /**
      * Identifies the generic SQL type {@code DATE}.
      */
@@ -107,9 +107,9 @@
      */
     VARBINARY,
     /**
-     * Identifies the generic SQL type {@code LONGVARBINARY}.
+     * Identifies the generic SQL type {@code LONG VARBINARY}.
      */
-    LONGVARBINARY,
+    LONG_VARBINARY,
     /**
      * Identifies the generic SQL value {@code NULL}.
      */
@@ -172,9 +172,9 @@
      */
     NVARCHAR,
     /**
-     * Identifies the generic SQL type {@code LONGNVARCHAR}.
+     * Identifies the generic SQL type {@code LONG NVARCHAR}.
      */
-    LONGNVARCHAR,
+    LONG_NVARCHAR,
     /**
      * Identifies the generic SQL type {@code NCLOB}.
      */
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayCountOperation.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayCountOperation.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -183,9 +183,6 @@
   public <A, S extends T> ArrayCountOperation<T> collect(Collector<? super Result.Count, A, S> c);
 
   @Override
-  public Submission<T> submit();
-
-  @Override
   public ArrayCountOperation<T> onError(Consumer<Throwable> handler);
 
   @Override
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Connection.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Connection.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 import java.time.Duration;
 import java.util.Map;
 import java.util.concurrent.CompletionStage;
-import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
@@ -38,9 +37,22 @@
  * etc) blocks with the exception of those few methods with "Wait" in their
  * name. Any other method that might block must execute any potentially blocking
  * action in a thread other than the calling thread.
- *
+
+* <p>
  * All methods inherited from OperationGroup throw IllegalStateException if the
- * the connection is not active.
+ * the connection is not active.</p>
+
+* <p>
+ * An implementation of this type must be thread safe as result and error
+ * handlers running asynchronously may be accessing a {@link Connection} in
+ * parallel with each other and with a user thread. {@link Connection}s are not
+ * required to support multiplexed use; a single {@link Connection} should be
+ * used for only one unit of work at a time. Executing independent units of work
+ * on a single {@link Connection} in parallel will most likely lead to
+ * unpredictable outcomes. As a rule of thumb only one user thread should access
+ * a {@link Connection} at a time. Such a user thread should execute a complete
+ * unit of work before another user thread accesses the {@link Connection}. An
+ * implementation may support parallel multiplexed use, but it is not required.</p>
  */
 public interface Connection extends AutoCloseable, OperationGroup<Object, Object> {
 
@@ -238,8 +250,8 @@
      * @param v value for the property
      * @return this {@link Builder}
      * @throws IllegalArgumentException if {@code p.validate(v)} does not return
-     * true or if this method has already been called with the property
-     * {@code p}.
+     * true, if this method has already been called with the property
+     * {@code p}, or the implementation does not support the {@link ConnectionProperty}.
      */
     public Builder property(ConnectionProperty p, Object v);
 
@@ -250,7 +262,9 @@
      * a server. The lifecycle of the new {@link Connection} is {@link Lifecycle#NEW}.
      *
      * @return a {@link Connection}
-     * @throws IllegalStateException if this method has already been called.
+     * @throws IllegalStateException if this method has already been called or
+     * if the implementation cannot create a Connection with the specified
+     * {@link ConnectionProperty}s.
      */
     public Connection build();
   }
@@ -335,7 +349,8 @@
    * that at some point between the beginning and end of the {@link Operation}
    * the Connection was working properly to the extent specified by {@code depth}.
    * There is no guarantee that the {@link Connection} is still working after 
-   * completion.
+   * completion. If the {@link Connection} is not valid the Operation completes
+   * exceptionally.
    *
    * @param depth how completely to check that resources are available and
    * operational. Not {@code null}.
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ConnectionProperty.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ConnectionProperty.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,8 @@
  * {@link Connection}s. The {@link Connection.Builder#property} method is used to set the values
  * of {@link Connection} properties.
  * 
+ * Implementations must be thread safe.
+ * 
  */
 public interface ConnectionProperty {
 
@@ -54,7 +56,7 @@
    * {@code true} if {@code value} is valid and {@code false} otherwise.
    * 
    * @param value a value for this {@link ConnectionProperty}
-   * @return {@code true} if {@code value} is valid for this {@link ConnectionProperty}
+   * @return {@code true} iff {@code value} is valid for this {@link ConnectionProperty}
    */
   public default boolean validate(Object value) {
     return (value == null && this.range() == Void.class) || this.range().isInstance(value);
@@ -74,7 +76,7 @@
    * Returns true if this {@link ConnectionProperty} is contains sensitive information
    * such as a password or encryption key.
    *
-   * @return true if this is sensitive
+   * @return true iff this is sensitive
    */
   public boolean isSensitive();
 
@@ -87,7 +89,7 @@
    * in the {@link Connection.Builder#property} method. ConnectionProperties known to the implementation
    * may return {@code null} and rely on the implementation to do the right thing.
    *
-   * @param <S> Operation Type
+   * @param <S>
    * @param group an {@link OperationGroup} which will be the container of the returned
    * {@link Operation}, if any
    * @param value the value to which the property is to be set. May be null if
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,8 @@
 /**
  * Uses the builder pattern to get a {@link Connection}. A {@link getConnection}
  * method is provided as a convenience.
+ * 
+ * Implementations must be thread safe.
  */
 public interface DataSource
         extends AutoCloseable {
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,14 +24,16 @@
  */
 package jdk.incubator.sql2;
 
-import java.util.Objects;
 import java.util.ServiceLoader;
 import java.util.ServiceLoader.Provider;
+import java.util.function.Function;
 
 /**
  * This interface supports injecting a {@link DataSourceFactory}. The SPI
  * mechanism will find {@link DataSourceFactory} implementations with the
  * given class name.
+ * 
+ * Implementations must be thread safe.
  *
  */
 public interface DataSourceFactory {
@@ -43,10 +45,9 @@
    * @param name the name of the class that implements the factory
    * @return a {@link DataSourceFactory} for {@code name} or {@code null} if one
    * is not found
-   * @throws NullPointerException if name is {@code null}
    */
   public static DataSourceFactory forName(String name) {
-    Objects.requireNonNull(name, "DataSourceFactory name is null");
+    if (name == null) throw new IllegalArgumentException("DataSourceFactory name is null");
     return ServiceLoader
             .load(DataSourceFactory.class)
             .stream()
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  * 
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 import java.util.function.Consumer;
 
 /**
- * An {@link Operation} that calls a user defined function when executed. Does
+ * An {@link Operation} that executes a user defined action when executed. Does
  * not perform any database action. The result of a {@link LocalOperation} is
  * the result of calling the {@link Callable}. This type allows user code to
  * execute arbitrary code at particular points in the sequence of
@@ -41,18 +41,18 @@
 public interface LocalOperation<T> extends Operation<T> {
 
   /**
-   * Provides a result processor for this {@link Operation}. The result
-   * processor is called when this {@link LocalOperation} is executed. The
-   * result of this {@link LocalOperation} is the result of calling
-   * {@code callable}.
+   * Provides an action for this {@link Operation}. The action is called when this
+   * {@link LocalOperation} is executed. The result of this {@link LocalOperation} 
+   * is the result of executing the action.
+   * 
+   * ISSUE: Should this use Supplier rather than Callable?
    *
-   * @param callable the result processor called when this {@link Operation} is
-   * executed
+   * @param action called when this {@link Operation} is executed
    * @return this {@link LocalOperation}
    * @throws IllegalStateException if this method has already been called or
    * this {@link Operation} has been submitted.
    */
-  public LocalOperation<T> onExecution(Callable<T> callable);
+  public LocalOperation<T> onExecution(Callable<T> action);
 
   @Override
   public LocalOperation<T> onError(Consumer<Throwable> handler);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/MultiOperation.java	Mon Apr 23 13:55:47 2018 -0400
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.sql2;
+
+import java.time.Duration;
+import java.util.concurrent.CompletionStage;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * A multi-operation is an {@link Operation} that returns one or more results in
+ * addition to the out result defined by the {@link Operation}. Each result is
+ * processed by an Operation. The Operations can be created by calling rowOperation,
+ * rowProcessorOperation, or countOperation if the kind of results is known. These
+ * results are processed in the order the Operations are submitted. Any results
+ * not processed by an explicit Operation is processed by calling the appropriate
+ * handler specified by onRows or onCount. If any result is an error that error
+ * is processed by calling the handler specified by onError. If the appropriate
+ * handler is not specified that result is ignored, including errors.
+ * 
+ * ISSUE: Should this have a collector?
+ *
+ * @param <T> The type of the result of this {@link Operation}
+ */
+public interface MultiOperation<T> extends OutOperation<T> {
+
+  /**
+   * Returns a {@link RowOperation} to process a row sequence result. The
+   * {@link Operation}s are executed in the order they are submitted. If a
+   * result is of the wrong type for the next submitted {@link Operation} the
+   * {@link MultiOperation} is completed with
+   * {@link IllegalStateException}.
+   *
+   * @return a {@link RowOperation} that is part of this {@link MultiOperation}
+   */
+  public RowOperation<T> rowOperation();
+
+  /**
+   * Returns a {@link RowProcessorOperation} to process a row sequence result. The
+   * {@link Operation}s are executed in the order they are submitted. If a
+   * result is of the wrong type for the next submitted {@link Operation} the
+   * {@link MultiOperation} is completed with
+   * {@link IllegalStateException}.
+   *
+   * @return a {@link RowProcessorOperation} that is part of this {@link MultiOperation}
+   */
+  public RowProcessorOperation<T> rowProcessorOperation();
+
+  /**
+   * Returns a {@link CountOperation} to process a count result. The {@link Operation}s
+   * are executed in the order they are submitted. If a result is of the wrong
+   * type for the next submitted Operation the {@link MultiOperation} is completed
+   * with {@link IllegalStateException}.
+   *
+   * @return a {@link CountOperation} that is part of this {@link MultiOperation}
+   */
+  public CountOperation<T> countOperation();
+
+  /**
+   * Provides a handler for trailing count results. The provided handler is called for
+   * each count result not processed by CountOperation. When called the first argument is the number of results
+   * that preceeded the current result. The second argument is a
+   * {@link CountOperation} that will process the current result. This
+   * {@link CountOperation} has not been configured in any way nor has it been
+   * submitted. The handler configures the {@link CountOperation} and submits
+   * it. The count result is processed when the {@link CountOperation} is
+   * submitted. If the {@link CountOperation} is not submitted when the handler
+   * returns the count result is ignored.
+   * 
+   * If this method is not called any trailing count results are ignored.
+   *
+   * @param handler not null
+   * @return this MultiOperation
+   * @throws IllegalStateException if this method was called previously
+   */
+  public MultiOperation<T> onCount(BiConsumer<Integer, CountOperation<T>> handler);
+
+  /**
+   * Provides a handler for trailing row sequence results. The provided handler is called
+   * for each row sequence result not processed by a RowOperation. When called the first argument is the number
+   * of results that preceeded the current result. The second argument is a
+   * {@link RowOperation} that will process the current result. This
+   * {@link RowOperation} has not been configured in any way nor has it been
+   * submitted. The handler configures the {@link RowOperation} and submits it.
+   * The row sequence result is processed when the {@link RowOperation} is
+   * submitted. If the {@link RowOperation} is not submitted when the handler
+   * returns, the row sequence result is ignored.
+   * 
+   * If this method is not called any trailing row sequence results are ignored.
+   * 
+   * ISSUE: Should there be a version of this method that provides 
+   * RowProcessorOperations? If so only one of that method or this one can be called.
+   *
+   * @param handler
+   * @return This MultiOperation
+   * @throws IllegalStateException if this method was called previously
+   */
+  public MultiOperation<T> onRows(BiConsumer<Integer, RowOperation<T>> handler);
+  
+  /**
+   * Provides an error handler for this {@link Operation}. The provided handler 
+   * is called for each error that occurs. When called the first argument is the 
+   * number of results, including errors, that preceeded the current error. The
+   * second argument is a {@link Throwable} corresponding to the error. When the
+   * handler returns processing of the MultiOperation results continues. 
+   * Only one onError method may be called.
+   * 
+   * @param handler a BiConsumer that handles an error
+   * @return this MultiOperation
+   * @throws IllegalStateException if this method was called previously
+   */
+  public MultiOperation<T> onError(BiConsumer<Integer, Throwable> handler);
+  // Covariant overrides
+
+  /**
+   * This handler is called if the execution fails completely. If the execution
+   * returns any individual results, even if any or all of those results are
+   * errors, this handler is not called.
+   * 
+   * @param handler
+   * @return 
+   */
+  @Override
+  public MultiOperation<T> onError(Consumer<Throwable> handler);
+  
+  @Override
+  public MultiOperation<T> apply(Function<Result.OutParameterMap, ? extends T> processor);
+
+  @Override
+  public MultiOperation<T> outParameter(String id, SqlType type);
+
+  @Override
+  public MultiOperation<T> set(String id, Object value, SqlType type);
+
+  @Override
+  public MultiOperation<T> set(String id, Object value);
+
+  @Override
+  public MultiOperation<T> set(String id, CompletionStage<?> source, SqlType type);
+
+  @Override
+  public MultiOperation<T> set(String id, CompletionStage<?> source);
+
+  @Override
+  public MultiOperation<T> timeout(Duration minTime);
+
+}
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,21 +33,37 @@
  * {@link OperationGroup}, configured and submitted. If not submitted it is not
  * executed. If submitted it is possibly executed according to the attributes of
  * the {@link OperationGroup} that created it.
- *
- * Note: A {@link Connection} is an {@link OperationGroup} and so can create
- * {@link Operation}s.
+ * 
+ * <p>
+ * If execution of the work results in an error, the Operation is completed
+ * exceptionally. The {@link Throwable} that completes the Operation is
+ * implementation dependent. It is recommended that an implementation use
+ * SqlException in the event of database problems. Other {@link Throwable}s such
+ * as {@link java.io.IOException}, {@link NullPointerException}, etc can be used
+ * as appropriate. An implementation should not wrap a useful exception in a
+ * {@link SqlException} unless that provides valuable additional information. An
+ * implementation should use whatever {@link Throwable} best facilitates
+ * appropriate error handling.</p>
+ * 
+ * <p>
+ * An Operation is not required to be thread safe. In general a single user
+ * thread will configure and submit an Operation. Once an Operation is submitted
+ * it is immutable. {@link OperationGroup} is an exception and is thread safe.</p>
  *
  * @param <T> the type of the result of the {@link Operation}
  */
-public interface Operation<T> {
+public interface Operation<T> extends PrimitiveOperation<T> {
   
   /**
    * Provides an error handler for this {@link Operation}. If execution of this
    * {@link Operation} results in an error, before the Operation is completed,
-   * the handler is called with the {@link Throwable} as the argument.
+   * the handler is called with the {@link Throwable} as the argument. The type
+   * of the {@link Throwable} is implementation dependent.
    * 
-   * @param handler the error handler for this operation
+   * @param handler
    * @return this {@link Operation}
+   * @throws IllegalStateException if this method is called more than once on
+   * this operation
    */
   public Operation<T> onError(Consumer<Throwable> handler);
   
@@ -63,23 +79,11 @@
    *
    * @param minTime minimum time to wait before attempting to cancel
    * @return this Operation
-   * @throws IllegalArgumentException if minTime &lt;= 0 seconds
+   * @throws IllegalArgumentException if minTime &lt;= {@link java.time.Duration#ZERO}
    * @throws IllegalStateException if this method is called more than once on
    * this operation
    */
   public Operation<T> timeout(Duration minTime);
 
-  /**
-   * Add this {@link Operation} to the tail of the {@link Operation} collection
-   * of the {@link Connection} that created this {@link Operation}. An
-   * {@link Operation} can be submitted only once. Once an {@link Operation} is
-   * submitted it is immutable. Any attempt to modify a submitted
-   * {@link Operation} will throw {@link IllegalStateException}.
-   *
-   * @return a {@link Submission} for this {@link Operation}
-   * @throws IllegalStateException if this method is called more than once on
-   * this operation
-   */
-  public Submission<T> submit();
 
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,58 +32,80 @@
 import java.util.stream.Collector;
 
 /**
+ * <p>
  * A set of {@link Operation}s that share certain properties, are managed as a
  * unit, and are executed as a unit. The {@link Operation}s created by an
  * {@link OperationGroup} and submitted are the member {@link Operation}s of
  * that {@link OperationGroup}. An {@link OperationGroup} is not a transaction
- * and is not related to a transaction in any way.
+ * and is not related to a transaction in any way.</p>
  *
+ * <p>
  * An {@link OperationGroup} conceptually has a collection of member
  * {@link Operation}s. When an {@link OperationGroup} is submitted it is placed
  * in the collection of the {@link OperationGroup} of which it is a member. The
  * member {@link OperationGroup} is executed according to the attributes of the
  * {@link OperationGroup} of which it is a member. The member {@link Operation}s
  * of an {@link OperationGroup} are executed according to the attributes of that
- * {@link OperationGroup}.
+ * {@link OperationGroup}.</p>
  *
- * How an {@link OperationGroup} is executed depends on its attributes.
+ * <p>
+ * How an {@link OperationGroup} is executed depends on its attributes.</p>
  *
+ * <p>
  * If an {@link OperationGroup} has a condition and the value of that condition
  * is {@link Boolean#TRUE} then execute the member {@link Operation}s as below.
  * If it is {@link Boolean#FALSE} then the {@link OperationGroup} is completed
  * with the value null. If the condition completed exceptionally then the
  * {@link OperationGroup} is completed exceptionally with a
- * {@link SqlSkippedException} that has that exception as its cause.
- *
+ * {@link SqlSkippedException} that has that exception as its cause.</p>
+ * 
+ * <p>
  * If the {@link OperationGroup} is sequential the member {@link Operation}s are
  * executed in the order they were submitted. If it is parallel, they may be
- * executed in any order including simultaneously.
+ * executed in any order including simultaneously.</p>
  *
+ * <p>
  * If an {@link OperationGroup} is dependent and a member {@link Operation}
  * completes exceptionally the remaining member {@link Operation}s in the
  * collection are completed exceptionally with a {@link SqlSkippedException}
  * that has the initial {@link Exception} as its cause and the {@link OperationGroup}
  * is completed exceptionally with the initial {@link Exception}. A member
  * {@link Operation} in-flight may either complete normally or be completed
- * exceptionally but must complete one way or the other. [NOTE: Too strong?]
+ * exceptionally but must complete one way or the other. [NOTE: Too strong?]</p>
  *
+ * <p>
+ * After a call to {@link OperationGroup#submitHoldingForMoreMembers) the
+ * {@link OperationGroup} is submitted and held. After a call to 
+ * {@link OperationGroup#releaseProhibitingMoreMembers} the {@link OperationGroup} 
+ * is no longer held and is still submitted. Holding permits member {@link Operation}s
+ * to be executed at the same time additional member {@link Operation}s are
+ * submitted. Collecting the member {@link Opreation}s' results does not begin
+ * until the {@link OperationGroup} is no longer held.</p>
+ * 
+ * <p>
  * If an {@link OperationGroup} is held additional member {@link Operation}s may
- * be submitted after the {@link OperationGroup} is submitted. If an
- * {@link OperationGroup} is not held, no additional member {@link Operation}s
- * may be submitted after the {@link OperationGroup} is submitted. If an
- * {@link OperationGroup} is held it will be completed only after it is released
- * or if conditional and the condition is not {@link Boolean#TRUE}. If a
- * {@link OperationGroup} is dependent, held, one of its member
+ * be submitted. If an {@link OperationGroup} is not held, no additional member 
+ * {@link Operation}s  may be submitted after the {@link OperationGroup} is 
+ * submitted. If an {@link OperationGroup} is held it will be completed only after 
+ * it is released or if conditional and the condition is not {@link Boolean#TRUE}. 
+ * If a {@link OperationGroup} is dependent, held, one of its member
  * {@link Operation}s completed exceptionally, and its queue is empty then the
- * {@link OperationGroup} is released.
+ * {@link OperationGroup} is released.</p>
  *
+ * <p>
  * The result of this {@link OperationGroup} is the result of collecting the
  * results of its member {@link Operation}s. If the {@link OperationGroup} is 
  * dependent and one of its member {@link Operation}s completes exceptionally,
- * the {@link OperationGroup} is completed exceptionally.
- *
- * ISSUE: Currently no way to create a nested {@link OperationGroup}. That is a
- * intentional limitation but may be a simplification we can live with. Or not.
+ * the {@link OperationGroup} is completed exceptionally.</p>
+ * 
+ * <p>
+ * An implementation of this class must be thread safe as result and error
+ * handlers running asynchronously may be accessing an {@link OperationGroup} in
+ * parallel with each other and with a user thread.</p>
+
+* <p>
+ * ISSUE: Currently no way to create a nested {@link OperationGroup}. That is an
+ * intentional limitation but may be a simplification we can live with. Or not.</p>
  *
  * @param <S> The type of the result of the member {@link Operation}s
  * @param <T> The type of the collected results the member {@link Operation}s
@@ -103,7 +125,8 @@
    *
    * @return this {@link OperationGroup}
    * @throws IllegalStateException if this {@link OperationGroup} has been
-   * submitted or any member {@link Operation}s have been created.
+   * submitted, any member {@link Operation}s have been created, or this method
+   * has been called previously
    */
   public OperationGroup<S, T> parallel();
 
@@ -124,9 +147,9 @@
    * as there is only a small likelihood of needing it.
    *
    * @return this {@link OperationGroup}
-   * @throws IllegalStateException f this {@link OperationGroup} blocks errors
-   * or if this {@link OperationGroup} has been submitted or any member
-   * {@link Operation}s have been created
+   * @throws IllegalStateException if this {@link OperationGroup} has been 
+   * submitted, any member {@link Operation}s have been created, or this method
+   * has been called previously
    */
   public OperationGroup<S, T> independent();
 
@@ -149,18 +172,23 @@
    * @param condition a {@link CompletionStage} the value of which determines
    * whether this {@link OperationGroup} is executed or not
    * @return this OperationGroup
-   * @throws IllegalStateException iif this {@link OperationGroup} has been
-   * submitted or any member {@link Operation}s have been created
+   * @throws IllegalStateException if this {@link OperationGroup} has been
+   * submitted, any member {@link Operation}s have been created, or this method
+   * has been called previously
    */
   public OperationGroup<S, T> conditional(CompletionStage<Boolean> condition);
 
   /**
-   * Mark this {@link OperationGroup} as held. It can be executed but cannot be
+   * Mark this {@link OperationGroup} as submitted and held. It can be executed but cannot be
    * completed. A {@link OperationGroup} that is held remains in the queue even
    * if all of its current member {@link Operation}s have completed. So long as
    * the {@link OperationGroup} is held new member {@link Operation}s can be
    * submitted. A {@link OperationGroup} that is held must be released before it
    * can be completed and removed from the queue.
+   * 
+   * If the {@link OperationGroup} is dependent and one of its member {@link Operation]s
+   * completes exceptionally and its queue is empty the {@link OperationGroup}
+   * is completed.
    *
    * Note: There is no covariant override of this method in Connection as there
    * is only a small likelihood of needing it.
@@ -191,7 +219,7 @@
    *
    * @return this OperationGroup
    * @throws IllegalStateException if this {@link OperationGroup} has been
-   * completed
+   * completed or is not held.
    */
   public OperationGroup<S, T> releaseProhibitingMoreMembers();
 
@@ -221,18 +249,26 @@
   public OperationGroup<S, T> collect(Collector<S, ?, T> c);
   
   /**
-   * Returns an Operation that is never skipped. Skipping stops with a catchOperation
-   * and the subsequent Operation is executed normally. The value of a 
-   * catchOperation is always null.
-   * 
-   * @return an unskippable Operation;
+   * Return a new member {@link PrimitiveOperation} that is never skipped.
+   * Skipping of member {@link Opreation}s stops with a catchOperation and the
+   * subsequent {@link Operation} is executed normally. The value of a
+   * catchOperation is always null. Since a catchOperation is never completed
+   * exceptionally, it has no error handler or timeout.
+   *
+   * @return an {@link PrimitiveOperation} that is never skipped;
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held or if the {@link OperationGroup} is parallel or
+   * independent.
    */
-  public Operation<S> catchOperation();
+  public PrimitiveOperation<S> catchOperation();
   
   /**
    * Creates and submits a catch Operation. Convenience method.
    *
    * @return this OperationGroup
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held or if the {@link OperationGroup} is parallel or
+   * independent.
    */
   public default OperationGroup<S, T> catchErrors() {
     catchOperation().submit();
@@ -255,6 +291,8 @@
    * @param sql SQL to be executed. Must return an update count.
    * @return a new {@link ArrayCountOperation} that is a member of this
    * {@link OperationGroup}
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held
    */
   public <R extends S> ArrayCountOperation<R> arrayCountOperation(String sql);
 
@@ -265,7 +303,8 @@
    * @param sql SQL to be executed. Must return an update count.
    * @return an new {@link CountOperation} that is a member of this
    * {@link OperationGroup}
-   *
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held
    */
   public <R extends S> ParameterizedCountOperation<R> countOperation(String sql);
 
@@ -276,59 +315,71 @@
    * @param sql SQL for the {@link Operation}.
    * @return a new {@link Operation} that is a member of this
    * {@link OperationGroup}
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held
    */
   public Operation<S> operation(String sql);
 
   /**
-   * Return a new {@link OutOperation}. The SQL must return a set of zero or
-   * more out parameters or function results.
+   * Return a new {@link OutOperation} that is a member {@link Operation} of this 
+   * {@link OperationGroup}. The SQL must return a set of zero or more out 
+   * parameters or function results.
    *
    * @param <R> the result type of the returned {@link OutOperation}
    * @param sql SQL for the {@link Operation}. Must return zero or more out
    * parameters or function results.
    * @return a new {@link OutOperation} that is a member of this
    * {@link OperationGroup}
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held
    */
   public <R extends S> OutOperation<R> outOperation(String sql);
 
   /**
-   * Return a {@link ParameterizedRowOperation}.
+   * Return a new {@link ParameterizedRowOperation} that is a member 
+   * {@link Operation} of this {@link OperationGroup}.
    *
    * @param <R> the type of the result of the returned
    * {@link ParameterizedRowOperation}
    * @param sql SQL for the {@link Operation}. Must return a row sequence.
    * @return a new {@link ParameterizedRowOperation} that is a member of this
    * {@link OperationGroup}
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held
    */
   public <R extends S> ParameterizedRowOperation<R> rowOperation(String sql);
 
+  /**
+   * Return a new {@link RowProcessorOperation} that is a member {@link Operation} 
+   * of this {@link OperationGroup}.
+   * 
+   * @param <R> the type of the result of the returned
+   * {@link RowProcessorOperation}
+   * @param sql SQL for the {@link Operation}. Must return a row sequence.
+   * @return a new {@link RowProcessorOperation} that is a member of this
+   * {@link OperationGroup}
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held
+   */
   public <R extends S> RowProcessorOperation<R> rowProcessorOperation(String sql);
 
   /**
-   * Return a {@link StaticMultiOperation}.
+   * Return a new {@link MultiOperation} that is a member 
+   * {@link Operation} of this {@link OperationGroup}.
    *
    * @param <R> the type of the result of the returned
-   * {@link StaticMultiOperation}
+   * {@link MultiOperation}
    * @param sql SQL for the {@link Operation}
-   * @return a new {@link StaticMultiOperation} that is a member of this
+   * @return a new {@link MultiOperation} that is a member of this
    * {@link OperationGroup}
+   * @throws IllegalStateException if the {@link OperationGroup} has been
+   * submitted and is not held
    */
-  public <R extends S> StaticMultiOperation<R> staticMultiOperation(String sql);
+  public <R extends S> MultiOperation<R> multiOperation(String sql);
 
   /**
-   * Return a {@link DynamicMultiOperation}. Use this when the number and type
-   * of the results is not knowable.
-   *
-   * @param <R> the type of the result of the returned
-   * {@link DynamicMultiOperation}
-   * @param sql SQL for the {@link Operation}
-   * @return a new {@link DynamicMultiOperation} that is a member of this
-   * {@link OperationGroup}
-   */
-  public <R extends S> DynamicMultiOperation<R> dynamicMultiOperation(String sql);
-
-  /**
-   * Return an {@link Operation} that ends the database transaction. The
+   * Return a new {@link Operation} that ends the database transaction.  This
+   * {@link Operation} is a member of the {@link OperationGroup}. The
    * transaction is ended with a commit unless the {@link Transaction} has been
    * {@link Transaction#setRollbackOnly} in which case the transaction is ended
    * with a rollback.
@@ -349,7 +400,7 @@
    * {@link Operation} that commits by default but can be set to rollback by
    * calling {@link Transaction#setRollbackOnly}.
    *
-   * @param trans the Transaction that determines whether the Operation is a
+   * @param trans the Transaction that determines whether the {@link Operation} is a
    * database commit or a database rollback.
    * @return this {@link OperationGroup}
    * @throws IllegalStateException if this {@link OperationGroup} has been
@@ -360,11 +411,12 @@
   }
 
   /**
-   * Return a {@link LocalOperation}.
+   * Return a new {@link LocalOperation} that is a member {@link Operation} of 
+   * this {@link OperationGroup}.
    *
-   * @param <R> value type of the returned local Operation
+   * @param <R> value type of the returned local {@link Operation}
    * @return a LocalOperation
-   * @throws IllegalStateException if this OperationGroup has been submitted and
+   * @throws IllegalStateException if this {@link OperationGroup} has been submitted and
    * is not held
    */
   public <R extends S> LocalOperation<R> localOperation();
@@ -399,10 +451,11 @@
    * rather than passing it to onNext, the Submission returned by the submit
    * call will not be published.
    *
-   * @param <R> the type of the result of the returned
-   * {@link Flow.Processor}
-   * @return a Flow.Processor that accepts Operations and generates Submissions
-   * @throws IllegalStateException if there is an active Processor
+   * @param <R>
+   * @return a Flow.Processor that accepts {@link Operation}s and generates 
+   * {@link Submission}s
+   * @throws IllegalStateException if there is an active Processor or if this
+   * {@link OperationGroup} is submitted and not held
    */
   public <R extends S> Flow.Processor<Operation<R>, Submission<R>> operationProcessor();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/PrimitiveOperation.java	Mon Apr 23 13:55:47 2018 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.incubator.sql2;
+
+/**
+ * A PrimitiveOperation can be submitted, nothing more. Used only by
+ * {@link OperationGroup#catchOperation} and as a supertype to {@link Operation}.
+ * 
+ * References in JavaDoc to the "collection of Operations" and "member
+ * Operations" should be understood to include PrimitiveOperations. The
+ * distinction between {@link Operation} and {@link PrimitiveOperation} in the
+ * API is strictly followed as it enables the compiler to catch a significant
+ * class of errors. The two types are not distinguished in the JavaDoc as making 
+ * such a distinction would not add clarity.
+ * 
+ * @see {@link Operation}
+ * @see {@link OperationGroup#catchOperation}
+ */
+public interface PrimitiveOperation<T> {
+
+  /**
+   * Add this {@link PrimitiveOperation} to the tail of the {@link Operation}
+   * collection of the {@link Connection} that created this
+   * {@link PrimitiveOperation}. A {@link PrimitiveOperation} can be submitted
+   * only once. Once a {@link PrimitiveOperation} is submitted it is immutable.
+   * Any attempt to modify a submitted {@link PrimitiveOperation} will throw
+   * {@link IllegalStateException}.
+   *
+   * @return a {@link Submission} for this {@link PrimitiveOperation}
+   * @throws IllegalStateException if this method is called more than once on
+   * this {@link PrimitiveOperation}
+   */
+  Submission<T> submit();
+
+}
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,40 +54,33 @@
 
   /**
    */
-  private String sqlState = null;
+  private final String sqlState;
 
   /**
    */
-  private int vendorCode = -1;
+  private final int vendorCode;
 
   /**
    * The SQL string that was sent to the database.
    */
-  private String sqlString = null;
+  private final String sqlString;
 
   /**
    * The index of the first character in SQL where an error is detected. Zero
    * based.
    */
-  private int position = -1;
+  private final int position;
   
   // Constructors
 
-  private SqlException() {
-    super();
-  }
-
   /**
    *
-   * @param message a description of the exception
-   * @param cause the underlying reason for this SqlException
-   * (which is saved for later retrieval by the getCause() method);
-   * may be null indicating the cause is non-existent or unknown.
-   * @param sqlState an XOPEN or SQL:2003 code identifying the exception
-   * @param vendorCode a database vendor-specific exception code
-   * @param sql the SQL string that was sent to the database
-   * @param position the index of the first character in SQL where an error is detected. Zero
-   * based
+   * @param message
+   * @param cause
+   * @param sqlState
+   * @param vendorCode
+   * @param sql
+   * @param position
    */
   public SqlException(String message, Throwable cause, String sqlState, int vendorCode, String sql, int position) {
     super(message, cause);
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,17 +40,30 @@
 
   /**
    *
-   * @param message a description of the exception
-   * @param cause the underlying reason for this SqlSkippedException
-   * (which is saved for later retrieval by the getCause() method);
-   * may be null indicating the cause is non-existent or unknown.
-   * @param sqlState an XOPEN or SQL:2003 code identifying the exception
-   * @param vendorCode a database vendor-specific exception code
-   * @param sql the SQL string that was sent to the database
-   * @param position the index of the first character in SQL where an error is detected. Zero
-   * based
+   * @param message
+   * @param cause
+   * @param sqlState
+   * @param vendorCode
+   * @param sql
+   * @param position
    */
   public SqlSkippedException(String message, Throwable cause, String sqlState, int vendorCode, String sql, int position) {
     super(message, cause, sqlState, vendorCode, sql, position);
   }
+  
+  /**
+   *
+   * @param cause
+   */
+  public SqlSkippedException(SqlException cause) {
+    super(cause.getMessage(), cause, cause.getSqlState(), cause.getVendorCode(), cause.getSqlString(), cause.getPosition());
+  }
+  
+  /**
+   *
+   * @param cause
+   */
+  public SqlSkippedException(Throwable cause) {
+    super(cause.getMessage(), cause, null, -1, null, -1);
+  }
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/package-info.java	Wed Apr 11 11:25:58 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/package-info.java	Mon Apr 23 13:55:47 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c)  2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c)  2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,8 +65,8 @@
  * <p>
  * Possibly blocking actions are represented as {@link Operation}s. An
  * application using the API creates and submits one or more {@link Operation}s.
- * The driver executes these {@link Operation}s asynchronously, reporting their
- * results via {@link java.util.concurrent.CompletionStage}s. An application
+ * The implementation executes these {@link Operation}s asynchronously, reporting 
+ * their results via {@link java.util.concurrent.CompletionStage}s. An application
  * can respond to the results via the
  * {@link java.util.concurrent.CompletionStage}s or via callbacks that can be
  * configured on many of the {@link Operation}s or both. Creating and submitting
@@ -134,7 +134,7 @@
  *
  * <p>
  * One way this API simplifies things in to define types as single use. Many
- * types are created, configured, used once, and are then no longer usable. Many
+ * types are created, configured, used once, and are then no longer usable. Most
  * configuration methods can be called only once on a given instance. Once an
  * instance is configured it cannot be reconfigured. Once an instance is used it
  * cannot be reused. This simplifies things by eliminating the need to
@@ -177,6 +177,17 @@
  * <p>
  * Note: It would be a reasonable future project to develop a SQL builder API
  * that creates vendor specific SQL from some more abstract representation.</p>
+ * 
+ * <p>
+ * This API is targeted at high-throughput apps. If a particular feature of this
+ * API would have a surprising performance impact for a particular implementation
+ * it is recommended that the implementation not implement that feature. It is
+ * better that a feature be unsupported as opposed to users investing substantial
+ * effort in an app using that feature only to discover in production that the
+ * performance is unacceptable. For example, if an implementation can only support
+ * {@link Operation#timeout} through active polling it would be better for that
+ * implementation to throw {@link UnsupportedFeatureException} if 
+ * {@link Operation#timeout} is called.</p>
  *
  * <h3>Execution Model</h3>
  *
@@ -241,9 +252,16 @@
  * flight {@link Operation} may either be allowed to complete uninterrupted or
  * it may be completed exceptionally. The {@link OperationGroup} is completed
  * exceptionally with the {@link Throwable} that caused the {@link Operation} to
- * complete exceptionally. Note: the {@link Operation} returned by
- * {@link Connection#closeOperation} is never skipped, i.e. never completed
- * exceptionally with {@link SqlSkippedException}. It is always executed.</li>
+ * complete exceptionally. 
+ * 
+ * <p>
+ * Note: the {@link Operation}s returned by {@link Connection#closeOperation}
+ * and {@link OperationGroup#catchOperation) are never skipped, i.e. never 
+ * completed exceptionally with {@link SqlSkippedException}. The {@link Operation}
+ * returned by {@link OperationGroup#catchOperation} never completes 
+ * execeptionally so the following {@link Operation} is always executed normally. 
+ * No {@link Operation} can be submitted after the {@link Operation} returned by 
+ * {@link Connection#closeOperation} has been submitted.</p> </li>
  * <li>
  * If the {@link OperationGroup} is independent and an {@link Operation}
  * completes exceptionally all other {@link Operation}s are executed regardless.
@@ -280,19 +298,19 @@
  * it might be necessary to rollback the transaction rather than commit it. This
  * determination depends on the execution of the Operations long after the
  * endTransaction Operation is created. To address this mismatch, the endTransaction Operation
- * specified by this API is conditioned by a {@link Transaction}. It commits the 
- * transaction by default, a {@link Transaction} will cause an endTransaciton
- * {@link Operation} to commit the transaction but a Transaction can be set
- * to rollback the transaction at any time before the endTransaction 
- * {@link Operation} that references it is executed.</p>
+ * specified by this API is conditioned by a {@link Transaction}. By default, a 
+ * {@link Transaction} will cause an endTransaciton {@link Operation} to commit 
+ * the transaction. At any time before the endTransaction {@link Operation} that 
+ * references it is executed a {@link Transaction} can be set
+ * to rollback the transaction .</p>
  *
  * <p>
- * An endTransaction Operation, like all Operations, is immutable once submitted.
- * But an endTransaction Operation is created with a Transaction and that
- * Transaction can be set to commit or rollback. A Transaction controls the
- * endTransaction Operation created with it. Using this mechanism an
+ * An endTransaction {@link Operation}, like all {@link Operation}s, is immutable once submitted.
+ * But an endTransaction {@link Operation} is created with a {@link Transaction} and that
+ * {@link Transaction} can be set to commit or rollback. A {@link Transaction} controls the
+ * endTransaction {@link Operation} created with it. Using this mechanism an
  * error handler, result handler or other code can cause a subsequent endTransaction
- * Operation to rollback instead of the default which is to commit.</p>
+ * {@link Operation} to rollback instead of the default which is to commit.</p>
  *
  * <pre>
  * {@code
@@ -303,6 +321,7 @@
  *           return null; 
  *       } )
  *       .submit();
+ *   conn.catchErrors();
  *   conn.commitMaybeRollback(t);
  * }
  * </pre>
@@ -314,122 +333,6 @@
  * the transaction to rollback.</p>
  * 
  *
- * <h3>POJOs</h3>
- * 
- * <p><i>Does this feature carry its weight? It is a nice ease of use feature
- * for hand written code but it is not of much valuable for framework code. It
- * certainly is not strictly necessary. Arguably it should be removed.</i></p>
- *
- * <p>
- * This API supports setting and getting POJOs (Plain Old Java Objects) as
- * parameter values and results. This is not a comprehensive ORM (Object
- * Relational Mapping). It is just a convenience.
- *
- * <p>
- * To set parameters of a SQL statement to the values of a POJO, the type of the
- * POJO must be annotated with the @SqlParameter annotation. One or more public
- * getter methods must be so annotated. The @SqlParameter annotation defines the
- * parameter marker base name and SQL type. The call to the
- * ParameterizedOperation.set method provides the POJO itself and the parameter
- * marker prefix. The implementation binds the return value of the annotated
- * method to the parameter identified by the parameter marker prefix prepended
- * to the parameter marker base name.</p>
- *
- * <pre>
- * {@code
- *   public class Employee {
- *     private String name;
- *     private String department;
- *     \@SqlParameter("name", "VARCHAR")
- *     public String getName() { return name; }
- *     public String getDepartement() { return department; }
- *     \@SqlColumns("name", "dept")
- *     public static Employee createEmployee(String name, String department) {
- *       Employee e = new Employee();
- *       e.name = name;
- *       e.department = department;
- *       return e;
- *     }
- *   }
- *
- *   conn.countOperation("insert into emp values(:emp_name, :emp_dept)")
- *       .set("emp_", employee);
- * }
- * </pre>
- *
- * <p>
- * The above code fragment is identical to</p>
- *
- * <pre>
- * {@code
- *    conn.countOperation("insert into emp values(emp_name, emp_dept)")
- *       .set("emp_name", employee.getName(), JdbcType.VARCHAR);
- *       .set("emp_dept", employee.getDepartment(), JdbcType.VARCHAR)
- * }
- * </pre>
- *
- * <p>
- * The prefix may be the empty string but may not be null. IllegalStateException
- * is thrown if a parameter is set more than once either by a POJO set or a
- * single value set. Implementations may attempt to bind a parameter for every
- * annotated getter method. An implementation is not required to check whether
- * or not there is a parameter with the specified name. It is implementation
- * dependent whether an annotated getter with no corresponding parameter is an
- * error or not and whether the implementation or the database detect it if it
- * is an error.</p>
- *
- * <p>
- * To construct a POJO from the result of an Operation the type of the POJO must
- * be annotated with @SqlColumns. The annotation may be applied to a public
- * static factory method, a public constructor, or one or more public setter
- * methods. If applied to setters, there must be a public zero-arg constructor
- * or public static zero-arg factory method. The annotation provides the base
- * names for column or out parameter marker that provides the value for the
- * corresponding parameter or setter method. The get method call provides the
- * prefix.</p>
- *
- * <pre>
- * {@code
- *     conn.rowOperation("select name, dept from emp")
- *     .collect(Collector.of(
- *         () -> new ArrayList(),
- *         (l, r) -> { 
- *             l.add(r.get("", Employee.class)); 
- *         }
- *         (l, r) -> l
- *     ) )
- * }
- * </pre>
- *
- * <p>
- * The above code fragment is identical to</p>
- *
- * <pre>
- * {@code
- *     conn.rowOperation("select name, dept from emp")
- *     .collect(Collector.of(
- *         () -> new ArrayList(),
- *         (l, r) -> { 
- *             l.add(Employee.createEmployee(r.get("name", String.class), 
- *                                         r.get("dept", String.class))); 
- *         }
- *         (l, r) -> l
- *     ) )
- * }
- * </pre>
- *
- * <p>
- * If more than one factory method, constructor, or set of setters is annotated
- * it is implementation dependent which is used to construct a POJO. An
- * implementation is not required to determine the best choice for any meaning
- * of "best". An implementation my instead throw an exception if more than one
- * alternative is annotated. If setters are annotated an implementation should
- * call every annotated setter. It is implementation dependent whether it
- * attempts to call a subset of the setters if all the columns named in the
- * annotations are not present. In summary, best practice is to annotate exactly
- * what is required and no more and to use exactly what is annotated and no more.
- * </p>
- *
  */
-package jdk.incubator.sql2;
-
+ package jdk.incubator.sql2;
+ 
\ No newline at end of file