001 002package gudusoft.gsqlparser.dlineage.dataflow.model; 003 004 005import gudusoft.gsqlparser.TCustomSqlStatement; 006import gudusoft.gsqlparser.TSourceToken; 007import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 008import gudusoft.gsqlparser.dlineage.util.Pair3; 009import gudusoft.gsqlparser.nodes.TParseTreeNode; 010import gudusoft.gsqlparser.util.SQLUtil; 011 012public class CallRelationship extends AbstractRelationship { 013 014 private String sqlHash; 015 private String sqlComment; 016 private Long procedureId; 017 private Boolean builtIn; 018 private TParseTreeNode callObject; 019 protected Pair3<Long, Long, String> startPosition; 020 protected Pair3<Long, Long, String> endPosition; 021 022 @Override 023 public RelationshipType getRelationshipType() { 024 return RelationshipType.call; 025 } 026 027 public String getSqlHash() { 028 return sqlHash; 029 } 030 031 public void setTarget(RelationshipElement<?> target) { 032 super.setTarget(target); 033 if(ModelBindingManager.getGlobalOption().isTraceSQL()) { 034 TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek()); 035 this.sqlHash = ModelBindingManager.get().getSqlHash(stmt); 036 try { 037 this.sqlComment = stmt.getCommentBeforeNode(); 038 } catch (Exception e) { 039 } 040 } 041 else if(ModelBindingManager.getGlobalOption().isShowComment() 042 && !ModelBindingManager.isSyntheticStmtContext()) { 043 // The label above THIS call, e.g. `--DW0403:销售发货单` above 044 // `DW_RPC_DW_NC_SO_DELIVERY;`. Not getTopStmt(): that climbs to the enclosing 045 // procedure and would give every call in the body the procedure's header. The call 046 // node itself is more precise still — `f1() + /* SECOND */ f2()` has two calls in one 047 // statement — and setCallObject usually runs BEFORE this, so it must not be undone. 048 try { 049 TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().peek(); 050 // Bounded by the statement's own first token: a call is labelled by a comment 051 // INSIDE its statement, wherever the line breaks fall. Anything before the 052 // statement belongs to the statement, and is picked up by the fallback below. 053 String callSiteComment = (this.callObject == null) ? null 054 : this.callObject.getCommentBeforeNode(true, 055 stmt == null ? null : stmt.getStartToken()); 056 if (SQLUtil.isEmpty(callSiteComment) && stmt != null) { 057 callSiteComment = stmt.getCommentBeforeNode(true); 058 } 059 this.sqlComment = callSiteComment; 060 } catch (Exception e) { 061 } 062 } 063 064 if(ModelBindingManager.getGlobalOption().isTraceProcedure()) { 065 TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek()); 066 Object model = ModelBindingManager.get().getModel(stmt); 067 if(model instanceof Procedure) { 068 this.procedureId = ((Procedure)model).getId(); 069 } 070 } 071 } 072 073 public String getSqlComment() { 074 return sqlComment; 075 } 076 077 public Long getProcedureId() { 078 return procedureId; 079 } 080 081 public Boolean getBuiltIn() { 082 return builtIn; 083 } 084 085 public void setBuiltIn(Boolean builtIn) { 086 this.builtIn = builtIn; 087 } 088 089 public TParseTreeNode getCallObject() { 090 return callObject; 091 } 092 093 public void setCallObject(TParseTreeNode callObject) { 094 this.callObject = callObject; 095 if (callObject != null && ModelBindingManager.getGlobalOption() != null 096 && ModelBindingManager.getGlobalOption().isShowComment() 097 && !ModelBindingManager.getGlobalOption().isTraceSQL()) { 098 // The call node is the most precise site there is; prefer it over whatever the 099 // enclosing statement had when the relationship was wired up. 100 try { 101 TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().isEmpty() 102 ? null : ModelBindingManager.getGlobalStmtStack().peek(); 103 String callSiteComment = callObject.getCommentBeforeNode(true, 104 stmt == null ? null : stmt.getStartToken()); 105 if (!SQLUtil.isEmpty(callSiteComment)) { 106 this.sqlComment = callSiteComment; 107 } 108 } catch (Exception e) { 109 } 110 } 111 if (callObject != null && callObject.toString() != null) { 112 TSourceToken startToken = callObject.getStartToken(); 113 TSourceToken endToken = callObject.getEndToken(); 114 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, 115 ModelBindingManager.getGlobalHash()); 116 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 117 endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 118 } 119 } 120 121 public Pair3<Long, Long, String> getStartPosition() { 122 return startPosition; 123 } 124 125 public Pair3<Long, Long, String> getEndPosition() { 126 return endPosition; 127 } 128 129}