001package gudusoft.gsqlparser.nodes; 002 003 004import gudusoft.gsqlparser.EDataType; 005import gudusoft.gsqlparser.ESqlClause; 006import gudusoft.gsqlparser.ESqlStatementType; 007import gudusoft.gsqlparser.TCustomSqlStatement; 008import gudusoft.gsqlparser.nodes.TExpression; 009import gudusoft.gsqlparser.nodes.TParseTreeNode; 010import gudusoft.gsqlparser.nodes.TParseTreeVisitor; 011import gudusoft.gsqlparser.sqlenv.TSQLColumn; 012import gudusoft.gsqlparser.stmt.TSelectSqlStatement; 013 014 015public class TUnnestClause extends TParseTreeNode { 016 017 private TObjectNameList derivedColumnList = null; 018 private TAliasClause withOffsetAlais; 019 020 public TAliasClause getWithOffsetAlais() { 021 return withOffsetAlais; 022 } 023 024 public TDummy getWithOffset() { 025 return withOffset; 026 } 027 028 private TDummy withOffset; 029 private TObjectNameList columns; 030 031 public TObjectNameList getColumns() { 032 return columns; 033 } 034 035 private TExpression arrayExpr; 036 037 public TExpression getArrayExpr() { 038 return arrayExpr; 039 } 040 041 public void init(Object arg1){ 042 if (arg1 instanceof TExpression){ 043 //bigquery, athena 044 arrayExpr = (TExpression)arg1; 045 }else if (arg1 instanceof TObjectNameList){ 046 //presto,bigquery 047 columns = (TObjectNameList)arg1; 048 } 049 050 } 051 052 public void init(Object arg1, Object arg2){ 053 init(arg1); 054 this.withOffset = (TDummy)arg2; 055 if (this.withOffset != null){ 056 if (this.withOffset.int1 == 2){ 057 this.withOffsetAlais = (TAliasClause)this.withOffset.node1; 058 } 059 } 060 } 061 062 public TObjectNameList getDerivedColumnList() { 063 return derivedColumnList; 064 } 065 066 public void doParse(TCustomSqlStatement psql, ESqlClause plocation) 067 { 068 if (arrayExpr != null){ 069 arrayExpr.doParse(psql,plocation); 070 }else if (columns != null){ 071 // link to the first table of the from clause 072 TTable lcFirstTable = null; 073 for(TObjectName pColumn:columns){ 074 if (psql.getTables().size() > 0){ 075 lcFirstTable = psql.getTables().getTable(0); 076 lcFirstTable.getLinkedColumns().addObjectName(pColumn); 077 pColumn.setSourceTable(lcFirstTable); 078 }else if ((psql.getParentStmt() != null) && (psql.getParentStmt().sqlstatementtype == ESqlStatementType.sstselect)){ 079 // search up level 080 TSelectSqlStatement selectSqlStatement = (TSelectSqlStatement)psql.getParentStmt(); 081 if (selectSqlStatement.getTables().size()>0){ 082 lcFirstTable = selectSqlStatement.getTables().getTable(0); 083 lcFirstTable.getLinkedColumns().addObjectName(pColumn); 084 pColumn.setSourceTable(lcFirstTable); 085 } 086 } 087 088 // get derived columns from this column if it's type of struct<> 089 // create table absolute-runner-302907.gudu_sqlflow.ADDRESS_NESTED ( 090 // Emp_id INT64,Name STRING 091 // ,Address ARRAY<STRUCT<State STRING, City STRING, Zipcode INT64>> ); 092 093 if ((psql.getSqlEnv() != null)&&(lcFirstTable != null)&&(lcFirstTable.getFullName()!=null)) { 094 // System.out.println("env\n"+psql.getSqlEnv().toString()); 095 096 TSQLColumn tsqlColumn = psql.getSqlEnv().getColumnInTable(lcFirstTable.getFullName(), pColumn.toString()); 097 if (tsqlColumn != null){ 098 TTypeName columnDataType = tsqlColumn.getColumnDataType(); 099 if (columnDataType != null){ 100 if (columnDataType.getDataType() == EDataType.array_t){ 101 TTypeName subDataType = columnDataType.getTypeOfList(); 102 if (subDataType.getDataType() == EDataType.struct_t){ 103 if (derivedColumnList == null){ 104 derivedColumnList = new TObjectNameList(); 105 } 106 //System.out.println("element name in struct: "+subDataType.getDataTypeName()); 107 for(int i=0;i<subDataType.getColumnDefList().size();i++){ 108 //System.out.println(subDataType.getColumnDefList().getColumn(i).getColumnName().toString()); 109 TObjectName attributeName = subDataType.getColumnDefList().getColumn(i).getColumnName(); 110 attributeName.setParentObjectName(pColumn); 111 derivedColumnList.addObjectName(attributeName); 112 } 113 } 114 } 115 else if (columnDataType.getDataType() == EDataType.struct_t){ 116 if (derivedColumnList == null){ 117 derivedColumnList = new TObjectNameList(); 118 } 119 //System.out.println("element name in struct: "+subDataType.getDataTypeName()); 120 for(int i=0;i<columnDataType.getColumnDefList().size();i++){ 121 //System.out.println(subDataType.getColumnDefList().getColumn(i).getColumnName().toString()); 122 TObjectName attributeName = columnDataType.getColumnDefList().getColumn(i).getColumnName(); 123 attributeName.setParentObjectName(pColumn); 124 derivedColumnList.addObjectName(attributeName); 125 } 126 } 127 } 128 //System.out.println("Find column: "+pColumn.toString()+" in table: "+ lcFirstTable.getFullName().toString()+" with datatype:"+tsqlColumn.getColumnDataType()); 129 } 130 } 131 132 } 133 } 134 } 135 136 public void accept(TParseTreeVisitor v){ 137 v.preVisit(this); 138 v.postVisit(this); 139 } 140 141 public void acceptChildren(TParseTreeVisitor v){ 142 v.preVisit(this); 143 if (this.getColumns() != null){ 144 this.getColumns().acceptChildren(v); 145 } 146 if (this.getArrayExpr() != null){ 147 this.getArrayExpr().acceptChildren(v); 148 } 149 v.postVisit(this); 150 } 151}