001package gudusoft.gsqlparser.resolver2.expansion; 002 003import gudusoft.gsqlparser.nodes.TResultColumn; 004 005import java.util.ArrayList; 006import java.util.HashMap; 007import java.util.List; 008import java.util.Map; 009 010/** 011 * Result of star column expansion. 012 * 013 * <p>Tracks: 014 * - Which star columns were expanded 015 * - Which star columns could not be expanded (and why) 016 * - Non-star columns (passed through) 017 * - Statistics about the expansion 018 * 019 * <p>Example: 020 * <pre> 021 * SELECT t1.*, t2.id, t3.* 022 * FROM t1 JOIN t2 JOIN t3 023 * 024 * ExpansionResult: 025 * - expandedStars: {t1.* -> [t1.id, t1.name], t3.* -> [t3.id, t3.status]} 026 * - nonStarColumns: [t2.id] 027 * - unexpandableStars: {} 028 * </pre> 029 */ 030public class ExpansionResult { 031 032 /** Star columns that were successfully expanded */ 033 private final Map<TResultColumn, List<ExpandedColumn>> expandedStars = new HashMap<>(); 034 035 /** Star columns that could not be expanded */ 036 private final Map<TResultColumn, String> unexpandableStars = new HashMap<>(); 037 038 /** Non-star columns (passed through unchanged) */ 039 private final List<TResultColumn> nonStarColumns = new ArrayList<>(); 040 041 /** 042 * Add a successfully expanded star column. 043 * 044 * @param starColumn the original star column 045 * @param expandedColumns the expanded columns 046 */ 047 public void addExpandedStar(TResultColumn starColumn, List<ExpandedColumn> expandedColumns) { 048 if (starColumn != null && expandedColumns != null) { 049 expandedStars.put(starColumn, new ArrayList<>(expandedColumns)); 050 } 051 } 052 053 /** 054 * Add a star column that could not be expanded. 055 * 056 * @param starColumn the star column 057 * @param reason why it could not be expanded 058 */ 059 public void addUnexpandableStar(TResultColumn starColumn, String reason) { 060 if (starColumn != null) { 061 unexpandableStars.put(starColumn, reason != null ? reason : "Unknown reason"); 062 } 063 } 064 065 /** 066 * Add a non-star column. 067 * 068 * @param column the non-star column 069 */ 070 public void addNonStarColumn(TResultColumn column) { 071 if (column != null) { 072 nonStarColumns.add(column); 073 } 074 } 075 076 /** 077 * Get all expanded stars. 078 * 079 * @return map of star column to expanded columns 080 */ 081 public Map<TResultColumn, List<ExpandedColumn>> getExpandedStars() { 082 return new HashMap<>(expandedStars); 083 } 084 085 /** 086 * Get all unexpandable stars. 087 * 088 * @return map of star column to reason 089 */ 090 public Map<TResultColumn, String> getUnexpandableStars() { 091 return new HashMap<>(unexpandableStars); 092 } 093 094 /** 095 * Get all non-star columns. 096 * 097 * @return list of non-star columns 098 */ 099 public List<TResultColumn> getNonStarColumns() { 100 return new ArrayList<>(nonStarColumns); 101 } 102 103 /** 104 * Get all expanded columns (flattened list). 105 * 106 * @return all expanded columns from all stars 107 */ 108 public List<ExpandedColumn> getAllExpandedColumns() { 109 List<ExpandedColumn> all = new ArrayList<>(); 110 for (List<ExpandedColumn> columns : expandedStars.values()) { 111 all.addAll(columns); 112 } 113 return all; 114 } 115 116 /** 117 * Get the total number of columns after expansion. 118 * This includes expanded star columns and non-star columns. 119 * 120 * @return total column count 121 */ 122 public int getTotalColumnCount() { 123 int count = nonStarColumns.size(); 124 for (List<ExpandedColumn> columns : expandedStars.values()) { 125 count += columns.size(); 126 } 127 return count; 128 } 129 130 /** 131 * Get the number of star columns that were expanded. 132 * 133 * @return expanded star count 134 */ 135 public int getExpandedStarCount() { 136 return expandedStars.size(); 137 } 138 139 /** 140 * Get the number of star columns that could not be expanded. 141 * 142 * @return unexpandable star count 143 */ 144 public int getUnexpandableStarCount() { 145 return unexpandableStars.size(); 146 } 147 148 /** 149 * Check if all stars were successfully expanded. 150 * 151 * @return true if no unexpandable stars, false otherwise 152 */ 153 public boolean isFullyExpanded() { 154 return unexpandableStars.isEmpty(); 155 } 156 157 /** 158 * Check if any stars were expanded. 159 * 160 * @return true if at least one star was expanded 161 */ 162 public boolean hasExpandedStars() { 163 return !expandedStars.isEmpty(); 164 } 165 166 /** 167 * Get statistics about the expansion. 168 * 169 * @return statistics string 170 */ 171 public String getStatistics() { 172 return String.format( 173 "ExpansionResult[expanded=%d stars -> %d columns, unexpandable=%d, non-star=%d, total=%d]", 174 expandedStars.size(), 175 getAllExpandedColumns().size(), 176 unexpandableStars.size(), 177 nonStarColumns.size(), 178 getTotalColumnCount() 179 ); 180 } 181 182 @Override 183 public String toString() { 184 return getStatistics(); 185 } 186}