001package gudusoft.gsqlparser.nodes; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.sqlenv.TSQLTable; 005import gudusoft.gsqlparser.visitors.TColumnNameVisitor; 006 007import java.util.ArrayList; 008 009/** 010* use the PIVOT and UNPIVOT relational operators to change a table-valued expression into another table. 011*/ 012 013public class TPivotClause extends TNodeWithAliasClause implements IRelation { 014 015 016 ArrayList<TAttributeNode> relationAttributes = new ArrayList<>(); 017 @Override 018 public ArrayList<TAttributeNode> getAttributes(){ 019 return relationAttributes; 020 } 021 022 @Override 023 public int size(){ 024 return relationAttributes.size(); 025 } 026 027 @Override 028 public String getRelationName(){ 029 return displayName; 030 }; 031 032 private String displayName; 033 public String getDisplayName(){ 034 return displayName; 035 } 036 public void initAttributes(){ 037 displayName = ""; 038 ArrayList<String> columns = new ArrayList<>(); 039 040 switch (getType()) { 041 case pivot: 042 displayName = TTable.PIVOT_CLAUSE_ALIAS; 043 if (pivotInClause.getItems() != null){ 044 for(TResultColumn resultColumn: pivotInClause.getItems()){ 045 columns.add(resultColumn.getDisplayName()); 046 } 047 } 048 break; 049 case unpivot: 050 displayName = TTable.UNPIVOT_CLAUSE_ALIAS; 051 break; 052 } 053 054 055 if (getAliasClause() != null){ 056 displayName = getAliasClause().getAliasName().toString(); 057 if (getAliasClause().getColumns() != null){ 058 columns.clear(); 059 for(TObjectName column:getAliasClause().getColumns()){ 060 061 columns.add(column.toString()); 062 } 063 } 064 } 065 066 for(String c:columns){ 067 TAttributeNode node = new TAttributeNode(displayName+"."+c,pivotTable); 068 //relationAttributes.add(node); 069 TAttributeNode.addNodeToList(node,relationAttributes); 070 } 071 072 } 073 074 075 public final static int pivot = 1; 076 public final static int unpivot = 2; 077 078 private int type = pivot; 079 080 public TTable getPivotTable() { 081 return pivotTable; 082 } 083 084 private TTable pivotTable = null; 085 086 087// private TAliasClause aliasClause = null; 088// 089// @Override 090// public TAliasClause getAliasClause() { 091// return aliasClause; 092// } 093// 094// @Override 095// public void setAliasClause(TAliasClause aliasClause) { 096// 097// this.aliasClause = aliasClause; 098// } 099 100 private TPivotInClause pivotInClause; 101 102 public TPivotInClause getPivotInClause() { 103 return pivotInClause; 104 } 105 106 private TUnpivotInClause unpivotInClause; 107 108 public TUnpivotInClause getUnpivotInClause() { 109 return unpivotInClause; 110 } 111 112 private TResultColumnList aggregation_function_list; 113 /** 114 * @deprecated since 1.7.1.1 115 */ 116 private TResultColumnList in_result_list; 117 118 private TObjectNameList pivotColumnList; 119 120 public TObjectNameList getPivotColumnList() { 121 return pivotColumnList; 122 } 123 124 /** 125 * @deprecated since 1.7.1.1, use {@link #getPivotInClause} instead 126 * @return result column list 127 */ 128 public TResultColumnList getIn_result_list() { 129 return in_result_list; 130 } 131 132 public TResultColumnList getAggregation_function_list() { 133 134 return aggregation_function_list; 135 } 136 137 public void setType(int type) { 138 this.type = type; 139 } 140 141 public int getType() { 142 143 return type; 144 } 145 146 private TFunctionCall aggregation_function = null; 147 /** 148 * @deprecated since 1.7.1.1, use {@link #valueColumnList} instead 149 */ 150 private TObjectName valueColumn = null; 151 private TObjectNameList valueColumnList = null; 152 153 public TObjectNameList getValueColumnList() { 154 return valueColumnList; 155 } 156 157 /** 158 * @deprecated since 1.7.1.1, use {@link #getPivotColumnList} instead. 159 */ 160 private TObjectName pivotColumn = null; 161 private TObjectNameList columnList = null; 162 163 /** 164 * 165 * @return Is a system or user-defined aggregate function that accepts one or more inputs. 166 */ 167 public TFunctionCall getAggregation_function() { 168 return aggregation_function; 169 } 170 171 /** 172 * 173 * @return In the PIVOT clause, lists the values in the pivot_column that will become the column names of the output table. The list cannot specify any column names that already exist in the input table_source that is being pivoted. 174 * In the UNPIVOT clause, lists the columns in table_source that will be narrowed into a single pivot_column. 175 */ 176 public TObjectNameList getColumnList() { 177 return columnList; 178 } 179 180 /** 181 * @deprecated since 1.7.1.1 , use {@link #getPivotColumnList} instead. 182 * @return Is the pivot column of the PIVOT operator. 183 */ 184 public TObjectName getPivotColumn() { 185 return pivotColumn; 186 } 187 188 /** 189 * @deprecated since 1.7.1.1, use {@link #getValueColumnList} instead. 190 * @return Is the value column of the PIVOT operator. 191 * When used with UNPIVOT, value_column cannot be the name of an existing column in the input table_source. 192 */ 193 public TObjectName getValueColumn() { 194 return valueColumn; 195 } 196 197 public void init(Object arg1,Object arg2){ 198 if (arg1 instanceof TFunctionCall){ 199 aggregation_function = (TFunctionCall)arg1; // pivot clause, sql server 200 }else if (arg1 instanceof TResultColumnList){ 201 aggregation_function_list = (TResultColumnList)arg1; // pivot clause, oracle 202 }else if (arg1 instanceof TObjectNameList){ 203 valueColumnList = (TObjectNameList)arg1; // unpivot clause 204 }else if (arg1 instanceof TObjectName){ 205 valueColumn = (TObjectName)arg1; 206 } 207 208 if (arg2 instanceof TObjectName){ 209 pivotColumn = (TObjectName)arg2; 210 }else if (arg2 instanceof TObjectNameList){ 211 pivotColumnList = (TObjectNameList)arg2; 212 } 213 } 214 215 public void init(Object arg1,Object arg2,Object arg3){ 216 init(arg1,arg2); 217 if (arg3 instanceof TUnpivotInClause){ 218 unpivotInClause = (TUnpivotInClause)arg3; 219 } else if (arg3 instanceof TPivotInClause){ 220 pivotInClause = (TPivotInClause)arg3; 221 } 222// else if (arg3 instanceof TResultColumnList){ 223// in_result_list = (TResultColumnList)arg3; 224// } else if (arg3 instanceof TObjectNameList){ 225// pivotColumnList = (TObjectNameList)arg3; 226// } 227 } 228 229 public void doParse(TCustomSqlStatement psql, ESqlClause plocation){ 230 TSQLTable sqlTable = null; 231 boolean addColumnFromAlias = false; 232 233 if (getAliasClause() != null){ 234 getAliasClause().doParse(psql,plocation); 235 236 pivotTable = new TTable(); 237 238 pivotTable.setTableName(getAliasClause().getAliasName()); 239 pivotTable.setTableType(ETableSource.pivoted_table); 240 pivotTable.setEffectType(ETableEffectType.tetPivot); 241 psql.getTables().addTable(pivotTable); 242 243 pivotTable.setSourceTableOfPivot(psql.getTables().getTable(0)); 244 245 if (psql.getSqlEnv() != null) { 246 sqlTable = psql.getSqlEnv().addTable(pivotTable.getFullName(), true); 247 } 248 if (getAliasClause().getColumns()!=null){ 249 addColumnFromAlias = true; 250 for(TObjectName column:getAliasClause().getColumns()){ 251 pivotTable.getLinkedColumns().addObjectName(column); 252 column.setSourceTable(pivotTable); 253 } 254 255 if (sqlTable != null){ 256 for(TObjectName column:getAliasClause().getColumns()){ 257 sqlTable.addColumn(column.toString()); 258 } 259 } 260 } 261 }else { // alias is not specified 262 263 pivotTable = new TTable(); 264 if (getType() == pivot){ 265 pivotTable.setTableName(TObjectName.createObjectName (psql.dbvendor, EDbObjectType.column_alias,new TSourceToken("pivot_alias"))); 266 }else{ 267 pivotTable.setTableName(TObjectName.createObjectName (psql.dbvendor,EDbObjectType.column_alias,new TSourceToken("unpivot_alias"))); 268 } 269 270 271 pivotTable.setTableType(ETableSource.pivoted_table); 272 pivotTable.setEffectType(ETableEffectType.tetPivot); 273 psql.getTables().addTable(pivotTable); 274 275 pivotTable.setSourceTableOfPivot(psql.getTables().getTable(0)); 276 277 if (psql.getSqlEnv() != null) { 278 sqlTable = psql.getSqlEnv().addTable(pivotTable.getFullName(), true); 279 } 280 } 281 282 switch (getType()){ 283 case pivot: 284 if (aggregation_function_list != null){ 285 TColumnNameVisitor objectNameVisitor = new TColumnNameVisitor(); 286 aggregation_function_list.acceptChildren(objectNameVisitor); 287 for(TObjectName objectName:objectNameVisitor.getObjectNames()){ 288 pivotTable.getSourceTableOfPivot().getLinkedColumns().addObjectName(objectName); 289 objectName.setSourceTable(pivotTable.getSourceTableOfPivot()); 290 } 291 aggregation_function_list.doParse(psql,plocation); 292 }else if (aggregation_function != null){ 293 TColumnNameVisitor objectNameVisitor = new TColumnNameVisitor(); 294 aggregation_function.getArgs().acceptChildren(objectNameVisitor); 295 for(TObjectName objectName:objectNameVisitor.getObjectNames()){ 296 pivotTable.getSourceTableOfPivot().getLinkedColumns().addObjectName(objectName); 297 objectName.setSourceTable(pivotTable.getSourceTableOfPivot()); 298 } 299 300 aggregation_function.doParse(psql,plocation); 301 }; 302 303 if (pivotColumnList != null){ 304 for(TObjectName objectName:pivotColumnList){ 305 pivotTable.getSourceTableOfPivot().getLinkedColumns().addObjectName(objectName); 306 objectName.setSourceTable(pivotTable.getSourceTableOfPivot()); 307 } 308 } 309 pivotInClause.doParse(psql,plocation); 310 if (!addColumnFromAlias){ 311 pivotInClause.linkColumnToTable(pivotTable, sqlTable); 312 } 313 314 break; 315 case unpivot: 316 //valueColumnList. 317 if (pivotTable!=null){ 318 if (valueColumnList != null){ 319 for(TObjectName objectName: valueColumnList){ 320 pivotTable.getLinkedColumns().addObjectName(objectName); 321 objectName.setSourceTable(pivotTable); 322 if (sqlTable != null){ 323 sqlTable.addColumn(objectName.toString()); 324 } 325 } 326 } 327 328 if (pivotColumnList!=null){ 329 for(TObjectName objectName: pivotColumnList){ 330 pivotTable.getLinkedColumns().addObjectName(objectName); 331 objectName.setSourceTable(pivotTable); 332 if (sqlTable != null){ 333 sqlTable.addColumn(objectName.toString()); 334 } 335 } 336 } 337 } 338 unpivotInClause.doParse(psql,plocation); 339 unpivotInClause.linkColumnToPivotSourceTable(pivotTable.getSourceTableOfPivot()); 340 break; 341 } 342 } 343 344 public void accept(TParseTreeVisitor v){ 345 v.preVisit(this); 346 v.postVisit(this); 347 } 348 349 public void acceptChildren(TParseTreeVisitor v){ 350 v.preVisit(this); 351 // pivotTable.acceptChildren(v); 352 switch (getType()){ 353 case pivot: 354 if (aggregation_function_list != null){ 355 aggregation_function_list.acceptChildren(v); 356 }else if (aggregation_function != null){ 357 aggregation_function.acceptChildren(v); 358 } 359 pivotColumnList.acceptChildren(v); 360 if (pivotInClause != null){ 361 pivotInClause.acceptChildren(v); 362 } 363 break; 364 case unpivot: 365 valueColumnList.acceptChildren(v); 366 pivotColumnList.acceptChildren(v); 367 unpivotInClause.acceptChildren(v); 368 break; 369 } 370 371 372 if (getAliasClause() != null){ 373 getAliasClause().acceptChildren(v); 374 } 375 v.postVisit(this); 376 } 377 378 public void setPivotInClause(TPivotInClause pivotInClause) { 379 this.pivotInClause = pivotInClause; 380 } 381 382 public void setUnpivotInClause(TUnpivotInClause unpivotInClause) { 383 this.unpivotInClause = unpivotInClause; 384 } 385 386 public void setAggregation_function_list(TResultColumnList aggregation_function_list) { 387 this.aggregation_function_list = aggregation_function_list; 388 } 389 390 public void setPivotColumnList(TObjectNameList pivotColumnList) { 391 this.pivotColumnList = pivotColumnList; 392 } 393 394 public void setAggregation_function(TFunctionCall aggregation_function) { 395 this.aggregation_function = aggregation_function; 396 } 397 398 public void setValueColumnList(TObjectNameList valueColumnList) { 399 this.valueColumnList = valueColumnList; 400 } 401 402 public void setColumnList(TObjectNameList columnList) { 403 this.columnList = columnList; 404 } 405}