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}