001package gudusoft.gsqlparser.resolver2.scope; 002 003import gudusoft.gsqlparser.nodes.TParseTreeNode; 004import gudusoft.gsqlparser.resolver2.ScopeType; 005import gudusoft.gsqlparser.resolver2.matcher.INameMatcher; 006import gudusoft.gsqlparser.resolver2.model.QualifiedName; 007import gudusoft.gsqlparser.resolver2.model.ScopeChild; 008import gudusoft.gsqlparser.resolver2.namespace.INamespace; 009 010import java.util.List; 011 012/** 013 * Represents a name resolution scope in SQL. 014 * Each scope defines what names (tables, columns, CTEs) are visible at a given point. 015 * 016 * Design based on: 017 * - Apache Calcite's SqlValidatorScope 018 * - Classic compiler scope chain 019 * 020 * Key concepts: 021 * 1. Delegation: Most scopes delegate unknown names to parent scope 022 * 2. Hierarchy: Scopes form a tree matching SQL structure 023 * 3. Children: FROM clause scopes contain table/subquery children 024 */ 025public interface IScope { 026 027 /** 028 * Get the parent scope. 029 * Root scope (GlobalScope) has EmptyScope as parent. 030 * 031 * @return Parent scope, never null 032 */ 033 IScope getParent(); 034 035 /** 036 * Get the associated AST node 037 * 038 * @return AST node for this scope 039 */ 040 TParseTreeNode getNode(); 041 042 /** 043 * Get the scope type 044 * 045 * @return Scope type enum 046 */ 047 ScopeType getScopeType(); 048 049 /** 050 * Resolve a qualified or unqualified name. 051 * This is the core method for name resolution. 052 * 053 * @param names Name parts (e.g., ["schema", "table", "column"]) 054 * @param matcher Name matcher for case sensitivity rules 055 * @param deep Whether to recursively resolve into record fields 056 * @param resolved Callback to collect all matches 057 */ 058 void resolve(List<String> names, 059 INameMatcher matcher, 060 boolean deep, 061 IResolved resolved); 062 063 /** 064 * Resolve a table name or alias to its namespace. 065 * 066 * @param tableName Table name or alias 067 * @return Namespace if found, null otherwise 068 */ 069 INamespace resolveTable(String tableName); 070 071 /** 072 * Add a child namespace to this scope. 073 * Typically used in FROM clauses to add tables/subqueries. 074 * 075 * @param namespace The namespace to add 076 * @param alias The alias for this namespace 077 * @param nullable Whether this namespace is nullable (e.g., RIGHT side of LEFT JOIN) 078 */ 079 void addChild(INamespace namespace, String alias, boolean nullable); 080 081 /** 082 * Get all child namespaces in this scope. 083 * 084 * @return List of scope children 085 */ 086 List<ScopeChild> getChildren(); 087 088 /** 089 * Get all namespaces visible in this scope. 090 * Includes children and namespaces from parent scopes. 091 * 092 * @return List of visible namespaces 093 */ 094 List<INamespace> getVisibleNamespaces(); 095 096 /** 097 * Fully qualify a name based on this scope. 098 * E.g., "col" -> "table.col" if only one table has that column 099 * 100 * @param name Name to qualify 101 * @return Qualified name 102 */ 103 QualifiedName fullyQualify(String name); 104 105 /** 106 * Check if this scope is within (nested inside) another scope. 107 * 108 * @param ancestorScope Potential ancestor scope 109 * @return true if this scope is nested within ancestorScope 110 */ 111 boolean isWithin(IScope ancestorScope); 112}