docs: public static AdHocPlannedStatement compileAdHocSQL(PlannerTool plannerTool,
                                                          String sqlStatement,
                                                          boolean inferPartitioning,
                                                          Object userPartitionKey,
                                                          ExplainMode explainMode,
                                                          boolean isLargeQuery,
                                                          boolean isSwapTables,
                                                          Object[] userParamSet)
                                                                  throws AdHocPlanningException
      {
          assert(plannerTool != null);
          assert(sqlStatement != null);
          final PlannerTool ptool = plannerTool;
  
          // Take advantage of the planner optimization for inferring single partition work
          // when the batch has one statement.
          StatementPartitioning partitioning = null;
  
          if (inferPartitioning) {
              partitioning = StatementPartitioning.inferPartitioning();
          }
          else if (userPartitionKey == null) {
              partitioning = StatementPartitioning.forceMP();
          }
          else {
              partitioning = StatementPartitioning.forceSP();
          }
  
          try {
              return ptool.planSql(sqlStatement,
                                   partitioning,
                                   explainMode != ExplainMode.NONE,
                                   userParamSet,
                                   isSwapTables,
                                   isLargeQuery);
          }
          catch (Exception e) {
              throw new AdHocPlanningException(e.getMessage());
          }
          catch (StackOverflowError error) {
              // Overly long predicate expressions can cause a
              // StackOverflowError in various code paths that may be
              // covered by different StackOverflowError/Error/Throwable
              // catch blocks. The factors that determine which code path
              // and catch block get activated appears to be platform
              // sensitive for reasons we do not entirely understand.
              // To generate a deterministic error message regardless of
              // these factors, purposely defer StackOverflowError handling
              // for as long as possible, so that it can be handled
              // consistently by a minimum number of high level callers like
              // this one.
              // This eliminates the need to synchronize error message text
              // in multiple catch blocks, which becomes a problem when some
              // catch blocks lead to re-wrapping of exceptions which tends
              // to adorn the final error text in ways that are hard to track
              // and replicate.
              // Deferring StackOverflowError handling MAY mean ADDING
              // explicit StackOverflowError catch blocks that re-throw
              // the error to bypass more generic catch blocks
              // for Error or Throwable on the same try block.
              throw new AdHocPlanningException("Encountered stack overflow error. " +
                      "Try reducing the number of predicate expressions in the query.");
          }
          catch (AssertionError ae) {
              String msg = "An unexpected internal error occurred when planning a statement issued via @AdHoc.  "
                      + "Please contact VoltDB at support@voltdb.com with your log files.";
              StringWriter stringWriter = new StringWriter();
              PrintWriter writer = new PrintWriter(stringWriter);
              ae.printStackTrace(writer);
              String stackTrace = stringWriter.toString();
  
              adhocLog.error(msg + "\n" + stackTrace);
              throw new AdHocPlanningException(msg);
          }
      }