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}