001package gudusoft.gsqlparser.dlineage.dataflow.model;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import gudusoft.gsqlparser.EDbVendor;
007import gudusoft.gsqlparser.nodes.TObjectName;
008import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
009import gudusoft.gsqlparser.util.SQLUtil;
010
011public abstract class Column {
012        private List<Column> starSourceColumns = new ArrayList<>();
013
014        public List<Column> getStarSourceColumns() {
015                return starSourceColumns;
016        }
017
018        public void appendStarSourceColumn(Column starSourceColumn) {
019                if (starSourceColumn != null && !starSourceColumns.contains(starSourceColumn)) {
020                        starSourceColumns.add(starSourceColumn);
021                        List<TObjectName> columns = getStarLinkColumnList();
022                        if (columns != null) {
023                                if (starSourceColumn instanceof ResultColumn) {
024                                        ResultSet parent = ((ResultColumn) starSourceColumn).getResultSet();
025                                        boolean found = false;
026                                        for (TObjectName column : columns) {
027                                                for (ResultColumn resultColumn : parent.getColumns()) {
028                                                        if (sameColumnRef(resultColumn.getName(), column.toString())
029                                                                        || sameColumnName(resultColumn.getName(), column.getColumnNameOnly())) {
030                                                                found = true;
031                                                                break;
032                                                        }
033                                                }
034                                                if (!found) {
035                                                        starSourceColumn.bindStarLinkColumn(column);
036                                                }
037                                        }
038                                } else if (starSourceColumn instanceof TableColumn) {
039                                        Table parent = ((TableColumn) starSourceColumn).getTable();
040                                        boolean found = false;
041                                        for (TObjectName column : columns) {
042                                                for (TableColumn resultColumn : parent.getColumns()) {
043                                                        if (sameColumnRef(resultColumn.getName(), column.toString())
044                                                                        || sameColumnName(resultColumn.getName(), column.getColumnNameOnly())) {
045                                                                found = true;
046                                                                break;
047                                                        }
048                                                }
049                                                if (!found) {
050                                                        starSourceColumn.bindStarLinkColumn(column);
051                                                }
052                                        }
053                                } 
054                        }
055                }
056        }
057
058         public abstract boolean bindStarLinkColumn(TObjectName objectName);
059
060         public abstract List<TObjectName> getStarLinkColumnList();
061
062        /**
063         * Column-name equality routed through the unified façade; falls back to
064         * case-insensitive comparison when no analysis vendor is bound.
065         */
066        private static boolean sameColumnName(String a, String b) {
067                if (a == null || b == null) {
068                        return false;
069                }
070                EDbVendor vendor = ModelBindingManager.getGlobalVendor();
071                return vendor == null ? a.equalsIgnoreCase(b)
072                                : SQLUtil.sameName(vendor, ESQLDataObjectType.dotColumn, a, b);
073        }
074
075        /**
076         * Like {@link #sameColumnName} but for possibly-qualified references
077         * (TObjectName.toString() can be {@code table.column}); routes through the
078         * segmenting compare instead of the single-segment façade.
079         */
080        private static boolean sameColumnRef(String a, String b) {
081                if (a == null || b == null) {
082                        return false;
083                }
084                EDbVendor vendor = ModelBindingManager.getGlobalVendor();
085                return vendor == null ? a.equalsIgnoreCase(b)
086                                : SQLUtil.compareIdentifier(vendor, ESQLDataObjectType.dotColumn, a, b);
087        }
088
089}