001package gudusoft.gsqlparser.nodes;
002
003
004import gudusoft.gsqlparser.TBaseType;
005
006import java.util.ArrayList;
007import java.util.HashMap;
008import java.util.List;
009
010/**
011* Collections of {@link TCTE}.
012*/
013public class TCTEList extends TParseTreeNodeList <TCTE>{
014
015    /**
016     * @deprecated please use {@link #size()} and {@link #getCTE(int)} to access the cte in the list
017     */
018    public HashMap<String, TCTE> cteNames;
019
020    private int indexModCount = -1;
021    private HashMap<String, List<TCTE>> cteIndex;
022
023    private void ensureIndex() {
024        if (cteIndex != null && indexModCount == modCount) return;
025        cteIndex = new HashMap<>();
026        for (int i = 0; i < size(); i++) {
027            TCTE cte = getCTE(i);
028            String key = TBaseType.getTextWithoutQuoted(
029                cte.getTableName().toString()).toLowerCase();
030            List<TCTE> list = cteIndex.get(key);
031            if (list == null) {
032                list = new ArrayList<>();
033                cteIndex.put(key, list);
034            }
035            list.add(cte);
036        }
037        indexModCount = modCount;
038    }
039
040    public TCTE searchCTEByName(String cteName, int beforeThisPos){
041        ensureIndex();
042        String key = TBaseType.getTextWithoutQuoted(cteName).toLowerCase();
043        List<TCTE> candidates = cteIndex.get(key);
044        if (candidates == null) return null;
045        // Reverse scan for nearest CTE before the reference position (shadowing semantics)
046        for (int i = candidates.size() - 1; i >= 0; i--) {
047            TCTE cte = candidates.get(i);
048            if (cte.getStartToken().posinlist < beforeThisPos) {
049                return cte;
050            }
051        }
052        return null;
053    }
054
055    public TCTEList()
056    {
057    }
058
059    public void addCTE(TCTE cte)
060    {
061        addElement(cte);
062    }
063
064    public TCTE getCTE(int position)
065    {
066        if (position < size())
067        {
068            return (TCTE)elementAt(position);
069        }else{
070        return null;
071        }
072    }
073
074    void addParseTreeNode(Object arg1){
075        addCTE((TCTE)arg1);
076    }
077
078    public void accept(TParseTreeVisitor v){
079        v.preVisit(this);
080        v.postVisit(this);
081    }
082//
083    public void acceptChildren(TParseTreeVisitor v){
084        v.preVisit(this);
085        for(int i=0;i<this.size();i++){
086            this.getCTE(i).acceptChildren(v);
087        }
088        v.postVisit(this);
089    }
090
091}