q = new StringBuffer("SELECT ").append(idfield).append(" FROM ") .append(table) .append(rel.buildQuery(home, home.getNonVirtualParent(), null, " WHERE ", true)) .toString();
q = b.append(rel.buildQuery(home, home.getNonVirtualParent(), null, " WHERE ", true)).toString();
    public List getNodeIDs(Node home, Relation rel) throws Exception {        // Transactor tx = (Transactor) Thread.currentThread ();        // tx.timer.beginEvent ("getNodeIDs "+home);        if ((rel == null) || (rel.otherType == null) || !rel.otherType.isRelational()) {            // this should never be called for embedded nodes            throw new RuntimeException("NodeMgr.getNodeIDs called for non-relational node " +                                       home);        } else {            List retval = new ArrayList();            // if we do a groupby query (creating an intermediate layer of groupby nodes),            // retrieve the value of that field instead of the primary key            String idfield = (rel.groupby == null) ? rel.otherType.getIDField()                                                   : rel.groupby;            Connection con = rel.otherType.getConnection();            String table = rel.otherType.getTableName();            Statement stmt = null;            try {                String q = null;                if (home.getSubnodeRelation() != null) {                    // subnode relation was explicitly set                    q = new StringBuffer("SELECT ").append(table).append('.')                                                   .append(idfield).append(" FROM ")                                                   .append(table).append(" ")                                                   .append(home.getSubnodeRelation())                                                   .toString();                } else {                    // let relation object build the query                    q = new StringBuffer("SELECT ").append(idfield).append(" FROM ")                                                   .append(table)                                                   .append(rel.buildQuery(home,                                                                          home.getNonVirtualParent(),                                                                          null,                                                                          " WHERE ", true))                                                   .toString();                }                if (logSql) {                    app.logEvent("### getNodeIDs: " + q);                }                stmt = con.createStatement();                if (rel.maxSize > 0) {                    stmt.setMaxRows(rel.maxSize);                }                ResultSet result = stmt.executeQuery(q);                // problem: how do we derive a SyntheticKey from a not-yet-persistent Node?                Key k = (rel.groupby != null) ? home.getKey() : null;                while (result.next()) {                    String kstr = result.getString(1);                    // jump over null values - this can happen especially when the selected                    // column is a group-by column.                    if (kstr == null) {                        continue;                    }                    // make the proper key for the object, either a generic DB key or a groupby key                    Key key = (rel.groupby == null)                              ? (Key) new DbKey(rel.otherType, kstr)                              : (Key) new SyntheticKey(k, kstr);                    retval.add(new NodeHandle(key));                    // if these are groupby nodes, evict nullNode keys                    if (rel.groupby != null) {                        Node n = (Node) cache.get(key);                        if ((n != null) && n.isNullNode()) {                            evictKey(key);                        }                    }                }            } finally {                // tx.timer.endEvent ("getNodeIDs "+home);                if (stmt != null) {                    try {                        stmt.close();                    } catch (Exception ignore) {                    }                }            }            return retval;        }    }