docs: private PreparedStatement internalPrepareStatement(final String sql,
        final int resultSetScrollType,
        final int resultSetConcurrency,
        final int autoGeneratedKeys)
        throws SQLException {
  
      if (sql != null) {
  
        String sqlQuery = Utils.nativeSql(sql, protocol.noBackslashEscapes());
  
        if (options.useServerPrepStmts && PREPARABLE_STATEMENT_PATTERN.matcher(sqlQuery).find()) {
          //prepare isn't delayed -> if prepare fail, fallback to client preparedStatement?
          checkConnection();
          try {
            return new ServerSidePreparedStatement(this,
                sqlQuery,
                resultSetScrollType,
                resultSetConcurrency,
                autoGeneratedKeys);
          } catch (SQLNonTransientConnectionException e) {
            throw e;
          } catch (SQLException e) {
            //on some specific case, server cannot prepared data (CONJ-238)
            //will use clientPreparedStatement
          }
        }
        return new ClientSidePreparedStatement(this,
            sqlQuery,
            resultSetScrollType,
            resultSetConcurrency,
            autoGeneratedKeys);
      } else {
        throw new SQLException("SQL value can not be NULL");
      }
    }