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