001package gudusoft.gsqlparser.catalog.runtime; 002 003import java.util.ArrayList; 004import java.util.Arrays; 005import java.util.Collections; 006import java.util.List; 007import java.util.Objects; 008 009/** 010 * Ordered list of schema names consulted when resolving an unqualified reference. 011 * 012 * <p>Plan §7.2 / §9.3. PostgreSQL {@code search_path} is the canonical example; 013 * Oracle "PUBLIC" synonyms behave similarly.</p> 014 * 015 * <p>Segments are stored as supplied — case-folding happens at lookup time via 016 * {@code IdentifierService}, never inside this type.</p> 017 */ 018public final class CatalogSearchPath { 019 020 private static final CatalogSearchPath EMPTY = new CatalogSearchPath(Collections.<String>emptyList()); 021 022 private final List<String> segments; 023 024 private CatalogSearchPath(List<String> segments) { 025 this.segments = Collections.unmodifiableList(new ArrayList<String>(segments)); 026 } 027 028 public static CatalogSearchPath empty() { 029 return EMPTY; 030 } 031 032 public static CatalogSearchPath of(String... segments) { 033 if (segments == null || segments.length == 0) { 034 return EMPTY; 035 } 036 return new CatalogSearchPath(Arrays.asList(segments)); 037 } 038 039 public static CatalogSearchPath of(List<String> segments) { 040 if (segments == null || segments.isEmpty()) { 041 return EMPTY; 042 } 043 return new CatalogSearchPath(segments); 044 } 045 046 public List<String> segments() { 047 return segments; 048 } 049 050 public boolean isEmpty() { 051 return segments.isEmpty(); 052 } 053 054 @Override 055 public boolean equals(Object o) { 056 if (this == o) return true; 057 if (!(o instanceof CatalogSearchPath)) return false; 058 return segments.equals(((CatalogSearchPath) o).segments); 059 } 060 061 @Override 062 public int hashCode() { 063 return Objects.hash(segments); 064 } 065 066 @Override 067 public String toString() { 068 return "CatalogSearchPath" + segments; 069 } 070}