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