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 && !procedures.contains(obj)){
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 && !oraclePackages.contains(obj)){
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 && !processes.contains(obj)){
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                Set<Object> result = (Set<Object>)functionTableMap.get(gspModel);
542                if (result == null && gspModel instanceof String) {
543                        for (Object key : functionTableMap.keySet()) {
544                                if(!(key instanceof String)) {
545                                        continue;
546                                }
547                                String keyString = (String) key;
548                                String modelString = (String) gspModel;
549                                
550                                if (keyString.indexOf(".") != -1 && modelString.indexOf(".") == -1) {
551                                        keyString = keyString.substring(keyString.lastIndexOf(".") + 1);
552                                        if (keyString.equalsIgnoreCase(modelString)) {
553                                                return (Set<Object>)functionTableMap.get(key);
554                                        }
555                                }
556                                if (keyString.indexOf(".") == -1 && modelString.indexOf(".") != -1) {
557                                        modelString = modelString.substring(modelString.lastIndexOf(".") + 1);
558                                        if (keyString.equalsIgnoreCase(modelString)) {
559                                                return (Set<Object>)functionTableMap.get(key);
560                                        }
561                                }
562                                
563                        }
564                }
565                return result;
566        }
567
568        public Table getCreateTable(TTable table) {
569                if (table != null && table.getFullName() != null) {
570                        return (Table) createModelQuickBindingMap.get(DlineageUtil.getTableFullName(table.getTableName().toString()));
571                }
572                if(modelBindingMap.get(table) instanceof Table) {
573                        return (Table)modelBindingMap.get(table);
574                }
575                return null;
576        }
577
578        public Table getCreateModel(TTable table) {
579                return (Table) createModelBindingMap.get(table);
580        }
581
582        public void bindCreateModel(TTable table, Table tableModel) {
583                createModelBindingMap.put(table, tableModel);
584                if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(table.getTableName().toString()))) {
585                        createModelQuickBindingMap.put(DlineageUtil.getTableFullName(table.getTableName().toString()), tableModel);
586                }
587        }
588
589        public void bindCreateModel(TObjectName tableName, Table tableModel) {
590                if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(tableName.toString()))) {
591                        createModelQuickBindingMap.put(DlineageUtil.getTableFullName(tableName.toString()), tableModel);
592                }
593        }
594        
595        public void bindCreateModel(String tableName, Table tableModel) {
596                if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(tableName))) {
597                        createModelQuickBindingMap.put(DlineageUtil.getTableFullName(tableName), tableModel);
598                }
599        }
600
601        public TObjectName[] getTableColumns(TTable table) {
602                Table createTable = getCreateTable(table);
603                if (createTable != null) {
604                        List<TableColumn> columnList = createTable.getColumns();
605                        TObjectName[] columns = new TObjectName[columnList.size()];
606                        for (int i = 0; i < columns.length; i++) {
607                                columns[i] = columnList.get(i).getColumnObject();
608                        }
609                        Arrays.sort(columns, new Comparator<TObjectName>() {
610
611                                @Override
612                                public int compare(TObjectName o1, TObjectName o2) {
613                                        if (o1 == null) {
614                                                return -1;
615                                        }
616                                        if (o2 == null) {
617                                                return 1;
618                                        }
619                                        return o1.getStartToken().posinlist - o2.getStartToken().posinlist;
620                                }
621                        });
622                        return columns;
623                }
624                else if(modelBindingMap.get(table) instanceof QueryTable) {
625                        QueryTable queryTable = (QueryTable)modelBindingMap.get(table);
626                        List<TObjectName> columns = new ArrayList<TObjectName>();
627                        for (ResultColumn resultColumn : queryTable.getColumns()) {
628                                if(resultColumn.hasStarLinkColumn()) {
629                                        for(TObjectName column: resultColumn.getStarLinkColumnList()) {
630                                                columns.add(column);
631                                        }
632                                }
633                                else if (resultColumn.getColumnObject() instanceof TResultColumn) {
634                                        TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
635                                        TAliasClause alias = columnObject.getAliasClause();
636                                        if (alias != null && alias.getAliasName() != null) {
637                                                columns.add(alias.getAliasName());
638                                        } else {
639                                                if (columnObject.getFieldAttr() != null) {
640                                                        columns.add(columnObject.getFieldAttr());
641                                                } else {
642                                                        TObjectName column = new TObjectName();
643                                                        if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) {
644                                                                column.setString(columnObject.getExpr().getLeftOperand().toString());
645                                                        } else {
646                                                                column.setString(columnObject.toString());
647                                                        }
648                                                        columns.add(column);
649                                                }
650                                        }
651                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
652                                        columns.add((TObjectName) resultColumn.getColumnObject());
653                                }
654                        }
655                        return columns.toArray(new TObjectName[0]);
656                }
657
658                TObjectNameList list = table.getLinkedColumns();
659                List<TObjectName> columns = new ArrayList<TObjectName>();
660
661                if (table.getCTE() != null) {
662                        ResultSet resultSet = (ResultSet) getModel(table.getCTE());
663                        if (resultSet != null) {
664                                List<ResultColumn> columnList = resultSet.getColumns();
665                                for (int i = 0; i < columnList.size(); i++) {
666                                        ResultColumn resultColumn = columnList.get(i);
667                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
668                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
669                                                TAliasClause alias = columnObject.getAliasClause();
670                                                if (alias != null && alias.getAliasName() != null) {
671                                                        columns.add(alias.getAliasName());
672                                                } else {
673                                                        if (columnObject.getFieldAttr() != null) {
674                                                                columns.add(columnObject.getFieldAttr());
675                                                        } else {
676                                                                continue;
677                                                        }
678                                                }
679                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
680                                                columns.add((TObjectName) resultColumn.getColumnObject());
681                                        }
682                                }
683                        }
684                } else if (list.size() == 1 && list.toString().indexOf("*") != -1 && table.getSubquery() != null) {
685                        addSubqueryColumns(table, columns);
686                } else {
687                        for (int i = 0; i < list.size(); i++) {
688                                TObjectName object = list.getObjectName(i);
689                                if (object.toString().indexOf("*") != -1 && table.getSubquery() != null) {
690                                        addSubqueryColumns(table, columns);
691                                }
692                                else 
693                                        columns.add(object);
694                        }
695                }
696                Collections.sort(columns, new Comparator<TObjectName>() {
697
698                        @Override
699                        public int compare(TObjectName o1, TObjectName o2) {
700                                return o1.getStartToken().posinlist - o2.getStartToken().posinlist;
701                        }
702                });
703                return columns.toArray(new TObjectName[0]);
704        }
705
706        private void addSubqueryColumns(TTable table, List<TObjectName> columns) {
707                ResultSet resultSet = (ResultSet) getModel(table.getSubquery());
708                if (resultSet != null) {
709                        List<ResultColumn> columnList = resultSet.getColumns();
710                        for (int i = 0; i < columnList.size(); i++) {
711                                ResultColumn resultColumn = columnList.get(i);
712                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
713                                        TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
714                                        TAliasClause alias = columnObject.getAliasClause();
715                                        if (alias != null && alias.getAliasName() != null) {
716                                                columns.add(alias.getAliasName());
717                                        } else {
718                                                if (columnObject.getFieldAttr() != null) {
719                                                        columns.add(columnObject.getFieldAttr());
720                                                } else {
721                                                        TObjectName column = new TObjectName();
722                                                        if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) {
723                                                                column.setString(columnObject.getExpr().getLeftOperand().toString());
724                                                        } else {
725                                                                column.setString(columnObject.toString());
726                                                        }
727                                                        columns.add(column);
728                                                }
729                                        }
730                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
731                                        columns.add((TObjectName) resultColumn.getColumnObject());
732                                }
733                        }
734                }
735        }
736
737        public TTable getTableFromColumn(TObjectName column) {
738                if (column.getSourceTable() != null) {
739                        return column.getSourceTable();
740                }
741
742                if (column.getTableString() != null && column.getTableString().trim().length() > 0) {
743                        TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek();
744                        while (peekStmt != null) {
745                                TTable table = null;
746                                if (tableHashMap.containsKey(peekStmt)) {
747                                        table = tableAliasMap.get(tableHashMap.get(peekStmt) + ":"
748                                                        + DlineageUtil.getIdentifierNormalTableName(column.getTableString()));
749                                }
750                                if (table != null) {
751                                        return table;
752                                } else {
753                                        peekStmt = peekStmt.getParentStmt();
754                                }
755                        }
756                }
757                return null;
758        }
759        
760        public TTable getTable(TCustomSqlStatement stmt, TObjectName column) {
761                if (column.getSourceTable() != null) {
762                        return column.getSourceTable();
763                }
764
765                if (column.getTableString() != null && column.getTableString().trim().length() > 0) {
766                        TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek();
767                        while (peekStmt != null) {
768                                TTable table = null;
769                                if (tableHashMap.containsKey(peekStmt)) {
770                                        table = tableAliasMap.get(tableHashMap.get(peekStmt) + ":"
771                                                        + DlineageUtil.getIdentifierNormalTableName(column.getTableString()));
772                                }
773                                if (table != null && table.getSubquery() != stmt)
774                                        return table;
775                                
776                                if (peekStmt.getTables() != null) {
777                                        for (TTable tableItem : peekStmt.getTables()) {
778                                                if (DlineageUtil.getIdentifierNormalTableName(tableItem.getTableName().toString())
779                                                                .equals(DlineageUtil.getIdentifierNormalTableName(column.getTableString()))) {
780                                                        return tableItem;
781                                                }
782                                        }
783                                }
784                                
785                                peekStmt = peekStmt.getParentStmt();
786                        }
787                }
788
789                if (stmt.getTables() != null) {
790                        for (int j = 0; j < stmt.getTables().size(); j++) {
791                                TTable table = (TTable) stmt.getTables().getTable(j);
792                                if (table.getSubquery() == stmt)
793                                        continue;
794
795                                TObjectName[] columns = getTableColumns(table);
796                                for (int i = 0; i < columns.length; i++) {
797                                        TObjectName columnName = columns[i];
798                                        if (columnName == null || "*".equals(columnName.getColumnNameOnly()))
799                                                continue;
800                                        if (DlineageUtil.getIdentifierNormalColumnName(columnName.toString())
801                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(column.toString()))) {
802                                                if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) {
803                                                        return table;
804                                                }
805                                        }
806                                        if (!SQLUtil.isEmpty(columnName.getColumnNameOnly())
807                                                        && DlineageUtil.getIdentifierNormalColumnName(columnName.getColumnNameOnly())
808                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(column.getColumnNameOnly()))) {
809                                                if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) {
810                                                        return table;
811                                                }
812                                        }
813                                }
814                        }
815                }
816
817                // Iterator iter = tableSet.iterator();
818                // while (iter.hasNext()) {
819                // TTable table = (TTable) iter.next();
820                //
821                // if (table.getSubquery() == stmt)
822                // continue;
823                //
824                // if (table.getSubquery() != null) {
825                // int start = table.getSubquery().getStartToken().posinlist;
826                // int end = table.getSubquery().getEndToken().posinlist;
827                // if (start <= stmt.getStartToken().posinlist && end >=
828                // stmt.getEndToken().posinlist) {
829                // continue;
830                // }
831                // }
832                //
833                // TObjectName[] columns = getTableColumns(table);
834                // for (int i = 0; i < columns.length; i++) {
835                // TObjectName columnName = columns[i];
836                // if (columnName == null || "*".equals(columnName.getColumnNameOnly()))
837                // continue;
838                // if
839                // (DlineageUtil.getIdentifierNormalName(columnName.toString()).equals(DlineageUtil.getIdentifierNormalName(column.toString())))
840                // {
841                // if (columnName.getSourceTable() == null
842                // || columnName.getSourceTable() == table) {
843                // return table;
844                // }
845                // }
846                // if (columnName.getColumnNameOnly()!=null &&
847                // DlineageUtil.getIdentifierNormalName(columnName.getColumnNameOnly()).equals(DlineageUtil.getIdentifierNormalName(column.getColumnNameOnly())))
848                // {
849                // if (columnName.getSourceTable() == null
850                // || columnName.getSourceTable() == table) {
851                // return table;
852                // }
853                // }
854                // }
855                // }
856                return null;
857        }
858
859        public TTable guessTable(TCustomSqlStatement stmt, TObjectName column) {
860                if (column.getTableString() != null && column.getTableString().trim().length() > 0) {
861                        TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek();
862                        TTable table = null;
863                        if (tableHashMap.containsKey(peekStmt)) {
864                                table = tableAliasMap.get(
865                                                tableHashMap.get(peekStmt) + ":" + DlineageUtil.getIdentifierNormalTableName(column.getTableString()));
866                        }
867                        if (table != null && table.getSubquery() != stmt)
868                                return table;
869                }
870
871                Iterator iter = tableSet.iterator();
872                while (iter.hasNext()) {
873                        TTable table = (TTable) iter.next();
874
875                        if (table.getSubquery() == stmt)
876                                continue;
877
878                        TObjectName[] columns = getTableColumns(table);
879                        for (int i = 0; i < columns.length; i++) {
880                                TObjectName columnName = columns[i];
881                                if ("*".equals(columnName.getColumnNameOnly()))
882                                        continue;
883                                if (columnName.toString().equalsIgnoreCase(column.toString())) {
884                                        if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) {
885                                                return table;
886                                        }
887                                }
888                        }
889                }
890                return null;
891        }
892
893        public List<Table> getTablesByName() {
894                List<Table> tables = new ArrayList<Table>();
895                Iterator iter = tableNamesMap.values().iterator();
896                while (iter.hasNext()) {
897                        tables.add((Table) iter.next());
898                }
899                return tables;
900        }
901
902        public List<TTable> getBaseTables() {
903                List<TTable> tables = new ArrayList<TTable>();
904
905                Iterator iter = modelBindingMap.keySet().iterator();
906                while (iter.hasNext()) {
907                        Object key = iter.next();
908                        if (!(key instanceof TTable)) {
909                                continue;
910                        }
911                        TTable table = (TTable) key;
912                        if (table.getSubquery() == null) {
913                                tables.add(table);
914                        }
915                }
916
917                iter = createModelBindingMap.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                        tables.add(table);
925                }
926
927                iter = insertModelBindingMap.keySet().iterator();
928                while (iter.hasNext()) {
929                        Object key = iter.next();
930                        if (!(key instanceof TTable)) {
931                                continue;
932                        }
933                        TTable table = (TTable) key;
934                        tables.add(table);
935                }
936
937                iter = mergeModelBindingMap.keySet().iterator();
938                while (iter.hasNext()) {
939                        Object key = iter.next();
940                        if (!(key instanceof TTable)) {
941                                continue;
942                        }
943                        TTable table = (TTable) key;
944                        tables.add(table);
945                }
946
947                iter = updateModelBindingMap.keySet().iterator();
948                while (iter.hasNext()) {
949                        Object key = iter.next();
950                        if (!(key instanceof TTable)) {
951                                continue;
952                        }
953                        TTable table = (TTable) key;
954                        if (!tables.contains(table)) {
955                                tables.add(table);
956                        }
957                }
958
959                return tables;
960        }
961
962        public List<TCustomSqlStatement> getViews() {
963                List<TCustomSqlStatement> views = new ArrayList<TCustomSqlStatement>();
964
965                Iterator iter = viewModelBindingMap.keySet().iterator();
966                while (iter.hasNext()) {
967                        Object key = iter.next();
968                        if (!(key instanceof TCreateViewSqlStatement) && !(key instanceof TCreateMaterializedSqlStatement)) {
969                                continue;
970                        }
971                        TCustomSqlStatement view = (TCustomSqlStatement) key;
972                        if (!views.contains(view)) {
973                                views.add(view);
974                        }
975                }
976                return views;
977        }
978
979        public List<TResultColumnList> getSelectResultSets() {
980                List<TResultColumnList> resultSets = new ArrayList<TResultColumnList>();
981
982                Iterator iter = modelBindingMap.keySet().iterator();
983                while (iter.hasNext()) {
984                        Object key = iter.next();
985                        if (!(key instanceof TResultColumnList)) {
986                                continue;
987                        }
988                        TResultColumnList resultset = (TResultColumnList) key;
989                        resultSets.add(resultset);
990                }
991                return resultSets;
992        }
993
994        public List<TObjectNameList> getQueryAliasTables() {
995                List<TObjectNameList> resultSets = new ArrayList<TObjectNameList>();
996
997                Iterator iter = modelBindingMap.keySet().iterator();
998                while (iter.hasNext()) {
999                        Object key = iter.next();
1000                        if (!(key instanceof TObjectNameList)) {
1001                                continue;
1002                        }
1003                        TObjectNameList resultset = (TObjectNameList) key;
1004                        resultSets.add(resultset);
1005                }
1006                return resultSets;
1007        }
1008
1009        public List<TSelectSqlStatement> getSelectSetResultSets() {
1010                List<TSelectSqlStatement> resultSets = new ArrayList<TSelectSqlStatement>();
1011
1012                Iterator iter = modelBindingMap.keySet().iterator();
1013                while (iter.hasNext()) {
1014                        Object key = iter.next();
1015                        if (!(key instanceof TSelectSqlStatement)) {
1016                                continue;
1017                        }
1018
1019                        TSelectSqlStatement stmt = (TSelectSqlStatement) key;
1020                        if (stmt.getSetOperatorType() == ESetOperatorType.none)
1021                                continue;
1022
1023                        resultSets.add(stmt);
1024                }
1025                return resultSets;
1026        }
1027
1028        public List<TCTE> getCTEs() {
1029                List<TCTE> resultSets = new ArrayList<TCTE>();
1030
1031                Iterator iter = modelBindingMap.keySet().iterator();
1032                while (iter.hasNext()) {
1033                        Object key = iter.next();
1034                        if (!(key instanceof TCTE)) {
1035                                continue;
1036                        }
1037
1038                        TCTE cte = (TCTE) key;
1039                        resultSets.add(cte);
1040                }
1041                return resultSets;
1042        }
1043
1044        public List<TTable> getTableWithSelectSetResultSets() {
1045                List<TTable> resultSets = new ArrayList<TTable>();
1046
1047                Iterator iter = modelBindingMap.keySet().iterator();
1048                while (iter.hasNext()) {
1049                        Object key = iter.next();
1050                        if (!(key instanceof TTable)) {
1051                                continue;
1052                        }
1053
1054                        if (((TTable) key).getSubquery() == null)
1055                                continue;
1056                        TSelectSqlStatement stmt = ((TTable) key).getSubquery();
1057                        if (stmt.getSetOperatorType() == ESetOperatorType.none)
1058                                continue;
1059
1060                        resultSets.add((TTable) key);
1061                }
1062                return resultSets;
1063        }
1064
1065        public List<TParseTreeNode> getMergeResultSets() {
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 TMergeUpdateClause) && !(key instanceof TMergeInsertClause)) {
1072                                continue;
1073                        }
1074                        TParseTreeNode resultset = (TParseTreeNode) key;
1075                        resultSets.add(resultset);
1076                }
1077                return resultSets;
1078        }
1079
1080        public List<TParseTreeNode> getOutputResultSets() {
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 TOutputClause)) {
1087                                continue;
1088                        }
1089                        TParseTreeNode resultset = (TParseTreeNode) key;
1090                        resultSets.add(resultset);
1091                }
1092                return resultSets;
1093        }
1094
1095        public List<TParseTreeNode> getUpdateResultSets() {
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 TUpdateSqlStatement)) {
1102                                continue;
1103                        }
1104                        TParseTreeNode resultset = (TParseTreeNode) key;
1105                        resultSets.add(resultset);
1106                }
1107                return resultSets;
1108        }
1109
1110        public List<TParseTreeNode> getFunctoinCalls() {
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 TFunctionCall) && !(key instanceof TCaseExpression)) {
1117                                continue;
1118                        }
1119                        TParseTreeNode resultset = (TParseTreeNode) key;
1120                        resultSets.add(resultset);
1121                }
1122                return resultSets;
1123        }
1124
1125        public List<TParseTreeNode> getAliases() {
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 TAliasClause)) {
1132                                continue;
1133                        }
1134                        TParseTreeNode resultset = (TParseTreeNode) key;
1135                        resultSets.add(resultset);
1136                }
1137                return resultSets;
1138        }
1139        
1140        public List<TParseTreeNode> getCursors() {
1141                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1142
1143                Iterator iter = modelBindingMap.keySet().iterator();
1144                while (iter.hasNext()) {
1145                        Object key = iter.next();
1146                        if (!(key instanceof TCursorDeclStmt) && !(key instanceof TOpenforStmt)) {
1147                                continue;
1148                        }
1149                        TParseTreeNode resultset = (TParseTreeNode) key;
1150                        resultSets.add(resultset);
1151                }
1152                return resultSets;
1153        }
1154        
1155        public List<TParseTreeNode> getPivotdTables() {
1156                List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>();
1157
1158                Iterator iter = modelBindingMap.keySet().iterator();
1159                while (iter.hasNext()) {
1160                        Object key = iter.next();
1161                        if (!(key instanceof TPivotClause)) {
1162                                continue;
1163                        }
1164                        TParseTreeNode resultset = (TParseTreeNode) key;
1165                        resultSets.add(resultset);
1166                }
1167                return resultSets;
1168        }
1169
1170        public void addRelation(Relationship relation) {
1171                if (relation != null && !relationHolder.contains(relation)) {
1172                        relationHolder.add(relation);
1173                }
1174        }
1175        
1176        public void removeRelation(ImpactRelationship relation) {
1177                if (relation != null) {
1178                        relationHolder.remove(relation);
1179                }
1180        }
1181
1182        public Relationship[] getRelations() {
1183                return relationHolder.toArray(new Relationship[0]);
1184        }
1185
1186        public void reset() {
1187                modelBindingMap.clear();
1188                processModelBindingMap.clear();
1189                viewModelBindingMap.clear();
1190                insertModelBindingMap.clear();
1191                createModelBindingMap.clear();
1192                createModelQuickBindingMap.clear();
1193                mergeModelBindingMap.clear();
1194                updateModelBindingMap.clear();
1195                cursorModelBindingMap.clear();
1196                functionTableMap.clear();
1197                tableNamesMap.clear();
1198                procedureNamesMap.clear();
1199                oraclePackageNamesMap.clear();
1200                relationHolder.clear();
1201                tableAliasMap.clear();
1202                tableHashMap.clear();
1203                topStmtHashMap.clear();
1204                hashSQLMap.clear();
1205                dynamicSQLMap.clear();
1206                tableSet.clear();
1207                resultSetSet.clear();
1208                dblinkTableSet.clear();
1209                DISPLAY_ID.clear();
1210                DISPLAY_NAME.clear();
1211                virtualTableNames.clear();
1212        }
1213
1214        public void bindCursorModel(TCursorDeclStmt stmt, Variable resultSet) {
1215                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1216                String variableString = stmt.getCursorName().toString();
1217                if (variableString.startsWith(":")) {
1218                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1219                }
1220                if (!SQLUtil.isEmpty(procedureName)) {
1221                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1222                }
1223                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1224        }
1225        
1226        public void bindCursorModel(TMssqlDeclare stmt, Variable resultSet) {
1227                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1228                String variableString = stmt.getCursorName().toString();
1229                if (variableString.startsWith(":")) {
1230                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1231                }
1232                if (!SQLUtil.isEmpty(procedureName)) {
1233                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1234                }
1235                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1236        }
1237        
1238        public void bindCursorModel(TOpenforStmt stmt, Variable resultSet) {
1239                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1240                String variableString = stmt.getCursorVariableName().toString();
1241                if (variableString.startsWith(":")) {
1242                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1243                }
1244                if (!SQLUtil.isEmpty(procedureName)) {
1245                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1246                }
1247                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1248        }
1249        
1250        public void bindCursorModel(TForStmt stmt, Variable resultSet) {
1251                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1252                String variableString = stmt.getCursorName().toString();
1253                if (variableString.startsWith(":")) {
1254                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1255                }
1256                if (!SQLUtil.isEmpty(procedureName)) {
1257                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1258                }
1259                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1260        }
1261        
1262        public void bindCursorModel(TLoopStmt stmt, Variable resultSet) {
1263                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1264                String variableString = stmt.getRecordName().toString();
1265                if (variableString.startsWith(":")) {
1266                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1267                }
1268                if (!SQLUtil.isEmpty(procedureName)) {
1269                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1270                }
1271                createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet);
1272        }
1273
1274        public void bindCursorIndex(TObjectName indexName, TObjectName cursorName) {
1275                TCustomSqlStatement stmt = getGlobalStmtStack().peek();
1276                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1277                String variableString = cursorName.toString();
1278                if (variableString.startsWith(":")) {
1279                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1280                }
1281                if (!SQLUtil.isEmpty(procedureName)) {
1282                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1283                }
1284                
1285                Cursor cursor = ((Cursor) createModelBindingMap
1286                                .get(DlineageUtil.getTableFullName(variableString)));
1287                if (cursor != null) {
1288                        String indexNameString = indexName.toString();
1289                        if (!SQLUtil.isEmpty(procedureName)) {
1290                                indexNameString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(indexNameString);
1291                        }
1292                        bindModel(DlineageUtil.getTableFullName(indexNameString),
1293                                        modelBindingMap.get(cursor.getResultColumnObject()));
1294                        bindTableByName(DlineageUtil.getTableFullName(indexNameString),
1295                                        cursor);
1296                }
1297        }
1298
1299        public List<TStoredProcedureSqlStatement> getProcedures() {
1300                List<TStoredProcedureSqlStatement> procedures = new ArrayList();
1301                Iterator iter = this.modelBindingMap.keySet().iterator();
1302
1303                while (iter.hasNext()) {
1304                        Object key = iter.next();
1305                        if (key instanceof TStoredProcedureSqlStatement) {
1306                                TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) key;
1307                                procedures.add(procedure);
1308                        }
1309                }
1310
1311                return procedures;
1312        }
1313
1314        // public void bindTableByName(TObjectName tableName, Table tableModel) {
1315        // tableNamesMap.put(tableName, tableModel);
1316        //
1317        // }
1318        //
1319        public void bindTableByName(String tableName, Table tableModel) {
1320                tableNamesMap.put(tableName, tableModel);
1321
1322        }
1323
1324        // public Table getTableByName(TObjectName tableName) {
1325        // return (Table)tableNamesMap.get(tableName);
1326        // }
1327
1328        public Table getTableByName(String tableName) {
1329                Table table = (Table) tableNamesMap.get(tableName);
1330                if (table == null) {
1331                        TCustomSqlStatement stmt = getGlobalStmtStack().peek();
1332                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
1333                        String variableString = tableName.toString();
1334                        if (!SQLUtil.isEmpty(procedureName)) {
1335                                String variableWithProcedure = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1336                                if(tableNamesMap.containsKey(DlineageUtil.getTableFullName(variableWithProcedure))) {
1337                                        return  (Table) tableNamesMap.get(DlineageUtil.getTableFullName(variableWithProcedure));
1338                                }
1339                        }
1340                        return (Table) tableNamesMap.get(DlineageUtil.getTableFullName(variableString));
1341                } else {
1342                        return table;
1343                }
1344        }
1345
1346
1347        public void bindProcedureByName(String procedureName, Procedure procedureModel) {
1348                procedureNamesMap.put(procedureName, procedureModel);
1349
1350        }
1351        
1352        public Procedure getProcedureByName(String procedureName) {
1353                if(procedureName == null){
1354                        return null;
1355                }
1356
1357                if (ModelBindingManager.getGlobalOraclePackage() != null
1358                                && !procedureName.startsWith(ModelBindingManager.getGlobalOraclePackage().getName())) {
1359                        procedureName = ModelBindingManager.getGlobalOraclePackage().getName() + "." + procedureName;
1360                }
1361                Procedure procedure = (Procedure) procedureNamesMap.get(procedureName);
1362                if (procedure == null) {
1363                        if (procedureName.indexOf("(") == -1) {
1364                                for (Object name : procedureNamesMap.keySet()) {
1365                                        String fuctionName = name.toString();
1366                                        if (fuctionName.startsWith(procedureName + "(")) {
1367                                                return (Procedure) procedureNamesMap.get(name);
1368                                        }
1369                                        if (fuctionName.indexOf(".") != -1 && procedureName.indexOf(".") == -1) {
1370                                                fuctionName = fuctionName.substring(fuctionName.lastIndexOf(".") + 1);
1371                                                if (fuctionName.startsWith(procedureName + "(")) {
1372                                                        return (Procedure) procedureNamesMap.get(name);
1373                                                }
1374                                        }
1375                                        if (fuctionName.indexOf(".") == -1 && procedureName.indexOf(".") != -1) {
1376                                                String procedureNameSubstring = procedureName.substring(procedureName.lastIndexOf(".") + 1);
1377                                                if (fuctionName.startsWith(procedureNameSubstring + "(")) {
1378                                                        return (Procedure) procedureNamesMap.get(name);
1379                                                }
1380                                        }
1381                                }
1382                        }
1383                        else {
1384                                for (Object name : procedureNamesMap.keySet()) {
1385                                        String fuctionName = name.toString();
1386                                        if (fuctionName.startsWith(procedureName)) {
1387                                                return (Procedure) procedureNamesMap.get(name);
1388                                        }
1389                                        if (fuctionName.indexOf(".") != -1 && procedureName.indexOf(".") == -1) {
1390                                                fuctionName = fuctionName.substring(fuctionName.lastIndexOf(".") + 1);
1391                                                if (fuctionName.equalsIgnoreCase(procedureName)) {
1392                                                        return (Procedure) procedureNamesMap.get(name);
1393                                                }
1394                                        }
1395                                        if (fuctionName.indexOf(".") == -1 && procedureName.indexOf(".") != -1) {
1396                                                String procedureNameSubstring = procedureName.substring(procedureName.lastIndexOf(".") + 1);
1397                                                if (fuctionName.equalsIgnoreCase(procedureNameSubstring)) {
1398                                                        return (Procedure) procedureNamesMap.get(name);
1399                                                }
1400                                        }
1401                                }
1402                        }
1403                }
1404                return procedure;
1405        }
1406        
1407        public void bindOraclePackageByName(String oraclePackageName, OraclePackage oraclePackageModel) {
1408                oraclePackageNamesMap.put(oraclePackageName, oraclePackageModel);
1409
1410        }
1411        
1412        public OraclePackage getOraclePackageByName(String oraclePackageName) {
1413                return (OraclePackage) oraclePackageNamesMap.get(oraclePackageName);
1414        }
1415
1416
1417        public String getSqlHash(TCustomSqlStatement stmt) {
1418                return topStmtHashMap.get(stmt);
1419        }
1420
1421        public Map getHashSQLMap() {
1422                return hashSQLMap;
1423        }
1424
1425        public Map getDynamicSQLMap() {
1426                return dynamicSQLMap;
1427        }
1428
1429        public void collectSqlHash(TCustomSqlStatement stmt) {
1430                if (getGlobalOption().getAnalyzeMode() == AnalyzeMode.crud) {
1431                        String sql = stmt.toString();
1432                        if (sql != null) {
1433                                sql = stmt.getStartToken().lineNo + ":" + sql;
1434                                String hash = SQLUtil.stringToMD5(sql);
1435                                topStmtHashMap.put(stmt, hash);
1436                                hashSQLMap.put(hash, new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, stmt.getEndToken().lineNo, ModelBindingManager.getGlobalHash()));
1437                        }
1438                } else {
1439                        String sql = stmt.asCanonical();
1440                        if (sql != null) {
1441                                String hash = SQLUtil.stringToMD5(sql);
1442                                topStmtHashMap.put(stmt, hash);
1443                                hashSQLMap.put(hash, sql);
1444                        }
1445                }
1446        }
1447        
1448        public void collectDynamicSqlHash(TCustomSqlStatement stmt) {
1449                if (getGlobalOption().getAnalyzeMode() == AnalyzeMode.dynamic) {
1450                        String sql = stmt.toString();
1451                        if (sql != null) {
1452                                sql = stmt.getStartToken().lineNo + ":" + sql;
1453                                String hash = SQLUtil.stringToMD5(sql);
1454                                dynamicSQLMap.put(hash, new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, stmt.getEndToken().lineNo, ModelBindingManager.getGlobalHash()));
1455                        }
1456                }
1457        }
1458
1459        public void appendDblinkTable(String name) {
1460                if (!SQLUtil.isEmpty(name)) {
1461                        dblinkTableSet.add(name);
1462                }
1463        }
1464        
1465        public boolean isDblinkTable(String name) {
1466                return dblinkTableSet.contains(name);
1467        }
1468
1469        public Set<ResultSet> getResultSets() {
1470                return resultSetSet;
1471        }
1472        
1473        public void dropTable(Table table) {
1474                List tableNames = new ArrayList(tableNamesMap.keySet());
1475                for (Object tableName : tableNames) {
1476                        if(tableNamesMap.get(tableName) == table) {
1477                                tableNamesMap.remove(tableName);
1478                                dropTables.add(table);
1479                        }
1480                }
1481        }
1482        
1483        public void cleanTempTable() {
1484                Iterator<String> iter = tableNamesMap.keySet().iterator();
1485                while(iter.hasNext()) {
1486                        String tableName = iter.next();
1487                        if(DlineageUtil.isTempTable((Table)tableNamesMap.get(tableName), getGlobalVendor())) {
1488                                dropTables.add((Table)tableNamesMap.get(tableName));
1489                                iter.remove();
1490                        }
1491                }
1492        }
1493
1494        public Set<Table> getDropTables() {
1495                return dropTables;
1496        }
1497        
1498        
1499        
1500}