001 002package gudusoft.gsqlparser.dlineage.dataflow.model; 003 004import gudusoft.gsqlparser.EExpressionType; 005import gudusoft.gsqlparser.TCustomSqlStatement; 006import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 007import gudusoft.gsqlparser.nodes.*; 008import gudusoft.gsqlparser.stmt.TCreateViewSqlStatement; 009 010import java.util.Collection; 011import java.util.LinkedHashSet; 012import java.util.List; 013import java.util.Set; 014import java.util.Stack; 015 016public abstract class AbstractRelationship implements Relationship { 017 018 private long id; 019 020 private String function; 021 022 private EffectType effectType; 023 024 private String partition; 025 026 private boolean showStarRelation; 027 028 protected RelationshipElement<?> target; 029 030 protected Set<RelationshipElement<?>> sources = new LinkedHashSet<RelationshipElement<?>>(); 031 032 private Process process; 033 034 private String sqlHash; 035 036 private Long procedureId; 037 038 private String sqlComment; 039 040 public AbstractRelationship() { 041 id = ++ModelBindingManager.get().RELATION_ID; 042 } 043 044 public long getId() { 045 return id; 046 } 047 048 public RelationshipElement<?> getTarget() { 049 return target; 050 } 051 052 public void setTarget(RelationshipElement<?> target) { 053 this.target = target; 054 SqllrObservations observations = SqllrObservations.current(); 055 if (observations != null) { 056 observations.onTarget(this, target); 057 } 058 if(target.getElement() instanceof RelationRows<?>){ 059 ((RelationRows<?>)target.getElement()).holdRelation(this); 060 ((RelationRows<?>)target.getElement()).setHasRelation(true); 061 } 062 063 Stack<TCustomSqlStatement> stmtStack = ModelBindingManager.getGlobalStmtStack(); 064 if (stmtStack.isEmpty()) { 065 return; 066 } 067 TCustomSqlStatement stmt = DlineageUtil.getTopStmt(stmtStack.peek()); 068 069 if(ModelBindingManager.getGlobalOption().isTraceSQL()) { 070 this.sqlHash = ModelBindingManager.get().getSqlHash(stmt); 071 try { 072 this.sqlComment = stmt.getCommentBeforeNode(); 073 } catch (Exception e) { 074 } 075 } 076 else if(ModelBindingManager.getGlobalOption().isShowComment() 077 && !ModelBindingManager.isSyntheticStmtContext()) { 078 // The innermost statement, bounded at a blank line: the label the author put on THIS 079 // statement. `stmt` above is the top-level one, whose comment is the procedure header. 080 try { 081 this.sqlComment = stmtStack.peek().getCommentBeforeNode(true); 082 } catch (Exception e) { 083 } 084 } 085 086 if(ModelBindingManager.getGlobalOption().isTraceProcedure()) { 087 Object model = ModelBindingManager.get().getModel(stmt); 088 if(model instanceof Procedure) { 089 this.procedureId = ((Procedure)model).getId(); 090 } 091 } 092 } 093 094 public Collection<RelationshipElement<?>> getSources() { 095 return sources; 096 } 097 098 public void addSource(RelationshipElement<?> source) { 099 addSource(source, true); 100 } 101 102 private void addTransformsInReverse(RelationshipElement<?> source, List<Transform> transforms) { 103 if (transforms == null) return; 104 for (int i = transforms.size() - 1; i >= 0; i--) { 105 Transform transform = transforms.get(i); 106 source.addTransform(transform.getType(), transform.getCode()); 107 } 108 } 109 110 public void addSource(RelationshipElement<?> source, boolean inferStar) { 111 SqllrObservations observations = SqllrObservations.current(); 112 if (observations != null) { 113 observations.onSource(this, source); // before de-duplication: a + a reads a twice 114 } 115 if (source != null && !sources.contains(source)) { 116 sources.add(source); 117 118 Object obj = source.getElement(); 119 if (obj instanceof ResultColumn) { 120 ResultSet resultSet = ((ResultColumn) obj).getResultSet(); 121 if (resultSet.isTarget() && !(resultSet instanceof Function)) { 122 resultSet.setTarget(false); 123 } 124 } 125 126 if (getTarget() instanceof ResultColumnRelationshipElement) { 127 ResultColumn column = ((ResultColumnRelationshipElement) getTarget()).getElement(); 128 if (column != null) { 129 if (column.getTransforms() != null) { 130 addTransformsInReverse(source, column.getTransforms()); 131 } else if (column.getColumnObject() instanceof TResultColumn) { 132 TResultColumn columnObject = (TResultColumn) column.getColumnObject(); 133 TExpression expression = columnObject.getExpr(); 134 addExpressionTransform(source, expression); 135 } else if (column instanceof FunctionResultColumn) { 136 FunctionResultColumn functionColumn = (FunctionResultColumn) column; 137 if (functionColumn.getFunction() instanceof TFunctionCall) { 138 source.addTransform(Transform.FUNCTION, functionColumn.getFunction()); 139 } 140 if (functionColumn.getFunction() instanceof TCaseExpression) { 141 source.addTransform(Transform.CASE, functionColumn.getFunction()); 142 } 143 } else if (column.getColumnObject() instanceof TObjectName) { 144 source.addTransform(Transform.SIMPLE, (TObjectName) column.getColumnObject()); 145 } 146 } 147 148 if (source.getElement() instanceof ResultColumn) { 149 ResultColumn sourceColumn = (ResultColumn) source.getElement(); 150 if (column != null && sourceColumn.isStarColumn() && column.isStarColumn() && inferStar) { 151 column.appendStarSourceColumn(sourceColumn); 152 } 153 addTransformsInReverse(source, sourceColumn.getTransforms()); 154 } else if (source.getElement() instanceof TableColumn) { 155 TableColumn sourceColumn = (TableColumn) source.getElement(); 156 if (column != null && sourceColumn.isStarColumn() && column.isStarColumn() && inferStar) { 157 column.appendStarSourceColumn(sourceColumn); 158 } 159 addTransformsInReverse(source, sourceColumn.getTransforms()); 160 } 161 } else if (getTarget() instanceof ViewColumnRelationshipElement) { 162 TableColumn column = ((ViewColumnRelationshipElement) getTarget()).getElement(); 163 if (column.getTable() != null && column.getTable().getSqlStatement() instanceof TCreateViewSqlStatement) { 164 TCreateViewSqlStatement view = (TCreateViewSqlStatement) column.getTable().getSqlStatement(); 165 if (view.getSubquery() != null && column.getColumnObject() != null) { 166 source.addTransform(Transform.SIMPLE, column.getColumnObject()); 167 } 168 } 169 170 if (source.getElement() instanceof ResultColumn) { 171 ResultColumn sourceColumn = (ResultColumn) source.getElement(); 172 if (sourceColumn.isStarColumn() && column.isStarColumn() && inferStar) { 173 column.appendStarSourceColumn(sourceColumn); 174 } 175 addTransformsInReverse(source, sourceColumn.getTransforms()); 176 } else if (source.getElement() instanceof TableColumn) { 177 TableColumn sourceColumn = (TableColumn) source.getElement(); 178 if (sourceColumn.isStarColumn() && column.isStarColumn() && inferStar) { 179 column.appendStarSourceColumn(sourceColumn); 180 } 181 addTransformsInReverse(source, sourceColumn.getTransforms()); 182 } 183 } else if (getTarget() instanceof TableColumnRelationshipElement) { 184 if (source.getElement() instanceof ResultColumn) { 185 ResultColumn column = (ResultColumn) source.getElement(); 186 addTransformsInReverse(source, column.getTransforms()); 187 } 188 } else if (getTarget() == null && source.getElement() instanceof TableColumn) { 189 TableColumn column = (TableColumn) source.getElement(); 190 addTransformsInReverse(source, column.getTransforms()); 191 } 192 193 if (source.getElement() instanceof RelationRows<?>) { 194 ((RelationRows<?>) source.getElement()).setHasRelation(true); 195 } 196 } 197 } 198 199 protected void addExpressionTransform(RelationshipElement<?> source, TExpression expression) { 200 if (expression.getExpressionType() == EExpressionType.simple_object_name_t) { 201 source.addTransform(Transform.SIMPLE, expression); 202 } 203 else if (expression.getExpressionType() == EExpressionType.function_t) { 204 source.addTransform(Transform.FUNCTION, expression); 205 } 206 else if (expression.getExpressionType() == EExpressionType.simple_constant_t) { 207 source.addTransform(Transform.FUNCTION, expression); 208 } 209 else if (expression.getExpressionType() == EExpressionType.case_t) { 210 source.addTransform(Transform.CASE, expression); 211 } 212 else if (expression.getExpressionType() == EExpressionType.subquery_t) { 213 source.addTransform(Transform.SUBQUERY, expression); 214 } 215 else if (expression.getExpressionType() == EExpressionType.parenthesis_t) { 216 TExpression inner = expression.getLeftOperand(); 217 while (inner != null && inner.getExpressionType() == EExpressionType.parenthesis_t) { 218 inner = inner.getLeftOperand(); 219 } 220 if (inner != null) { 221 addExpressionTransform(source, inner); 222 } 223 } 224 else if (expression.getOperatorToken() != null) { 225 source.addTransform(Transform.EXPRESSION, expression); 226 } 227 } 228 229 public EffectType getEffectType() { 230 return effectType; 231 } 232 233 public void setEffectType(EffectType effectType) { 234 this.effectType = effectType; 235 } 236 237 public String getFunction() { 238 return function; 239 } 240 241 public void setFunction(String function) { 242 this.function = function; 243 } 244 245 public boolean isShowStarRelation() { 246 return showStarRelation; 247 } 248 249 public void setShowStarRelation(boolean showStarRelation) { 250 this.showStarRelation = showStarRelation; 251 } 252 253 public Process getProcess() { 254 return process; 255 } 256 257 public void setProcess(Process process) { 258 this.process = process; 259 } 260 261 262 public String getSqlHash() { 263 return sqlHash; 264 } 265 266 public String getSqlComment() { 267 return sqlComment; 268 } 269 270 public String getPartition() { 271 return partition; 272 } 273 274 public void setPartition(String partition) { 275 this.partition = partition; 276 } 277 278 public Long getProcedureId() { 279 return procedureId; 280 } 281 282 public void setProcedureId(Long procedureId) { 283 this.procedureId = procedureId; 284 } 285 286}