code: 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");
      }
    }
docs: Send ServerPrepareStatement or ClientPrepareStatement depending on SQL query and options If
  server side and PREPARE can be delayed, a facade will be return, to have a fallback on client
  prepareStatement.
  
  @param sql                  sql query
  @param resultSetScrollType  one of the following <code>ResultSet</code> constants:
  <code>ResultSet.TYPE_FORWARD_ONLY</code>,
  <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
  <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
  @param resultSetConcurrency a concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code>
  or
  <code>ResultSet.CONCUR_UPDATABLE</code>
  @param autoGeneratedKeys    a flag indicating whether auto-generated keys should be returned;
  one of
  <code>Statement.RETURN_GENERATED_KEYS</code>
  or <code>Statement.NO_GENERATED_KEYS</code>
  @return PrepareStatement
  @throws SQLException if a connection error occur during the server preparation.