001package gudusoft.gsqlparser.resolver2.model;
002
003import gudusoft.gsqlparser.resolver2.StructKind;
004
005import java.util.ArrayList;
006import java.util.List;
007
008/**
009 * Tracks the path taken during name resolution.
010 * Used for debugging and understanding how a name was resolved.
011 *
012 * Example path for resolving "t.address.city":
013 * 1. Found table 't' (users table)
014 * 2. Found field 'address' (type: address_type)
015 * 3. Found field 'city' (type: varchar)
016 */
017public class ResolvePath {
018    private final List<Step> steps;
019
020    public ResolvePath() {
021        this.steps = new ArrayList<>();
022    }
023
024    private ResolvePath(List<Step> steps) {
025        this.steps = new ArrayList<>(steps);
026    }
027
028    /**
029     * Adds a step to the resolution path
030     */
031    public ResolvePath plus(Object rowType, int ordinal, String name, StructKind kind) {
032        List<Step> newSteps = new ArrayList<>(steps);
033        newSteps.add(new Step(rowType, ordinal, name, kind));
034        return new ResolvePath(newSteps);
035    }
036
037    public List<Step> getSteps() {
038        return new ArrayList<>(steps);
039    }
040
041    public int getStepCount() {
042        return steps.size();
043    }
044
045    public boolean isEmpty() {
046        return steps.isEmpty();
047    }
048
049    @Override
050    public String toString() {
051        if (steps.isEmpty()) {
052            return "<empty path>";
053        }
054        StringBuilder sb = new StringBuilder();
055        for (int i = 0; i < steps.size(); i++) {
056            if (i > 0) sb.append(" -> ");
057            sb.append(steps.get(i).name);
058        }
059        return sb.toString();
060    }
061
062    /**
063     * A single step in the resolution path
064     */
065    public static class Step {
066        public final Object rowType;
067        public final int ordinal;
068        public final String name;
069        public final StructKind structKind;
070
071        public Step(Object rowType, int ordinal, String name, StructKind kind) {
072            this.rowType = rowType;
073            this.ordinal = ordinal;
074            this.name = name;
075            this.structKind = kind;
076        }
077
078        @Override
079        public String toString() {
080            return String.format("%s[%d] (%s)", name, ordinal, structKind);
081        }
082    }
083}