001package gudusoft.gsqlparser.nodes.structured; 002 003import gudusoft.gsqlparser.TSourceToken; 004import gudusoft.gsqlparser.nodes.TIndirection; 005import gudusoft.gsqlparser.nodes.TObjectName; 006 007import java.util.ArrayList; 008import java.util.Collections; 009import java.util.List; 010 011/** 012 * What the parse wrote for one name: the identifiers up to the first subscript, the identifiers before a trailing 013 * wildcard, and the indirection after them. Every parse shape of a nested read lands here: the Hive and Impala 014 * expression chain and BigQuery's subscript expression record their steps on the base name's indirection, as the 015 * Databricks and Trino grammars write them (plan section 4.1, "Why two layers"). 016 * <p> 017 * A snapshot read from the name when asked ({@code TObjectName.getNestedAccessSyntax()}); the resolver's re-slotting 018 * keeps the chain it reads. 019 */ 020public final class NestedAccessSyntax { 021 022 private final List<TSourceToken> chain; 023 private final List<TSourceToken> starQualifierChain; 024 private final TIndirection indirection; 025 026 private NestedAccessSyntax(List<TSourceToken> chain, List<TSourceToken> starQualifierChain, 027 TIndirection indirection) { 028 this.chain = Collections.unmodifiableList(chain); 029 this.starQualifierChain = Collections.unmodifiableList(starQualifierChain); 030 this.indirection = indirection; 031 } 032 033 /** The syntax of {@code name} as it reads now. */ 034 public static NestedAccessSyntax capture(TObjectName name) { 035 return new NestedAccessSyntax(new ArrayList<TSourceToken>(name.getIdentifierChain()), 036 new ArrayList<TSourceToken>(name.getStarQualifierChain()), name.getIndirection()); 037 } 038 039 /** {@link TObjectName#getIdentifierChain()} as written. */ 040 public List<TSourceToken> getChain() { 041 return chain; 042 } 043 044 /** {@link TObjectName#getStarQualifierChain()} as written. */ 045 public List<TSourceToken> getStarQualifierChain() { 046 return starQualifierChain; 047 } 048 049 /** The indirection the parse recorded on the name, or null. */ 050 public TIndirection getIndirection() { 051 return indirection; 052 } 053}