001package gudusoft.gsqlparser.ir.bound; 002 003import gudusoft.gsqlparser.ir.common.Confidence; 004import gudusoft.gsqlparser.ir.common.Evidence; 005import gudusoft.gsqlparser.ir.common.IRNode; 006import gudusoft.gsqlparser.ir.common.IRNodeKind; 007import gudusoft.gsqlparser.ir.common.IRVisitor; 008 009import java.util.Collections; 010import java.util.List; 011 012/** 013 * Bound reference to a column. 014 * <p> 015 * Resolves a column identifier to its source table/view and column name, 016 * with support for struct/nested field paths (BigQuery). 017 */ 018public class BoundColumnRef extends IRNode { 019 020 /** Original text (e.g., "t.col" or "a.b.c.d"). */ 021 private final String originalText; 022 023 /** Name parts. */ 024 private final List<String> nameParts; 025 026 /** Qualifier type. */ 027 private final EQualifierKind qualifierKind; 028 029 /** Binding status. */ 030 private final EBindingStatus bindingStatus; 031 032 /** Resolved relation object. */ 033 private final BoundObjectRef resolvedRelation; 034 035 /** Resolved column name. */ 036 private final String resolvedColumnName; 037 038 /** Field path for struct/nested scenarios (e.g., ["address","city"]). */ 039 private final List<String> fieldPath; 040 041 /** Owning scope. */ 042 private final BoundScope scope; 043 044 /** Candidate relations when AMBIGUOUS. */ 045 private final List<BoundObjectRef> candidateRelations; 046 047 /** Evidence and confidence. */ 048 private final Evidence evidence; 049 private final Confidence confidence; 050 051 public BoundColumnRef(String originalText, List<String> nameParts, 052 EQualifierKind qualifierKind, EBindingStatus bindingStatus, 053 BoundObjectRef resolvedRelation, String resolvedColumnName, 054 List<String> fieldPath, BoundScope scope, 055 List<BoundObjectRef> candidateRelations, 056 Evidence evidence, Confidence confidence) { 057 this.originalText = originalText; 058 this.nameParts = nameParts != null 059 ? Collections.unmodifiableList(nameParts) 060 : Collections.<String>emptyList(); 061 this.qualifierKind = qualifierKind; 062 this.bindingStatus = bindingStatus; 063 this.resolvedRelation = resolvedRelation; 064 this.resolvedColumnName = resolvedColumnName; 065 this.fieldPath = fieldPath != null 066 ? Collections.unmodifiableList(fieldPath) 067 : Collections.<String>emptyList(); 068 this.scope = scope; 069 this.candidateRelations = candidateRelations != null 070 ? Collections.unmodifiableList(candidateRelations) 071 : Collections.<BoundObjectRef>emptyList(); 072 this.evidence = evidence; 073 this.confidence = confidence; 074 } 075 076 public String getOriginalText() { return originalText; } 077 public List<String> getNameParts() { return nameParts; } 078 public EQualifierKind getQualifierKind() { return qualifierKind; } 079 public EBindingStatus getBindingStatus() { return bindingStatus; } 080 public BoundObjectRef getResolvedRelation() { return resolvedRelation; } 081 public String getResolvedColumnName() { return resolvedColumnName; } 082 public List<String> getFieldPath() { return fieldPath; } 083 public BoundScope getScope() { return scope; } 084 public List<BoundObjectRef> getCandidateRelations() { return candidateRelations; } 085 public Evidence getEvidence() { return evidence; } 086 public Confidence getConfidence() { return confidence; } 087 088 @Override 089 public IRNodeKind getKind() { 090 return IRNodeKind.BOUND_COLUMN_REF; 091 } 092 093 @Override 094 public <R, C> R accept(IRVisitor<R, C> visitor, C context) { 095 return visitor.visitBoundColumnRef(this, context); 096 } 097 098 @Override 099 public String toString() { 100 return "BoundColumnRef{" + originalText + ", " + bindingStatus + "}"; 101 } 102}