001
002package gudusoft.gsqlparser.dlineage.dataflow.model;
003
004import java.util.ArrayList;
005import java.util.List;
006
007import gudusoft.gsqlparser.ESqlClause;
008import gudusoft.gsqlparser.TSourceToken;
009import gudusoft.gsqlparser.dlineage.util.Pair3;
010import gudusoft.gsqlparser.nodes.TObjectName;
011import gudusoft.gsqlparser.nodes.TParseTreeNode;
012import gudusoft.gsqlparser.util.SQLUtil;
013
014public class ResultColumnRelationshipElement implements
015                RelationshipElement<ResultColumn>
016{
017
018        private ResultColumn column;
019
020        private TObjectName columnName;
021
022        private ESqlClause relationLocation;
023
024        private int starIndex = -1;
025
026        // Where THIS relation referenced the column (e.g. the operand in an ON or
027        // WHERE clause). A derived table's / CTE's ResultColumn model carries its
028        // select-list definition span, so it cannot hold the per-reference
029        // coordinate. Null when unknown or synthesized. Deliberately excluded from
030        // equals/hashCode.
031        private Pair3<Long, Long, String> referenceStartPosition;
032
033        private Pair3<Long, Long, String> referenceEndPosition;
034
035    private List<Transform> transforms = new ArrayList<Transform>();
036
037        public ResultColumnRelationshipElement(ResultColumn column)
038        {
039                this.column = column;
040        }
041        
042        public ResultColumnRelationshipElement(ResultColumn column, int starIndex )
043        {
044                this.column = column;
045                this.starIndex = starIndex;
046        }
047        
048        public ResultColumnRelationshipElement(ResultColumn column, TObjectName columnName) {
049                this.column = column;
050                this.columnName = columnName;
051        }
052
053        public ResultColumnRelationshipElement(ResultColumn column,
054                                                                                   ESqlClause relationLocation )
055        {
056                this.column = column;
057                this.relationLocation = relationLocation;
058        }
059
060        public ResultColumnRelationshipElement(ResultColumn column, ESqlClause relationLocation,
061                        TObjectName referenceObject)
062        {
063                this(column, relationLocation);
064                setReferencePosition(referenceObject);
065        }
066
067        /**
068         * Records the span of the object name this relation was built from, so the
069         * serialized source can point at the reference site (the ON/WHERE operand)
070         * instead of the result column's select-list definition span. Ignores
071         * synthesized object names, which have no real source token (their tokens
072         * sit at line 1, column 1).
073         */
074        public void setReferencePosition(TObjectName referenceObject) {
075                if (referenceObject == null || referenceObject.getStartToken() == null
076                                || referenceObject.getEndToken() == null) {
077                        return;
078                }
079                TSourceToken startToken = referenceObject.getStartToken();
080                TSourceToken endToken = referenceObject.getEndToken();
081                if (startToken.lineNo <= 0 || (startToken.lineNo == 1 && startToken.columnNo == 1)) {
082                        return;
083                }
084                this.referenceStartPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo,
085                                ModelBindingManager.getGlobalHash());
086                this.referenceEndPosition = new Pair3<Long, Long, String>(endToken.lineNo,
087                                endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(),
088                                ModelBindingManager.getGlobalHash());
089        }
090
091        public Pair3<Long, Long, String> getReferenceStartPosition() {
092                return referenceStartPosition;
093        }
094
095        public Pair3<Long, Long, String> getReferenceEndPosition() {
096                return referenceEndPosition;
097        }
098
099        @Override
100        public ResultColumn getElement( )
101        {
102                return column;
103        }
104
105        public ESqlClause getRelationLocation( )
106        {
107                return relationLocation;
108        }
109
110
111        public TObjectName getColumnName() {
112                return columnName;
113        }
114
115        @Override
116        public int hashCode( )
117        {
118                final int prime = 31;
119                int result = 1;
120                result = prime
121                                * result
122                                + ( ( column == null ) ? 0 : column.hashCode( ) );
123                result = prime
124                                * result
125                                + ( ( relationLocation == null ) ? 0
126                                                : relationLocation.hashCode( ) );
127                return result;
128        }
129
130        @Override
131        public boolean equals( Object obj )
132        {
133                if ( this == obj )
134                        return true;
135                if ( obj == null )
136                        return false;
137                if ( getClass( ) != obj.getClass( ) )
138                        return false;
139                ResultColumnRelationshipElement other = (ResultColumnRelationshipElement) obj;
140                if ( column == null )
141                {
142                        if ( other.column != null )
143                                return false;
144                }
145                else if ( !column.equals( other.column ) )
146                        return false;
147                if ( relationLocation != other.relationLocation )
148                        return false;
149                return true;
150        }
151        
152        @Override
153        public List<Transform> getTransforms() {
154                return transforms;
155        }
156        
157        public void addTransform(String type, TParseTreeNode code) {
158                if (ModelBindingManager.getGlobalOption()!=null && !ModelBindingManager.getGlobalOption().isTransform()) {
159                        return;
160                }
161                Transform transform = new Transform();
162                transform.setType(type);
163                transform.setCode(code);
164                transforms.add(transform);
165        }
166
167        public int getStarIndex() {
168                return starIndex;
169        }
170
171        public void setStarIndex(int starIndex) {
172                this.starIndex = starIndex;
173        }
174
175}