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 // The column is a star whose members' order is unknown, read at a position (an INSERT column list), so no 036 // member can be told to be the one at that position: the relation reads the star itself (Mantis 4856). 037 // Deliberately excluded from equals/hashCode. 038 private boolean positionUnproven; 039 040 private List<Transform> transforms = new ArrayList<Transform>(); 041 042 public ResultColumnRelationshipElement(ResultColumn column) 043 { 044 this.column = column; 045 } 046 047 public ResultColumnRelationshipElement(ResultColumn column, int starIndex ) 048 { 049 this.column = column; 050 this.starIndex = starIndex; 051 } 052 053 public ResultColumnRelationshipElement(ResultColumn column, TObjectName columnName) { 054 this.column = column; 055 this.columnName = columnName; 056 } 057 058 public ResultColumnRelationshipElement(ResultColumn column, 059 ESqlClause relationLocation ) 060 { 061 this.column = column; 062 this.relationLocation = relationLocation; 063 } 064 065 public ResultColumnRelationshipElement(ResultColumn column, ESqlClause relationLocation, 066 TObjectName referenceObject) 067 { 068 this(column, relationLocation); 069 setReferencePosition(referenceObject); 070 } 071 072 /** 073 * Records the span of the object name this relation was built from, so the 074 * serialized source can point at the reference site (the ON/WHERE operand) 075 * instead of the result column's select-list definition span. Ignores 076 * synthesized object names, which have no real source token (their tokens 077 * sit at line 1, column 1). 078 */ 079 public void setReferencePosition(TObjectName referenceObject) { 080 if (referenceObject == null || referenceObject.getStartToken() == null 081 || referenceObject.getEndToken() == null) { 082 return; 083 } 084 TSourceToken startToken = referenceObject.getStartToken(); 085 TSourceToken endToken = referenceObject.getEndToken(); 086 if (startToken.lineNo <= 0 || (startToken.lineNo == 1 && startToken.columnNo == 1)) { 087 return; 088 } 089 this.referenceStartPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 090 ModelBindingManager.getGlobalHash()); 091 this.referenceEndPosition = new Pair3<Long, Long, String>(endToken.lineNo, 092 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), 093 ModelBindingManager.getGlobalHash()); 094 } 095 096 public Pair3<Long, Long, String> getReferenceStartPosition() { 097 return referenceStartPosition; 098 } 099 100 public Pair3<Long, Long, String> getReferenceEndPosition() { 101 return referenceEndPosition; 102 } 103 104 @Override 105 public ResultColumn getElement( ) 106 { 107 return column; 108 } 109 110 public ESqlClause getRelationLocation( ) 111 { 112 return relationLocation; 113 } 114 115 116 public TObjectName getColumnName() { 117 return columnName; 118 } 119 120 @Override 121 public int hashCode( ) 122 { 123 final int prime = 31; 124 int result = 1; 125 result = prime 126 * result 127 + ( ( column == null ) ? 0 : column.hashCode( ) ); 128 result = prime 129 * result 130 + ( ( relationLocation == null ) ? 0 131 : relationLocation.hashCode( ) ); 132 return result; 133 } 134 135 @Override 136 public boolean equals( Object obj ) 137 { 138 if ( this == obj ) 139 return true; 140 if ( obj == null ) 141 return false; 142 if ( getClass( ) != obj.getClass( ) ) 143 return false; 144 ResultColumnRelationshipElement other = (ResultColumnRelationshipElement) obj; 145 if ( column == null ) 146 { 147 if ( other.column != null ) 148 return false; 149 } 150 else if ( !column.equals( other.column ) ) 151 return false; 152 if ( relationLocation != other.relationLocation ) 153 return false; 154 return true; 155 } 156 157 @Override 158 public List<Transform> getTransforms() { 159 return transforms; 160 } 161 162 public void addTransform(String type, TParseTreeNode code) { 163 if (ModelBindingManager.getGlobalOption()!=null && !ModelBindingManager.getGlobalOption().isTransform()) { 164 return; 165 } 166 Transform transform = new Transform(); 167 transform.setType(type); 168 transform.setCode(code); 169 transforms.add(transform); 170 } 171 172 public int getStarIndex() { 173 return starIndex; 174 } 175 176 public boolean isPositionUnproven() { 177 return positionUnproven; 178 } 179 180 public void setPositionUnproven(boolean positionUnproven) { 181 this.positionUnproven = positionUnproven; 182 } 183 184 public void setStarIndex(int starIndex) { 185 this.starIndex = starIndex; 186 } 187 188}