001
002package gudusoft.gsqlparser.dlineage.dataflow.model;
003
004import gudusoft.gsqlparser.EDbVendor;
005import gudusoft.gsqlparser.EExpressionType;
006import gudusoft.gsqlparser.ESetOperatorType;
007import gudusoft.gsqlparser.TCustomSqlStatement;
008import gudusoft.gsqlparser.dlineage.util.DlineageUtil;
009import gudusoft.gsqlparser.dlineage.util.Pair;
010import gudusoft.gsqlparser.dlineage.util.Pair3;
011import gudusoft.gsqlparser.dlineage.util.SHA256;
012import gudusoft.gsqlparser.nodes.*;
013import gudusoft.gsqlparser.sqlenv.TSQLEnv;
014import gudusoft.gsqlparser.stmt.*;
015import gudusoft.gsqlparser.stmt.mssql.TMssqlDeclare;
016import gudusoft.gsqlparser.util.IndexedLinkedHashMap;
017import gudusoft.gsqlparser.util.Logger;
018import gudusoft.gsqlparser.util.LoggerFactory;
019import gudusoft.gsqlparser.util.SQLUtil;
020
021import java.util.*;
022
023@SuppressWarnings({ "unchecked", "rawtypes" })
024public class ModelBindingManager {
025
026        private static final Logger logger = LoggerFactory.getLogger(ModelBindingManager.class);
027
028        private final Map modelBindingMap = new LinkedHashMap();
029        private final Map processModelBindingMap = new LinkedHashMap();
030        private final Map viewModelBindingMap = new LinkedHashMap();
031        private final Map insertModelBindingMap = new LinkedHashMap();
032        private final Map createModelBindingMap = new LinkedHashMap();
033        private final Map createModelQuickBindingMap = new LinkedHashMap();
034        private final Map mergeModelBindingMap = new LinkedHashMap();
035        private final Map updateModelBindingMap = new LinkedHashMap();
036        private final Map cursorModelBindingMap = new LinkedHashMap();
037        private final Map functionTableMap = new LinkedHashMap<>();
038        private final Map tableNamesMap = new LinkedHashMap();
039        private final Set<Table> dropTables = new HashSet<Table>();
040        private final Map procedureNamesMap = new LinkedHashMap();
041        private final Map oraclePackageNamesMap = new LinkedHashMap();
042        private final Set<Relationship> relationHolder = Collections.synchronizedSet(new LinkedHashSet<Relationship>());
043        private final Map<String, TTable> tableAliasMap = new LinkedHashMap();
044        private final Map<TCustomSqlStatement, String> tableHashMap = new LinkedHashMap();
045        private final Map<TCustomSqlStatement, String> topStmtHashMap = new HashMap();
046        private final Map hashSQLMap = new HashMap();
047        private final Map dynamicSQLMap = new HashMap();
048        private final Set tableSet = new LinkedHashSet();
049        private final Set resultSetSet = new LinkedHashSet();
050        private final Set<String> dblinkTableSet = new LinkedHashSet();
051        public Map<String, Long> DISPLAY_ID = new LinkedHashMap<String, Long>();
052        public Map<Long, String> DISPLAY_NAME = new LinkedHashMap<Long, String>();
053        public Map<String, String> virtualTableNames = new LinkedHashMap<String, String>();
054
055        public long TABLE_COLUMN_ID = 0;
056        public long RELATION_ID = 0;
057        public int virtualTableIndex = -1;
058
059        private final static ThreadLocal localManager = new ThreadLocal();
060        private final static ThreadLocal globalDatabase = new ThreadLocal();
061        private final static ThreadLocal globalSchema = new ThreadLocal();
062        private final static ThreadLocal globalVendor = new ThreadLocal();
063        private final static ThreadLocal globalSQLEnv = new ThreadLocal();
064        private final static ThreadLocal globalHash = new ThreadLocal();
065        private final static ThreadLocal globalStmtStack = new ThreadLocal();
066        private final static ThreadLocal globalSqlInfo = new ThreadLocal();
067        private final static ThreadLocal globalOption = new ThreadLocal();
068        private final static ThreadLocal globalOraclePackage = new ThreadLocal();
069        private final static ThreadLocal globalProcedure = new ThreadLocal();
070
071        public static void set(ModelBindingManager modelManager) {
072                if (modelManager != null) {
073                        localManager.set(modelManager);
074                }
075        }
076
077        public static ModelBindingManager get() {
078                return (ModelBindingManager) localManager.get();
079        }
080
081        public static void setGlobalDatabase(String database) {
082                if (database != null) {
083                        globalDatabase.set(database);
084                }
085        }
086
087        public static String getGlobalDatabase() {
088                return (String) globalDatabase.get();
089        }
090
091        public static void removeGlobalDatabase() {
092                globalDatabase.remove();
093        }
094
095        public static void setGlobalSchema(String schema) {
096                if (schema != null) {
097                        globalSchema.set(schema);
098                }
099        }
100
101        public static void removeGlobalSchema() {
102                globalSchema.remove();
103        }
104
105        public static String getGlobalSchema() {
106                return (String) globalSchema.get();
107        }
108
109        public static void setGlobalHash(String hash) {
110                if (hash != null) {
111                        globalHash.set(hash);
112                }
113        }
114
115        public static void removeGlobalHash() {
116                globalHash.remove();
117        }
118
119        public static String getGlobalHash() {
120                return (String) globalHash.get();
121        }
122
123        public static void setGlobalOraclePackage(OraclePackage currentOraclePackage) {
124                if (currentOraclePackage != null) {
125                        globalOraclePackage.set(currentOraclePackage);
126                }
127        }
128
129        public static void removeGlobalOraclePackage() {
130                globalOraclePackage.remove();
131        }
132
133        public static OraclePackage getGlobalOraclePackage() {
134                return (OraclePackage) globalOraclePackage.get();
135        }
136        
137        public static void setGlobalProcedure(TStoredProcedureSqlStatement procedureSqlStatement) {
138                if (procedureSqlStatement != null) {
139                        globalProcedure.set(procedureSqlStatement);
140                }
141        }
142
143        public static void removeGlobalProcedure() {
144                globalProcedure.remove();
145                ModelBindingManager.get().cleanTempTable();
146        }
147
148        public static TStoredProcedureSqlStatement getGlobalProcedure() {
149                return (TStoredProcedureSqlStatement) globalProcedure.get();
150        }
151        
152        public static void setGlobalVendor(EDbVendor vendor) {
153                if (vendor != null) {
154                        globalVendor.set(vendor);
155                }
156        }
157
158        public static void removeGlobalVendor() {
159                globalVendor.remove();
160        }
161
162        public static EDbVendor getGlobalVendor() {
163                return (EDbVendor) globalVendor.get();
164        }
165
166        public static void setGlobalSQLEnv(TSQLEnv sqlenv) {
167                if (sqlenv != null) {
168                        globalSQLEnv.set(sqlenv);
169                }
170        }
171
172        public static void removeGlobalSQLEnv() {
173                globalSQLEnv.remove();
174        }
175
176        public static TSQLEnv getGlobalSQLEnv() {
177                return (TSQLEnv) globalSQLEnv.get();
178        }
179
180        public static String getGlobalServer() {
181                TSQLEnv sqlEnv = getGlobalSQLEnv();
182                if (sqlEnv != null)
183                        return TSQLEnv.DEFAULT_SERVER_NAME.equals(sqlEnv.getDefaultServerName()) ? null : sqlEnv.getDefaultServerName();
184                return null;
185        }
186
187        public static void setGlobalStmtStack(Stack<TCustomSqlStatement> stack) {
188                if (stack != null) {
189                        globalStmtStack.set(stack);
190                }
191        }
192
193        public static void removeGlobalStmtStack() {
194                globalStmtStack.remove();
195        }
196        
197        public static void setGlobalSqlInfo(IndexedLinkedHashMap<String, List<SqlInfo>> sqlInfoMap) {
198                if (sqlInfoMap != null) {
199                        globalSqlInfo.set(sqlInfoMap);
200                }
201        }
202
203        public static void removeGlobalSqlInfo() {
204                globalSqlInfo.remove();
205        }
206
207        public static IndexedLinkedHashMap<String, List<SqlInfo>> getGlobalSqlInfo() {
208                return (IndexedLinkedHashMap<String, List<SqlInfo>>) globalSqlInfo.get();
209        }
210
211        public static void setGlobalOption(Option option) {
212                if (option != null) {
213                        globalOption.set(option);
214                }
215        }
216        
217        public static Option getGlobalOption() {
218                return (Option) globalOption.get();
219        }
220
221        public static void removeGlobalOption() {
222                globalOption.remove();
223        }
224
225        public static Stack<TCustomSqlStatement> getGlobalStmtStack() {
226                return (Stack<TCustomSqlStatement>) globalStmtStack.get();
227        }
228
229        public static void remove() {
230                localManager.remove();
231                globalDatabase.remove();
232                globalSchema.remove();
233                globalVendor.remove();
234                globalSQLEnv.remove();
235                globalHash.remove();
236                globalStmtStack.remove();
237                globalOption.remove();
238                globalSqlInfo.remove();
239        }
240
241        public void bindModel(Object gspModel, Object relationModel) {
242                if(gspModel == null) {
243                        return;
244                }
245                modelBindingMap.put(gspModel, relationModel);
246
247                TTable table = null;
248                if (gspModel instanceof TTable && !(gspModel instanceof TCTE)) {
249                        table = ((TTable) gspModel);
250                } else if (gspModel instanceof Table) {
251                        table = ((Table) gspModel).getTableObject();
252                } else if (gspModel instanceof QueryTable) {
253                        table = ((QueryTable) gspModel).getTableObject();
254                } else if (gspModel instanceof TCTE) {
255                        TTableList tables = ((TCTE) gspModel).getPreparableStmt().tables;
256                        for (int j = 0; j < tables.size(); j++) {
257                                TTable item = tables.getTable(j);
258                                if (item != null && !SQLUtil.isEmpty(item.getAliasName())) {
259                                        TCustomSqlStatement stmt = ((TCTE) gspModel).getPreparableStmt();
260                                        if (tableHashMap.containsKey(stmt)) {
261                                                tableAliasMap.put(
262                                                                tableHashMap.get(stmt) + ":" + DlineageUtil.getIdentifierNormalTableName(item.getAliasName()),
263                                                                item);
264                                        } else {
265                                                String sql = stmt.toString();
266                                                if(sql == null){
267                                                        System.err.println("Current statement toString() returns null.");
268                                                        continue;
269                                                }
270                                                String hash = SHA256.getMd5(sql);
271                                                tableHashMap.put(stmt, hash);
272                                                tableAliasMap.put(hash + ":" + DlineageUtil.getIdentifierNormalTableName(item.getAliasName()), item);
273                                        }
274                                }
275
276                                if (item != null) {
277                                        tableSet.add(item);
278                                }
279                        }
280                } else if (gspModel instanceof Pair && ((Pair) gspModel).first instanceof Table) {
281                        table = ((Table) ((Pair) gspModel).first).getTableObject();
282                }
283
284                if (table == null && relationModel instanceof QueryTable) {
285                        table = ((QueryTable) relationModel).getTableObject();
286                }
287
288                updateTableAliasMap(table);
289
290                if (table != null) {
291                        tableSet.add(table);
292                }
293                
294                if(relationModel instanceof ResultSet) {
295                        resultSetSet.add(relationModel);
296                }
297        }
298
299        protected void updateTableAliasMap(TTable table) {
300                if (table != null && !SQLUtil.isEmpty(table.getAliasName())) {
301                        TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().peek();
302                        if (tableHashMap.containsKey(stmt)) {
303                                tableAliasMap.put(tableHashMap.get(stmt) + ":" + DlineageUtil.getIdentifierNormalTableName(table.getAliasName()),
304                                                table);
305                        } else {
306                                String sql = stmt.toString();
307                                if(sql == null){
308                                        System.err.println("Current statement toString() returns null.");
309                                }
310                                else {
311                                        String hash = SHA256.getMd5(sql);
312                                        tableHashMap.put(stmt, hash);
313                                        tableAliasMap.put(hash + ":" + DlineageUtil.getIdentifierNormalTableName(table.getAliasName()),
314                                                        table);
315                                }
316                        }
317                }
318        }
319
320        public Object getModel(Object gspModel) {
321                if (gspModel == null) {
322                        return null;
323                }
324
325                if (gspModel instanceof TTable && !(gspModel instanceof TCTE)) {
326                        TTable table = (TTable) gspModel;
327                        if (table.getCTE() != null) {
328                                Object result =  modelBindingMap.get(table.getCTE());
329                                if (result != null) {
330                                        return result;
331                                }
332                        }
333                        if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null) {
334                                Object result = modelBindingMap.get(table.getAliasClause().getColumns());
335                                if (result != null) {
336                                        return result;
337                                }
338                        }
339                        if (table.getSubquery() != null && !table.getSubquery().isCombinedQuery()) {
340                                Object result =  modelBindingMap.get(table.getSubquery().getResultColumnList());
341                                if (result != null) {
342                                        return result;
343                                }
344                        }
345                }
346                if (gspModel instanceof TSelectSqlStatement) {
347                        TSelectSqlStatement select = (TSelectSqlStatement) gspModel;
348                        if (!select.isCombinedQuery()) {
349                                if (select.getResultColumnList() != null) {
350                                        Object result = modelBindingMap.get(select.getResultColumnList());
351                                        if (result != null) {
352                                                return result;
353                                        }
354                                }
355                                else if (select.getTransformClause() != null) {
356                                        Object result = modelBindingMap.get(select.getTransformClause());
357                                        if (result != null) {
358                                                return result;
359                                        }
360                                }
361                        }
362                }
363                Object result = modelBindingMap.get(gspModel);
364                if (result == null) {
365                        result = createModelBindingMap.get(gspModel);
366                }
367                if (result == null) {
368                        result = insertModelBindingMap.get(gspModel);
369                }
370                if (result == null) {
371                        result = updateModelBindingMap.get(gspModel);
372                }
373                if (result == null) {
374                        result = mergeModelBindingMap.get(gspModel);
375                }
376                if (result == null) {
377                        result = viewModelBindingMap.get(gspModel);
378                }
379                if (result == null) {
380                        result = cursorModelBindingMap.get(gspModel);
381                }
382
383                if (result == null && gspModel instanceof TTable) {
384                        result = getCreateTable((TTable) gspModel);
385                }
386
387                if (result == null && gspModel instanceof TTable) {
388                        result = (Table) getCreateModel((TTable) gspModel);
389                }
390
391                if (result == null && gspModel instanceof TTable) {
392                        TTable table = (TTable) gspModel;
393                        if (table.getLinkTable() != null) {
394                                result = (Table) getTableByName(
395                                                DlineageUtil.getTableFullName(table.getLinkTable().getTableName().toString()));
396                                if (result == null) {
397                                        result = (Table) getTableByName(
398                                                        DlineageUtil.getTableFullNameWithDefaultSchema(table.getLinkTable().getTableName().toString()));
399                                }
400                        } else {
401                                result = (Table) getTableByName(
402                                                DlineageUtil.getTableFullName(((TTable) gspModel).getTableName().toString()));
403                                if (result == null) {
404                                        result = (Table) getTableByName(
405                                                        DlineageUtil.getTableFullNameWithDefaultSchema(((TTable) gspModel).getTableName().toString()));
406                                }
407                        }
408                }
409                
410                if (result == null && gspModel instanceof TTable) {
411                        TTable table = (TTable) gspModel;
412                        if(table.getFuncCall()!=null) {
413                                result = getModel(table.getFuncCall());
414                        }
415                }
416                
417                if (result == null && gspModel instanceof TTable) {
418                        TTable table = (TTable) gspModel;
419                        Table tableModel = new Table(table);
420                        result = (Table) getTableByName(DlineageUtil.getTableFullName(tableModel.getName()));
421                }
422
423                return result;
424        }
425
426        public List<Procedure> getProcedureModels(){
427                List<Procedure> procedures = new ArrayList<Procedure>();
428                for (Object obj : modelBindingMap.values()) {
429                        if(obj instanceof Procedure && !procedures.contains(obj)){
430                                procedures.add((Procedure)obj);
431                        }
432                }
433                return procedures;
434        }
435        
436        public List<OraclePackage> getOraclePackageModels(){
437                List<OraclePackage> oraclePackages = new ArrayList<OraclePackage>();
438                for (Object obj : modelBindingMap.values()) {
439                        if(obj instanceof OraclePackage && !oraclePackages.contains(obj)){
440                                oraclePackages.add((OraclePackage)obj);
441                        }
442                }
443                return oraclePackages;
444        }
445        
446        public List<Process> getProcessModels(){
447                List<Process> processes = new ArrayList<Process>();
448                for (Object obj : processModelBindingMap.values()) {
449                        if(obj instanceof Process && !processes.contains(obj)){
450                                processes.add((Process)obj);
451                        }
452                }
453                return processes;
454        }
455        
456        public void bindProcessModel(TParseTreeNode gspModel, Object relationModel) {
457                processModelBindingMap.put(gspModel, relationModel);
458        }
459
460        public void unbindProcessModel(TParseTreeNode gspModel) {
461                processModelBindingMap.remove(gspModel);
462        }
463
464        public Process getProcessModel(TParseTreeNode gspModel) {
465                return (Process)processModelBindingMap.get(gspModel);
466        }
467        
468        public void bindViewModel(Object gspModel, Object relationModel) {
469                viewModelBindingMap.put(gspModel, relationModel);
470        }
471        
472        public Object getViewModel(Object gspModel) {
473                return viewModelBindingMap.get(gspModel);
474        }
475
476        public void bindUpdateModel(Object gspModel, Object relationModel) {
477                updateModelBindingMap.put(gspModel, relationModel);
478        }
479
480        public Object getUpdateModel(Object gspModel) {
481                return updateModelBindingMap.get(gspModel);
482        }
483
484        public void bindMergeModel(Object gspModel, Object relationModel) {
485                mergeModelBindingMap.put(gspModel, relationModel);
486        }
487
488        public Object getMergeModel(Object gspModel) {
489                return mergeModelBindingMap.get(gspModel);
490        }
491
492        public void bindInsertModel(Object gspModel, Object relationModel) {
493                insertModelBindingMap.put(gspModel, relationModel);
494        }
495
496        public Object getInsertModel(Object gspModel) {
497                return insertModelBindingMap.get(gspModel);
498        }
499
500        public void bindTableFunction(Object gspModel, Object functionTable) {
501                if (functionTableMap.containsKey(gspModel)) {
502                        ((Set) functionTableMap.get(gspModel)).add(functionTable);
503                } else {
504                        Set tableSet = new LinkedHashSet();
505                        tableSet.add(functionTable);
506                        functionTableMap.put(gspModel, tableSet);
507                }
508        }
509
510        public Set<Object> getFunctionTable(Object gspModel) {
511                Set<Object> result = (Set<Object>)functionTableMap.get(gspModel);
512                if (result == null && gspModel instanceof String) {
513                        for (Object key : functionTableMap.keySet()) {
514                                if(!(key instanceof String)) {
515                                        continue;
516                                }
517                                String keyString = (String) key;
518                                String modelString = (String) gspModel;
519                                
520                                if (keyString.indexOf(".") != -1 && modelString.indexOf(".") == -1) {
521                                        keyString = keyString.substring(keyString.lastIndexOf(".") + 1);
522                                        if (keyString.equalsIgnoreCase(modelString)) {
523                                                return (Set<Object>)functionTableMap.get(key);
524                                        }
525                                }
526                                if (keyString.indexOf(".") == -1 && modelString.indexOf(".") != -1) {
527                                        modelString = modelString.substring(modelString.lastIndexOf(".") + 1);
528                                        if (keyString.equalsIgnoreCase(modelString)) {
529                                                return (Set<Object>)functionTableMap.get(key);
530                                        }
531                                }
532                                
533                        }
534                }
535                return result;
536        }
537
538        public Table getCreateTable(TTable table) {
539                if (table != null && table.getFullName() != null) {
540                        return (Table) createModelQuickBindingMap.get(DlineageUtil.getTableFullName(table.getTableName().toString()));
541                }
542                if(modelBindingMap.get(table) instanceof Table) {
543                        return (Table)modelBindingMap.get(table);
544                }
545                return null;
546        }
547
548        public Table getCreateModel(TTable table) {
549                return (Table) createModelBindingMap.get(table);
550        }
551
552        public void bindCreateModel(TTable table, Table tableModel) {
553                createModelBindingMap.put(table, tableModel);
554                if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(table.getTableName().toString()))) {
555                        createModelQuickBindingMap.put(DlineageUtil.getTableFullName(table.getTableName().toString()), tableModel);
556                }
557        }
558
559        public void bindCreateModel(TObjectName tableName, Table tableModel) {
560                if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(tableName.toString()))) {
561                        createModelQuickBindingMap.put(DlineageUtil.getTableFullName(tableName.toString()), tableModel);
562                }
563        }
564        
565        public void bindCreateModel(String tableName, Table tableModel) {
566                if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(tableName))) {
567                        createModelQuickBindingMap.put(DlineageUtil.getTableFullName(tableName), tableModel);
568                }
569        }
570
571        public TObjectName[] getTableColumns(TTable table) {
572                Table createTable = getCreateTable(table);
573                if (createTable != null) {
574                        List<TableColumn> columnList = createTable.getColumns();
575                        TObjectName[] columns = new TObjectName[columnList.size()];
576                        for (int i = 0; i < columns.length; i++) {
577                                columns[i] = columnList.get(i).getColumnObject();
578                        }
579                        Arrays.sort(columns, new Comparator<TObjectName>() {
580
581                                @Override
582                                public int compare(TObjectName o1, TObjectName o2) {
583                                        if (o1 == null) {
584                                                return -1;
585                                        }
586                                        if (o2 == null) {
587                                                return 1;
588                                        }
589                                        return o1.getStartToken().posinlist - o2.getStartToken().posinlist;
590                                }
591                        });
592                        return columns;
593                }
594                else if(modelBindingMap.get(table) instanceof QueryTable) {
595                        QueryTable queryTable = (QueryTable)modelBindingMap.get(table);
596                        List<TObjectName> columns = new ArrayList<TObjectName>();
597                        for (ResultColumn resultColumn : queryTable.getColumns()) {
598                                if(resultColumn.hasStarLinkColumn()) {
599                                        for(TObjectName column: resultColumn.getStarLinkColumnList()) {
600                                                columns.add(column);
601                                        }
602                                }
603                                else if (resultColumn.getColumnObject() instanceof TResultColumn) {
604                                        TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
605                                        TAliasClause alias = columnObject.getAliasClause();
606                                        if (alias != null && alias.getAliasName() != null) {
607                                                columns.add(alias.getAliasName());
608                                        } else {
609                                                if (columnObject.getFieldAttr() != null) {
610                                                        columns.add(columnObject.getFieldAttr());
611                                                } else {
612                                                        TObjectName column = new TObjectName();
613                                                        if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) {
614                                                                column.setString(columnObject.getExpr().getLeftOperand().toString());
615                                                        } else {
616                                                                column.setString(columnObject.toString());
617                                                        }
618                                                        columns.add(column);
619                                                }
620                                        }
621                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
622                                        columns.add((TObjectName) resultColumn.getColumnObject());
623                                }
624                        }
625                        return columns.toArray(new TObjectName[0]);
626                }
627
628                TObjectNameList list = table.getLinkedColumns();
629                List<TObjectName> columns = new ArrayList<TObjectName>();
630
631                if (table.getCTE() != null) {
632                        ResultSet resultSet = (ResultSet) getModel(table.getCTE());
633                        if (resultSet != null) {
634                                List<ResultColumn> columnList = resultSet.getColumns();
635                                for (int i = 0; i < columnList.size(); i++) {
636                                        ResultColumn resultColumn = columnList.get(i);
637                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
638                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
639                                                TAliasClause alias = columnObject.getAliasClause();
640                                                if (alias != null && alias.getAliasName() != null) {
641                                                        columns.add(alias.getAliasName());
642                                                } else {
643                                                        if (columnObject.getFieldAttr() != null) {
644                                                                columns.add(columnObject.getFieldAttr());
645                                                        } else {
646                                                                continue;
647                                                        }
648                                                }
649                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
650                                                columns.add((TObjectName) resultColumn.getColumnObject());
651                                        }
652                                }
653                        }
654                } else if (list.size() == 1 && list.toString().indexOf("*") != -1 && table.getSubquery() != null) {
655                        addSubqueryColumns(table, columns);
656                } else {
657                        for (int i = 0; i < list.size(); i++) {
658                                TObjectName object = list.getObjectName(i);
659                                if (object.toString().indexOf("*") != -1 && table.getSubquery() != null) {
660                                        addSubqueryColumns(table, columns);
661                                }
662                                else 
663                                        columns.add(object);
664                        }
665                }
666                Collections.sort(columns, new Comparator<TObjectName>() {
667
668                        @Override
669                        public int compare(TObjectName o1, TObjectName o2) {
670                                return o1.getStartToken().posinlist - o2.getStartToken().posinlist;
671                        }
672                });
673                return columns.toArray(new TObjectName[0]);
674        }
675
676        private void addSubqueryColumns(TTable table, List<TObjectName> columns) {
677                ResultSet resultSet = (ResultSet) getModel(table.getSubquery());
678                if (resultSet != null) {
679                        List<ResultColumn> columnList = resultSet.getColumns();
680                        for (int i = 0; i < columnList.size(); i++) {
681                                ResultColumn resultColumn = columnList.get(i);
682                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
683                                        TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
684                                        TAliasClause alias = columnObject.getAliasClause();
685                                        if (alias != null && alias.getAliasName() != null) {
686                                                columns.add(alias.getAliasName());
687                                        } else {
688                                                if (columnObject.getFieldAttr() != null) {
689                                                        columns.add(columnObject.getFieldAttr());
690                                                } else {
691                                                        TObjectName column = new TObjectName();
692                                                        if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) {
693                                                                column.setString(columnObject.getExpr().getLeftOperand().toString());
694                                                        } else {
695                                                                column.setString(columnObject.toString());
696                                                        }
697                                                        columns.add(column);
698                                                }
699                                        }
700                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
701                                        columns.add((TObjectName) resultColumn.getColumnObject());
702                                }
703                        }
704                }
705        }
706
707        public TTable getTableFromColumn(TObjectName column) {
708                if (column.getSourceTable() != null) {
709                        return column.getSourceTable();
710                }
711
712                if (column.getTableString() != null && column.getTableString().trim().length() > 0) {
713                        TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek();
714                        while (peekStmt != null) {
715                                TTable table = null;
716                                if (tableHashMap.containsKey(peekStmt)) {
717                                        table = tableAliasMap.get(tableHashMap.get(peekStmt) + ":"
718                                                        + DlineageUtil.getIdentifierNormalTableName(column.getTableString()));
719                                }
720                                if (table != null) {
721                                        return table;
722                                } else {
723                                        peekStmt = peekStmt.getParentStmt();
724                                }
725                        }
726                }
727                return null;
728        }
729        
730        public TTable getTable(TCustomSqlStatement stmt, TObjectName column) {
731                if (column.getSourceTable() != null) {
732                        return column.getSourceTable();
733                }
734
735                if (column.getTableString() != null && column.getTableString().trim().length() > 0) {
736                        TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek();
737                        while (peekStmt != null) {
738                                TTable table = null;
739                                if (tableHashMap.containsKey(peekStmt)) {
740                                        table = tableAliasMap.get(tableHashMap.get(peekStmt) + ":"
741                                                        + DlineageUtil.getIdentifierNormalTableName(column.getTableString()));
742                                }
743                                if (table != null && table.getSubquery() != stmt)
744                                        return table;
745                                
746                                if (peekStmt.getTables() != null) {
747                                        for (TTable tableItem : peekStmt.getTables()) {
748                                                if (DlineageUtil.getIdentifierNormalTableName(tableItem.getTableName().toString())
749                                                                .equals(DlineageUtil.getIdentifierNormalTableName(column.getTableString()))) {
750                                                        return tableItem;
751                                                }
752                                        }
753                                }
754                                
755                                peekStmt = peekStmt.getParentStmt();
756                        }
757                }
758
759                if (stmt.getTables() != null) {
760                        for (int j = 0; j < stmt.getTables().size(); j++) {
761                                TTable table = (TTable) stmt.getTables().getTable(j);
762                                if (table.getSubquery() == stmt)
763                                        continue;
764
765                                TObjectName[] columns = getTableColumns(table);
766                                for (int i = 0; i < columns.length; i++) {
767                                        TObjectName columnName = columns[i];
768                                        if (columnName == null || "*".equals(columnName.getColumnNameOnly()))
769                                                continue;
770                                        if (DlineageUtil.getIdentifierNormalColumnName(columnName.toString())
771                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(column.toString()))) {
772                                                if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) {
773                                                        return table;
774                                                }
775                                        }
776                                        if (!SQLUtil.isEmpty(columnName.getColumnNameOnly())
777                                                        && DlineageUtil.getIdentifierNormalColumnName(columnName.getColumnNameOnly())
778                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(column.getColumnNameOnly()))) {
779                                                if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) {
780                                                        return table;
781                                                }
782                                        }
783                                }
784                        }
785                }
786
787                // Iterator iter = tableSet.iterator();
788                // while (iter.hasNext()) {
789                // TTable table = (TTable) iter.next();
790                //
791                // if (table.getSubquery() == stmt)
792                // continue;
793                //
794                // if (table.getSubquery() != null) {
795                // int start = table.getSubquery().getStartToken().posinlist;
796                // int end = table.getSubquery().getEndToken().posinlist;
797                // if (start <= stmt.getStartToken().posinlist && end >=
798                // stmt.getEndToken().posinlist) {
799                // continue;
800                // }
801                // }
802                //
803                // TObjectName[] columns = getTableColumns(table);
804                // for (int i = 0; i < columns.length; i++) {
805                // TObjectName columnName = columns[i];
806                // if (columnName == null || "*".equals(columnName.getColumnNameOnly()))
807                // continue;
808                // if
809                // (DlineageUtil.getIdentifierNormalName(columnName.toString()).equals(DlineageUtil.getIdentifierNormalName(column.toString())))
810                // {
811                // if (columnName.getSourceTable() == null
812                // || columnName.getSourceTable() == table) {
813                // return table;
814                // }
815                // }
816                // if (columnName.getColumnNameOnly()!=null &&
817                // DlineageUtil.getIdentifierNormalName(columnName.getColumnNameOnly()).equals(DlineageUtil.getIdentifierNormalName(column.getColumnNameOnly())))
818                // {
819                // if (columnName.getSourceTable() == null
820                // || columnName.getSourceTable() == table) {
821                // return table;
822                // }
823                // }
824                // }
825                // }
826                return null;
827        }
828
829        public TTable guessTable(TCustomSqlStatement stmt, TObjectName column) {
830                if (column.getTableString() != null && column.getTableString().trim().length() > 0) {
831                        TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek();
832                        TTable table = null;
833                        if (tableHashMap.containsKey(peekStmt)) {
834                                table = tableAliasMap.get(
835                                                tableHashMap.get(peekStmt) + ":" + DlineageUtil.getIdentifierNormalTableName(column.getTableString()));
836                        }
837                        if (table != null && table.getSubquery() != stmt)
838                                return table;
839                }
840
841                Iterator iter = tableSet.iterator();
842                while (iter.hasNext()) {
843                        TTable table = (TTable) iter.next();
844
845                        if (table.getSubquery() == stmt)
846                                continue;
847
848                        TObjectName[] columns = getTableColumns(table);
849                        for (int i = 0; i < columns.length; i++) {
850                                TObjectName columnName = columns[i];
851                                if ("*".equals(columnName.getColumnNameOnly()))
852                                        continue;
853                                if (columnName.toString().equalsIgnoreCase(column.toString())) {
854                                        if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) {
855                                                return table;
856                                        }
857                                }
858                        }
859                }
860                return null;
861        }
862
863        public List<Table> getTablesByName() {
864                List<Table> tables = new ArrayList<Table>();
865                Iterator iter = tableNamesMap.values().iterator();
866                while (iter.hasNext()) {
867                        tables.add((Table) iter.next());
868                }
869                return tables;
870        }
871
872        public List<TTable> getBaseTables() {
873                List<TTable> tables = new ArrayList<TTable>();
874
875                Iterator iter = modelBindingMap.keySet().iterator();
876                while (iter.hasNext()) {
877                        Object key = iter.next();
878                        if (!(key instanceof TTable)) {
879                                continue;
880                        }
881                        TTable table = (TTable) key;
882                        if (table.getSubquery() == null) {
883                                tables.add(table);
884                        }
885                }
886
887                iter = createModelBindingMap.keySet().iterator();
888                while (iter.hasNext()) {
889                        Object key = iter.next();
890                        if (!(key instanceof TTable)) {
891                                continue;
892                        }
893                        TTable table = (TTable) key;
894                        tables.add(table);
895                }
896
897                iter = insertModelBindingMap.keySet().iterator();
898                while (iter.hasNext()) {
899                        Object key = iter.next();
900                        if (!(key instanceof TTable)) {
901                                continue;
902                        }
903                        TTable table = (TTable) key;
904                        tables.add(table);
905                }
906
907                iter = mergeModelBindingMap.keySet().iterator();
908                while (iter.hasNext()) {
909                        Object key = iter.next();
910                        if (!(key instanceof TTable)) {
911                                continue;
912                        }
913                        TTable table = (TTable) key;
914                        tables.add(table);
915                }
916
917                iter = updateModelBindingMap.keySet().iterator();
918                while (iter.hasNext()) {
919                        Object key = iter.next();
920                        if (!(key instanceof TTable)) {
921                                continue;
922                        }
923                        TTable table = (TTable) key;
924                        if (!tables.contains(table)) {
925                                tables.add(table);
926                        }
927                }
928
929                return tables;
930        }
931
932        public List<TCustomSqlStatement> getViews() {
933                List<TCustomSqlStatement> views = new ArrayList<TCustomSqlStatement>();
934
935                Iterator iter = viewModelBindingMap.keySet().iterator();
936                while (iter.hasNext()) {
937                        Object key = iter.next();
938                        if (!(key instanceof TCreateViewSqlStatement) && !(key instanceof TCreateMaterializedSqlStatement)) {
939                                continue;
940                        }
941                        TCustomSqlStatement view = (TCustomSqlStatement) key;
942                        if (!views.contains(view)) {
943                                views.add(view);
944                        }
945                }
946                return views;
947        }
948
949        public List<TResultColumnList> getSelectResultSets() {
950                List<TResultColumnList> resultSets = new ArrayList<TResultColumnList>();
951
952                Iterator iter = modelBindingMap.keySet().iterator();
953                while (iter.hasNext()) {
954                        Object key = iter.next();
955                        if (!(key instanceof TResultColumnList)) {
956                                continue;
957                        }
958                        TResultColumnList resultset = (TResultColumnList) key;
959                        resultSets.add(resultset);
960                }
961                return resultSets;
962        }
963
964        public List<TObjectNameList> getQueryAliasTables() {
965                List<TObjectNameList> resultSets = new ArrayList<TObjectNameList>();
966
967                Iterator iter = modelBindingMap.keySet().iterator();
968                while (iter.hasNext()) {
969                        Object key = iter.next();
970                        if (!(key instanceof TObjectNameList)) {
971                                continue;
972                        }
973                        TObjectNameList resultset = (TObjectNameList) key;
974                        resultSets.add(resultset);
975                }
976                return resultSets;
977        }
978
979        public List<TSelectSqlStatement> getSelectSetResultSets() {
980                List<TSelectSqlStatement> resultSets = new ArrayList<TSelectSqlStatement>();
981
982                Iterator iter = modelBindingMap.keySet().iterator();
983                while (iter.hasNext()) {
984                        Object key = iter.next();
985                        if (!(key instanceof TSelectSqlStatement)) {
986                                continue;
987                        }
988
989                        TSelectSqlStatement stmt = (TSelectSqlStatement) key;
990                        if (stmt.getSetOperatorType() == ESetOperatorType.none)
991                                continue;
992
993                        resultSets.add(stmt);
994                }
995                return resultSets;
996        }
997
998        public List<TCTE> getCTEs() {
999                List<TCTE> resultSets = new ArrayList<TCTE>();
1000
1001                Iterator iter = modelBindingMap.keySet().iterator();
1002                while (iter.hasNext()) {
1003                        Object key = iter.next();
1004                        if (!(key instanceof TCTE)) {
1005                                continue;
1006                        }
1007
1008                        TCTE cte = (TCTE) key;
1009                        resultSets.add(cte);
1010                }
1011                return resultSets;
1012        }
1013
1014        public List<TTable> getTableWithSelectSetResultSets() {
1015                List<TTable> resultSets = new ArrayList<TTable>();
1016
1017                Iterator iter = modelBindingMap.keySet().iterator();
1018                while (iter.hasNext()) {
1019                        Object key = iter.next();
1020                        if (!(key instanceof TTable)) {
1021                                continue;
1022                        }
1023
1024                        if (((TTable) key).getSubquery() == null)
1025                                continue;
1026                        TSelectSqlStatement stmt = ((TTable) key).getSubquery();
1027                        if (stmt.getSetOperatorType() == ESetOperatorType.none)
1028                                continue;
1029
1030                        resultSets.add((TTable) key);
1031                }
1032                return resultSets;
1033        }
1034
1035        public List<TParseTreeNode> getMergeResultSets() {
1036                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1037
1038                Iterator iter = modelBindingMap.keySet().iterator();
1039                while (iter.hasNext()) {
1040                        Object key = iter.next();
1041                        if (!(key instanceof TMergeUpdateClause) && !(key instanceof TMergeInsertClause)) {
1042                                continue;
1043                        }
1044                        TParseTreeNode resultset = (TParseTreeNode) key;
1045                        resultSets.add(resultset);
1046                }
1047                return resultSets;
1048        }
1049
1050        public List<TParseTreeNode> getOutputResultSets() {
1051                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1052
1053                Iterator iter = modelBindingMap.keySet().iterator();
1054                while (iter.hasNext()) {
1055                        Object key = iter.next();
1056                        if (!(key instanceof TOutputClause)) {
1057                                continue;
1058                        }
1059                        TParseTreeNode resultset = (TParseTreeNode) key;
1060                        resultSets.add(resultset);
1061                }
1062                return resultSets;
1063        }
1064
1065        public List<TParseTreeNode> getUpdateResultSets() {
1066                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1067
1068                Iterator iter = modelBindingMap.keySet().iterator();
1069                while (iter.hasNext()) {
1070                        Object key = iter.next();
1071                        if (!(key instanceof TUpdateSqlStatement)) {
1072                                continue;
1073                        }
1074                        TParseTreeNode resultset = (TParseTreeNode) key;
1075                        resultSets.add(resultset);
1076                }
1077                return resultSets;
1078        }
1079
1080        public List<TParseTreeNode> getFunctoinCalls() {
1081                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1082
1083                Iterator iter = modelBindingMap.keySet().iterator();
1084                while (iter.hasNext()) {
1085                        Object key = iter.next();
1086                        if (!(key instanceof TFunctionCall) && !(key instanceof TCaseExpression)) {
1087                                continue;
1088                        }
1089                        TParseTreeNode resultset = (TParseTreeNode) key;
1090                        resultSets.add(resultset);
1091                }
1092                return resultSets;
1093        }
1094
1095        public List<TParseTreeNode> getAliases() {
1096                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1097
1098                Iterator iter = modelBindingMap.keySet().iterator();
1099                while (iter.hasNext()) {
1100                        Object key = iter.next();
1101                        if (!(key instanceof TAliasClause)) {
1102                                continue;
1103                        }
1104                        TParseTreeNode resultset = (TParseTreeNode) key;
1105                        resultSets.add(resultset);
1106                }
1107                return resultSets;
1108        }
1109        
1110        public List<TParseTreeNode> getCursors() {
1111                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1112
1113                Iterator iter = modelBindingMap.keySet().iterator();
1114                while (iter.hasNext()) {
1115                        Object key = iter.next();
1116                        if (!(key instanceof TCursorDeclStmt) && !(key instanceof TOpenforStmt)) {
1117                                continue;
1118                        }
1119                        TParseTreeNode resultset = (TParseTreeNode) key;
1120                        resultSets.add(resultset);
1121                }
1122                return resultSets;
1123        }
1124        
1125        public List<TParseTreeNode> getPivotdTables() {
1126                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1127
1128                Iterator iter = modelBindingMap.keySet().iterator();
1129                while (iter.hasNext()) {
1130                        Object key = iter.next();
1131                        if (!(key instanceof TPivotClause)) {
1132                                continue;
1133                        }
1134                        TParseTreeNode resultset = (TParseTreeNode) key;
1135                        resultSets.add(resultset);
1136                }
1137                return resultSets;
1138        }
1139
1140        public void addRelation(Relationship relation) {
1141                if (relation != null && !relationHolder.contains(relation)) {
1142                        relationHolder.add(relation);
1143                }
1144        }
1145        
1146        public void removeRelation(ImpactRelationship relation) {
1147                if (relation != null) {
1148                        relationHolder.remove(relation);
1149                }
1150        }
1151
1152        public Relationship[] getRelations() {
1153                return relationHolder.toArray(new Relationship[0]);
1154        }
1155
1156        public void reset() {
1157                modelBindingMap.clear();
1158                processModelBindingMap.clear();
1159                viewModelBindingMap.clear();
1160                insertModelBindingMap.clear();
1161                createModelBindingMap.clear();
1162                createModelQuickBindingMap.clear();
1163                mergeModelBindingMap.clear();
1164                updateModelBindingMap.clear();
1165                cursorModelBindingMap.clear();
1166                functionTableMap.clear();
1167                tableNamesMap.clear();
1168                procedureNamesMap.clear();
1169                oraclePackageNamesMap.clear();
1170                relationHolder.clear();
1171                tableAliasMap.clear();
1172                tableHashMap.clear();
1173                topStmtHashMap.clear();
1174                hashSQLMap.clear();
1175                dynamicSQLMap.clear();
1176                tableSet.clear();
1177                resultSetSet.clear();
1178                dblinkTableSet.clear();
1179                DISPLAY_ID.clear();
1180                DISPLAY_NAME.clear();
1181                virtualTableNames.clear();
1182        }
1183
1184        public void bindCursorModel(TCursorDeclStmt stmt, Variable resultSet) {
1185                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1186                String variableString = stmt.getCursorName().toString();
1187                if (variableString.startsWith(":")) {
1188                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1189                }
1190                if (!SQLUtil.isEmpty(procedureName)) {
1191                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1192                }
1193                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1194        }
1195        
1196        public void bindCursorModel(TMssqlDeclare stmt, Variable resultSet) {
1197                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1198                String variableString = stmt.getCursorName().toString();
1199                if (variableString.startsWith(":")) {
1200                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1201                }
1202                if (!SQLUtil.isEmpty(procedureName)) {
1203                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1204                }
1205                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1206        }
1207        
1208        public void bindCursorModel(TOpenforStmt stmt, Variable resultSet) {
1209                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1210                String variableString = stmt.getCursorVariableName().toString();
1211                if (variableString.startsWith(":")) {
1212                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1213                }
1214                if (!SQLUtil.isEmpty(procedureName)) {
1215                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1216                }
1217                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1218        }
1219        
1220        public void bindCursorModel(TForStmt stmt, Variable resultSet) {
1221                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1222                String variableString = stmt.getCursorName().toString();
1223                if (variableString.startsWith(":")) {
1224                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1225                }
1226                if (!SQLUtil.isEmpty(procedureName)) {
1227                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1228                }
1229                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1230        }
1231        
1232        public void bindCursorModel(TLoopStmt stmt, Variable resultSet) {
1233                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1234                String variableString = stmt.getRecordName().toString();
1235                if (variableString.startsWith(":")) {
1236                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1237                }
1238                if (!SQLUtil.isEmpty(procedureName)) {
1239                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1240                }
1241                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1242        }
1243
1244        public void bindCursorIndex(TObjectName indexName, TObjectName cursorName) {
1245                TCustomSqlStatement stmt = getGlobalStmtStack().peek();
1246                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1247                String variableString = cursorName.toString();
1248                if (variableString.startsWith(":")) {
1249                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1250                }
1251                if (!SQLUtil.isEmpty(procedureName)) {
1252                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1253                }
1254                
1255                Cursor cursor = ((Cursor) createModelBindingMap
1256                                .get(DlineageUtil.getTableFullName(variableString)));
1257                if (cursor != null) {
1258                        String indexNameString = indexName.toString();
1259                        if (!SQLUtil.isEmpty(procedureName)) {
1260                                indexNameString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(indexNameString);
1261                        }
1262                        bindModel(DlineageUtil.getTableFullName(indexNameString),
1263                                        modelBindingMap.get(cursor.getResultColumnObject()));
1264                        bindTableByName(DlineageUtil.getTableFullName(indexNameString),
1265                                        cursor);
1266                }
1267        }
1268
1269        public List<TStoredProcedureSqlStatement> getProcedures() {
1270                List<TStoredProcedureSqlStatement> procedures = new ArrayList();
1271                Iterator iter = this.modelBindingMap.keySet().iterator();
1272
1273                while (iter.hasNext()) {
1274                        Object key = iter.next();
1275                        if (key instanceof TStoredProcedureSqlStatement) {
1276                                TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) key;
1277                                procedures.add(procedure);
1278                        }
1279                }
1280
1281                return procedures;
1282        }
1283
1284        // public void bindTableByName(TObjectName tableName, Table tableModel) {
1285        // tableNamesMap.put(tableName, tableModel);
1286        //
1287        // }
1288        //
1289        public void bindTableByName(String tableName, Table tableModel) {
1290                tableNamesMap.put(tableName, tableModel);
1291
1292        }
1293
1294        // public Table getTableByName(TObjectName tableName) {
1295        // return (Table)tableNamesMap.get(tableName);
1296        // }
1297
1298        public Table getTableByName(String tableName) {
1299                Table table = (Table) tableNamesMap.get(tableName);
1300                if (table == null) {
1301                        TCustomSqlStatement stmt = getGlobalStmtStack().peek();
1302                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
1303                        String variableString = tableName.toString();
1304                        if (!SQLUtil.isEmpty(procedureName)) {
1305                                String variableWithProcedure = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1306                                if(tableNamesMap.containsKey(DlineageUtil.getTableFullName(variableWithProcedure))) {
1307                                        return  (Table) tableNamesMap.get(DlineageUtil.getTableFullName(variableWithProcedure));
1308                                }
1309                        }
1310                        return (Table) tableNamesMap.get(DlineageUtil.getTableFullName(variableString));
1311                } else {
1312                        return table;
1313                }
1314        }
1315
1316
1317        public void bindProcedureByName(String procedureName, Procedure procedureModel) {
1318                procedureNamesMap.put(procedureName, procedureModel);
1319
1320        }
1321        
1322        public Procedure getProcedureByName(String procedureName) {
1323                if(procedureName == null){
1324                        return null;
1325                }
1326
1327                if (ModelBindingManager.getGlobalOraclePackage() != null
1328                                && !procedureName.startsWith(ModelBindingManager.getGlobalOraclePackage().getName())) {
1329                        procedureName = ModelBindingManager.getGlobalOraclePackage().getName() + "." + procedureName;
1330                }
1331                Procedure procedure = (Procedure) procedureNamesMap.get(procedureName);
1332                if (procedure == null) {
1333                        if (procedureName.indexOf("(") == -1) {
1334                                for (Object name : procedureNamesMap.keySet()) {
1335                                        String fuctionName = name.toString();
1336                                        if (fuctionName.startsWith(procedureName + "(")) {
1337                                                return (Procedure) procedureNamesMap.get(name);
1338                                        }
1339                                        if (fuctionName.indexOf(".") != -1 && procedureName.indexOf(".") == -1) {
1340                                                fuctionName = fuctionName.substring(fuctionName.lastIndexOf(".") + 1);
1341                                                if (fuctionName.startsWith(procedureName + "(")) {
1342                                                        return (Procedure) procedureNamesMap.get(name);
1343                                                }
1344                                        }
1345                                        if (fuctionName.indexOf(".") == -1 && procedureName.indexOf(".") != -1) {
1346                                                String procedureNameSubstring = procedureName.substring(procedureName.lastIndexOf(".") + 1);
1347                                                if (fuctionName.startsWith(procedureNameSubstring + "(")) {
1348                                                        return (Procedure) procedureNamesMap.get(name);
1349                                                }
1350                                        }
1351                                }
1352                        }
1353                        else {
1354                                for (Object name : procedureNamesMap.keySet()) {
1355                                        String fuctionName = name.toString();
1356                                        if (fuctionName.startsWith(procedureName)) {
1357                                                return (Procedure) procedureNamesMap.get(name);
1358                                        }
1359                                        if (fuctionName.indexOf(".") != -1 && procedureName.indexOf(".") == -1) {
1360                                                fuctionName = fuctionName.substring(fuctionName.lastIndexOf(".") + 1);
1361                                                if (fuctionName.equalsIgnoreCase(procedureName)) {
1362                                                        return (Procedure) procedureNamesMap.get(name);
1363                                                }
1364                                        }
1365                                        if (fuctionName.indexOf(".") == -1 && procedureName.indexOf(".") != -1) {
1366                                                String procedureNameSubstring = procedureName.substring(procedureName.lastIndexOf(".") + 1);
1367                                                if (fuctionName.equalsIgnoreCase(procedureNameSubstring)) {
1368                                                        return (Procedure) procedureNamesMap.get(name);
1369                                                }
1370                                        }
1371                                }
1372                        }
1373                }
1374                return procedure;
1375        }
1376        
1377        public void bindOraclePackageByName(String oraclePackageName, OraclePackage oraclePackageModel) {
1378                oraclePackageNamesMap.put(oraclePackageName, oraclePackageModel);
1379
1380        }
1381        
1382        public OraclePackage getOraclePackageByName(String oraclePackageName) {
1383                return (OraclePackage) oraclePackageNamesMap.get(oraclePackageName);
1384        }
1385
1386
1387        public String getSqlHash(TCustomSqlStatement stmt) {
1388                return topStmtHashMap.get(stmt);
1389        }
1390
1391        public Map getHashSQLMap() {
1392                return hashSQLMap;
1393        }
1394
1395        public Map getDynamicSQLMap() {
1396                return dynamicSQLMap;
1397        }
1398
1399        public void collectSqlHash(TCustomSqlStatement stmt) {
1400                if (getGlobalOption().getAnalyzeMode() == AnalyzeMode.crud) {
1401                        String sql = stmt.toString();
1402                        if (sql != null) {
1403                                sql = stmt.getStartToken().lineNo + ":" + sql;
1404                                String hash = SQLUtil.stringToMD5(sql);
1405                                topStmtHashMap.put(stmt, hash);
1406                                hashSQLMap.put(hash, new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, stmt.getEndToken().lineNo, ModelBindingManager.getGlobalHash()));
1407                        }
1408                } else {
1409                        try {
1410                                String sql = stmt.asCanonical();
1411                                if (sql != null) {
1412                                        String hash = SQLUtil.stringToMD5(sql);
1413                                        topStmtHashMap.put(stmt, hash);
1414                                        hashSQLMap.put(hash, sql);
1415                                }
1416                        } catch (Exception e) {
1417                                logger.error("collectSqlHash error: " + e.getMessage(), e);
1418                        }
1419                }
1420        }
1421        
1422        public void collectDynamicSqlHash(TCustomSqlStatement stmt) {
1423                if (getGlobalOption().getAnalyzeMode() == AnalyzeMode.dynamic) {
1424                        String sql = stmt.toString();
1425                        if (sql != null) {
1426                                sql = stmt.getStartToken().lineNo + ":" + sql;
1427                                String hash = SQLUtil.stringToMD5(sql);
1428                                dynamicSQLMap.put(hash, new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, stmt.getEndToken().lineNo, ModelBindingManager.getGlobalHash()));
1429                        }
1430                }
1431        }
1432
1433        public void appendDblinkTable(String name) {
1434                if (!SQLUtil.isEmpty(name)) {
1435                        dblinkTableSet.add(name);
1436                }
1437        }
1438        
1439        public boolean isDblinkTable(String name) {
1440                return dblinkTableSet.contains(name);
1441        }
1442
1443        public Set<ResultSet> getResultSets() {
1444                return resultSetSet;
1445        }
1446        
1447        public void dropTable(Table table) {
1448                List tableNames = new ArrayList(tableNamesMap.keySet());
1449                for (Object tableName : tableNames) {
1450                        if(tableNamesMap.get(tableName) == table) {
1451                                tableNamesMap.remove(tableName);
1452                                dropTables.add(table);
1453                        }
1454                }
1455        }
1456        
1457        public void cleanTempTable() {
1458                Iterator<String> iter = tableNamesMap.keySet().iterator();
1459                while(iter.hasNext()) {
1460                        String tableName = iter.next();
1461                        if(DlineageUtil.isTempTable((Table)tableNamesMap.get(tableName), getGlobalVendor())) {
1462                                dropTables.add((Table)tableNamesMap.get(tableName));
1463                                iter.remove();
1464                        }
1465                }
1466        }
1467
1468        public Set<Table> getDropTables() {
1469                return dropTables;
1470        }
1471        
1472        
1473        
1474}