Skip to content

Commit

Permalink
feat: parsing Piped SQL, complete all Operators
Browse files Browse the repository at this point in the history
Signed-off-by: Andreas Reichel <[email protected]>
  • Loading branch information
manticore-projects committed Feb 1, 2025
1 parent f687f77 commit 48cc2f7
Show file tree
Hide file tree
Showing 10 changed files with 386 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
package net.sf.jsqlparser.statement.piped;

import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.statement.select.TableFunction;

public class CallPipeOperator extends PipeOperator {
private TableFunction tableFunction;
private Alias alias;

public CallPipeOperator(TableFunction tableFunction, Alias alias) {
this.tableFunction = tableFunction;
this.alias = alias;
}

public TableFunction getTableFunction() {
return tableFunction;
}

public CallPipeOperator setTableFunction(TableFunction tableFunction) {
this.tableFunction = tableFunction;
return this;
}

public Alias getAlias() {
return alias;
}

public CallPipeOperator setAlias(Alias alias) {
this.alias = alias;
return this;
}

@Override
public StringBuilder appendTo(StringBuilder builder) {
builder.append("|> CALL ").append(tableFunction);
if (alias != null) {
builder.append(" ").append(alias);
}

return builder;
}

@Override
public <T, S> T accept(PipeOperatorVisitor<T> visitor, S context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,78 @@
package net.sf.jsqlparser.statement.piped;

import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.schema.Column;

public class PivotPipeOperator extends PipeOperator {
private Expression aggregateExpression;
private Column inputColumn;
private ExpressionList<Column> pivotColumns;
private Alias alias = null;

public PivotPipeOperator(Expression aggregateExpression, Column inputColumn,
ExpressionList<Column> pivotColumns, Alias alias) {
this.aggregateExpression = aggregateExpression;
this.inputColumn = inputColumn;
this.pivotColumns = pivotColumns;
this.alias = alias;
}

public Expression getAggregateExpression() {
return aggregateExpression;
}

public PivotPipeOperator setAggregateExpression(Expression aggregateExpression) {
this.aggregateExpression = aggregateExpression;
return this;
}

public Column getInputColumn() {
return inputColumn;
}

public PivotPipeOperator setInputColumn(Column inputColumn) {
this.inputColumn = inputColumn;
return this;
}

public ExpressionList<Column> getPivotColumns() {
return pivotColumns;
}

public PivotPipeOperator setPivotColumns(ExpressionList<Column> pivotColumns) {
this.pivotColumns = pivotColumns;
return this;
}

public Alias getAlias() {
return alias;
}

public PivotPipeOperator setAlias(Alias alias) {
this.alias = alias;
return this;
}

@Override
public StringBuilder appendTo(StringBuilder builder) {
builder
.append("|> ")
.append("PIVOT( ")
.append(aggregateExpression)
.append(" FOR ")
.append(inputColumn)
.append(" IN (")
.append(pivotColumns)
.append("))");
if (alias != null) {
builder.append(" ").append(alias);
}
builder.append("\n");
return builder;
}

@Override
public <T, S> T accept(PipeOperatorVisitor<T> visitor, S context) {
return visitor.visit(this, context);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
package net.sf.jsqlparser.statement.piped;

public class TableSamplePipeOperator extends PipeOperator {
double percent;

public TableSamplePipeOperator(double percent) {
this.percent = percent;
}

public TableSamplePipeOperator(String percentStr) {
this.percent = Double.parseDouble(percentStr);
}

public double getPercent() {
return percent;
}

public TableSamplePipeOperator setPercent(double percent) {
this.percent = percent;
return this;
}

@Override
public StringBuilder appendTo(StringBuilder builder) {
builder.append("|> ").append("TABLESAMPLE SYSTEM (").append(percent).append(" PERCENT)");
return builder;
}

@Override
public <T, S> T accept(PipeOperatorVisitor<T> visitor, S context) {
return visitor.visit(this, context);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,77 @@
package net.sf.jsqlparser.statement.piped;

import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.schema.Column;

public class UnPivotPipeOperator extends PipeOperator {
private Column valuesColumn;
private Column nameColumn;
private ExpressionList<Column> pivotColumns;
private Alias alias = null;

public UnPivotPipeOperator(Column valuesColumn, Column nameColumn,
ExpressionList<Column> pivotColumns, Alias alias) {
this.valuesColumn = valuesColumn;
this.nameColumn = nameColumn;
this.pivotColumns = pivotColumns;
this.alias = alias;
}

public Column getValuesColumn() {
return valuesColumn;
}

public UnPivotPipeOperator setValuesColumn(Column valuesColumn) {
this.valuesColumn = valuesColumn;
return this;
}

public Column getNameColumn() {
return nameColumn;
}

public UnPivotPipeOperator setNameColumn(Column nameColumn) {
this.nameColumn = nameColumn;
return this;
}

public ExpressionList<Column> getPivotColumns() {
return pivotColumns;
}

public UnPivotPipeOperator setPivotColumns(ExpressionList<Column> pivotColumns) {
this.pivotColumns = pivotColumns;
return this;
}

public Alias getAlias() {
return alias;
}

public UnPivotPipeOperator setAlias(Alias alias) {
this.alias = alias;
return this;
}

@Override
public StringBuilder appendTo(StringBuilder builder) {
builder
.append("|> ")
.append("UNPIVOT( ")
.append(valuesColumn)
.append(" FOR ")
.append(nameColumn)
.append(" IN (")
.append(pivotColumns)
.append("))");
if (alias != null) {
builder.append(" ").append(alias);
}
builder.append("\n");
return builder;
}

@Override
public <T, S> T accept(PipeOperatorVisitor<T> visitor, S context) {
return visitor.visit(this, context);
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,12 @@ public <S> StringBuilder visit(AsPipeOperator as, S context) {

@Override
public <S> StringBuilder visit(CallPipeOperator call, S context) {
builder.append("|> CALL ");
call.getTableFunction().accept(this);
if (call.getAlias() != null) {
builder.append(" ").append(call.getAlias());
}

return builder;
}

Expand Down Expand Up @@ -951,6 +957,19 @@ public <S> StringBuilder visit(OrderByPipeOperator orderBy, S context) {

@Override
public <S> StringBuilder visit(PivotPipeOperator pivot, S context) {
builder
.append("|> ")
.append("PIVOT( ")
.append(pivot.getAggregateExpression())
.append(" FOR ")
.append(pivot.getInputColumn())
.append(" IN (")
.append(pivot.getPivotColumns())
.append("))");
if (pivot.getAlias() != null) {
builder.append(" ").append(pivot.getAlias());
}
builder.append("\n");
return builder;
}

Expand Down Expand Up @@ -983,6 +1002,8 @@ public <S> StringBuilder visit(SetPipeOperator set, S context) {

@Override
public <S> StringBuilder visit(TableSamplePipeOperator tableSample, S context) {
builder.append("|> ").append("TABLESAMPLE SYSTEM (").append(tableSample.getPercent())
.append(" PERCENT)");
return builder;
}

Expand All @@ -1006,6 +1027,19 @@ public <S> StringBuilder visit(SetOperationPipeOperator setOperationPipeOperator

@Override
public <S> StringBuilder visit(UnPivotPipeOperator unPivot, S context) {
builder
.append("|> ")
.append("UNPIVOT( ")
.append(unPivot.getValuesColumn())
.append(" FOR ")
.append(unPivot.getNameColumn())
.append(" IN (")
.append(unPivot.getPivotColumns())
.append("))");
if (unPivot.getAlias() != null) {
builder.append(" ").append(unPivot.getAlias());
}
builder.append("\n");
return builder;
}

Expand Down
71 changes: 70 additions & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -2377,6 +2377,14 @@ PipeOperator PipeOperator() #PipeOperator:
operator = SetOperationPipeOperator()
|
operator = JoinPipeOperator()
|
operator = CallPipeOperator()
|
operator = TableSamplePipeOperator()
|
operator = PivotPipeOperator()
|
operator = UnPivotPipeOperator()
)
{
return operator;
Expand Down Expand Up @@ -2562,6 +2570,67 @@ SetOperationPipeOperator SetOperationPipeOperator():
}
}

CallPipeOperator CallPipeOperator():
{
TableFunction tableFunction;
Alias alias=null;
}
{
<K_CALL> tableFunction = TableFunction() [ LOOKAHEAD(2) alias = Alias() ]

{
return new CallPipeOperator(tableFunction, alias);
}
}


TableSamplePipeOperator TableSamplePipeOperator():
{
Token token;
}
{
<K_TABLESAMPLE> <K_SYSTEM> "(" ( token=<S_DOUBLE> | token=<S_LONG> ) <K_PERCENT> ")"
{
return new TableSamplePipeOperator( token.image );
}
}

PivotPipeOperator PivotPipeOperator():
{
Expression aggregateExpression;
Column inputColumn;
ExpressionList<Column> pivotColumns;
Alias alias = null;
}
{
<K_PIVOT> "(" aggregateExpression=Expression()
<K_FOR> inputColumn=Column()
<K_IN> "(" pivotColumns = ColumnList() ")"
")"
[ LOOKAHEAD(2) alias = Alias() ]
{
return new PivotPipeOperator(aggregateExpression, inputColumn, pivotColumns, alias);
}
}

UnPivotPipeOperator UnPivotPipeOperator():
{
Column valuesColumn;
Column nameColumn;
ExpressionList<Column> pivotColumns;
Alias alias = null;
}
{
<K_UNPIVOT> "(" valuesColumn=Column()
<K_FOR> nameColumn=Column()
<K_IN> "(" pivotColumns = ColumnList() ")"
")"
[ LOOKAHEAD(2) alias = Alias() ]
{
return new UnPivotPipeOperator(valuesColumn, nameColumn, pivotColumns, alias);
}
}

TableStatement TableStatement():
{
Table table = null;
Expand All @@ -2574,7 +2643,7 @@ TableStatement TableStatement():
table = Table()
{ tableStatement.setTable(table); }
[ LOOKAHEAD(<K_ORDER> <K_BY>) orderByElements = OrderByElements() { tableStatement.setOrderByElements(orderByElements); } ]
[ LOOKAHEAD(<K_LIMIT>) limit=LimitWithOffset() { tableStatement.setLimit(limit);} ]
[ LOOKAHEAD(<K_LIMIT>) limit = LimitWithOffset() { tableStatement.setLimit(limit);} ]
[ LOOKAHEAD(<K_OFFSET>) offset = Offset() { tableStatement.setOffset(offset);} ]
{ return tableStatement; }
/* Support operationList */
Expand Down
Loading

0 comments on commit 48cc2f7

Please sign in to comment.