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