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