001package gudusoft.gsqlparser.resolver2.model; 002 003import gudusoft.gsqlparser.resolver2.ResolutionStatus; 004 005/** 006 * The complete result of resolving a column reference. 007 * Contains status, source(s), and optional error information. 008 * 009 * This is the primary data structure stored in TObjectName.resolution 010 */ 011public class ResolutionResult { 012 private final ResolutionStatus status; 013 private final ColumnSource columnSource; 014 private final AmbiguousColumnSource ambiguousSource; 015 private final String errorMessage; 016 017 /** 018 * Private constructor - use factory methods instead 019 */ 020 private ResolutionResult(ResolutionStatus status, 021 ColumnSource columnSource, 022 AmbiguousColumnSource ambiguousSource, 023 String errorMessage) { 024 this.status = status; 025 this.columnSource = columnSource; 026 this.ambiguousSource = ambiguousSource; 027 this.errorMessage = errorMessage; 028 } 029 030 /** 031 * Creates a successful exact match result 032 */ 033 public static ResolutionResult exactMatch(ColumnSource source) { 034 if (source == null) { 035 throw new IllegalArgumentException("Column source cannot be null for exact match"); 036 } 037 return new ResolutionResult(ResolutionStatus.EXACT_MATCH, source, null, null); 038 } 039 040 /** 041 * Creates an ambiguous result with multiple candidates 042 */ 043 public static ResolutionResult ambiguous(AmbiguousColumnSource ambiguousSource) { 044 if (ambiguousSource == null || ambiguousSource.getCandidateCount() == 0) { 045 throw new IllegalArgumentException("Ambiguous source must have at least one candidate"); 046 } 047 return new ResolutionResult(ResolutionStatus.AMBIGUOUS, null, ambiguousSource, null); 048 } 049 050 /** 051 * Creates a not found result 052 */ 053 public static ResolutionResult notFound(String columnName) { 054 String message = "Column '" + columnName + "' not found in any visible table"; 055 return new ResolutionResult(ResolutionStatus.NOT_FOUND, null, null, message); 056 } 057 058 /** 059 * Creates a not found result with custom error message 060 */ 061 public static ResolutionResult notFound(String columnName, String errorMessage) { 062 return new ResolutionResult(ResolutionStatus.NOT_FOUND, null, null, errorMessage); 063 } 064 065 public ResolutionStatus getStatus() { 066 return status; 067 } 068 069 public ColumnSource getColumnSource() { 070 return columnSource; 071 } 072 073 public AmbiguousColumnSource getAmbiguousSource() { 074 return ambiguousSource; 075 } 076 077 public String getErrorMessage() { 078 return errorMessage; 079 } 080 081 public boolean isExactMatch() { 082 return status == ResolutionStatus.EXACT_MATCH; 083 } 084 085 public boolean isAmbiguous() { 086 return status == ResolutionStatus.AMBIGUOUS; 087 } 088 089 public boolean isNotFound() { 090 return status == ResolutionStatus.NOT_FOUND; 091 } 092 093 public boolean isResolved() { 094 return status != ResolutionStatus.NOT_FOUND; 095 } 096 097 @Override 098 public String toString() { 099 switch (status) { 100 case EXACT_MATCH: 101 return "Exact match: " + columnSource; 102 case AMBIGUOUS: 103 return ambiguousSource.toString(); 104 case NOT_FOUND: 105 return errorMessage; 106 default: 107 return "Unknown status"; 108 } 109 } 110}