protected String generateIdInsertSelect(Queryable persister, String tableAlias, AST whereClause) {
    Select select = new Select(getFactory().getDialect());
    SelectFragment selectFragment =
        new SelectFragment()
            .addColumns(
                tableAlias,
                persister.getIdentifierColumnNames(),
                persister.getIdentifierColumnNames());
    select.setSelectClause(selectFragment.toFragmentString().substring(2));

    String rootTableName = persister.getTableName();
    String fromJoinFragment = persister.fromJoinFragment(tableAlias, true, false);
    String whereJoinFragment = persister.whereJoinFragment(tableAlias, true, false);

    select.setFromClause(rootTableName + ' ' + tableAlias + fromJoinFragment);

    if (whereJoinFragment == null) {
      whereJoinFragment = "";
    } else {
      whereJoinFragment = whereJoinFragment.trim();
      if (whereJoinFragment.startsWith("and")) {
        whereJoinFragment = whereJoinFragment.substring(4);
      }
    }

    String userWhereClause = "";
    if (whereClause.getNumberOfChildren() != 0) {
      // If a where clause was specified in the update/delete query, use it to limit the
      // returned ids here...
      try {
        SqlGenerator sqlGenerator = new SqlGenerator(getFactory());
        sqlGenerator.whereClause(whereClause);
        userWhereClause = sqlGenerator.getSQL().substring(7); // strip the " where "
      } catch (RecognitionException e) {
        throw new HibernateException("Unable to generate id select for DML operation", e);
      }
      if (whereJoinFragment.length() > 0) {
        whereJoinFragment += " and ";
      }
    }

    select.setWhereClause(whereJoinFragment + userWhereClause);

    InsertSelect insert = new InsertSelect(getFactory().getDialect());
    if (getFactory().getSettings().isCommentsEnabled()) {
      insert.setComment("insert-select for " + persister.getEntityName() + " ids");
    }
    insert.setTableName(persister.getTemporaryIdTableName());
    insert.setSelect(select);
    return insert.toStatementString();
  }
  protected void postProcessDML(RestrictableStatement statement) throws SemanticException {
    statement.getFromClause().resolve();

    FromElement fromElement = (FromElement) statement.getFromClause().getFromElements().get(0);
    Queryable persister = fromElement.getQueryable();
    // Make #@%$^#^&# sure no alias is applied to the table name
    fromElement.setText(persister.getTableName());

    // append any filter fragments; the EMPTY_MAP is used under the assumption that
    // currently enabled filters should not affect this process
    if (persister.getDiscriminatorType() != null) {
      new SyntheticAndFactory(getASTFactory())
          .addDiscriminatorWhereFragment(
              statement, persister, java.util.Collections.EMPTY_MAP, fromElement.getTableAlias());
    }
  }