001package gudusoft.gsqlparser.resolver2.enhancement; 002 003import gudusoft.gsqlparser.nodes.TObjectName; 004import gudusoft.gsqlparser.resolver2.model.ResolutionEvidence; 005import gudusoft.gsqlparser.resolver2.model.SourceLocation; 006import gudusoft.gsqlparser.resolver2.namespace.INamespace; 007 008/** 009 * Represents a column reference collected during resolution that needs 010 * to be added to a namespace. 011 * 012 * This is used by the explicit namespace enhancement phase to track 013 * which columns should be added to which namespaces between resolution passes. 014 */ 015public class CollectedColumnRef { 016 017 /** The column name to add */ 018 private final String columnName; 019 020 /** The target namespace to add the column to */ 021 private final INamespace targetNamespace; 022 023 /** The AST node that referenced this column */ 024 private final TObjectName sourceReference; 025 026 /** The pass number when this was collected */ 027 private final int passNumber; 028 029 /** 030 * Confidence score for this column (0.0 to 1.0) 031 * @deprecated Use {@link #evidenceDetail} instead 032 */ 033 private final double confidence; 034 035 /** 036 * Evidence/reason for adding this column 037 * @deprecated Use {@link #evidenceDetail} instead 038 */ 039 private final String evidence; 040 041 /** Structured evidence detail for this column reference */ 042 private final ResolutionEvidence evidenceDetail; 043 044 /** Source location description (for debugging) */ 045 private final String sourceLocation; 046 047 /** 048 * Legacy constructor for backward compatibility. 049 * 050 * @deprecated Use {@link #CollectedColumnRef(String, INamespace, TObjectName, int, ResolutionEvidence)} instead 051 */ 052 public CollectedColumnRef(String columnName, 053 INamespace targetNamespace, 054 TObjectName sourceReference, 055 int passNumber, 056 double confidence, 057 String evidence) { 058 this.columnName = columnName; 059 this.targetNamespace = targetNamespace; 060 this.sourceReference = sourceReference; 061 this.passNumber = passNumber; 062 this.confidence = confidence; 063 this.evidence = evidence; 064 this.sourceLocation = formatLocation(sourceReference); 065 // Create evidenceDetail from legacy parameters 066 this.evidenceDetail = ResolutionEvidence.fromLegacyEvidence(evidence, confidence, sourceReference); 067 } 068 069 /** 070 * Constructor with ResolutionEvidence (preferred for new code). 071 * 072 * @param columnName The column name to add 073 * @param targetNamespace The target namespace 074 * @param sourceReference The AST node that referenced this column 075 * @param passNumber The resolution pass number 076 * @param evidenceDetail Structured evidence detail 077 */ 078 public CollectedColumnRef(String columnName, 079 INamespace targetNamespace, 080 TObjectName sourceReference, 081 int passNumber, 082 ResolutionEvidence evidenceDetail) { 083 this.columnName = columnName; 084 this.targetNamespace = targetNamespace; 085 this.sourceReference = sourceReference; 086 this.passNumber = passNumber; 087 this.evidenceDetail = evidenceDetail; 088 // Derive legacy fields from evidenceDetail 089 this.confidence = evidenceDetail != null ? evidenceDetail.getWeight() : 0.5; 090 this.evidence = evidenceDetail != null ? evidenceDetail.toLegacyEvidence() : null; 091 this.sourceLocation = formatLocation(sourceReference); 092 } 093 094 private String formatLocation(TObjectName objName) { 095 if (objName == null) return "unknown"; 096 return String.format("line %d, col %d", 097 objName.getLineNo(), objName.getColumnNo()); 098 } 099 100 public String getColumnName() { 101 return columnName; 102 } 103 104 public INamespace getTargetNamespace() { 105 return targetNamespace; 106 } 107 108 public TObjectName getSourceReference() { 109 return sourceReference; 110 } 111 112 public int getPassNumber() { 113 return passNumber; 114 } 115 116 public double getConfidence() { 117 return confidence; 118 } 119 120 public String getEvidence() { 121 return evidence; 122 } 123 124 /** 125 * Get the structured evidence detail for this column reference. 126 * 127 * @return The structured evidence detail 128 */ 129 public ResolutionEvidence getEvidenceDetail() { 130 return evidenceDetail; 131 } 132 133 public String getSourceLocation() { 134 return sourceLocation; 135 } 136 137 @Override 138 public String toString() { 139 return String.format("CollectedColumnRef{column='%s', namespace='%s', pass=%d, conf=%.2f, evidence='%s', loc=%s}", 140 columnName, 141 targetNamespace != null ? targetNamespace.getDisplayName() : "null", 142 passNumber, 143 confidence, 144 evidence, 145 sourceLocation); 146 } 147 148 @Override 149 public boolean equals(Object o) { 150 if (this == o) return true; 151 if (o == null || getClass() != o.getClass()) return false; 152 153 CollectedColumnRef that = (CollectedColumnRef) o; 154 155 if (!columnName.equalsIgnoreCase(that.columnName)) return false; 156 return targetNamespace == that.targetNamespace; // Identity comparison for namespace 157 } 158 159 @Override 160 public int hashCode() { 161 int result = columnName.toLowerCase().hashCode(); 162 result = 31 * result + System.identityHashCode(targetNamespace); 163 return result; 164 } 165}