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