001
002package gudusoft.gsqlparser.dlineage.dataflow.model;
003
004import java.util.ArrayList;
005import java.util.LinkedHashMap;
006import java.util.LinkedHashSet;
007import java.util.List;
008import java.util.Map;
009import java.util.Set;
010
011import gudusoft.gsqlparser.EDbVendor;
012import gudusoft.gsqlparser.EExpressionType;
013import gudusoft.gsqlparser.TSourceToken;
014import gudusoft.gsqlparser.dlineage.util.DlineageUtil;
015import gudusoft.gsqlparser.dlineage.util.Pair3;
016import gudusoft.gsqlparser.nodes.TConstant;
017import gudusoft.gsqlparser.nodes.TExpression;
018import gudusoft.gsqlparser.nodes.TFunctionCall;
019import gudusoft.gsqlparser.nodes.TObjectName;
020import gudusoft.gsqlparser.nodes.TResultColumn;
021import gudusoft.gsqlparser.nodes.TResultColumnList;
022import gudusoft.gsqlparser.sqlenv.TSQLEnv;
023import gudusoft.gsqlparser.util.SQLUtil;
024
025public class TableColumn extends Column{
026
027
028    private Table table;
029
030    private long id;
031    protected String name;
032
033    protected Pair3<Long, Long, String> startPosition;
034    protected Pair3<Long, Long, String> endPosition;
035
036    private TObjectName columnObject;
037    private Map<String, Set<TObjectName>> starLinkColumns = new LinkedHashMap<String, Set<TObjectName>>();
038    
039    private boolean showStar;
040    
041    private boolean expandStar = true;
042    
043        private Integer columnIndex;
044        
045        private boolean isVariant;
046        
047        private boolean isPseduo = false;
048        
049        private boolean notBindStarColumn = false;
050        
051        private String displayName;
052
053    private String dataType;
054
055    private Boolean primaryKey = false;
056
057    private Boolean unqiueKey = false;
058
059    private Boolean indexKey = false;
060
061    private Boolean foreignKey = false;
062    
063    private boolean isStruct = false;
064
065        private Transform transform;
066        
067    private List<Object> candidateParents;
068
069        public TableColumn(Table view, TObjectName columnObject, int index) {
070                this(view, columnObject);
071                this.columnIndex = index;
072        }
073        
074    public TableColumn(Table table, TObjectName columnObject) {
075        if (table == null || columnObject == null)
076            throw new IllegalArgumentException("TableColumn arguments can't be null.");
077
078        id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
079
080        this.columnObject = columnObject;
081
082        TSourceToken startToken = columnObject.getStartToken();
083        TSourceToken endToken = columnObject.getEndToken();
084        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo,
085                startToken.columnNo, ModelBindingManager.getGlobalHash());
086        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
087                endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash());
088
089        if (columnObject.getColumnNameOnly() != null
090                && !"".equals(columnObject.getColumnNameOnly())) {
091                        if (columnObject.getPartToken() != null && columnObject.getPropertyToken() != null) {
092                                if(supportProperty()) {
093                                        this.name = columnObject.toString();
094                                }
095                                else {
096                                        this.name = columnObject.getPartToken().astext + "." + columnObject.getPropertyToken().astext;
097                                }
098                        } else {
099                                this.name = columnObject.getColumnNameOnly();
100                        }
101        }
102        else if (columnObject.toString().indexOf(".") != -1 && "".equals(columnObject.getColumnNameOnly()) && 
103                        supportProperty()) {
104                this.name = columnObject.toString();
105                }
106                else if (columnObject.toString().indexOf(".") != -1) {
107                        List<String> splits = SQLUtil.parseNames(columnObject.toString());
108                        this.name = splits.get(splits.size() - 1);
109                }
110        else {
111            this.name = columnObject.toString();
112        }
113
114        this.table = table;
115        table.addColumn(this);
116        
117        if("*".equals(this.name) && !table.isDetermined()){
118                showStar = true;
119        }
120    }
121
122        protected boolean supportProperty() {
123                return ModelBindingManager.getGlobalVendor() == EDbVendor.dbvbigquery || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvredshift;
124        }
125
126    public TableColumn(Table table, TConstant columnObject, int columnIndex) {
127        if (table == null || columnObject == null)
128            throw new IllegalArgumentException("TableColumn arguments can't be null.");
129
130        id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
131
132        TSourceToken startToken = columnObject.getStartToken();
133        TSourceToken endToken = columnObject.getEndToken();
134        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo,
135                startToken.columnNo, ModelBindingManager.getGlobalHash());
136        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
137                endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash());
138
139        this.name = columnObject.toString();
140        
141        this.table = table;
142        table.addColumn(this);
143    }
144    
145    public TableColumn(Table table, TConstant columnObject) {
146        if (table == null || columnObject == null)
147            throw new IllegalArgumentException("TableColumn arguments can't be null.");
148
149        id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
150
151        TSourceToken startToken = columnObject.getStartToken();
152        TSourceToken endToken = columnObject.getEndToken();
153        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo,
154                startToken.columnNo, ModelBindingManager.getGlobalHash());
155        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
156                endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash());
157
158        this.name = columnObject.toString();        
159        this.table = table;
160        table.addColumn(this);
161    }
162    
163    public TableColumn(Table table, TFunctionCall columnObject) {
164        if (table == null || columnObject == null)
165            throw new IllegalArgumentException("TableColumn arguments can't be null.");
166
167        id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
168
169        TSourceToken startToken = columnObject.getStartToken();
170        TSourceToken endToken = columnObject.getEndToken();
171        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo,
172                startToken.columnNo, ModelBindingManager.getGlobalHash());
173        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
174                endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash());
175
176        this.name = columnObject.toString();        
177        this.table = table;
178        table.addColumn(this);
179        }
180
181    
182    public TableColumn(Table table, TExpression columnObject, int columnIndex) {
183        if (table == null || columnObject == null)
184            throw new IllegalArgumentException("TableColumn arguments can't be null.");
185
186        id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
187
188        TSourceToken startToken = columnObject.getStartToken();
189        TSourceToken endToken = columnObject.getEndToken();
190        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo,
191                startToken.columnNo, ModelBindingManager.getGlobalHash());
192        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
193                endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash());
194
195                this.name = getColumnName(columnObject);
196        
197        this.table = table;
198        table.addColumn(this);
199    }
200    
201    protected String getColumnName(TExpression expr) {
202                if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
203                        return expr.toString();
204                } else if (expr.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
205                        return expr.getLeftOperand().toString();
206                } else if (expr.getExpressionType() == EExpressionType.function_t) {
207                        return expr.getFunctionCall().toString();
208                } else if (expr.getExpressionType() == EExpressionType.typecast_t) {
209                        return expr.getLeftOperand().toString();
210                } else if (expr.getExpressionType() == EExpressionType.parenthesis_t) {
211                        return getColumnName(expr.getLeftOperand());
212                } else if (expr.getExpressionType() == EExpressionType.simple_object_name_t) {
213                        TObjectName columnName = expr.getObjectOperand();
214                        if (columnName.getPropertyToken() != null) {
215                                return columnName.getPropertyToken().astext;
216                        } else {
217                                return columnName.getColumnNameOnly();
218                        }
219                } else if (expr.getExpressionType() == EExpressionType.subquery_t) {
220                        TResultColumnList resultset = expr.getSubQuery().getResultColumnList();
221                        if (resultset != null && resultset.size() == 1) {
222                                TResultColumn resultColumn = resultset.getResultColumn(0);
223                                if (!SQLUtil.isEmpty(resultColumn.getColumnAlias())) {
224                                        return resultColumn.getColumnAlias();
225                                } else if (resultColumn.getExpr() != null) {
226                                        return getColumnName(resultColumn.getExpr());
227                                } else if (resultColumn.getColumnNameOnly() != null
228                                                && !"".equals(resultColumn.getColumnNameOnly())) {
229                                        if (resultColumn.getExpr().getObjectOperand() != null
230                                                        && resultColumn.getExpr().getObjectOperand().getPropertyToken() != null) {
231                                                this.name = resultColumn.getExpr().getObjectOperand().getPropertyToken().astext;
232                                        } else {
233                                                this.name = resultColumn.getColumnNameOnly();
234                                        }
235                                } else {
236                                        this.name = resultColumn.toString();
237                                }
238                        }
239                }
240                return quote(expr.toString());
241        }
242    
243 
244        private String quote(String column) {
245        EDbVendor vendor = ModelBindingManager.getGlobalVendor();
246        String delimitedChar = TSQLEnv.delimitedChar(vendor);
247        if (!DlineageUtil.isQuote(column)){
248                if(vendor == EDbVendor.dbvmssql || vendor == EDbVendor.dbvazuresql) {
249                        return "[" + column + "]";
250                }
251                else {
252                                return delimitedChar + column + delimitedChar;
253                        }
254        }
255        else return column;
256    }
257
258    public Table getTable() {
259        return table;
260    }
261
262    public long getId() {
263        return id;
264    }
265
266    public String getName() {
267        return name;
268    }
269
270    public Pair3<Long, Long, String> getStartPosition() {
271        return startPosition;
272    }
273
274    public Pair3<Long, Long, String> getEndPosition() {
275        return endPosition;
276    }
277
278    public TObjectName getColumnObject() {
279        return columnObject;
280    }
281
282    public void bindStarLinkColumns(Map<String, Set<TObjectName>> starLinkColumns) {
283        if (starLinkColumns != null && !starLinkColumns.isEmpty()) {
284            this.starLinkColumns.putAll(starLinkColumns);
285        }
286    }
287
288    public Map<String, Set<TObjectName>> getStarLinkColumns() {
289        return starLinkColumns;
290    }
291    
292        public boolean hasStarLinkColumn(){
293                return (starLinkColumns!=null && !starLinkColumns.isEmpty());
294        }
295    
296        public boolean bindStarLinkColumn(TObjectName objectName) {
297                if (objectName == null) {
298                        return false;
299                }
300
301                String columnName = DlineageUtil.getColumnName(objectName);
302
303                if ("*".equals(columnName)) {
304                        return false;
305                }
306                
307                boolean flag = false;
308                if (!starLinkColumns.containsKey(columnName)) {
309                        starLinkColumns.put(columnName, new LinkedHashSet<TObjectName>());
310                        flag = true;
311                }
312
313                starLinkColumns.get(columnName).add(objectName);
314                
315                
316                if(this.getStarSourceColumns()!=null) {
317                        for(Column column: this.getStarSourceColumns()) {
318                                column.bindStarLinkColumn(objectName);
319                        }
320                }
321                
322                return flag;
323        }
324    
325        public List<TObjectName> getStarLinkColumnList() {
326                List<TObjectName> columns = new ArrayList<TObjectName>();
327                if (starLinkColumns != null) {
328                        for (Set<TObjectName> columnSet : starLinkColumns.values()) {
329                                columns.addAll(columnSet);
330                        }
331                }
332                return columns;
333        }
334        
335        public List<String> getStarLinkColumnNames() {
336                List<String> columns = new ArrayList<>();
337                if (starLinkColumns != null) {
338                        columns.addAll(starLinkColumns.keySet());
339                }
340                return columns;
341        }
342
343        public boolean isShowStar() {
344                return showStar;
345        }
346
347        public void setShowStar(boolean showStar) {
348                this.showStar = showStar;
349        }
350        
351        public Table getView() {
352                return getTable();
353        }
354
355        public Integer getColumnIndex() {
356                return columnIndex;
357        }
358
359        public boolean isVariant() {
360                return isVariant;
361        }
362
363        public void setVariant(boolean isVariant) {
364                this.isVariant = isVariant;
365        }
366
367        public String getDisplayName() {
368                return displayName;
369        }
370
371        public void setDisplayName(String displayName) {
372                this.displayName = displayName;
373        }
374
375        public void setExpandStar(boolean expandStar) {
376                this.expandStar = expandStar;
377        }
378
379        public boolean isExpandStar() {
380                return expandStar;
381        }
382
383        public boolean isPseduo() {
384                return isPseduo;
385        }
386
387        public void setPseduo(boolean isPseduo) {
388                this.isPseduo = isPseduo;
389        }
390
391        public void notBindStarLinkColumn(boolean notBindStarColumn) {
392                this.notBindStarColumn = notBindStarColumn;
393        }
394        
395        public boolean isNotBindStarLinkColumn() {
396                return notBindStarColumn;
397        }
398
399    public Boolean getPrimaryKey() {
400        return primaryKey;
401    }
402
403    public void setPrimaryKey(Boolean primaryKey) {
404        this.primaryKey = primaryKey;
405    }
406
407    public Boolean getUnqiueKey() {
408        return unqiueKey;
409    }
410
411    public void setUnqiueKey(Boolean unqiueKey) {
412        this.unqiueKey = unqiueKey;
413    }
414
415    public Boolean getIndexKey() {
416        return indexKey;
417    }
418
419    public void setIndexKey(Boolean indexKey) {
420        this.indexKey = indexKey;
421    }
422
423    public Boolean getForeignKey() {
424        return foreignKey;
425    }
426
427    public void setForeignKey(Boolean foreignKey) {
428        this.foreignKey = foreignKey;
429    }
430
431    public String getDataType() {
432        return dataType;
433    }
434
435    public void setDataType(String dataType) {
436        this.dataType = dataType;
437    }
438    
439    @Override
440    public String toString() {
441        return this.name;
442    }
443
444        public void setColumnIndex(int columnIndex) {
445                this.columnIndex = columnIndex;
446        }
447
448        public boolean isStruct() {
449                return isStruct;
450        }
451
452        public void setStruct(boolean isStruct) {
453                this.isStruct = isStruct;
454        }
455
456        public Transform getTransform() {
457                return transform;
458        }
459
460        public void setTransform(Transform transform) {
461                this.transform = transform;
462        }
463
464        public List<Object> getCandidateParents() {
465                return candidateParents;
466        }
467
468        public void setCandidateParents(List<Object> candidateParents) {
469                this.candidateParents = candidateParents;
470        }
471}