001package gudusoft.gsqlparser.nodes; 002 003import gudusoft.gsqlparser.EDbObjectType; 004import gudusoft.gsqlparser.ETableEffectType; 005import gudusoft.gsqlparser.ETableSource; 006import gudusoft.gsqlparser.TBaseType; 007 008import java.util.HashMap; 009 010/* 011* Date: 2010-2-4 012* Time: 16:59:33 013*/ 014public class TTableList extends TParseTreeNodeList <TTable>{ 015 016 private int indexModCount = -1; 017 private HashMap<String, Integer> nameIndex; 018 019 public TTableList() 020 { 021 } 022 023 public void addTable(TTable table) 024 { 025 addElement(table); 026 } 027 028 /** 029 * add a table reference to table list, if there is already a corresponding table in table list 030 * just add this reference to that table, otherwise, create a new table instance, then add this reference. 031 * @param tableref 032 */ 033 public void addTableByTableRefernce(TTableReference tableref) 034 { 035 //addElement(table); 036 boolean isAdded = false; 037 for(int i=0; i<size();i++){ 038 if (getTable(i).isTableRefBelongToThisTable(tableref)){ 039 getTable(i).tablerefs.addTableReference(tableref); 040 isAdded = true; 041 break; 042 } 043 } 044 if (!isAdded){ 045 addTable(new TTable(tableref.objectname)); 046 } 047 } 048 049 050 public TTable getTable(int position) 051 { 052 if (position < size()) 053 { 054 return (TTable)elementAt(position); 055 }else{ 056 return null; 057 } 058 } 059 060 void addParseTreeNode(Object arg1){ 061 addTable((TTable)arg1); 062 } 063 064 private void ensureIndex() { 065 if (nameIndex != null && indexModCount == modCount) return; 066 nameIndex = new HashMap<>(size() * 2 + 4); 067 for (int i = 0; i < size(); i++) { 068 TTable t = getTable(i); 069 String tStr = t.toString(); 070 if (tStr != null) { 071 nameIndex.putIfAbsent(tStr.toLowerCase(), i); 072 } 073 if (t.getAliasClause() != null) { 074 String alias = t.getAliasClause().toString(); 075 if (alias != null) { 076 nameIndex.putIfAbsent(alias.toLowerCase(), i); 077 } 078 } 079 } 080 indexModCount = modCount; 081 } 082 083 /** 084 * 085 * @param crf column reference 086 * @return return position of table this column reference belongs to, 0 means first table. < 0 means not found 087 * if no qualifier before column name, always return -2, 088 * if return -1,this column name must be found in uplevel tables 089 */ 090 public int checkColumnReferenceInTables(TObjectName crf){ 091 int retval = -1; 092 if (crf.getObjectToken() == null) return -2; 093 094 String crfObjectStr = crf.getObjectToken().toString(); 095 String crfUnquoted = TBaseType.getTextWithoutQuoted(crfObjectStr); 096 TTable lcTable = null; 097 for(int i=0; i<size();i++){ 098 lcTable = getTable(i); 099 if (lcTable.getAliasClause() != null){ 100 if (lcTable.getAliasClause().getAliasName().toString().compareToIgnoreCase(crfObjectStr) == 0){ 101 crf.getObjectToken().setDbObjectType(EDbObjectType.table_alias); 102 return i; 103 } 104 }else{ 105 if (lcTable.getTableType() != ETableSource.objectname) {continue;} 106 String tableObjStr = lcTable.getTableName().getObjectToken().toString(); 107 if (tableObjStr.compareToIgnoreCase(crfObjectStr) == 0){ 108 crf.getObjectToken().setDbObjType(TObjectName.ttobjTable); 109 return i; 110 } 111 String s1 = TBaseType.getTextWithoutQuoted(tableObjStr); 112 if (s1.equalsIgnoreCase(crfUnquoted)) { 113 crf.getObjectToken().setDbObjType(TObjectName.ttobjTable); 114 return i; 115 } 116 } 117 } 118 return retval; 119 } 120 121 public int searchTableByNameOrAlias(String pTableName){ 122 ensureIndex(); 123 String key = pTableName.toLowerCase(); 124 Integer idx = nameIndex.get(key); 125 if (idx != null) return idx; 126 127 // Fallback: linear scan for safety (covers edge cases index might miss) 128 TTable lcTable = null; 129 int iRet = -1; 130 for(int i=0; i<size();i++) { 131 lcTable = getTable(i); 132 if (lcTable.toString().equalsIgnoreCase(pTableName)){ 133 iRet = i; 134 break; 135 }else if (lcTable.getAliasClause() != null){ 136 if (lcTable.getAliasClause().toString().equalsIgnoreCase(pTableName)){ 137 iRet = i; 138 break; 139 } 140 } 141 } 142 return iRet; 143 } 144 145}