001package gudusoft.gsqlparser.dlineage.util;
002
003import java.io.File;
004import java.util.ArrayList;
005import java.util.Arrays;
006import java.util.LinkedHashSet;
007import java.util.List;
008import java.util.Map;
009import java.util.Set;
010
011import gudusoft.gsqlparser.EDbVendor;
012import gudusoft.gsqlparser.EParameterMode;
013import gudusoft.gsqlparser.TCustomSqlStatement;
014import gudusoft.gsqlparser.dlineage.dataflow.model.AnalyzeMode;
015import gudusoft.gsqlparser.dlineage.dataflow.model.ModelBindingManager;
016import gudusoft.gsqlparser.dlineage.dataflow.model.Option;
017import gudusoft.gsqlparser.dlineage.dataflow.model.SqlInfo;
018import gudusoft.gsqlparser.dlineage.dataflow.model.SubType;
019import gudusoft.gsqlparser.dlineage.dataflow.model.Table;
020import gudusoft.gsqlparser.dlineage.dataflow.model.xml.*;
021import gudusoft.gsqlparser.nodes.TFunctionCall;
022import gudusoft.gsqlparser.nodes.TObjectName;
023import gudusoft.gsqlparser.nodes.TParameterDeclaration;
024import gudusoft.gsqlparser.nodes.TParameterDeclarationList;
025import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
026import gudusoft.gsqlparser.sqlenv.TSQLEnv;
027import gudusoft.gsqlparser.stmt.TCommonBlock;
028import gudusoft.gsqlparser.stmt.TSelectSqlStatement;
029import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement;
030import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreatePackage;
031import gudusoft.gsqlparser.TBaseType;
032import gudusoft.gsqlparser.util.SQLUtil;
033import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure;
034import gudusoft.gsqlparser.util.SQLUtil;
035import gudusoft.gsqlparser.util.functionChecker;
036import gudusoft.gsqlparser.util.keywordChecker;
037import gudusoft.gsqlparser.util.json.JSON;
038
039public class DlineageUtil {
040
041    public static boolean compareIdentifier(String source, String target, ESQLDataObjectType sqlDataObjectType) {
042        return SQLUtil.compareIdentifier(ModelBindingManager.getGlobalVendor(), sqlDataObjectType, source, target);
043    }
044
045    public static boolean compareColumnIdentifier(String source, String target) {
046        return SQLUtil.compareIdentifier(ModelBindingManager.getGlobalVendor(), ESQLDataObjectType.dotColumn, source,
047                target);
048    }
049
050    public static boolean compareTableIdentifier(String source, String target) {
051        return SQLUtil.compareIdentifier(ModelBindingManager.getGlobalVendor(), ESQLDataObjectType.dotTable, source,
052                target);
053    }
054
055        public static String getIdentifierNormalColumnName(String name) {
056                EDbVendor dbVendor = ModelBindingManager.getGlobalVendor();
057                return SQLUtil.getIdentifierNormalName(dbVendor, name, ESQLDataObjectType.dotColumn);
058        }
059
060        public static String getIdentifierNormalColumnName(String name, EDbVendor dbVendor) {
061                return SQLUtil.getIdentifierNormalName(dbVendor, name, ESQLDataObjectType.dotColumn);
062        }
063
064    public static String normalizeColumnName(String name) {
065        return SQLUtil.normalizeIdentifier(ModelBindingManager.getGlobalVendor(),  ESQLDataObjectType.dotColumn, name);
066    }
067    
068    public static String normalizeColumnName(String name, EDbVendor dbVendor) {
069        return SQLUtil.normalizeIdentifier(dbVendor,  ESQLDataObjectType.dotColumn, name);
070    }
071
072    
073    public static String getIdentifierNormalTableName(String name) {
074                if (ModelBindingManager.get() != null && ModelBindingManager.get().isDblinkTable(name)) {
075                        int index = name.lastIndexOf("@");
076                        if (index > 0) {
077                                return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name.substring(0, index),
078                                                ESQLDataObjectType.dotTable) + name.substring(index);
079                        } else {
080                                return name;
081                        }
082                }
083                if (name.endsWith(")") && name.indexOf("(") != -1) {
084                        return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(),
085                                        name.substring(0, name.lastIndexOf("(")), ESQLDataObjectType.dotTable)
086                                        + name.substring(name.lastIndexOf("("));
087                }
088        return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name,
089                ESQLDataObjectType.dotTable);
090    }
091
092    public static String getIdentifierNormalFunctionName(String name) {
093        return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name,
094                ESQLDataObjectType.dotFunction);
095    }
096
097    public static String getIdentifierNormalName(String name, ESQLDataObjectType sqlDataObjectType) {
098        return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name, sqlDataObjectType);
099    }
100
101    public static String getColumnName(TObjectName column) {
102        if (column == null || column.toString() == null) {
103            return null;
104        }
105        String name = column.getColumnNameOnly();
106        if (name == null || "".equals(name.trim())) {
107            return getIdentifierNormalColumnName(column.toString().trim());
108        } else
109            return getIdentifierNormalColumnName(name.trim());
110    }
111    
112    public static String getColumnName(String column) {
113                if (column == null) {
114                        return null;
115                }
116                String name = column.substring(column.lastIndexOf(".") + 1);
117                if (name == null || "".equals(name.trim())) {
118                        return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim());
119                } else
120                        return DlineageUtil.getIdentifierNormalColumnName(name.trim());
121        }
122
123    public static boolean isTempTable(Table tableModel, EDbVendor vendor) {
124                if (SubType.temp_table == tableModel.getSubType()) {
125                        return true;
126                }
127        switch (vendor) {
128            case dbvmssql:
129            case dbvazuresql:
130                return tableModel.getName().startsWith("#") && !tableModel.getName().startsWith("##");
131            default:
132                return false;
133        }
134    }
135
136    public static String getTableFullName(String tableName) {
137                if (ModelBindingManager.get() != null && ModelBindingManager.get().isDblinkTable(tableName)) {
138                        return tableName;
139                }
140
141        if(tableName == null){
142            return null;
143        }
144
145        if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1
146                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
147                        tableName = SQLUtil.trimColumnStringQuote(tableName);
148                }
149        List<String> segments = SQLUtil.parseNames(tableName);
150        if (segments.size() == 1) {
151            StringBuffer buffer = new StringBuffer();
152            if (ModelBindingManager.getGlobalDatabase() != null) {
153                buffer.append(ModelBindingManager.getGlobalDatabase()).append(".");
154            }
155            if (ModelBindingManager.getGlobalSchema() != null) {
156                buffer.append(ModelBindingManager.getGlobalSchema()).append(".");
157            }
158            buffer.append(tableName);
159            return getIdentifierNormalTableName(buffer.toString());
160        } else if (segments.size() == 2) {
161            if (ModelBindingManager.getGlobalDatabase() != null) {
162                return getIdentifierNormalTableName(ModelBindingManager.getGlobalDatabase() + "." + tableName);
163            } else {
164                return getIdentifierNormalTableName(tableName);
165            }
166        } else {
167            if ((ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql
168                    || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvazuresql) && tableName.indexOf("..") != -1) {
169                if (ModelBindingManager.getGlobalSchema() != null) {
170                    return getIdentifierNormalTableName(
171                            tableName.replace("..", "." + ModelBindingManager.getGlobalSchema() + "."));
172                } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql
173                        || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvazuresql) {
174                    return getIdentifierNormalTableName(tableName.replace("..", ".dbo."));
175                } else {
176                    return getIdentifierNormalTableName(tableName);
177                }
178            } else {
179                return getIdentifierNormalTableName(tableName);
180            }
181        }
182    }
183
184
185    
186    public static String getSimpleTableName(String tableName) {
187        if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1
188                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
189                        tableName = SQLUtil.trimColumnStringQuote(tableName);
190                }
191        List<String> segments = SQLUtil.parseNames(tableName);
192        return segments.get(segments.size()-1);
193    }
194    
195    public static String getColumnNameOnly(String columnName) {
196        if (columnName.startsWith("`") && columnName.endsWith("`") && columnName.indexOf(".") != -1
197                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
198                columnName = SQLUtil.trimColumnStringQuote(columnName);
199                }
200        List<String> segments = SQLUtil.parseNames(columnName);
201        return segments.get(segments.size()-1);
202    }
203
204    public static String getTableSchema(String tableName) {
205        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
206        boolean supportSchema = TSQLEnv.supportSchema(vendor);
207
208        if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1
209                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
210            tableName = SQLUtil.trimColumnStringQuote(tableName);
211        }
212        List<String> segments = SQLUtil.parseNames(tableName);
213        if (segments.size() == 1) {
214            if (supportSchema && ModelBindingManager.getGlobalSchema() != null) {
215                return ModelBindingManager.getGlobalSchema();
216            }
217        } else if (segments.size() == 2) {
218            if(supportSchema) {
219                return segments.get(0);
220            }
221        } else {
222            if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql && tableName.indexOf("..") != -1) {
223                if (ModelBindingManager.getGlobalSchema() != null) {
224                    return ModelBindingManager.getGlobalSchema();
225                } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
226                    return "dbo";
227                }
228            } else {
229                if(supportSchema) {
230                    return segments.get(segments.size() - 2);
231                }
232            }
233        }
234        return null;
235    }
236
237    public static String getTableServer(String tableName) {
238        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
239        boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
240        boolean supportSchema = TSQLEnv.supportSchema(vendor);
241
242        if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1
243                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
244            tableName = SQLUtil.trimColumnStringQuote(tableName);
245        }
246        List<String> segments = SQLUtil.parseNames(tableName);
247        if (segments.size() <= 2) {
248            return ModelBindingManager.getGlobalServer();
249        } else if (segments.size() == 3) {
250            if(supportCatalog && supportSchema) {
251                return ModelBindingManager.getGlobalServer();
252            } else {
253                return segments.get(0);
254            }
255        } else {
256            if(supportCatalog && supportSchema) {
257                    return segments.get(segments.size() - 4);
258            } else {
259                return segments.get(segments.size() - 3);
260            }
261        }
262    }
263
264    public static String getTableDatabase(String tableName) {
265        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
266        boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
267        boolean supportSchema = TSQLEnv.supportSchema(vendor);
268
269        if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1
270                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
271                        tableName = SQLUtil.trimColumnStringQuote(tableName);
272                }
273        List<String> segments = SQLUtil.parseNames(tableName);
274        if (segments.size() == 1) {
275            if (supportCatalog && ModelBindingManager.getGlobalDatabase() != null) {
276                return ModelBindingManager.getGlobalDatabase();
277            }
278        } else if (segments.size() == 2) {
279            if(supportCatalog && supportSchema) {
280                if (ModelBindingManager.getGlobalDatabase() != null) {
281                    return ModelBindingManager.getGlobalDatabase();
282                }
283            } else {
284                if (supportCatalog) {
285                    return segments.get(0);
286                }
287            }
288        } else {
289            if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql && tableName.indexOf("..") != -1) {
290                String fullName = tableName;
291                if (ModelBindingManager.getGlobalSchema() != null) {
292                    fullName = getIdentifierNormalTableName(
293                            tableName.replace("..", "." + ModelBindingManager.getGlobalSchema() + "."));
294                } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
295                    fullName = getIdentifierNormalTableName(tableName.replace("..", ".dbo."));
296                } else {
297                    fullName = getIdentifierNormalTableName(tableName);
298                }
299                return getTableDatabase(fullName);
300            } else {
301                if(supportCatalog && supportSchema) {
302                    return segments.get(segments.size() - 3);
303                }
304                else if(supportCatalog){
305                    return segments.get(segments.size() - 2);
306                }
307            }
308        }
309        return null;
310    }
311
312    public static String getTableFullNameWithDefaultSchema(String tableName) {
313        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
314        boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
315        boolean supportSchema = TSQLEnv.supportSchema(vendor);
316
317        if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1
318                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
319                        tableName = SQLUtil.trimColumnStringQuote(tableName);
320                }
321        List<String> segments = SQLUtil.parseNames(tableName);
322        if (segments.size() == 1) {
323            StringBuffer buffer = new StringBuffer();
324            if (supportCatalog && ModelBindingManager.getGlobalDatabase() != null) {
325                buffer.append(ModelBindingManager.getGlobalDatabase()).append(".");
326            }
327            if (supportSchema && ModelBindingManager.getGlobalSchema() != null) {
328                buffer.append(ModelBindingManager.getGlobalSchema()).append(".");
329            } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
330                buffer.append("dbo").append(".");
331            }
332            buffer.append(tableName);
333            return getIdentifierNormalTableName(buffer.toString());
334        } else if (segments.size() == 2) {
335            if (supportCatalog && supportSchema && ModelBindingManager.getGlobalDatabase() != null) {
336                return getIdentifierNormalTableName(ModelBindingManager.getGlobalDatabase() + "." + tableName);
337            } else {
338                return getIdentifierNormalTableName(tableName);
339            }
340        } else {
341            if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql && tableName.indexOf("..") != -1) {
342                if (ModelBindingManager.getGlobalSchema() != null) {
343                    return getIdentifierNormalTableName(
344                            tableName.replace("..", "." + ModelBindingManager.getGlobalSchema() + "."));
345                } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
346                    return getIdentifierNormalTableName(tableName.replace("..", ".dbo."));
347                } else {
348                    return getIdentifierNormalTableName(tableName);
349                }
350            } else {
351                return getIdentifierNormalTableName(tableName);
352            }
353        }
354    }
355
356    @SuppressWarnings("rawtypes")
357    public static SqlInfo[] convertSQL(File file, String json) {
358        List<SqlInfo> sqlInfos = new ArrayList<SqlInfo>();
359        try {
360            List sqlContents = (List) JSON.parseObject(json);
361            for (int j = 0; j < sqlContents.size(); j++) {
362                Map sqlContent = (Map) sqlContents.get(j);
363                String sql = (String) sqlContent.get("sql");
364                String fileName = (String) sqlContent.get("fileName");
365                String filePath = (String) sqlContent.get("filePath");
366                if (sql != null && sql.trim().startsWith("{")) {
367                    Map queryObject = (Map) JSON.parseObject(sql);
368                    List querys = (List) queryObject.get("queries");
369                    if (querys != null) {
370                        for (int i = 0; i < querys.size(); i++) {
371                            Map object = (Map) querys.get(i);
372                            SqlInfo info = new SqlInfo();
373                            info.setSql(JSON.toJSONString(object));
374                            info.setFileName(fileName);
375                            info.setFilePath(filePath);
376                            info.setOriginIndex(i);
377                            sqlInfos.add(info);
378                        }
379                    } else {
380                        SqlInfo info = new SqlInfo();
381                        info.setSql(JSON.toJSONString(queryObject));
382                        info.setFileName(fileName);
383                        info.setFilePath(filePath);
384                        info.setOriginIndex(0);
385                        sqlInfos.add(info);
386                    }
387                } else if (sql != null) {
388                    SqlInfo info = new SqlInfo();
389                    info.setSql(sql);
390                    info.setFileName(fileName);
391                    info.setFilePath(filePath);
392                    info.setOriginIndex(0);
393                    sqlInfos.add(info);
394                }
395            }
396        } catch (Exception e) {
397            try {
398                Map queryObject = (Map) JSON.parseObject(json);
399                List querys = (List) queryObject.get("queries");
400                if (querys != null) {
401                    for (int i = 0; i < querys.size(); i++) {
402                        Map object = (Map) querys.get(i);
403                        SqlInfo info = new SqlInfo();
404                        info.setSql(JSON.toJSONString(object));
405                        if (file != null) {
406                            info.setFileName(file.getName());
407                            info.setFilePath(file.getAbsolutePath());
408                        }
409                        info.setOriginIndex(i);
410                        sqlInfos.add(info);
411                    }
412                } else {
413                    SqlInfo info = new SqlInfo();
414                    info.setSql(JSON.toJSONString(queryObject));
415                    if (file != null) {
416                        info.setFileName(file.getName());
417                        info.setFilePath(file.getAbsolutePath());
418                    }
419                    info.setOriginIndex(0);
420                    sqlInfos.add(info);
421                }
422            } catch (Exception e1) {
423                SqlInfo info = new SqlInfo();
424                info.setSql(json);
425                if (file != null) {
426                    info.setFileName(file.getName());
427                    info.setFilePath(file.getAbsolutePath());
428                }
429                info.setOriginIndex(0);
430                sqlInfos.add(info);
431            }
432        }
433        return sqlInfos.toArray(new SqlInfo[0]);
434    }
435
436    
437        public static String getQualifiedTableName(table table) {
438                boolean supportCatalog = TSQLEnv.supportCatalog(ModelBindingManager.getGlobalVendor());
439                boolean supportSchema = TSQLEnv.supportSchema(ModelBindingManager.getGlobalVendor());
440                StringBuilder buffer = new StringBuilder();
441                if (supportCatalog && supportSchema) {
442                        if (!SQLUtil.isEmpty(table.getDatabase())) {
443                                if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvoracle
444                                                && SubType.dblink.name().equals(table.getSubType())) {
445                                        //dblink doesn't set database
446                                } else {
447                                        buffer.append(table.getDatabase());
448                                }
449                        }
450                        if (!SQLUtil.isEmpty(table.getSchema())) {
451                                if (buffer.length() > 0) {
452                                        buffer.append(".");
453                                }
454                                buffer.append(table.getSchema());
455                        } else {
456                                if (buffer.length() > 0) {
457                                        buffer.append(".");
458                                        if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
459                                                buffer.append("dbo");
460                                        } else {
461                                                buffer.append(TSQLEnv.DEFAULT_SCHEMA_NAME);
462                                        }
463                                }
464                        }
465                        if (buffer.length() > 0) {
466                                buffer.append(".");
467                        }
468                        buffer.append(table.getTableNameOnly());
469                }
470                else if(supportCatalog) {
471                        if (!SQLUtil.isEmpty(table.getDatabase())) {
472                                buffer.append(table.getDatabase());
473                        }
474                        if (buffer.length() > 0) {
475                                buffer.append(".");
476                        }
477                        buffer.append(table.getTableNameOnly());
478                }
479                else if(supportSchema) {
480                        if (!SQLUtil.isEmpty(table.getSchema())) {
481                                buffer.append(table.getSchema());
482                        }
483                        if (buffer.length() > 0) {
484                                buffer.append(".");
485                        }
486                        buffer.append(table.getTableNameOnly());
487                }
488                if (SubType.dblink.name().equals(table.getSubType())) {
489                        buffer.append("@").append(table.getDatabase());
490                }
491                return buffer.toString();
492        }
493
494    public static TCustomSqlStatement getTopStmt(TCustomSqlStatement stmt) {
495        if (ModelBindingManager.getGlobalOption() != null && ModelBindingManager.getGlobalOption().getAnalyzeMode() == AnalyzeMode.crud) {
496            TCustomSqlStatement parent = stmt.getParentStmt();
497            if (parent == null || parent instanceof TPlsqlCreatePackage
498                    || parent instanceof TStoredProcedureSqlStatement || parent instanceof TCommonBlock)
499                return stmt;
500            return getTopStmt(parent);
501        } else {
502            TCustomSqlStatement parent = stmt.getParentStmt();
503            if (parent == null || parent instanceof TPlsqlCreatePackage)
504                return stmt;
505            return getTopStmt(parent);
506        }
507    }
508
509    public static boolean isQuote(String column) {
510        return (column.startsWith("\"") && column.endsWith("\"")) || (column.startsWith("'") && column.endsWith("'"))
511                || (column.startsWith("[") && column.endsWith("]")) || (column.startsWith("`") && column.endsWith("`"));
512    }
513
514    public static String getProcedureNameWithArgs(TStoredProcedureSqlStatement stmt) {
515                StringBuilder buffer = new StringBuilder();
516                buffer.append(stmt.getStoredProcedureName().toString());
517                if (stmt.getParameterDeclarations() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) {
518                        buffer.append("(");
519                        TParameterDeclarationList parameters = stmt.getParameterDeclarations();
520                        for (int i = 0; i < parameters.size(); ++i) {
521                                TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i);
522                                if(parameter.getDataType()!=null) {
523                                        buffer.append(parameter.getDataType().getDataTypeName());
524                                }
525                                if(i<parameters.size()-1) {
526                                        buffer.append(",");
527                                }
528                        }
529                        buffer.append(")");
530                }
531                return buffer.toString();
532        }
533
534    public static String getIdentifierProcedureNameWithArgNum(procedure procedure) {
535        StringBuilder buffer = new StringBuilder();
536        buffer.append(SQLUtil.trimColumnStringQuote(procedure.getName()));
537        if (procedure.getArguments() != null && procedure.getArguments().size() > 0 && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) {
538            buffer.append("(");
539            buffer.append(procedure.getArguments().size());
540            buffer.append(")");
541        }
542        return buffer.toString().toUpperCase();
543    }
544
545    public static String getIdentifierOraclePackageNameWithArgNum(oraclePackage pkg) {
546        StringBuilder buffer = new StringBuilder();
547        buffer.append(SQLUtil.trimColumnStringQuote(pkg.getName()));
548        if (pkg.getArguments() != null && pkg.getArguments().size() > 0 && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) {
549            buffer.append("(");
550            buffer.append(pkg.getArguments().size());
551            buffer.append(")");
552        }
553        return buffer.toString().toUpperCase();
554    }
555
556    public static String getIdentifierFunctionName(table function) {
557        StringBuilder buffer = new StringBuilder();
558        buffer.append(SQLUtil.trimColumnStringQuote(function.getName()));
559        return buffer.toString().toUpperCase();
560    }
561
562    public static String getProcedureNameWithArgNum(TStoredProcedureSqlStatement stmt) {
563                StringBuilder buffer = new StringBuilder();
564                buffer.append(stmt.getStoredProcedureName().toString());
565                if (stmt.getParameterDeclarations() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) {
566                        buffer.append("(");
567                        buffer.append(stmt.getParameterDeclarations().size());
568                        buffer.append(")");
569                }
570                return buffer.toString();
571        }
572    
573        public static String getProcedureNameWithInputArgNum(TStoredProcedureSqlStatement stmt) {
574                StringBuilder buffer = new StringBuilder();
575                buffer.append(stmt.getStoredProcedureName().toString());
576                if (stmt.getParameterDeclarations() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) {
577                        buffer.append("(");
578                        int count = 0;
579                        for (int i = 0; i < stmt.getParameterDeclarations().size(); i++) {
580                                if (stmt.getParameterDeclarations().getParameterDeclarationItem(i)
581                                                .getParameterMode() == EParameterMode.in) {
582                                        count++;
583                                }
584                        }
585                        if (count == 0) {
586                                count = stmt.getParameterDeclarations().size();
587                        }
588                        buffer.append(count);
589                        buffer.append(")");
590                }
591                return buffer.toString();
592        }
593
594        public static String getFunctionNameWithArgNum(TFunctionCall function) {
595                StringBuilder buffer = new StringBuilder();
596                buffer.append(function.getFunctionName().toString());
597                if (function.getArgs() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) {
598                        buffer.append("(");
599                        buffer.append(function.getArgs().size());
600                        buffer.append(")");
601                }
602                return buffer.toString();
603        }
604
605        public static String getTableSchema(Table tableModel) {
606                StringBuilder buffer = new StringBuilder();
607                if(tableModel.getDatabase()!=null) {
608                        buffer.append(tableModel.getDatabase());
609                }
610                else {
611                        buffer.append(TSQLEnv.DEFAULT_DB_NAME);
612                }
613                buffer.append(".");
614                if(tableModel.getSchema()!=null) {
615                        buffer.append(tableModel.getSchema());
616                }
617                else {
618                        buffer.append(TSQLEnv.DEFAULT_SCHEMA_NAME);
619                }
620                return buffer.toString();
621        }
622        
623        public static String getTableSQLEnvKey(Table tableModel) {
624                StringBuilder buffer = new StringBuilder();
625                if(tableModel.getDatabase()!=null) {
626                        buffer.append(tableModel.getDatabase());
627                }
628                else {
629                        buffer.append(TSQLEnv.DEFAULT_DB_NAME);
630                }
631                buffer.append(".");
632                if(tableModel.getSchema()!=null) {
633                        buffer.append(tableModel.getSchema());
634                }
635                else {
636                        buffer.append(TSQLEnv.DEFAULT_SCHEMA_NAME);
637                }
638                buffer.append(".");
639                buffer.append(DlineageUtil.getSimpleTableName(tableModel.getName()));
640                return buffer.toString();
641        }
642        
643        public static String getProcedureParentName(TCustomSqlStatement stmt) {
644                if (stmt instanceof TStoredProcedureSqlStatement) {
645                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
646                                return getOraclePackageName() + ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
647                        }
648                }
649                stmt = stmt.getParentStmt();
650                if (stmt == null)
651                        return null;
652
653        if (stmt instanceof TCommonBlock) {
654                        if(((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) {
655                                stmt = (TStoredProcedureSqlStatement)((TCommonBlock) stmt).getBlockBody().getParentObjectName();
656                        }
657                }
658        
659                if (stmt instanceof TStoredProcedureSqlStatement) {
660                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
661                                String procedureName = getOraclePackageName() + ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
662                return getTableFullName(procedureName);
663                        }
664                }
665                if (stmt instanceof TTeradataCreateProcedure) {
666                        if (((TTeradataCreateProcedure) stmt).getProcedureName() != null) {
667                                String procedureName =  ((TTeradataCreateProcedure) stmt).getProcedureName().toString();
668                return getTableFullName(procedureName);
669                        }
670                }
671
672                return getProcedureParentName(stmt);
673        }
674
675        private static String getOraclePackageName() {
676                if (ModelBindingManager.getGlobalOraclePackage() != null) {
677                        return ModelBindingManager.getGlobalOraclePackage().getName() + ".";
678                }
679                return "";
680        }
681
682        public static sourceColumn copySourceColumn(sourceColumn oldSourceName) {
683                sourceColumn newSourceColumn = new sourceColumn();
684                newSourceColumn.setClauseType(oldSourceName.getClauseType());
685                newSourceColumn.setColumn(oldSourceName.getColumn());
686                newSourceColumn.setColumn_type(oldSourceName.getColumn_type());
687                newSourceColumn.setCoordinate(oldSourceName.getCoordinate());
688                newSourceColumn.setId(oldSourceName.getId());
689                newSourceColumn.setName(oldSourceName.getName());
690                newSourceColumn.setParent_alias(oldSourceName.getParent_alias());
691                newSourceColumn.setParent_id(oldSourceName.getParent_id());
692                newSourceColumn.setParent_name(oldSourceName.getParent_name());
693                newSourceColumn.setSource(oldSourceName.getSource());
694                newSourceColumn.setSource_id(oldSourceName.getSource_id());
695                newSourceColumn.setSource_name(oldSourceName.getSource_name());
696                newSourceColumn.setStruct(oldSourceName.isStruct());
697                newSourceColumn.setType(oldSourceName.getType());
698                newSourceColumn.setValue(oldSourceName.getValue());
699                if(oldSourceName.getTransforms()!=null) {
700                        newSourceColumn.setTransforms(new LinkedHashSet<transform>());
701                        for(transform transform: oldSourceName.getTransforms()) {
702                                newSourceColumn.getTransforms().add(transform);
703                        }
704                }
705                if(oldSourceName.getCandidateParents()!=null) {
706                        newSourceColumn.setCandidateParents(new LinkedHashSet<candidateTable>());
707                        for(candidateTable candidateTable: oldSourceName.getCandidateParents()) {
708                                newSourceColumn.getCandidateParents().add(candidateTable);
709                        }
710                }
711                return newSourceColumn;
712        }
713
714        public static boolean supportFunctionOverride(EDbVendor vendor) {
715                switch (vendor) {
716                case dbvpostgresql:
717                case dbvoracle:
718                case dbvdb2:
719                case dbvmysql:
720                case dbvsnowflake:
721                case dbvhana:
722                case dbvgreenplum:
723                case dbvgaussdb:
724                case dbvedb:
725                case dbvdameng:
726                        return true;
727                default:
728                        return false;
729                }
730        }
731        
732        private static final List<String> TERADATA_BUILTIN_FUNCTIONS = Arrays
733                        .asList(new String[] { "ACCOUNT", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
734                                        "CURRENT_USER", "DATABASE", "DATE", "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", });
735        
736        public static boolean isBuiltInFunctionName(String functionName) {
737                if (functionName == null)
738                        return false;
739                try {
740                        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
741                        if (vendor == EDbVendor.dbvteradata) {
742                                boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(functionName.toUpperCase());
743                                if (result) {
744                                        return true;
745                                }
746                        }
747
748                        List<String> versions = functionChecker.getAvailableDbVersions(vendor);
749                        if (versions != null && versions.size() > 0) {
750                                for (int i = 0; i < versions.size(); i++) {
751                                        boolean result = functionChecker.isBuiltInFunction(functionName.toUpperCase(),
752                                                        vendor, versions.get(i));
753                                        if (result) {
754                                                return result;
755                                        }
756                                }
757
758                                // boolean result =
759                                // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString());
760                                // if (result) {
761                                // return true;
762                                // }
763                        }
764                } catch (Exception e) {
765                }
766
767                return false;
768        }
769        
770        public static boolean isKeyword(String objectName) {
771                if (objectName == null)
772                        return false;
773                try {
774                        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
775
776                        List<String> versions = keywordChecker.getAvailableDbVersions(vendor);
777                        if (versions != null && versions.size() > 0) {
778                                for (int i = 0; i < versions.size(); i++) {
779                                        List<String> segments = SQLUtil.parseNames(objectName);
780                                        boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1),
781                                                        vendor, versions.get(i), false);
782                                        if (result) {
783                                                return result;
784                                        }
785                                }
786                        }
787                } catch (Exception e) {
788                }
789
790                return false;
791        }
792
793        public static TSelectSqlStatement getLeftStmt(TSelectSqlStatement stmt) {
794                TSelectSqlStatement current = stmt.getLeftStmt();
795                if (current == null) return null;
796                while (current.getLeftStmt() != null) {
797                        current = current.getLeftStmt();
798                }
799                return current;
800        }
801
802        public static String stripQuotesFromQualifiedName(String qualifiedName) {
803                if (SQLUtil.isEmpty(qualifiedName)) {
804                        return qualifiedName;
805                }
806
807                List<String> segments = SQLUtil.parseNames(qualifiedName);
808                StringBuilder sb = new StringBuilder();
809                for (int i = 0; i < segments.size(); i++) {
810                        if (i > 0) {
811                                sb.append('.');
812                        }
813                        String seg = segments.get(i);
814                        sb.append(TBaseType.getTextWithoutQuoted(seg));
815                }
816                return sb.toString();
817        }
818
819        public static boolean isProcedureExcluded(String fullName) {
820                if (SQLUtil.isEmpty(fullName)) {
821                        return false;
822                }
823
824                Option option = ModelBindingManager.getGlobalOption();
825                if (option == null) {
826                        return false;
827                }
828
829                Set<String> excludedNames = option.getExcludedProcedureNames();
830                Set<String> excludedPatterns = option.getExcludedProcedurePatterns();
831
832                if ((excludedNames == null || excludedNames.isEmpty()) &&
833                        (excludedPatterns == null || excludedPatterns.isEmpty())) {
834                        return false;
835                }
836
837        if (excludedNames != null) {
838            for (String excludedName : excludedNames) {
839                if (DlineageUtil.compareIdentifier(fullName, excludedName, ESQLDataObjectType.dotFunction)) {
840                    return true;
841                }
842            }
843        }
844
845        String normalizedFullName = stripQuotesFromQualifiedName(fullName);
846        if (excludedPatterns != null && !excludedPatterns.isEmpty()) {
847            for (String pattern : excludedPatterns) {
848                if (SQLUtil.isEmpty(pattern)) {
849                        continue;
850                }
851                String normalizedPattern = stripQuotesFromQualifiedName(pattern);
852                StringBuilder regexBuilder = new StringBuilder();
853                for (char c : normalizedPattern.toCharArray()) {
854                    switch (c) {
855                        case '.':
856                            regexBuilder.append("\\.");
857                            break;
858                        case '*':
859                            regexBuilder.append(".*");
860                            break;
861                        case '?':
862                            regexBuilder.append(".");
863                            break;
864                        case '(': case ')': case '[': case ']': case '{': case '}':
865                        case '|': case '^': case '$': case '+': case '\\':
866                            regexBuilder.append("\\").append(c);
867                            break;
868                        default:
869                            regexBuilder.append(c);
870                    }
871                }
872                String regex = "^" + regexBuilder.toString() + "$";
873                if (normalizedFullName.matches("(?i)" + regex)) {
874                    return true;
875                }
876            }
877        }
878
879                return false;
880        }
881}