001package gudusoft.gsqlparser.resolver2.namespace; 002 003import gudusoft.gsqlparser.nodes.TObjectName; 004import gudusoft.gsqlparser.nodes.TObjectNameList; 005import gudusoft.gsqlparser.nodes.TTable; 006import gudusoft.gsqlparser.resolver2.ColumnLevel; 007import gudusoft.gsqlparser.resolver2.matcher.INameMatcher; 008import gudusoft.gsqlparser.resolver2.model.ColumnSource; 009 010import java.util.ArrayList; 011import java.util.LinkedHashMap; 012import java.util.List; 013 014/** 015 * The relation a Hive-family LATERAL VIEW adds to its SELECT: {@code lv} in 016 * {@code FROM events LATERAL VIEW explode(items) lv AS item}, with the columns its column aliases name, {@code item}. 017 * A reference to one of them, {@code lv.item}, {@code item} or a field of it, {@code lv.item.name}, resolves to this 018 * relation (Mantis 4845). The parser gives the LATERAL VIEW a table of type {@code ETableSource.lateralView} that 019 * shares its alias clause ({@code TLateralView.createATable}). 020 */ 021public class LateralViewNamespace extends AbstractNamespace { 022 023 private final TTable table; 024 private final String alias; 025 private final TObjectNameList columns; 026 027 /** {@code columns}: the LATERAL VIEW's column aliases, {@code item} in {@code lv AS item}; null for none. */ 028 public LateralViewNamespace(TTable table, String alias, TObjectNameList columns, INameMatcher nameMatcher) { 029 super(table, nameMatcher); 030 this.table = table; 031 this.alias = alias; 032 this.columns = columns; 033 } 034 035 @Override 036 public String getDisplayName() { 037 return alias; 038 } 039 040 @Override 041 public TTable getFinalTable() { 042 return table; 043 } 044 045 @Override 046 public List<TTable> getAllFinalTables() { 047 List<TTable> tables = new ArrayList<>(); 048 tables.add(table); 049 return tables; 050 } 051 052 @Override 053 protected void doValidate() { 054 columnSources = new LinkedHashMap<>(); 055 // the aliases themselves: the table's linked columns also get the references the first pass linked to it 056 for (int i = 0; columns != null && i < columns.size(); i++) { 057 TObjectName column = columns.getObjectName(i); 058 if (column != null) { 059 String name = column.toString(); 060 columnSources.put(name, new ColumnSource(this, name, column, 1.0, "lateral_view_column")); 061 } 062 } 063 } 064 065 @Override 066 public boolean hasStarColumn() { 067 return false; 068 } 069 070 @Override 071 public boolean supportsDynamicInference() { 072 // the column aliases are all its columns 073 return false; 074 } 075 076 @Override 077 public ColumnLevel hasColumn(String columnName) { 078 ensureValidated(); 079 for (String existing : columnSources.keySet()) { 080 if (nameMatcher.matches(existing, columnName)) { 081 return ColumnLevel.EXISTS; 082 } 083 } 084 return ColumnLevel.NOT_EXISTS; 085 } 086 087 @Override 088 public ColumnSource resolveColumn(String columnName) { 089 ensureValidated(); 090 return super.resolveColumn(columnName); 091 } 092 093 public TTable getTable() { 094 return table; 095 } 096 097 /** The LATERAL VIEW's own table: the source table of a column resolved through it. */ 098 @Override 099 public TTable getSourceTable() { 100 return table; 101 } 102 103 @Override 104 public String toString() { 105 return String.format("LateralViewNamespace(%s, columns=%d)", alias, 106 columnSources != null ? columnSources.size() : 0); 107 } 108}