public ExpState initialize()

in openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java [518:676]


    public ExpState initialize(Select sel, ExpContext ctx, int flags) {
        PathExpState pstate = new PathExpState(sel.newJoins());
        boolean key = false;
        boolean forceOuter = false;
        ClassMapping rel = _candidate;

        sel.setSchemaAlias(_schemaAlias);

        // iterate to the final field
        ClassMapping owner;
        ClassMapping from, to;
        Action action;
        Variable var;
        Iterator itr = (_actions == null) ? null : _actions.iterator();
        FieldMapping field = null;
        Action prevaction = null;
        boolean isCorrelatedPath = false;
        boolean fromParentRootInSubselect = navigateFromParentRootInSubselect(sel);

        while (itr != null && itr.hasNext()) {
            action = (Action) itr.next();

            // treat subqueries like variables for alias generation purposes
            if (action.op == Action.VAR) {
                if (sel.getParent() != null && action.var != null &&
                    prevaction != null && prevaction.data != null &&
                    sel.ctx().getVariable(action.var) == null) {
                    isCorrelatedPath = true;
                    pstate.joins = pstate.joins.setCorrelatedVariable(action.var);
                } else
                    pstate.joins = pstate.joins.setVariable((String) action.data);
            }
            else if (action.op == Action.SUBQUERY) {
                pstate.joins = pstate.joins.setSubselect((String) action.data);
            }
            else if (action.op == Action.UNBOUND_VAR) {
                // unbound vars are cross-joined to the candidate table
                var = (Variable) action.data;
                rel = (ClassMapping) var.getMetaData();
                if (rel == null)
                	throw new IllegalArgumentException(_loc.get(
                	    "invalid-unbound-var", var.getName()).toString());

                if (sel.getParent() != null && action.var != null &&
                    sel.ctx().getVariable(action.var) == null) {
                    //System.out.println("Correlated action var="+action.var);
                    isCorrelatedPath = true;
                    pstate.joins = pstate.joins.setCorrelatedVariable(var.getName());
                } else
                    pstate.joins = pstate.joins.setVariable(var.getName());

                pstate.joins = pstate.joins.crossJoin(_candidate.getTable(),
                    rel.getTable());
                if (!itr.hasNext() && isVariable()) {
                    checkObjectPathInheritanceTypeJoined(pstate);
                }
            } else {
                // move past the previous field, if any
                field = (FieldMapping) ((action.op == Action.GET_XPATH) ?
                    _xmlfield : action.data);

                if (pstate.field != null) {
                    // if this is the second-to-last field and the last is
                    // the related field this field joins to, no need to
                    // traverse: just use this field's fk columns
                    if (!itr.hasNext() && (flags & JOIN_REL) == 0
                        && isJoinedField(pstate.field, key, field)) {
                        pstate.cmpfield = field;
                        break;
                    }

                    if (fromParentRootInSubselect) {
                        isCorrelatedPath = true;
                        pstate.joins = pstate.joins.setCorrelatedVariable(_schemaAlias);
                        pstate.joins.setJoinContext(null);
                    }

                    rel = traverseField(pstate, key, forceOuter ||
                              ctx.store.getDBDictionary().fullResultCollectionInOrderByRelation, false);
                }

                // mark if the next traversal should go through
                // the key rather than value
                key = action.op == Action.GET_KEY;
                forceOuter |= action.op == Action.GET_OUTER;

                if (key && itr.hasNext())
                    _keyPath = true;

                // get mapping for the current field
                pstate.field = field;

                owner = pstate.field.getDefiningMapping();
                if (pstate.field.getManagement()
                    != FieldMetaData.MANAGE_PERSISTENT)
                    throw new UserException(_loc.get("non-pers-field",
                        pstate.field));

                // find the most-derived type between the declared relation
                // type and the field's owner, and join from that type to
                // the lesser derived type
                if (rel != owner && rel != null) {
                    if (rel.getDescribedType().isAssignableFrom
                        (owner.getDescribedType())) {
                        from = owner;
                        to = rel;
                    } else {
                        from = rel;
                        to = owner;
                    }

                    for (; from != null && from != to;
                        from = from.getJoinablePCSuperclassMapping()) {
                    	FieldMapping cast = from.getFieldMapping(pstate.field
                    			.getName());
                    	if (cast != null)
                    		pstate.field = cast;
                        pstate.joins = from.joinSuperclass(pstate.joins, false);
                    }
                }
                // nothing more to do from here on as we encountered an xpath
                // action
                if (action.op == Action.GET_XPATH)
                    break;
            }
            prevaction = action;
            if (prevaction != null && prevaction.context != null) {
                Context jCtx = JDBCStoreQuery.getThreadLocalContext(prevaction.context);
                pstate.joins = pstate.joins.setJoinContext(jCtx);
            }
        }
        if (_varName != null)
            pstate.joins = pstate.joins.setVariable(_varName);

        // if we're not comparing to null or doing an isEmpty, then
        // join into the data on the final field; obviously we can't do these
        // joins when comparing to null b/c the whole purpose is to see
        // whether the joins even exist
        if ((flags & NULL_CMP) == 0)
            traverseField(pstate, key, forceOuter, true);
        pstate.joinedRel = false;
        if ((flags & JOIN_REL) != 0)
            joinRelation(pstate, key, forceOuter || (flags & FORCE_OUTER) != 0,
                false);
        if (isCorrelatedPath) {
            // check if there are joins that belong to parent
            pstate.joins.moveJoinsToParent();
        }
        pstate.joins.setJoinContext(null);

        if (_actions == null) {
            String subqAlias = findSubqAlias(sel);
            pstate.joins = pstate.joins.setSubselect(subqAlias);
            pstate.joins.setCorrelatedVariable(_schemaAlias);
            checkObjectPathInheritanceTypeJoined(pstate);
        }

        return pstate;
    }