Skip to content

Commit 0c0c32e

Browse files
Support alias for UnPivot statement (see discussion #1374) (#1380)
- Changed JSqlParserCC.jjt file to add the alias to the UnPivot lexical entity. - Added Alias to the UnPivot object. - Improved SelectDeParser to correctly deparse SubSelect's UnPivot component.
1 parent a8afd9a commit 0c0c32e

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

src/main/java/net/sf/jsqlparser/statement/select/UnPivot.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
package net.sf.jsqlparser.statement.select;
1111

12+
import net.sf.jsqlparser.expression.Alias;
1213
import net.sf.jsqlparser.schema.Column;
1314

1415
import java.util.List;
@@ -20,6 +21,7 @@ public class UnPivot {
2021
private Column unpivotClause;
2122
private List<Column> unpivotForClause;
2223
private List<SelectExpressionItem> unpivotInClause;
24+
private Alias alias;
2325

2426
public void accept(PivotVisitor pivotVisitor) {
2527
pivotVisitor.visit(this);
@@ -69,11 +71,20 @@ public String toString() {
6971
+ (includeNullsSpecified && !includeNulls ? " EXCLUDE NULLS" : "")
7072
+ " (" + unpivotClause
7173
+ " FOR " + PlainSelect.getStringList(unpivotForClause, true, unpivotForClause != null && unpivotForClause.size() > 1)
72-
+ " IN " + PlainSelect.getStringList(unpivotInClause, true, true) + ")";
74+
+ " IN " + PlainSelect.getStringList(unpivotInClause, true, true) + ")"
75+
+ (alias!=null ? alias.toString() : "");
7376
}
7477

7578
public UnPivot withIncludeNulls(boolean includeNulls) {
7679
this.setIncludeNulls(includeNulls);
7780
return this;
7881
}
82+
83+
public Alias getAlias() {
84+
return alias;
85+
}
86+
87+
public void setAlias(Alias alias) {
88+
this.alias = alias;
89+
}
7990
}

src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,17 @@ public void visit(SubSelect subSelect) {
253253
buffer.append(subSelect.isUseBrackets() ? ")" : "");
254254
Alias alias = subSelect.getAlias();
255255
if (alias != null) {
256-
buffer.append(alias.toString());
256+
buffer.append(alias);
257257
}
258258
Pivot pivot = subSelect.getPivot();
259259
if (pivot != null) {
260260
pivot.accept(this);
261261
}
262+
263+
UnPivot unPivot = subSelect.getUnPivot();
264+
if (unPivot != null) {
265+
unPivot.accept(this);
266+
}
262267
}
263268

264269
@Override
@@ -308,6 +313,9 @@ public void visit(UnPivot unpivot) {
308313
.append(PlainSelect.getStringList(unpivotForClause, true,
309314
unpivotForClause != null && unpivotForClause.size() > 1))
310315
.append(" IN ").append(PlainSelect.getStringList(unpivot.getUnPivotInClause(), true, true)).append(")");
316+
if (unpivot.getAlias() != null) {
317+
buffer.append(unpivot.getAlias().toString());
318+
}
311319
}
312320

313321
@Override

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,6 +2273,7 @@ UnPivot UnPivot():
22732273
Column unpivotClause;
22742274
List<Column> unpivotForClause;
22752275
List<SelectExpressionItem> unpivotInClause;
2276+
Alias alias = null;
22762277
}
22772278
{
22782279
<K_UNPIVOT>
@@ -2284,10 +2285,12 @@ UnPivot UnPivot():
22842285
unpivotInClause = PivotSingleInItems()
22852286
")"
22862287
")"
2288+
[ alias = Alias() ]
22872289
{
22882290
retval.setUnPivotClause(unpivotClause);
22892291
retval.setUnPivotForClause(unpivotForClause);
22902292
retval.setUnPivotInClause(unpivotInClause);
2293+
retval.setAlias(alias);
22912294
return retval;
22922295
}
22932296
}

src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,6 +2516,31 @@ public void testPivotFunction() throws JSQLParserException {
25162516
assertSqlCanBeParsedAndDeparsed("SELECT to_char((SELECT col1 FROM (SELECT times_purchased, state_code FROM customers t) PIVOT (count(state_code) FOR state_code IN ('NY', 'CT', 'NJ', 'FL', 'MO')) ORDER BY times_purchased)) FROM DUAL");
25172517
}
25182518

2519+
@Test
2520+
public void testUnPivotWithAlias() throws JSQLParserException {
2521+
assertSqlCanBeParsedAndDeparsed("SELECT simulation_id, un_piv_alias.signal, un_piv_alias.val AS value FROM" +
2522+
" (SELECT simulation_id," +
2523+
" convert(numeric(18, 2), sum(convert(int, init_on))) DosingOnStatus_TenMinutes_sim," +
2524+
" convert(numeric(18, 2), sum(CASE WHEN pump_status = 0 THEN 10 ELSE 0 END)) AS DosingOffDurationHour_Hour_sim" +
2525+
" FROM ft_simulation_result" +
2526+
" WHERE simulation_id = 210 AND data_timestamp BETWEEN convert(datetime, '2021-09-14', 120) AND convert(datetime, '2021-09-18', 120)" +
2527+
" GROUP BY simulation_id) sim_data" +
2528+
" UNPIVOT" +
2529+
" (" +
2530+
"val" +
2531+
" FOR signal IN (DosingOnStatus_TenMinutes_sim, DosingOnDuration_Hour_sim)" +
2532+
") un_piv_alias");
2533+
}
2534+
2535+
@Test
2536+
public void testUnPivot() throws JSQLParserException {
2537+
String stmt = "SELECT * FROM sale_stats" +
2538+
" UNPIVOT (" +
2539+
"quantity" +
2540+
" FOR product_code IN (product_a AS 'A', product_b AS 'B', product_c AS 'C'))";
2541+
assertSqlCanBeParsedAndDeparsed(stmt);
2542+
}
2543+
25192544
@Test
25202545
public void testPivotWithAlias() throws JSQLParserException {
25212546
assertSqlCanBeParsedAndDeparsed("SELECT * FROM (SELECT * FROM mytable LEFT JOIN mytable2 ON Factor_ID = Id) f PIVOT (max(f.value) FOR f.factoryCode IN (ZD, COD, SW, PH))");

0 commit comments

Comments
 (0)