001
002package gudusoft.gsqlparser.dlineage.dataflow.model;
003
004import gudusoft.gsqlparser.EDbVendor;
005import gudusoft.gsqlparser.ESqlStatementType;
006import gudusoft.gsqlparser.ETableSource;
007import gudusoft.gsqlparser.TCustomSqlStatement;
008import gudusoft.gsqlparser.dlineage.util.DlineageUtil;
009import gudusoft.gsqlparser.dlineage.util.Objects;
010import gudusoft.gsqlparser.dlineage.util.Pair;
011import gudusoft.gsqlparser.nodes.TAliasClause;
012import gudusoft.gsqlparser.nodes.TCaseExpression;
013import gudusoft.gsqlparser.nodes.TConstant;
014import gudusoft.gsqlparser.nodes.TDeclareVariable;
015import gudusoft.gsqlparser.nodes.TExpression;
016import gudusoft.gsqlparser.nodes.TFunctionCall;
017import gudusoft.gsqlparser.nodes.TObjectName;
018import gudusoft.gsqlparser.nodes.TObjectNameList;
019import gudusoft.gsqlparser.nodes.TParameterDeclaration;
020import gudusoft.gsqlparser.nodes.TParseTreeNode;
021import gudusoft.gsqlparser.nodes.TPivotClause;
022import gudusoft.gsqlparser.nodes.TResultColumn;
023import gudusoft.gsqlparser.nodes.TTable;
024import gudusoft.gsqlparser.nodes.TWhenClauseItemList;
025import gudusoft.gsqlparser.sqlenv.TSQLColumn;
026import gudusoft.gsqlparser.sqlenv.TSQLEnv;
027import gudusoft.gsqlparser.sqlenv.TSQLTable;
028import gudusoft.gsqlparser.stmt.TCreateTableSqlStatement;
029import gudusoft.gsqlparser.stmt.TCreateViewSqlStatement;
030import gudusoft.gsqlparser.stmt.TCursorDeclStmt;
031import gudusoft.gsqlparser.stmt.TForStmt;
032import gudusoft.gsqlparser.stmt.TInsertSqlStatement;
033import gudusoft.gsqlparser.stmt.TLoopStmt;
034import gudusoft.gsqlparser.stmt.TMergeSqlStatement;
035import gudusoft.gsqlparser.stmt.TOpenforStmt;
036import gudusoft.gsqlparser.stmt.TSelectSqlStatement;
037import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement;
038import gudusoft.gsqlparser.stmt.mssql.TMssqlDeclare;
039import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreatePackage;
040import gudusoft.gsqlparser.util.SQLUtil;
041
042import java.util.ArrayList;
043import java.util.LinkedHashMap;
044import java.util.List;
045import java.util.Map;
046import java.util.Set;
047
048public class ModelFactory {
049
050        private ModelBindingManager modelManager;
051
052        public ModelFactory(ModelBindingManager modelManager) {
053                this.modelManager = modelManager;
054        }
055
056        public ResultSet createResultSet(TSelectSqlStatement select, boolean isTarget) {
057                if (select.getResultColumnList() != null) {
058                        if (modelManager.getModel(select.getResultColumnList()) instanceof ResultSet) {
059                                return (ResultSet) modelManager.getModel(select.getResultColumnList());
060                        }
061                        SelectResultSet resultSet = new SelectResultSet(select, isTarget);
062                        modelManager.bindModel(select.getResultColumnList(), resultSet);
063                        return resultSet;
064                } else if (select.getTransformClause() != null) {
065                        if (modelManager.getModel(select.getTransformClause()) instanceof ResultSet) {
066                                return (ResultSet) modelManager.getModel(select.getTransformClause());
067                        }
068                        SelectResultSet resultSet = new SelectResultSet(select, isTarget);
069                        modelManager.bindModel(select.getTransformClause(), resultSet);
070                        return resultSet;
071                } else
072                        return null;
073        }
074
075        public ResultSet createResultSet(TParseTreeNode gspObject, boolean isTarget) {
076                if (modelManager.getModel(gspObject) instanceof ResultSet) {
077                        return (ResultSet) modelManager.getModel(gspObject);
078                }
079                ResultSet resultSet = new ResultSet(gspObject, isTarget);
080                modelManager.bindModel(gspObject, resultSet);
081                return resultSet;
082        }
083
084        public ResultColumn createResultColumn(ResultSet resultSet, TResultColumn resultColumn) {
085                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
086                        return (ResultColumn) modelManager.getModel(resultColumn);
087                }
088                ResultColumn column = new ResultColumn(resultSet, resultColumn);
089                modelManager.bindModel(resultColumn, column);
090                return column;
091        }
092
093        public ResultColumn createStarResultColumn(ResultSet resultSetModel, TResultColumn resultColumn,
094                        String refColumnName) {
095                if (modelManager.getModel(resultColumn) instanceof LinkedHashMap) {
096                        LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) modelManager
097                                        .getModel(resultColumn);
098                        if (resultColumns.containsKey(refColumnName)) {
099                                return resultColumns.get(refColumnName);
100                        }
101
102                        ResultColumn column = new ResultColumn(resultSetModel, resultColumn, refColumnName);
103                        resultColumns.put(refColumnName, column);
104                        return column;
105                } else {
106                        LinkedHashMap<String, ResultColumn> resultColumns = new LinkedHashMap<String, ResultColumn>();
107                        ResultColumn column = new ResultColumn(resultSetModel, resultColumn, refColumnName);
108                        resultColumns.put(refColumnName, column);
109                        modelManager.bindModel(resultColumn, resultColumns);
110                        return column;
111                }
112        }
113
114        public ResultColumn createSelectSetResultColumn(ResultSet resultSet, ResultColumn resultColumn) {
115                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
116                        return (ResultColumn) modelManager.getModel(resultColumn);
117                }
118                String columnName = DlineageUtil.getIdentifierNormalColumnName(resultColumn.getName());
119                for (int i = 0; i < resultSet.getColumns().size(); i++) {
120                        ResultColumn columnModel = resultSet.getColumns().get(i);
121                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
122                                modelManager.bindModel(resultColumn, columnModel);
123                                return columnModel;
124                        }
125                }
126                ResultColumn column = new SelectSetResultColumn(resultSet, resultColumn);
127                if(resultColumn.isStruct()) {
128                        column.setStruct(true);
129                }
130                modelManager.bindModel(resultColumn, column);
131                return column;
132        }
133
134        public ResultColumn createSelectSetResultColumn(ResultSet resultSet, TResultColumn resultColumn, int index) {
135                
136                for (int i = 0; i < resultSet.getColumns().size(); i++) {
137                        ResultColumn columnModel = resultSet.getColumns().get(i);
138                        if(columnModel.getColumnObject() == resultColumn) {
139                                return columnModel;
140                        }
141                }
142                
143                SelectSetResultColumn column = new SelectSetResultColumn(resultSet, resultColumn, index);
144                modelManager.bindModel(resultColumn, column);
145                return column;
146        }
147
148        public ResultColumn createAndBindingSelectSetResultColumn(ResultSet resultSet, TResultColumn resultColumn,
149                        int index) {
150                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
151                        return (ResultColumn) modelManager.getModel(resultColumn);
152                }
153                ResultColumn column = new SelectSetResultColumn(resultSet, resultColumn, index);
154                modelManager.bindModel(resultColumn, column);
155                return column;
156        }
157
158        public ResultColumn createResultColumn(ResultSet resultSet, TObjectName resultColumn) {
159                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
160                        return (ResultColumn) modelManager.getModel(resultColumn);
161                }
162                if(EDbVendor.dbvoracle == ModelBindingManager.getGlobalVendor()){
163                        ResultColumn column = new ResultColumn(resultSet, resultColumn);
164                        modelManager.bindModel(resultColumn, column);
165                        return column;
166                }
167                else {
168                        String columnName = DlineageUtil.getIdentifierNormalColumnName(resultColumn.toString());
169                        for (int i = 0; i < resultSet.getColumns().size(); i++) {
170                                ResultColumn columnModel = resultSet.getColumns().get(i);
171                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
172                                        modelManager.bindModel(resultColumn, columnModel);
173                                        return columnModel;
174                                }
175                        }
176                        ResultColumn column = new ResultColumn(resultSet, resultColumn);
177                        modelManager.bindModel(resultColumn, column);
178                        return column;
179                }
180        }
181        
182        public ResultColumn createDeterminedResultColumn(ResultSet resultSet, TObjectName resultColumn) {
183                ResultColumn column = new ResultColumn(resultSet, resultColumn);
184                modelManager.bindModel(resultColumn, column);
185                return column;
186        }
187
188        public ResultColumn createResultColumn(ResultSet resultSet, TExpression expression) {
189                if (modelManager.getModel(expression) instanceof ResultColumn) {
190                        return (ResultColumn) modelManager.getModel(expression);
191                }
192                ResultColumn column = new ResultColumn(resultSet, expression);
193                modelManager.bindModel(expression, column);
194                return column;
195        }
196
197        public ResultColumn createResultColumn(ResultSet resultSet, TObjectName resultColumn, boolean forceCreate) {
198                if (!forceCreate) {
199                        if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
200                                return (ResultColumn) modelManager.getModel(resultColumn);
201                        }
202                }
203
204                String columnName = DlineageUtil.getIdentifierNormalColumnName(resultColumn.toString());
205                for (int i = 0; i < resultSet.getColumns().size(); i++) {
206                        ResultColumn columnModel = resultSet.getColumns().get(i);
207                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
208                                modelManager.bindModel(resultColumn, columnModel);
209                                return columnModel;
210                        }
211                }
212
213                ResultColumn column = new ResultColumn(resultSet, resultColumn);
214                modelManager.bindModel(resultColumn, column);
215                return column;
216        }
217
218        public FunctionResultColumn createFunctionResultColumn(Function function, TObjectName functionName) {
219                if (modelManager.getModel(functionName) instanceof FunctionResultColumn) {
220                        return (FunctionResultColumn) modelManager.getModel(functionName);
221                }
222                FunctionResultColumn column = new FunctionResultColumn(function, function.getFunctionObject(), functionName);
223                modelManager.bindModel(functionName, column);
224                return column;
225        }
226
227        public FunctionResultColumn createFunctionResultColumn(Function function, TWhenClauseItemList caseFunction) {
228                if (modelManager.getModel(caseFunction) instanceof FunctionResultColumn) {
229                        return (FunctionResultColumn) modelManager.getModel(caseFunction);
230                }
231                FunctionResultColumn column = new FunctionResultColumn(function, function.getFunctionObject(), caseFunction);
232                modelManager.bindModel(caseFunction, column);
233                return column;
234        }
235
236        public ResultColumn createMergeResultColumn(ResultSet resultSet, TObjectName resultColumn) {
237                if (modelManager.getMergeModel(resultColumn) instanceof ResultColumn) {
238                        return (ResultColumn) modelManager.getMergeModel(resultColumn);
239                }
240                ResultColumn column = new ResultColumn(resultSet, resultColumn);
241                modelManager.bindMergeModel(resultColumn, column);
242                return column;
243        }
244
245        public ResultColumn createUpdateResultColumn(ResultSet resultSet, TObjectName resultColumn) {
246                if (modelManager.getUpdateModel(resultColumn) instanceof ResultColumn) {
247                        return (ResultColumn) modelManager.getUpdateModel(resultColumn);
248                }
249                ResultColumn column = new ResultColumn(resultSet, resultColumn);
250                modelManager.bindUpdateModel(resultColumn, column);
251                return column;
252        }
253
254        public ResultColumn createResultColumn(QueryTable queryTableModel, TResultColumn resultColumn) {
255                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
256                        return (ResultColumn) modelManager.getModel(resultColumn);
257                }
258                ResultColumn column = new ResultColumn(queryTableModel, resultColumn);
259                modelManager.bindModel(resultColumn, column);
260                return column;
261        }
262        
263        public Table createTableFromCreateDDL(TTable table, boolean fromDDL, String tableName) {
264                if (modelManager.getCreateModel(table) instanceof Table) {
265                        return (Table) modelManager.getCreateModel(table);
266                }
267                if (modelManager.getModel(table) instanceof Table) {
268                        return (Table) modelManager.getModel(table);
269                }
270                if (modelManager
271                                .getTableByName(DlineageUtil.getTableFullName(tableName.toString())) instanceof Table) {
272                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(tableName.toString()));
273                }
274                if (modelManager.getTableByName(
275                                DlineageUtil.getTableFullNameWithDefaultSchema(tableName.toString())) instanceof Table) {
276                        return (Table) modelManager
277                                        .getTableByName(DlineageUtil.getTableFullNameWithDefaultSchema(tableName.toString()));
278                }
279                Table tableModel = new Table(table, tableName);
280                tableModel.setCreateTable(fromDDL);
281                if (!fromDDL) {
282                        Table existTable = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getName()));
283                        if (existTable != null) {
284                                return existTable;
285                        }
286                }
287                modelManager.bindCreateModel(table, tableModel);
288                if(table.getTableType() == ETableSource.unnest) {
289                        
290                }
291                else {
292                        modelManager.bindTableByName(DlineageUtil.getTableFullName(tableName.toString()), tableModel);
293                }
294                return tableModel;
295        }
296
297        public Table createTableFromCreateDDL(TTable table, boolean fromDDL) {
298                if (modelManager.getCreateModel(table) instanceof Table) {
299                        return (Table) modelManager.getCreateModel(table);
300                }
301                if (modelManager.getModel(table) instanceof Table) {
302                        return (Table) modelManager.getModel(table);
303                }
304                if (modelManager
305                                .getTableByName(DlineageUtil.getTableFullName(table.getTableName().toString())) instanceof Table) {
306                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(table.getTableName().toString()));
307                }
308                if (modelManager.getTableByName(
309                                DlineageUtil.getTableFullNameWithDefaultSchema(table.getTableName().toString())) instanceof Table) {
310                        return (Table) modelManager
311                                        .getTableByName(DlineageUtil.getTableFullNameWithDefaultSchema(table.getTableName().toString()));
312                }
313                Table tableModel = new Table(table);
314                tableModel.setCreateTable(fromDDL, fromDDL);
315                if (!fromDDL) {
316                        Table existTable = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getName()));
317                        if (existTable != null) {
318                                return existTable;
319                        }
320                }
321                modelManager.bindCreateModel(table, tableModel);
322                modelManager.bindTableByName(DlineageUtil.getTableFullName(table.getTableName().toString()), tableModel);
323                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableModel.getName()), tableModel);
324                return tableModel;
325        }
326
327        public Table createJsonTable(TTable table) {
328                String tableName = table.toString();
329                if (tableName.toLowerCase().indexOf("with") != -1) {
330                        tableName = table.toString().substring(0, tableName.toLowerCase().indexOf("with")).trim();
331                }
332
333                if (table.isLinkTable()) {
334                        table = table.getLinkTable();
335                }
336
337                if (modelManager.getCreateTable(table) != null) {
338                        return modelManager.getCreateTable(table);
339                }
340                if (modelManager.getModel(table) instanceof Table) {
341                        return (Table) modelManager.getModel(table);
342                }
343                if (modelManager.getTableByName(DlineageUtil.getTableFullName(tableName)) instanceof Table) {
344                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(tableName));
345                }
346
347                if (modelManager.getTableByName(DlineageUtil.getTableFullNameWithDefaultSchema(tableName)) instanceof Table) {
348                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullNameWithDefaultSchema(tableName));
349                }
350
351                Table tableModel = new Table(table);
352                tableModel.setName(tableName);
353                modelManager.bindModel(table, tableModel);
354                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableName), tableModel);
355                return tableModel;
356        }
357
358        public Table createTable(TTable table, TObjectName tableBinding) {
359                Table tableModel = createTable(table);
360                modelManager.bindModel(table, tableModel);
361                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableBinding.toString()), tableModel);
362                return tableModel;
363        }
364
365        public Table createTable(TTable table) {
366                if (table.isLinkTable()) {
367                        table = table.getLinkTable();
368                }
369
370                Table tableModel = null;
371                if (modelManager.getCreateTable(table) != null) {
372                        tableModel = modelManager.getCreateTable(table);
373                }
374                if (tableModel == null && modelManager.getModel(table) instanceof Table) {
375                        tableModel = (Table) modelManager.getModel(table);
376                }
377
378                String tableName = table.getTableName().toString();
379                if (table.getSubquery() != null && table.getAliasClause() != null) {
380                        tableName = table.getAliasClause().toString();
381                }
382
383                if (tableModel == null
384                                && modelManager.getTableByName(DlineageUtil.getTableFullName(tableName)) instanceof Table) {
385                        tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(tableName));
386                }
387
388                if (tableModel == null && modelManager
389                                .getTableByName(DlineageUtil.getTableFullNameWithDefaultSchema(tableName)) instanceof Table) {
390                        tableModel = modelManager.getTableByName(DlineageUtil.getTableFullNameWithDefaultSchema(tableName));
391                }
392
393                if (tableModel != null) {
394                        if (table.getAliasClause() != null) {
395                                tableModel.setAlias(table.getAliasName());
396                        }
397                        tableModel.setCurrentAlias(table.getAliasName());
398                        modelManager.updateTableAliasMap(table);
399                        return tableModel;
400                }
401
402                tableModel = new Table(table);
403                Table existTable = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getName()));
404                if (existTable != null) {
405                        return existTable;
406                }
407                modelManager.bindModel(table, tableModel);
408                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableName), tableModel);
409                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableModel.getName()), tableModel);
410
411                appendTableColumns(tableModel);
412
413                return tableModel;
414        }
415
416        protected void appendTableColumns(Table tableModel) {
417                TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().peek();
418                if (stmt instanceof TCreateTableSqlStatement || stmt instanceof TCreateViewSqlStatement) {
419                        return;
420                }
421                if (stmt instanceof TInsertSqlStatement && ((TInsertSqlStatement) stmt).getColumnList() != null) {
422                        return;
423                }
424                if (ModelBindingManager.getGlobalSQLEnv() != null) {
425                        ArrayList<String> columns = ModelBindingManager.getGlobalSQLEnv()
426                                        .getColumnsInTable(DlineageUtil.getTableFullName(tableModel.getName()), true);
427                        if (columns != null && !columns.isEmpty()) {
428                                for (String column : columns) {
429                                        if (SQLUtil.isEmpty(column)) {
430                                                continue;
431                                        }
432                                        createInsertTableColumn(tableModel, column);
433                                }
434                                tableModel.setFromDDL(true);
435                                tableModel.setCreateTable(true);
436                        }
437                }
438        }
439
440        public Table createTriggerOnTable(TTable table) {
441                if (modelManager.getCreateTable(table) != null) {
442                        return modelManager.getCreateTable(table);
443                }
444                if (modelManager.getModel(table) instanceof Table) {
445                        return (Table) modelManager.getModel(table);
446                }
447                if (modelManager
448                                .getTableByName(DlineageUtil.getTableFullName(table.getTableName().toString())) instanceof Table) {
449                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(table.getTableName().toString()));
450                }
451                if (modelManager.getTableByName(
452                                DlineageUtil.getTableFullNameWithDefaultSchema(table.getTableName().toString())) instanceof Table) {
453                        return (Table) modelManager
454                                        .getTableByName(DlineageUtil.getTableFullNameWithDefaultSchema(table.getTableName().toString()));
455                }
456                Table tableModel = new Table(table);
457                Table existTable = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getName()));
458                if (existTable != null) {
459                        return existTable;
460                }
461                modelManager.bindModel(table, tableModel);
462                modelManager.bindTableByName(DlineageUtil.getTableFullName(table.getTableName().toString()), tableModel);
463                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableModel.getName()), tableModel);
464                return tableModel;
465        }
466
467        public Table createTableByName(TObjectName tableName) {
468                return createTableByName(tableName, false);
469        }
470
471        public Table createTableByName(TObjectName tableName, boolean create) {
472                if (modelManager.getTableByName(DlineageUtil.getTableFullName(tableName.toString())) instanceof Table) {
473                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(tableName.toString()));
474                }
475                Table tableModel = new Table(tableName);
476                Table existTable = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getName()));
477                if (existTable != null) {
478                        return existTable;
479                }
480                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
481                        tableModel.addColumnsFromSQLEnv();
482                }
483                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableName.toString()), tableModel);
484                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableModel.getName()), tableModel);
485                if (create) {
486                        modelManager.bindCreateModel(tableName, tableModel);
487                }
488                return tableModel;
489        }
490
491        public Table createTableByName(String tableName, boolean create) {
492                if (modelManager.getTableByName(DlineageUtil.getTableFullName(tableName.toString())) instanceof Table) {
493                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(tableName.toString()));
494                }
495                Table tableModel = new Table(tableName);
496                Table existTable = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getName()));
497                if (existTable != null) {
498                        return existTable;
499                }
500                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
501                        tableModel.addColumnsFromSQLEnv();
502                }
503                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableName.toString()), tableModel);
504                modelManager.bindTableByName(DlineageUtil.getTableFullName(tableModel.getName()), tableModel);
505                if (create) {
506                        modelManager.bindCreateModel(tableName, tableModel);
507                }
508                return tableModel;
509        }
510
511        public Table createStage(TObjectName stageName) {
512                if (modelManager.getTableByName(DlineageUtil.getTableFullName(stageName.toString())) instanceof Table) {
513                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(stageName.toString()));
514                }
515                Table tableModel = new Table(stageName);
516                modelManager.bindTableByName(DlineageUtil.getTableFullName(stageName.toString()), tableModel);
517                modelManager.bindCreateModel(stageName, tableModel);
518
519                TObjectName stageVariableName = new TObjectName();
520                stageVariableName.setString("@" + stageName.getColumnNameOnly());
521                modelManager.bindCreateModel(stageVariableName, tableModel);
522
523                return tableModel;
524        }
525
526        public Table createDataSource(TObjectName dataSourceName) {
527                if (modelManager.getTableByName(DlineageUtil.getTableFullName(dataSourceName.toString())) instanceof Table) {
528                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(dataSourceName.toString()));
529                }
530                Table tableModel = new Table(dataSourceName);
531                tableModel.setDataSource(true);
532                modelManager.bindTableByName(DlineageUtil.getTableFullName(dataSourceName.toString()), tableModel);
533                modelManager.bindCreateModel(dataSourceName, tableModel);
534
535                return tableModel;
536        }
537
538        public Table createStream(TObjectName streamName) {
539                if (modelManager.getTableByName(DlineageUtil.getTableFullName(streamName.toString())) instanceof Table) {
540                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(streamName.toString()));
541                }
542                Table tableModel = new Table(streamName);
543                tableModel.setStream(true);
544                modelManager.bindTableByName(DlineageUtil.getTableFullName(streamName.toString()), tableModel);
545                modelManager.bindCreateModel(streamName, tableModel);
546                return tableModel;
547        }
548
549        public Table createConstantsTable(TCustomSqlStatement stmt) {
550                stmt = DlineageUtil.getTopStmt(stmt);
551                String sqlHash = String.valueOf(stmt.hashCode());
552                if (modelManager.getTableByName(sqlHash) instanceof Table) {
553                        return (Table) modelManager.getTableByName(sqlHash);
554                }
555                Table tableModel = new Table("SQL_CONSTANTS");
556                tableModel.setConstant(true);
557                modelManager.bindTableByName(sqlHash, tableModel);
558                modelManager.bindCreateModel(sqlHash, tableModel);
559                return tableModel;
560        }
561        
562        public Table createConstantsTable(String sqlHash) {
563                if (modelManager.getTableByName(sqlHash) instanceof Table) {
564                        return (Table) modelManager.getTableByName(sqlHash);
565                }
566                Table tableModel = new Table("SQL_CONSTANTS");
567                tableModel.setConstant(true);
568                modelManager.bindTableByName(sqlHash, tableModel);
569                modelManager.bindCreateModel(sqlHash, tableModel);
570                return tableModel;
571        }
572
573        public Table createJsonVariable(TObjectName jsonVariable) {
574                if (modelManager.getTableByName(DlineageUtil.getTableFullName(jsonVariable.toString())) instanceof Table) {
575                        return (Table) modelManager.getTableByName(DlineageUtil.getTableFullName(jsonVariable.toString()));
576                }
577                Table tableModel = new Table(jsonVariable);
578                modelManager.bindTableByName(DlineageUtil.getTableFullName(jsonVariable.toString()), tableModel);
579                modelManager.bindCreateModel(jsonVariable, tableModel);
580
581                modelManager.bindCreateModel(jsonVariable, tableModel);
582
583                return tableModel;
584        }
585
586        public Alias createAlias(TAliasClause aliasClause) {
587                if (modelManager.getModel(aliasClause) instanceof Alias) {
588                        return (Alias) modelManager.getModel(aliasClause);
589                }
590
591                Alias alias = new Alias(aliasClause);
592                modelManager.bindModel(aliasClause, alias);
593
594                return alias;
595        }
596
597        public Function createFunction(TFunctionCall functionCall) {
598                if (modelManager.getModel(functionCall) instanceof Function) {
599                        return (Function) modelManager.getModel(functionCall);
600                }
601
602                Function function = new Function(functionCall);
603                function.setDetermined(false);
604                modelManager.bindModel(functionCall, function);
605
606                return function;
607        }
608
609        public Function createFunction(TObjectName functionName) {
610                if (modelManager.getModel(functionName) instanceof Function) {
611                        return (Function) modelManager.getModel(functionName);
612                }
613
614                Function function = new Function(functionName);
615                function.setDetermined(false);
616                modelManager.bindModel(functionName, function);
617
618                return function;
619        }
620
621        public Function createFunction(TCaseExpression caseExpression) {
622                if (modelManager.getModel(caseExpression) instanceof Function) {
623                        return (Function) modelManager.getModel(caseExpression);
624                }
625
626                Function function = new Function(caseExpression);
627                modelManager.bindModel(caseExpression, function);
628
629                return function;
630        }
631
632        public QueryTable createQueryTable(TTable table) {
633                QueryTable tableModel = null;
634
635                if (table.getCTE() != null) {
636                        if (modelManager.getModel(table.getCTE()) instanceof QueryTable) {
637                                return (QueryTable) modelManager.getModel(table.getCTE());
638                        }
639
640                        tableModel = new QueryTable(table);
641
642                        modelManager.bindModel(table.getCTE(), tableModel);
643                } else if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null) {
644                        if (modelManager.getModel(table.getAliasClause().getColumns()) instanceof QueryTable) {
645                                return (QueryTable) modelManager.getModel(table.getAliasClause().getColumns());
646                        }
647
648                        tableModel = new QueryTable(table);
649                        TObjectNameList columns = table.getAliasClause().getColumns();
650                        modelManager.bindModel(columns, tableModel);
651                        for (int i = 0; i < columns.size(); i++) {
652                                createResultColumn(tableModel, columns.getObjectName(i));
653                        }
654                        modelManager.bindModel(table, tableModel);
655                } else if (table.getSubquery() != null && !table.getSubquery().isCombinedQuery()) {
656                        if (modelManager.getModel(table.getSubquery().getResultColumnList()) instanceof QueryTable) {
657                                return (QueryTable) modelManager.getModel(table.getSubquery().getResultColumnList());
658                        }
659
660                        tableModel = new QueryTable(table);
661                        if (table.getSubquery().getResultColumnList() != null) {
662                                modelManager.bindModel(table.getSubquery().getResultColumnList(), tableModel);
663                        } else if (table.getSubquery().getTransformClause() != null) {
664                                modelManager.bindModel(table.getSubquery().getTransformClause(), tableModel);
665                        }
666                        modelManager.bindModel(table, tableModel);
667                } else if (table.getOutputMerge() != null) {
668                        if (modelManager
669                                        .getModel(table.getOutputMerge().getOutputClause().getSelectItemList()) instanceof QueryTable) {
670                                return (QueryTable) modelManager.getModel(table.getOutputMerge().getOutputClause().getSelectItemList());
671                        }
672
673                        tableModel = new QueryTable(table);
674                        modelManager.bindModel(table.getOutputMerge().getOutputClause().getSelectItemList(), tableModel);
675                        modelManager.bindModel(table, tableModel);
676                } else {
677                        if (modelManager.getModel(table) instanceof QueryTable) {
678                                return (QueryTable) modelManager.getModel(table);
679                        }
680                        
681                        if(ModelBindingManager.getGlobalStmtStack().peek() instanceof TMergeSqlStatement) {
682                                TMergeSqlStatement mergeStmt = (TMergeSqlStatement)ModelBindingManager.getGlobalStmtStack().peek();
683                                if (modelManager.getModel(mergeStmt) instanceof QueryTable) {
684                                        return (QueryTable) modelManager.getModel(mergeStmt);
685                                }
686                                tableModel = new QueryTable(mergeStmt);
687                                modelManager.bindModel(mergeStmt, tableModel);
688                        }
689                        else {
690                                tableModel = new QueryTable(table);
691                                modelManager.bindModel(table, tableModel);
692                        }
693                }
694                return tableModel;
695        }
696
697        public TableColumn createTableColumn(Table table, TObjectName column, boolean fromCreateTable) {
698                if (modelManager.getModel(new Pair<Table, TObjectName>(table, column)) instanceof TableColumn) {
699                        return (TableColumn) modelManager.getModel(new Pair<Table, TObjectName>(table, column));
700                }
701
702                if (table.isCreateTable() && !fromCreateTable) {
703                        String columnName = DlineageUtil.getColumnName(column);
704                        for (int i = 0; i < table.getColumns().size(); i++) {
705                                TableColumn columnModel = table.getColumns().get(i);
706                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
707                                        return columnModel;
708                                }
709                        }
710
711                        for (int i = 0; i < table.getColumns().size(); i++) {
712                                TableColumn columnModel = table.getColumns().get(i);
713                                if (columnModel.isVariant()) {
714                                        columnModel.bindStarLinkColumn(column);
715                                        return columnModel;
716                                }
717                                if (columnModel.hasStarLinkColumn()) {
718                                        columnModel.bindStarLinkColumn(column);
719                                        return columnModel;
720                                }
721                        }
722                        
723                        if(table.isDetermined()) {
724                                return null;
725                        }
726                } else {
727                        String columnName = DlineageUtil.getColumnName(column);
728                        for (int i = 0; i < table.getColumns().size(); i++) {
729                                TableColumn columnModel = table.getColumns().get(i);
730                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
731                                        return columnModel;
732                                }
733                        }
734                }
735
736                if ("*".equals(column.toString())) {
737                        if (!fromCreateTable && table.isCreateTable()) {
738                                return null;
739                        }
740                        for (int i = 0; i < table.getColumns().size(); i++) {
741                                TableColumn columnModel = table.getColumns().get(i);
742                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals("*")) {
743                                        return columnModel;
744                                }
745                        }
746                }
747
748                if (table.isCreateTable() && !fromCreateTable && "*".equals(column.getColumnNameOnly())) {
749                        return null;
750                }
751
752                if (table.isDetermined() && "*".equals(column.getColumnNameOnly())) {
753                        return null;
754                }
755
756                TableColumn columnModel = new TableColumn(table, column);
757                modelManager.bindModel(new Pair<Table, TObjectName>(table, column), columnModel);
758
759                if ("*".equals(column.getColumnNameOnly())) {
760                        TSQLEnv sqlenv = ModelBindingManager.getGlobalSQLEnv();
761                        if (sqlenv != null && sqlenv.searchTable(getQualifiedTableName(table)) != null) {
762                                table.setHasSQLEnv(true);
763                                TSQLTable sqlTable = sqlenv.searchTable(getQualifiedTableName(table));
764                                if (sqlTable.getColumnList() != null) {
765                                        boolean isDetermine = true;
766                                        for (TSQLColumn sqlColumn : sqlTable.getColumnList()) {
767                                                TObjectName objectName = new TObjectName();
768                                                if(sqlColumn.getName() == null){
769                                                        System.err.println("sqlevn table " + getQualifiedTableName(table) + " sqlColumn getName() returns null.");
770                                                        continue;
771                                                }
772                                                if(sqlColumn.getName().endsWith("*")) {
773                                                        isDetermine = false;
774                                                        continue;
775                                                }
776                                                objectName.setString(sqlColumn.getName());
777                                                columnModel.bindStarLinkColumn(objectName);
778                                        }
779                                        if (isDetermine) {
780                                                columnModel.setShowStar(false);
781                                                columnModel.setExpandStar(true);
782                                        }
783                                }
784                        } else if (column.getSourceTable() != null) {
785                                TObjectNameList columns = column.getSourceTable().getLinkedColumns();
786                                Map<String, TObjectName> columnMap = new LinkedHashMap<String, TObjectName>();
787                                for (int i = 0; i < columns.size(); i++) {
788                                        TObjectName item = columns.getObjectName(i);
789                                        String columnName = item.getColumnNameOnly();
790                                        if (Objects.equal(item.getSourceTable(), column.getSourceTable()) && !"*".equals(columnName)) {
791                                                columnMap.put(DlineageUtil.getIdentifierNormalColumnName(columnName), item);
792                                        }
793                                }
794                                for (int i = 0; i < columns.size(); i++) {
795                                        TObjectName item = columns.getObjectName(i);
796                                        String columnName = item.getColumnNameOnly();
797                                        if (!Objects.equal(item.getSourceTable(), column.getSourceTable()) && !"*".equals(columnName)) {
798                                                String key = DlineageUtil.getIdentifierNormalColumnName(columnName);
799                                                if (!columnMap.containsKey(key)) {
800                                                        columnMap.put(key, item);
801                                                }
802                                        }
803                                }
804                                columnModel.bindStarLinkColumns(new LinkedHashMap<String, Set<TObjectName>>());
805                        }
806                }
807
808                return columnModel;
809        }
810
811        public static String getQualifiedTableName(Table table) {
812                List<String> segments = SQLUtil.parseNames(table.name);
813                boolean supportCatalog = TSQLEnv.supportCatalog(ModelBindingManager.getGlobalVendor());
814                boolean supportSchema = TSQLEnv.supportSchema(ModelBindingManager.getGlobalVendor());
815                if (segments.size() < 2) {
816                        if (supportCatalog && supportSchema) {
817                                return getDefaultDatabase() + "." + getDefaultSchema() + "." + table.name;
818                        } else if (supportCatalog) {
819                                return TSQLEnv.DEFAULT_DB_NAME + "." + getDefaultDatabase() + "." + table.name;
820                        } else {
821                                return TSQLEnv.DEFAULT_DB_NAME + "." + getDefaultSchema() + "." + table.name;
822                        }
823                } else if (segments.size() < 3) {
824                        if (supportCatalog && supportSchema) {
825                                return getDefaultDatabase() + "." + table.name;
826                        } else {
827                                return TSQLEnv.DEFAULT_DB_NAME + "." + table.name;
828                        }
829                } else {
830                        return table.name;
831                }
832        }
833
834        protected static String getDefaultSchema() {
835                String defaultSchema = null;
836                if (ModelBindingManager.getGlobalSQLEnv() != null) {
837                        defaultSchema = ModelBindingManager.getGlobalSQLEnv().getDefaultSchemaName();
838                }
839                if (!SQLUtil.isEmpty(defaultSchema))
840                        return defaultSchema;
841                return TSQLEnv.DEFAULT_SCHEMA_NAME;
842        }
843
844        protected static String getDefaultDatabase() {
845                String defaultDatabase = null;
846                if (ModelBindingManager.getGlobalSQLEnv() != null) {
847                        defaultDatabase = ModelBindingManager.getGlobalSQLEnv().getDefaultCatalogName();
848                }
849                if (!SQLUtil.isEmpty(defaultDatabase))
850                        return defaultDatabase;
851                return TSQLEnv.DEFAULT_DB_NAME;
852        }
853
854        public TableColumn createStageLocation(Table table, TObjectName location) {
855                if (modelManager.getModel(new Pair<Table, TObjectName>(table, location)) instanceof TableColumn) {
856                        return (TableColumn) modelManager.getModel(new Pair<Table, TObjectName>(table, location));
857                }
858
859                StageLocation columnModel = new StageLocation(table, location);
860                modelManager.bindModel(new Pair<Table, TObjectName>(table, location), columnModel);
861                return columnModel;
862        }
863
864        public TableColumn createFileUri(Table table, TObjectName fileUri) {
865                if (modelManager.getModel(new Pair<Table, TObjectName>(table, fileUri)) instanceof TableColumn) {
866                        return (TableColumn) modelManager.getModel(new Pair<Table, TObjectName>(table, fileUri));
867                }
868
869                FileUri columnModel = new FileUri(table, fileUri);
870                modelManager.bindModel(new Pair<Table, TObjectName>(table, fileUri), columnModel);
871                return columnModel;
872        }
873
874        public TableColumn createVariableProperty(Table variableTable, TDeclareVariable variable) {
875                if (modelManager.getModel(new Pair<Table, TDeclareVariable>(variableTable, variable)) instanceof TableColumn) {
876                        return (TableColumn) modelManager.getModel(new Pair<Table, TDeclareVariable>(variableTable, variable));
877                }
878
879                TObjectName variableName = new TObjectName();
880                variableName.setString("property");
881                VariableProperty columnModel = new VariableProperty(variableTable, variableName, variable);
882                modelManager.bindModel(new Pair<Table, TDeclareVariable>(variableTable, variable), columnModel);
883                return columnModel;
884        }
885
886        public TableColumn createJsonTableColumn(Table table, TObjectName column) {
887                if (modelManager.getModel(new Pair<Table, TObjectName>(table, column)) instanceof TableColumn) {
888                        return (TableColumn) modelManager.getModel(new Pair<Table, TObjectName>(table, column));
889                }
890
891                JsonTableColumn columnModel = new JsonTableColumn(table, column);
892                modelManager.bindModel(new Pair<Table, TObjectName>(table, column), columnModel);
893                return columnModel;
894        }
895
896        public DataFlowRelationship createDataFlowRelation() {
897                DataFlowRelationship relation = new DataFlowRelationship();
898                modelManager.addRelation(relation);
899                return relation;
900        }
901
902        public CallRelationship createCallRelation() {
903                CallRelationship relation = new CallRelationship();
904                modelManager.addRelation(relation);
905                return relation;
906        }
907        
908        public CrudRelationship createCrudRelation() {
909                CrudRelationship relation = new CrudRelationship();
910                modelManager.addRelation(relation);
911                return relation;
912        }
913
914        public ERRelationship createERRelation() {
915                ERRelationship relation = new ERRelationship();
916                modelManager.addRelation(relation);
917                return relation;
918        }
919
920        public TableColumn createTableColumn(Table table, TResultColumn column) {
921                if (column.getAliasClause() != null && column.getAliasClause().getAliasName() != null) {
922                        TableColumn columnModel = new TableColumn(table, column.getAliasClause().getAliasName());
923                        modelManager.bindModel(column, columnModel);
924                        return columnModel;
925                } else if (column.getFieldAttr() != null) {
926                        TableColumn columnModel = new TableColumn(table, column.getFieldAttr());
927                        modelManager.bindModel(column, columnModel);
928                        return columnModel;
929                }
930                return null;
931        }
932
933        public TableColumn createTableColumn(Table table, TConstant constant) {
934                if (modelManager.getModel(new Pair<Table, TConstant>(table, constant)) instanceof TableColumn) {
935                        return (TableColumn) modelManager.getModel(new Pair<Table, TConstant>(table, constant));
936                }
937
938                TableColumn columnModel = new TableColumn(table, constant);
939                modelManager.bindModel(new Pair<Table, TConstant>(table, constant), columnModel);
940                return columnModel;
941        }
942
943        public TableColumn createTableColumn(Table table, TFunctionCall constantFunction) {
944                if (modelManager.getModel(new Pair<Table, TFunctionCall>(table, constantFunction)) instanceof TableColumn) {
945                        return (TableColumn) modelManager.getModel(new Pair<Table, TFunctionCall>(table, constantFunction));
946                }
947
948                TableColumn columnModel = new TableColumn(table, constantFunction);
949                modelManager.bindModel(new Pair<Table, TFunctionCall>(table, constantFunction), columnModel);
950                return columnModel;
951        }
952
953        public RecordSetRelationship createRecordSetRelation() {
954                RecordSetRelationship relation = new RecordSetRelationship();
955                modelManager.addRelation(relation);
956                return relation;
957        }
958
959        public ImpactRelationship createImpactRelation() {
960                ImpactRelationship relation = new ImpactRelationship();
961                modelManager.addRelation(relation);
962                return relation;
963        }
964
965        public IndirectImpactRelationship createIndirectImpactRelation() {
966                IndirectImpactRelationship relation = new IndirectImpactRelationship();
967                modelManager.addRelation(relation);
968                return relation;
969        }
970
971        public JoinRelationship createJoinRelation() {
972                JoinRelationship relation = new JoinRelationship();
973                modelManager.addRelation(relation);
974                return relation;
975        }
976
977        public Table createView(TCustomSqlStatement viewStmt, TObjectName viewName) {
978                return createView(viewStmt, viewName, false);
979        }
980
981        public Table createView(TCustomSqlStatement viewStmt, TObjectName viewName, boolean fromCreateView) {
982                if (modelManager.getViewModel(viewStmt) instanceof Table) {
983                        Table table = (Table) modelManager.getViewModel(viewStmt);
984                        table.setView(true);
985                        return table;
986                }
987
988                if (modelManager.getTableByName(DlineageUtil.getTableFullName(viewName.toString())) != null) {
989                        Table table = modelManager.getTableByName(DlineageUtil.getTableFullName(viewName.toString()));
990                        table.setView(true);
991                        return table;
992                }
993
994                Table viewModel = new Table(viewStmt, viewName);
995                viewModel.setCreateTable(fromCreateView);
996                viewModel.setView(true);
997                modelManager.bindViewModel(viewStmt, viewModel);
998                modelManager.bindTableByName(DlineageUtil.getTableFullName(viewName.toString()), viewModel);
999                return viewModel;
1000        }
1001
1002        public Process createProcess(TCustomSqlStatement processStmt) {
1003                if (modelManager.getProcessModel(processStmt) instanceof Process) {
1004                        Process process = (Process) modelManager.getProcessModel(processStmt);
1005                        return process;
1006                }
1007
1008                Process processModel = new Process(processStmt);
1009                modelManager.bindProcessModel(processStmt, processModel);
1010                return processModel;
1011        }
1012
1013        public Process createProcess(TFunctionCall functionCall) {
1014                if (modelManager.getProcessModel(functionCall) instanceof Process) {
1015                        Process process = (Process) modelManager.getProcessModel(functionCall);
1016                        return process;
1017                }
1018
1019                Process processModel = new Process(functionCall);
1020                modelManager.bindProcessModel(functionCall, processModel);
1021                return processModel;
1022        }
1023
1024        public TableColumn createViewColumn(Table viewModel, TObjectName column, int index, boolean fromCreateView) {
1025                Pair<Table, TObjectName> bindingModel = new Pair<Table, TObjectName>(viewModel, column);
1026                if (modelManager.getViewModel(bindingModel) instanceof TableColumn) {
1027                        return (TableColumn) modelManager.getViewModel(bindingModel);
1028                }
1029
1030                if (viewModel.isCreateTable() && !fromCreateView) {
1031                        if (index < viewModel.getColumns().size()) {
1032                                return (TableColumn) viewModel.getColumns().get(index);
1033                        } else {
1034                                return null;
1035                        }
1036                }
1037
1038                TableColumn columnModel = new TableColumn(viewModel, column, index);
1039                modelManager.bindViewModel(bindingModel, columnModel);
1040                return columnModel;
1041        }
1042
1043        public TableColumn createInsertTableColumn(Table tableModel, String columnName) {
1044                TObjectName columnNameObject = new TObjectName();
1045                columnNameObject.setString(columnName);
1046                Pair<Table, String> bindingModel = new Pair<Table, String>(tableModel, columnName);
1047
1048                if (tableModel.isCreateTable()) {
1049                        for (int i = 0; i < tableModel.getColumns().size(); i++) {
1050                                TableColumn columnModel = tableModel.getColumns().get(i);
1051                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
1052                                        modelManager.bindInsertModel(bindingModel, columnModel);
1053                                        return columnModel;
1054                                }
1055                        }
1056                }
1057
1058                if (modelManager.getInsertModel(bindingModel) instanceof TableColumn) {
1059                        return (TableColumn) modelManager.getInsertModel(bindingModel);
1060                }
1061                TableColumn columnModel = new TableColumn(tableModel, columnNameObject);
1062                modelManager.bindInsertModel(bindingModel, columnModel);
1063                return columnModel;
1064        }
1065
1066        public TableColumn createInsertTableColumn(Table tableModel, TObjectName column) {
1067                Pair<Table, TObjectName> bindingModel = new Pair<Table, TObjectName>(tableModel, column);
1068
1069                if (tableModel.isCreateTable()) {
1070                        String columnName = DlineageUtil.getColumnName(column);
1071                        for (int i = 0; i < tableModel.getColumns().size(); i++) {
1072                                TableColumn columnModel = tableModel.getColumns().get(i);
1073                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
1074                                        modelManager.bindInsertModel(bindingModel, columnModel);
1075                                        return columnModel;
1076                                }
1077                        }
1078                }
1079
1080                if (modelManager.getInsertModel(bindingModel) instanceof TableColumn) {
1081                        return (TableColumn) modelManager.getInsertModel(bindingModel);
1082                }
1083                TableColumn columnModel = new TableColumn(tableModel, column);
1084                modelManager.bindInsertModel(bindingModel, columnModel);
1085                return columnModel;
1086        }
1087
1088        public TableColumn createInsertTableColumn(Table tableModel, TExpression column, int columnIndex) {
1089                Pair<Table, TExpression> bindingModel = new Pair<Table, TExpression>(tableModel, column);
1090
1091                if (tableModel.isCreateTable()) {
1092                        if (columnIndex < tableModel.getColumns().size()) {
1093                                TableColumn columnModel = tableModel.getColumns().get(columnIndex);
1094                                modelManager.bindInsertModel(bindingModel, columnModel);
1095                                return columnModel;
1096                        } else {
1097                                return null;
1098                        }
1099                }
1100
1101                if (modelManager.getInsertModel(bindingModel) instanceof TableColumn) {
1102                        return (TableColumn) modelManager.getInsertModel(bindingModel);
1103                }
1104                TableColumn columnModel = new TableColumn(tableModel, column, columnIndex);
1105                modelManager.bindInsertModel(bindingModel, columnModel);
1106                return columnModel;
1107        }
1108
1109        public TableColumn createInsertTableColumn(Table tableModel, TConstant column, int columnIndex) {
1110                Pair<Table, TConstant> bindingModel = new Pair<Table, TConstant>(tableModel, column);
1111
1112                if (tableModel.isCreateTable()) {
1113                        if (columnIndex < tableModel.getColumns().size()) {
1114                                TableColumn columnModel = tableModel.getColumns().get(columnIndex);
1115                                modelManager.bindInsertModel(bindingModel, columnModel);
1116                                return columnModel;
1117                        } else {
1118                                return null;
1119                        }
1120                }
1121
1122                if (modelManager.getInsertModel(bindingModel) instanceof TableColumn) {
1123                        return (TableColumn) modelManager.getInsertModel(bindingModel);
1124                }
1125                TableColumn columnModel = new TableColumn(tableModel, column, columnIndex);
1126                modelManager.bindInsertModel(bindingModel, columnModel);
1127                return columnModel;
1128        }
1129
1130        public SelectSetResultSet createSelectSetResultSet(TSelectSqlStatement stmt) {
1131                if (modelManager.getModel(stmt) instanceof SelectSetResultSet) {
1132                        return (SelectSetResultSet) modelManager.getModel(stmt);
1133                }
1134                SelectSetResultSet resultSet = new SelectSetResultSet(stmt, stmt.getParentStmt() == null);
1135                modelManager.bindModel(stmt, resultSet);
1136                return resultSet;
1137        }
1138
1139        public ResultColumn createStarResultColumn(SelectResultSet resultSet,
1140                        Pair<TResultColumn, TObjectName> starColumnPair) {
1141                if (modelManager.getModel(starColumnPair) instanceof ResultColumn) {
1142                        return (ResultColumn) modelManager.getModel(starColumnPair);
1143                }
1144                ResultColumn column = new ResultColumn(resultSet, starColumnPair);
1145                modelManager.bindModel(starColumnPair, column);
1146                return column;
1147        }
1148
1149        public Variable createCursor(TCursorDeclStmt stmt) {
1150                String variableName = stmt.getCursorName().toString();
1151                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1152                String variableString = variableName.toString();
1153                if (variableString.startsWith(":")) {
1154                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1155                }
1156                if (!SQLUtil.isEmpty(procedureName)) {
1157                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1158                }
1159                
1160                if (modelManager
1161                                .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1162                        return (Variable) modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
1163                }
1164                Cursor tableModel = new Cursor(stmt);
1165                if (!SQLUtil.isEmpty(procedureName)) {
1166                        tableModel.setParent(procedureName);
1167                }
1168                modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString), tableModel);
1169                modelManager.bindModel(DlineageUtil.getTableFullName(variableString), tableModel);
1170                return tableModel;
1171        }
1172
1173        public Variable createCursor(TMssqlDeclare stmt) {
1174                String variableName = stmt.getCursorName().toString();
1175                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1176                String variableString = variableName.toString();
1177                if (variableString.startsWith(":")) {
1178                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1179                }
1180                if (!SQLUtil.isEmpty(procedureName)) {
1181                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1182                }
1183                
1184                if (modelManager
1185                                .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1186                        return (Variable) modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
1187                }
1188                Cursor tableModel = new Cursor(stmt);
1189                if (!SQLUtil.isEmpty(procedureName)) {
1190                        tableModel.setParent(procedureName);
1191                }
1192                modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString), tableModel);
1193                modelManager.bindModel(DlineageUtil.getTableFullName(variableString), tableModel);
1194                return tableModel;
1195        }
1196
1197        public Variable createCursor(TLoopStmt stmt) {
1198                String variableName = stmt.getRecordName().toString();
1199                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1200                String variableString = variableName.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                
1208                if (modelManager
1209                                .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1210                        return (Variable) modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
1211                }
1212                Cursor tableModel = new Cursor(stmt);
1213                if (!SQLUtil.isEmpty(procedureName)) {
1214                        tableModel.setParent(procedureName);
1215                }
1216                modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString), tableModel);
1217                modelManager.bindModel(DlineageUtil.getTableFullName(variableString), tableModel);
1218                return tableModel;
1219        }
1220
1221        public Variable createCursor(TForStmt stmt) {
1222                String variableName = stmt.getLoopName().toString();
1223                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1224                String variableString = variableName.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                
1232                if (modelManager
1233                                .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1234                        return (Variable) modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
1235                }
1236                Cursor tableModel = new Cursor(stmt);
1237                if (!SQLUtil.isEmpty(procedureName)) {
1238                        tableModel.setParent(procedureName);
1239                }
1240                modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString), tableModel);
1241                modelManager.bindModel(DlineageUtil.getTableFullName(variableString), tableModel);
1242                return tableModel;
1243        }
1244
1245        public Variable createCursor(TOpenforStmt stmt) {
1246                String variableName = stmt.getCursorVariableName().toString();
1247                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1248                String variableString = variableName.toString();
1249                if (variableString.startsWith(":")) {
1250                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1251                }
1252                if (!SQLUtil.isEmpty(procedureName)) {
1253                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1254                }
1255                
1256                if (modelManager.getTableByName(
1257                                DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1258                        return (Variable) modelManager
1259                                        .getTableByName(DlineageUtil.getTableFullName(variableString));
1260                }
1261                Cursor tableModel = new Cursor(stmt);
1262                if (!SQLUtil.isEmpty(procedureName)) {
1263                        tableModel.setParent(procedureName);
1264                }
1265                modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString),
1266                                tableModel);
1267                modelManager.bindModel(DlineageUtil.getTableFullName(variableString), tableModel);
1268                return tableModel;
1269        }
1270
1271        public Variable createVariable(TObjectName variableName) {
1272                TCustomSqlStatement stmt = modelManager.getGlobalStmtStack().peek();
1273                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1274                String variableString = variableName.toString();
1275                if (variableString.startsWith(":")) {
1276                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1277                }
1278                if (variableString.indexOf(".") != -1) {
1279                        variableString = variableString.substring(0, variableString.indexOf("."));
1280                }
1281                
1282                if (!SQLUtil.isEmpty(procedureName)) {
1283                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1284                }
1285                
1286                if (modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1287                        return (Variable) modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
1288                }
1289                Variable variable = new Variable(variableName);
1290                if (!SQLUtil.isEmpty(procedureName)) {
1291                        variable.setParent(procedureName);
1292                }
1293                modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString), variable);
1294                modelManager.bindModel(DlineageUtil.getTableFullName(variableString), variable);
1295//              modelManager.bindTableByName(DlineageUtil.getTableFullName(variableName.toString()), variable);
1296//              modelManager.bindModel(DlineageUtil.getTableFullName(variableName.toString()), variable);
1297                return variable;
1298        }
1299
1300        public Variable createVariable(String variableName) {
1301                return createVariable(variableName, true);
1302        }
1303        
1304        public Variable createVariable(String variableName, boolean create) {
1305                TCustomSqlStatement stmt = modelManager.getGlobalStmtStack().peek();
1306                String procedureName = DlineageUtil.getProcedureParentName(stmt);
1307                String variableString = variableName.toString();
1308                if (variableString.startsWith(":")) {
1309                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1310                }
1311                if (!SQLUtil.isEmpty(procedureName)) {
1312                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1313                }
1314                
1315                if (modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1316                        return (Variable) modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
1317                }
1318                
1319                if (create) {
1320                        Variable variable = new Variable(variableName);
1321                        if (!SQLUtil.isEmpty(procedureName)) {
1322                                variable.setParent(procedureName);
1323                        }
1324                        modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString), variable);
1325                        modelManager.bindModel(DlineageUtil.getTableFullName(variableString), variable);
1326//                      modelManager.bindTableByName(DlineageUtil.getTableFullName(variableName.toString()), variable);
1327//                      modelManager.bindModel(DlineageUtil.getTableFullName(variableName.toString()), variable);
1328                        return variable;
1329                }
1330                else {
1331                        return null;
1332                }
1333        }
1334
1335        public Variable createVariable(Procedure procedure, String variableName, boolean create) {
1336                String procedureName = procedure.getName();
1337                String variableString = variableName.toString();
1338                if (variableString.startsWith(":")) {
1339                        variableString = variableString.substring(variableString.indexOf(":") + 1);
1340                }
1341                if (!SQLUtil.isEmpty(procedureName)) {
1342                        variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString);
1343                }
1344
1345                if (modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
1346                        return (Variable) modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
1347                }
1348
1349                if (create) {
1350                        Variable variable = new Variable(variableName);
1351                        if (!SQLUtil.isEmpty(procedureName)) {
1352                                variable.setParent(procedureName);
1353                        }
1354                        modelManager.bindTableByName(DlineageUtil.getTableFullName(variableString), variable);
1355                        modelManager.bindModel(DlineageUtil.getTableFullName(variableString), variable);
1356//                      modelManager.bindTableByName(DlineageUtil.getTableFullName(variableName.toString()), variable);
1357//                      modelManager.bindModel(DlineageUtil.getTableFullName(variableName.toString()), variable);
1358                        return variable;
1359                }
1360                else {
1361                        return null;
1362                }
1363        }
1364
1365        public Database createDatabase(TObjectName databaseName) {
1366                if (modelManager.getTableByName(DlineageUtil.getTableFullName(databaseName.toString())) instanceof Database) {
1367                        return (Database) modelManager.getTableByName(DlineageUtil.getTableFullName(databaseName.toString()));
1368                }
1369                Database database = new Database(databaseName);
1370                modelManager.bindTableByName(DlineageUtil.getTableFullName(databaseName.toString()), database);
1371                modelManager.bindModel(DlineageUtil.getTableFullName(databaseName.toString()), database);
1372                return database;
1373        }
1374
1375        public Schema createSchema(TObjectName schemaName) {
1376                if (modelManager
1377                                .getTableByName(DlineageUtil.getIdentifierNormalTableName(schemaName.toString())) instanceof Schema) {
1378                        return (Schema) modelManager
1379                                        .getTableByName(DlineageUtil.getIdentifierNormalTableName(schemaName.toString()));
1380                }
1381                Schema schema = new Schema(schemaName);
1382                modelManager.bindTableByName(DlineageUtil.getIdentifierNormalTableName(schemaName.toString()), schema);
1383                modelManager.bindModel(DlineageUtil.getIdentifierNormalTableName(schemaName.toString()), schema);
1384                return schema;
1385        }
1386
1387        public PivotedTable createPivotdTable(TPivotClause pivotedTable) {
1388                if (modelManager.getModel(pivotedTable) instanceof PivotedTable) {
1389                        return (PivotedTable) modelManager.getModel(pivotedTable);
1390                }
1391                PivotedTable resultSet = new PivotedTable(pivotedTable);
1392                modelManager.bindModel(pivotedTable, resultSet);
1393                if (pivotedTable.getPivotTable() != null) {
1394                        modelManager.bindModel(pivotedTable.getPivotTable(), resultSet);
1395                }
1396                return resultSet;
1397        }
1398
1399        public Procedure createProcedure(TStoredProcedureSqlStatement stmt) {
1400                if (stmt == null || stmt.getStoredProcedureName() == null) {
1401                        return null;
1402                }
1403                String procedureNameWithArgs = DlineageUtil
1404                                .getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt));
1405                String procedureNameWithArgNum = DlineageUtil
1406                                .getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgNum(stmt));
1407                String procedureNameWithInputArgNum = DlineageUtil
1408                                .getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithInputArgNum(stmt));
1409                if (ModelBindingManager.getGlobalOraclePackage() != null) {
1410                        procedureNameWithArgs = ModelBindingManager.getGlobalOraclePackage().getName() + "."
1411                                        + procedureNameWithArgs;
1412                        procedureNameWithArgNum = ModelBindingManager.getGlobalOraclePackage().getName() + "."
1413                                        + procedureNameWithArgNum;
1414                        procedureNameWithInputArgNum = ModelBindingManager.getGlobalOraclePackage().getName() + "."
1415                                        + procedureNameWithInputArgNum;
1416                }
1417                if (this.modelManager.getModel(stmt) instanceof Procedure) {
1418                        return (Procedure) this.modelManager.getModel(stmt);
1419                } else if (this.modelManager.getProcedureByName(procedureNameWithArgs) != null) {
1420                        return (Procedure) this.modelManager.getProcedureByName(procedureNameWithArgs);
1421                } else if (this.modelManager.getProcedureByName(procedureNameWithArgNum) != null) {
1422                        return (Procedure) this.modelManager.getProcedureByName(procedureNameWithArgNum);
1423                } else if (this.modelManager.getProcedureByName(procedureNameWithInputArgNum) != null) {
1424                        return (Procedure) this.modelManager.getProcedureByName(procedureNameWithInputArgNum);
1425                } else {
1426                        Procedure procedure = new Procedure(stmt);
1427                        this.modelManager.bindModel(stmt, procedure);
1428                        this.modelManager.bindProcedureByName(procedureNameWithArgs, procedure);
1429                        this.modelManager.bindProcedureByName(procedureNameWithArgNum, procedure);
1430                        this.modelManager.bindProcedureByName(procedureNameWithInputArgNum, procedure);
1431                        return procedure;
1432                }
1433        }
1434
1435        public OraclePackage createOraclePackage(TPlsqlCreatePackage stmt) {
1436                if (this.modelManager.getModel(stmt) instanceof OraclePackage) {
1437                        return (OraclePackage) this.modelManager.getModel(stmt);
1438                } else {
1439                        OraclePackage oraclePackage = new OraclePackage(stmt);
1440                        this.modelManager.bindModel(stmt, oraclePackage);
1441                        this.modelManager.bindOraclePackageByName(
1442                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt)),
1443                                        oraclePackage);
1444                        this.modelManager.bindOraclePackageByName(
1445                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgNum(stmt)),
1446                                        oraclePackage);
1447                        this.modelManager.bindOraclePackageByName(
1448                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithInputArgNum(stmt)),
1449                                        oraclePackage);
1450                        return oraclePackage;
1451                }
1452        }
1453
1454        public Procedure createProcedureFromFunctionCall(TFunctionCall function) {
1455                if (this.modelManager.getModel(function) instanceof Procedure) {
1456                        return (Procedure) this.modelManager.getModel(function);
1457                } else {
1458                        Procedure procedure = new Procedure(function);
1459                        procedure.setType(ESqlStatementType.sstcreateprocedure);
1460                        this.modelManager.bindModel(function, procedure);
1461                        this.modelManager.bindProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedure.getName()),
1462                                        procedure);
1463                        return procedure;
1464                }
1465        }
1466        
1467//      public Procedure createProcedureByName(TObjectName procedureName) {
1468//              if (this.modelManager.getModel(procedureName) instanceof Procedure) {
1469//                      return (Procedure) this.modelManager.getModel(procedureName);
1470//              }
1471//              else if (this.modelManager
1472//                              .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureName.toString())) != null) {
1473//                      return modelManager.getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureName.toString()));
1474//              }
1475//              else {
1476//                      Procedure procedure = new Procedure(procedureName);
1477//                      procedure.setType(ESqlStatementType.sstcreateprocedure);
1478//                      this.modelManager.bindModel(procedureName, procedure);
1479//                      this.modelManager.bindProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedure.getName()),
1480//                                      procedure);
1481//                      return procedure;
1482//              }
1483//      }
1484
1485        public Procedure createProcedureByName(TObjectName procedureName, int argumentSize) {
1486                String procedureNameWithArgSize = procedureName.toString() + "(" + argumentSize + ")";
1487                if (argumentSize <= 0 || !DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) {
1488                        procedureNameWithArgSize = procedureName.toString();
1489                }
1490                if (this.modelManager.getModel(procedureName) instanceof Procedure) {
1491                        return (Procedure) this.modelManager.getModel(procedureName);
1492                }
1493                else if (this.modelManager
1494                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureNameWithArgSize)) != null) {
1495                        return modelManager.getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureNameWithArgSize));
1496                }
1497                else {
1498                        Procedure procedure = new Procedure(procedureName);
1499                        procedure.setType(ESqlStatementType.sstcreateprocedure);
1500                        this.modelManager.bindModel(procedureName, procedure);
1501                        this.modelManager.bindProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureNameWithArgSize),
1502                                        procedure);
1503                        return procedure;
1504                }
1505        }
1506
1507        public Argument createProcedureArgument(Procedure procedure, TParameterDeclaration parameter, int index) {
1508                if (this.modelManager.getModel(parameter) instanceof Argument) {
1509                        return (Argument) this.modelManager.getModel(parameter);
1510                } else {
1511                        if (procedure.getArguments() != null) {
1512                                for (Argument argument : procedure.getArguments()) {
1513                                        if (parameter.getParameterName() == null) {
1514                                                continue;
1515                                        }
1516                                        if (argument.getName().equals(parameter.getParameterName().toString())) {
1517                                                return argument;
1518                                        }
1519                                }
1520                        }
1521                        Argument argumentModel = new Argument(procedure, parameter, index);
1522                        this.modelManager.bindModel(parameter, argumentModel);
1523                        this.modelManager.bindModel(procedure.getName() + ":" + argumentModel.getName(), argumentModel);
1524                        return argumentModel;
1525                }
1526        }
1527
1528        public Argument createProcedureArgument(OraclePackage oraclePackage, TParameterDeclaration parameter, int index) {
1529                if (this.modelManager.getModel(parameter) instanceof Argument) {
1530                        return (Argument) this.modelManager.getModel(parameter);
1531                } else {
1532                        Argument argumentModel = new Argument(oraclePackage, parameter, index);
1533                        this.modelManager.bindModel(parameter, argumentModel);
1534                        return argumentModel;
1535                }
1536        }
1537
1538}