001package gudusoft.gsqlparser.resolver; 002 003import gudusoft.gsqlparser.TBaseType; 004import gudusoft.gsqlparser.TLog; 005import gudusoft.gsqlparser.TStatementList; 006import gudusoft.gsqlparser.compiler.TContext; 007 008/** 009 * TSQLResolver handles all semantic analysis and resolution steps for SQL statements. 010 * This class consolidates various resolution algorithms to provide a clear, maintainable 011 * structure for SQL semantic analysis. 012 * 013 * 涉及的重要 类有: 014 * @see gudusoft.gsqlparser.TAttributeNode 015 */ 016public class TSQLResolver { 017 private final TContext globalContext; 018 private final TStatementList sqlStatements; 019 // private final TLog logger; 020 private int iterationCount; 021 private int newColumnsLastIteration; 022 023 /** 024 * Creates a new SQL resolver instance. 025 * 026 * @param context The global context containing SQL environment and scope information 027 * @param statements List of SQL statements to analyze 028 */ 029 public TSQLResolver(TContext context, TStatementList statements) { 030 this.globalContext = context; 031 this.sqlStatements = statements; 032 // this.logger = new TLog(); 033 this.iterationCount = 0; 034 this.newColumnsLastIteration = 0; 035 } 036 037 /** 038 * Performs complete semantic analysis of SQL statements. 039 * Executes all resolution steps in the correct order. 040 * 041 * @return true if resolution completes successfully, false if errors occurred 042 */ 043 public boolean resolve() { 044 TLog.clearLogs(); 045 if (!TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 046 TLog.disableLog(); 047 }else{ 048 TLog.enableAllLevelLog(); 049 } 050 051 try { 052 collectMetadata(); 053 resolveDatabaseObjects(); 054 055 do { 056 iterationCount++; 057 newColumnsLastIteration = 0; 058 059 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 060 TBaseType.log(String.format("Starting resolve relationships in iteration %d", iterationCount), TLog.DEBUG); 061 } 062 resolveRelationships(); // 更新表属性 063 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 064 TBaseType.log(String.format("Starting expand star columns in iteration %d", iterationCount), TLog.DEBUG); 065 } 066 expandStarColumns(); // 展开星号列 067 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 068 TBaseType.log(String.format("Starting resolve attributes in iteration %d", iterationCount), TLog.DEBUG); 069 } 070 resolveAttributes(); // 先收集列引用 071 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 072 TBaseType.log(String.format("Starting resolve star columns in iteration %d", iterationCount), TLog.DEBUG); 073 } 074 075 resolveStarColumns(); // 推送星号列 076 077 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 078 TBaseType.log(String.format("Iteration %d: %d new columns inferred", iterationCount, newColumnsLastIteration), TLog.DEBUG); 079 } 080 } while (newColumnsLastIteration > 0 && iterationCount < 10); 081 082 } catch (Exception e) { 083 TBaseType.log("Exception raised in TSQLResolver.resolve(): " + e.getMessage(), TLog.ERROR); 084 throw e; 085 } 086 087 088 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 089 TBaseType.dumpLogs(false); 090 } 091 return true; 092 } 093 094 /** 095 * Collects metadata from DDL statements like CREATE TABLE, CREATE VIEW, etc. 096 * Uses TMetadataCollector to build the metadata repository. 097 */ 098 private void collectMetadata() { 099 TMetadataCollector collector = new TMetadataCollector(sqlStatements, globalContext); 100 collector.collect(); 101 } 102 103 /** 104 * Resolves database objects by linking references to their definitions. 105 * Handles table names, view names, and other database objects. 106 */ 107 private void resolveDatabaseObjects() { 108 TDatabaseObjectResolver resolver = new TDatabaseObjectResolver(sqlStatements,globalContext); 109 resolver.resolve(); 110 } 111 112 /** 113 * Resolves relationships between database objects. 114 * This includes JOIN conditions, foreign key relationships, etc. 115 */ 116 private void resolveRelationships() { 117 new TRelationResolver(sqlStatements, globalContext, this).resolve(); 118 } 119 120 /** 121 * Resolves relationships between database objects. 122 * This includes JOIN conditions, foreign key relationships, etc. 123 */ 124 private void resolveRelationships2() { 125 TRelationResolver2 resolver = new TRelationResolver2(sqlStatements,globalContext); 126 resolver.resolve(); 127 } 128 129 /** 130 * Expands star columns (*) and processes subqueries. 131 * Converts * to explicit column lists and handles subquery resolution. 132 */ 133 private void expandStarColumns() { 134 new TStarColumnExpander(sqlStatements, globalContext,this).resolve(); 135 } 136 137 /** 138 * Resolves column attributes including data types, constraints, etc. 139 */ 140 private void resolveAttributes() { 141 new TAttributeResolver(sqlStatements, globalContext, this).resolve(); 142 } 143 144 /** 145 * Performs final resolution of star columns after all other resolutions. 146 * This handles any remaining star column cases that depend on previous steps. 147 */ 148 private void resolveStarColumns() { 149 TStarColumnPushDownResolver starColumnPushDownResolver = new TStarColumnPushDownResolver(sqlStatements,globalContext); 150 starColumnPushDownResolver.resolve(); 151 } 152 153 public void reportNewColumns(int count) { 154 newColumnsLastIteration += count; 155 } 156 157 /** 158 * Gets the log containing resolution messages and errors. 159 * 160 * @return The resolution log 161 */ 162 // public TLog getLog() { 163 // return logger; 164 // } 165}