001package gudusoft.gsqlparser.lineage2.contract; 002 003import java.util.ArrayList; 004import java.util.Collections; 005import java.util.List; 006 007/** 008 * Contract {@code TransformGraph} (lineage2-contract.md ยง7) โ 009 * statement-local computation graph, TRANSFORM-GRAPH-V1 with coordinates. 010 * The engine emits local node ids only; node/step GUID materialization 011 * stays a repository concern per rev 3. 012 * 013 * <p>Internal API: not part of the public gsqlparser surface. 014 */ 015public final class TransformGraph { 016 017 /** Node kinds of TRANSFORM-GRAPH-V1. */ 018 public enum NodeKind { 019 PHYSICAL_COLUMN, CTE_COLUMN, DERIVED_COLUMN, TEMP_COLUMN, EXPRESSION, 020 CONSTANT, PARAMETER, UNKNOWN 021 } 022 023 /** Step operation types of TRANSFORM-GRAPH-V1. */ 024 public enum OperationType { 025 ASSIGN, CAST, FUNCTION, ARITHMETIC, CONCAT, CASE, AGGREGATE, JOIN, 026 FILTER, LOOKUP, WINDOW, UNION, EXPRESSION, UNKNOWN 027 } 028 029 public static final class Node { 030 private final String localNodeId; 031 private final NodeKind nodeKind; 032 private final String label; 033 private final SourceLocation sourceLocation; 034 private final LocationNullReason locationNullReason; 035 036 public Node(String localNodeId, NodeKind nodeKind, String label, 037 SourceLocation sourceLocation, 038 LocationNullReason locationNullReason) { 039 if (localNodeId == null || nodeKind == null) { 040 throw new IllegalArgumentException( 041 "localNodeId and nodeKind must not be null"); 042 } 043 this.localNodeId = localNodeId; 044 this.nodeKind = nodeKind; 045 this.label = label; 046 this.sourceLocation = sourceLocation; 047 this.locationNullReason = locationNullReason; 048 } 049 050 public String getLocalNodeId() { 051 return localNodeId; 052 } 053 054 public NodeKind getNodeKind() { 055 return nodeKind; 056 } 057 058 /** Nullable. */ 059 public String getLabel() { 060 return label; 061 } 062 063 /** Nullable. */ 064 public SourceLocation getSourceLocation() { 065 return sourceLocation; 066 } 067 068 /** Nullable โ set only when {@code sourceLocation} is null. */ 069 public LocationNullReason getLocationNullReason() { 070 return locationNullReason; 071 } 072 } 073 074 public static final class Step { 075 private final int stepIndex; 076 private final OperationType operationType; 077 private final List<String> inputNodeIds; 078 private final String outputNodeId; 079 private final String expressionHash; 080 private final SourceLocation sourceLocation; 081 private final LocationNullReason locationNullReason; 082 083 public Step(int stepIndex, OperationType operationType, 084 List<String> inputNodeIds, String outputNodeId, 085 String expressionHash, SourceLocation sourceLocation, 086 LocationNullReason locationNullReason) { 087 if (operationType == null || inputNodeIds == null 088 || outputNodeId == null) { 089 throw new IllegalArgumentException("operationType, inputNodeIds, " 090 + "and outputNodeId must not be null"); 091 } 092 this.stepIndex = stepIndex; 093 this.operationType = operationType; 094 this.inputNodeIds = Collections.unmodifiableList( 095 new ArrayList<>(inputNodeIds)); 096 this.outputNodeId = outputNodeId; 097 this.expressionHash = expressionHash; 098 this.sourceLocation = sourceLocation; 099 this.locationNullReason = locationNullReason; 100 } 101 102 public int getStepIndex() { 103 return stepIndex; 104 } 105 106 public OperationType getOperationType() { 107 return operationType; 108 } 109 110 public List<String> getInputNodeIds() { 111 return inputNodeIds; 112 } 113 114 public String getOutputNodeId() { 115 return outputNodeId; 116 } 117 118 /** Nullable. */ 119 public String getExpressionHash() { 120 return expressionHash; 121 } 122 123 /** Nullable. */ 124 public SourceLocation getSourceLocation() { 125 return sourceLocation; 126 } 127 128 /** Nullable โ set only when {@code sourceLocation} is null. */ 129 public LocationNullReason getLocationNullReason() { 130 return locationNullReason; 131 } 132 } 133 134 private final int statementIndex; 135 private final String occurrenceGuidRef; 136 private final List<Node> nodes; 137 private final List<Step> steps; 138 139 public TransformGraph(int statementIndex, String occurrenceGuidRef, 140 List<Node> nodes, List<Step> steps) { 141 this.statementIndex = statementIndex; 142 this.occurrenceGuidRef = occurrenceGuidRef; 143 this.nodes = (nodes == null) ? Collections.<Node>emptyList() 144 : Collections.unmodifiableList(new ArrayList<>(nodes)); 145 this.steps = (steps == null) ? Collections.<Step>emptyList() 146 : Collections.unmodifiableList(new ArrayList<>(steps)); 147 } 148 149 public int getStatementIndex() { 150 return statementIndex; 151 } 152 153 /** Nullable. */ 154 public String getOccurrenceGuidRef() { 155 return occurrenceGuidRef; 156 } 157 158 public List<Node> getNodes() { 159 return nodes; 160 } 161 162 public List<Step> getSteps() { 163 return steps; 164 } 165}