Skip to content

Commit 415353f

Browse files
authored
Add support to transcribe AST to SQL for window function and window clause (#1851)
## Relevant Issues - [Related To] Issue partiql/partiql-scribe#81 ## Description - Add support to transcribe AST to SQL for window function and window clause ## Other Information - Updated Unreleased Section in CHANGELOG: NO - Any backward-incompatible changes? NO - Any new external dependencies? NO - Do your changes comply with the [contributing][cg] and [code style][csg] guidelines? YES ## License Information By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. <!-- DO NOT DELETE BELOW --> [cg]: https://github.com/partiql/partiql-lang-kotlin/blob/main/CONTRIBUTING.md [csg]: https://github.com/partiql/partiql-lang-kotlin/blob/main/CODE_STYLE.md --------- Signed-off-by: Di Xiao <[email protected]>
1 parent 52716df commit 415353f

File tree

12 files changed

+732
-12
lines changed

12 files changed

+732
-12
lines changed

partiql-ast/api/partiql-ast.api

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public final class org/partiql/ast/Ast {
103103
public static final fun exprWindow (Lorg/partiql/ast/expr/WindowFunction;Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/expr/ExprWindow$Over;)Lorg/partiql/ast/expr/ExprWindow;
104104
public static final fun exprWindow (Lorg/partiql/ast/expr/WindowFunction;Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/expr/ExprWindow$Over;)Lorg/partiql/ast/expr/ExprWindow;
105105
public static synthetic fun exprWindow$default (Lorg/partiql/ast/expr/WindowFunction;Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/expr/ExprWindow$Over;ILjava/lang/Object;)Lorg/partiql/ast/expr/ExprWindow;
106+
public static final fun exprWindowFunction (Lorg/partiql/ast/WindowFunctionType;Lorg/partiql/ast/WindowSpecification;)Lorg/partiql/ast/expr/ExprWindowFunction;
106107
public static final fun exprWindowOver (Ljava/util/List;Ljava/util/List;)Lorg/partiql/ast/expr/ExprWindow$Over;
107108
public static final fun from (Ljava/util/List;)Lorg/partiql/ast/From;
108109
public static final fun fromExpr (Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/FromType;)Lorg/partiql/ast/FromExpr;
@@ -216,6 +217,10 @@ public final class org/partiql/ast/Ast {
216217
public static final fun upsert (Lorg/partiql/ast/Identifier;Lorg/partiql/ast/Identifier$Simple;Lorg/partiql/ast/dml/InsertSource;)Lorg/partiql/ast/dml/Upsert;
217218
public static final fun upsert (Lorg/partiql/ast/Identifier;Lorg/partiql/ast/dml/InsertSource;)Lorg/partiql/ast/dml/Upsert;
218219
public static synthetic fun upsert$default (Lorg/partiql/ast/Identifier;Lorg/partiql/ast/Identifier$Simple;Lorg/partiql/ast/dml/InsertSource;ILjava/lang/Object;)Lorg/partiql/ast/dml/Upsert;
220+
public static final fun windowClause (Ljava/util/List;)Lorg/partiql/ast/WindowClause;
221+
public static final fun windowClauseDefinition (Lorg/partiql/ast/Identifier$Simple;Lorg/partiql/ast/WindowSpecification;)Lorg/partiql/ast/WindowClause$Definition;
222+
public static final fun windowPartition (Lorg/partiql/ast/Identifier;)Lorg/partiql/ast/WindowPartition;
223+
public static final fun windowSpecification (Lorg/partiql/ast/Identifier$Simple;Ljava/util/List;Lorg/partiql/ast/OrderBy;)Lorg/partiql/ast/WindowSpecification;
219224
public static final fun with (Ljava/util/List;Z)Lorg/partiql/ast/With;
220225
public static final fun withListElement (Lorg/partiql/ast/Identifier$Simple;Lorg/partiql/ast/expr/ExprQuerySet;Ljava/util/List;)Lorg/partiql/ast/WithListElement;
221226
}
@@ -3660,6 +3665,8 @@ public abstract class org/partiql/ast/sql/SqlDialect : org/partiql/ast/AstVisito
36603665
public fun visitExprVarRef (Lorg/partiql/ast/expr/ExprVarRef;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
36613666
public synthetic fun visitExprVariant (Lorg/partiql/ast/expr/ExprVariant;Ljava/lang/Object;)Ljava/lang/Object;
36623667
public fun visitExprVariant (Lorg/partiql/ast/expr/ExprVariant;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3668+
public synthetic fun visitExprWindowFunction (Lorg/partiql/ast/expr/ExprWindowFunction;Ljava/lang/Object;)Ljava/lang/Object;
3669+
public fun visitExprWindowFunction (Lorg/partiql/ast/expr/ExprWindowFunction;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
36633670
public fun visitExprWrapped (Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/sql/SqlBlock;Z)Lorg/partiql/ast/sql/SqlBlock;
36643671
public static synthetic fun visitExprWrapped$default (Lorg/partiql/ast/sql/SqlDialect;Lorg/partiql/ast/expr/Expr;Lorg/partiql/ast/sql/SqlBlock;ZILjava/lang/Object;)Lorg/partiql/ast/sql/SqlBlock;
36653672
public synthetic fun visitFrom (Lorg/partiql/ast/From;Ljava/lang/Object;)Ljava/lang/Object;
@@ -3724,6 +3731,30 @@ public abstract class org/partiql/ast/sql/SqlDialect : org/partiql/ast/AstVisito
37243731
public fun visitUpdate (Lorg/partiql/ast/dml/Update;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
37253732
public synthetic fun visitUpsert (Lorg/partiql/ast/dml/Upsert;Ljava/lang/Object;)Ljava/lang/Object;
37263733
public fun visitUpsert (Lorg/partiql/ast/dml/Upsert;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3734+
public synthetic fun visitWindowClause (Lorg/partiql/ast/WindowClause;Ljava/lang/Object;)Ljava/lang/Object;
3735+
public fun visitWindowClause (Lorg/partiql/ast/WindowClause;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3736+
public synthetic fun visitWindowDefinition (Lorg/partiql/ast/WindowClause$Definition;Ljava/lang/Object;)Ljava/lang/Object;
3737+
public fun visitWindowDefinition (Lorg/partiql/ast/WindowClause$Definition;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3738+
public synthetic fun visitWindowFunctionType (Lorg/partiql/ast/WindowFunctionType;Ljava/lang/Object;)Ljava/lang/Object;
3739+
public fun visitWindowFunctionType (Lorg/partiql/ast/WindowFunctionType;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3740+
public synthetic fun visitWindowFunctionTypeCumeDist (Lorg/partiql/ast/WindowFunctionType$CumeDist;Ljava/lang/Object;)Ljava/lang/Object;
3741+
public fun visitWindowFunctionTypeCumeDist (Lorg/partiql/ast/WindowFunctionType$CumeDist;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3742+
public synthetic fun visitWindowFunctionTypeDenseRank (Lorg/partiql/ast/WindowFunctionType$DenseRank;Ljava/lang/Object;)Ljava/lang/Object;
3743+
public fun visitWindowFunctionTypeDenseRank (Lorg/partiql/ast/WindowFunctionType$DenseRank;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3744+
public synthetic fun visitWindowFunctionTypeLag (Lorg/partiql/ast/WindowFunctionType$Lag;Ljava/lang/Object;)Ljava/lang/Object;
3745+
public fun visitWindowFunctionTypeLag (Lorg/partiql/ast/WindowFunctionType$Lag;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3746+
public synthetic fun visitWindowFunctionTypeLead (Lorg/partiql/ast/WindowFunctionType$Lead;Ljava/lang/Object;)Ljava/lang/Object;
3747+
public fun visitWindowFunctionTypeLead (Lorg/partiql/ast/WindowFunctionType$Lead;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3748+
public synthetic fun visitWindowFunctionTypePercentRank (Lorg/partiql/ast/WindowFunctionType$PercentRank;Ljava/lang/Object;)Ljava/lang/Object;
3749+
public fun visitWindowFunctionTypePercentRank (Lorg/partiql/ast/WindowFunctionType$PercentRank;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3750+
public synthetic fun visitWindowFunctionTypeRank (Lorg/partiql/ast/WindowFunctionType$Rank;Ljava/lang/Object;)Ljava/lang/Object;
3751+
public fun visitWindowFunctionTypeRank (Lorg/partiql/ast/WindowFunctionType$Rank;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3752+
public synthetic fun visitWindowFunctionTypeRowNumber (Lorg/partiql/ast/WindowFunctionType$RowNumber;Ljava/lang/Object;)Ljava/lang/Object;
3753+
public fun visitWindowFunctionTypeRowNumber (Lorg/partiql/ast/WindowFunctionType$RowNumber;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3754+
public synthetic fun visitWindowPartition (Lorg/partiql/ast/WindowPartition;Ljava/lang/Object;)Ljava/lang/Object;
3755+
public fun visitWindowPartition (Lorg/partiql/ast/WindowPartition;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
3756+
public synthetic fun visitWindowSpecification (Lorg/partiql/ast/WindowSpecification;Ljava/lang/Object;)Ljava/lang/Object;
3757+
public fun visitWindowSpecification (Lorg/partiql/ast/WindowSpecification;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
37273758
public synthetic fun visitWith (Lorg/partiql/ast/With;Ljava/lang/Object;)Ljava/lang/Object;
37283759
public fun visitWith (Lorg/partiql/ast/With;Lorg/partiql/ast/sql/SqlBlock;)Lorg/partiql/ast/sql/SqlBlock;
37293760
public synthetic fun visitWithListElement (Lorg/partiql/ast/WithListElement;Ljava/lang/Object;)Ljava/lang/Object;

partiql-ast/src/main/java/org/partiql/ast/WindowFunctionNullTreatment.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ public int code() {
5555
@Override
5656
public String name() {
5757
switch (code) {
58-
case RESPECT_NULLS: return "RESPECT_NULLS";
59-
case IGNORE_NULLS: return "DISTINCT";
58+
case RESPECT_NULLS: return "RESPECT NULLS";
59+
case IGNORE_NULLS: return "IGNORE NULLS";
6060
default: throw new IllegalStateException("Invalid code: " + code);
6161
}
6262
}

partiql-ast/src/main/java/org/partiql/ast/sql/SqlDialect.kt

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ import org.partiql.ast.SetOp
4848
import org.partiql.ast.SetOpType
4949
import org.partiql.ast.SetQuantifier
5050
import org.partiql.ast.Sort
51+
import org.partiql.ast.WindowClause
52+
import org.partiql.ast.WindowFunctionNullTreatment
53+
import org.partiql.ast.WindowFunctionType
54+
import org.partiql.ast.WindowPartition
55+
import org.partiql.ast.WindowSpecification
5156
import org.partiql.ast.With
5257
import org.partiql.ast.WithListElement
5358
import org.partiql.ast.ddl.CreateTable
@@ -91,6 +96,7 @@ import org.partiql.ast.expr.ExprTrim
9196
import org.partiql.ast.expr.ExprValues
9297
import org.partiql.ast.expr.ExprVarRef
9398
import org.partiql.ast.expr.ExprVariant
99+
import org.partiql.ast.expr.ExprWindowFunction
94100
import org.partiql.ast.expr.PathStep
95101
import org.partiql.ast.expr.TruthValue
96102

@@ -195,6 +201,104 @@ public abstract class SqlDialect : AstVisitor<SqlBlock, SqlBlock>() {
195201
return tail concat "[*]"
196202
}
197203

204+
// Window Function Methods
205+
@Deprecated("This feature is experimental and is subject to change.")
206+
override fun visitExprWindowFunction(node: ExprWindowFunction, tail: SqlBlock): SqlBlock {
207+
var t = tail
208+
t = visitWindowFunctionType(node.functionType, t)
209+
t = t concat " OVER "
210+
t = visitWindowSpecification(node.windowSpecification, t)
211+
return t
212+
}
213+
214+
@Deprecated("This feature is experimental and is subject to change.")
215+
override fun visitWindowFunctionType(node: WindowFunctionType, tail: SqlBlock): SqlBlock {
216+
return node.accept(this, tail)
217+
}
218+
219+
@Deprecated("This feature is experimental and is subject to change.")
220+
override fun visitWindowFunctionTypeRank(node: WindowFunctionType.Rank, tail: SqlBlock): SqlBlock {
221+
return tail concat "RANK()"
222+
}
223+
224+
@Deprecated("This feature is experimental and is subject to change.")
225+
override fun visitWindowFunctionTypeDenseRank(node: WindowFunctionType.DenseRank, tail: SqlBlock): SqlBlock {
226+
return tail concat "DENSE_RANK()"
227+
}
228+
229+
@Deprecated("This feature is experimental and is subject to change.")
230+
override fun visitWindowFunctionTypePercentRank(node: WindowFunctionType.PercentRank, tail: SqlBlock): SqlBlock {
231+
return tail concat "PERCENT_RANK()"
232+
}
233+
234+
@Deprecated("This feature is experimental and is subject to change.")
235+
override fun visitWindowFunctionTypeCumeDist(node: WindowFunctionType.CumeDist, tail: SqlBlock): SqlBlock {
236+
return tail concat "CUME_DIST()"
237+
}
238+
239+
@Deprecated("This feature is experimental and is subject to change.")
240+
override fun visitWindowFunctionTypeRowNumber(node: WindowFunctionType.RowNumber, tail: SqlBlock): SqlBlock {
241+
return tail concat "ROW_NUMBER()"
242+
}
243+
244+
@Deprecated("This feature is experimental and is subject to change.")
245+
override fun visitWindowFunctionTypeLead(node: WindowFunctionType.Lead, tail: SqlBlock): SqlBlock {
246+
return visitWindowFunctionTypeLeadOrLag("LEAD(", node.extent, node.offset, node.defaultValue, node.nullTreatment, tail)
247+
}
248+
249+
@Deprecated("This feature is experimental and is subject to change.")
250+
override fun visitWindowFunctionTypeLag(node: WindowFunctionType.Lag, tail: SqlBlock): SqlBlock {
251+
return visitWindowFunctionTypeLeadOrLag("LAG(", node.extent, node.offset, node.defaultValue, node.nullTreatment, tail)
252+
}
253+
254+
@Deprecated("This feature is experimental and is subject to change.")
255+
override fun visitWindowPartition(node: WindowPartition, tail: SqlBlock): SqlBlock {
256+
return visitIdentifier(node.columnReference, tail)
257+
}
258+
259+
@Deprecated("This feature is experimental and is subject to change.")
260+
override fun visitWindowSpecification(node: WindowSpecification, tail: SqlBlock): SqlBlock {
261+
var t = tail
262+
if (node.existingName != null) {
263+
t = visitIdentifierSimple(node.existingName!!, t)
264+
if (!node.partitionClause.isNullOrEmpty() || node.orderClause != null) {
265+
t = t concat " "
266+
}
267+
} else {
268+
t = t concat "("
269+
// PARTITION BY clause
270+
if (!node.partitionClause.isNullOrEmpty()) {
271+
t = t concat "PARTITION BY "
272+
t = t concat list(start = null, end = null) { node.partitionClause!! }
273+
t = t concat " "
274+
}
275+
276+
// ORDER BY clause
277+
node.orderClause?.let { orderClause ->
278+
t = visitOrderBy(orderClause, t)
279+
}
280+
t = t concat ")"
281+
}
282+
283+
return t
284+
}
285+
286+
@Deprecated("This feature is experimental and is subject to change.")
287+
override fun visitWindowClause(node: WindowClause, tail: SqlBlock): SqlBlock {
288+
var t = tail concat "WINDOW "
289+
t = t concat list(start = null, end = null) { node.definitions }
290+
return t
291+
}
292+
293+
@Deprecated("This feature is experimental and is subject to change.")
294+
override fun visitWindowDefinition(node: WindowClause.Definition, tail: SqlBlock): SqlBlock {
295+
var t = tail
296+
t = visitIdentifierSimple(node.name, t)
297+
t = t concat " AS "
298+
t = visitWindowSpecification(node.specification, t)
299+
return t
300+
}
301+
198302
// TYPES
199303
override fun visitDataType(node: DataType, tail: SqlBlock): SqlBlock {
200304
return when (node.code()) {
@@ -707,6 +811,9 @@ public abstract class SqlDialect : AstVisitor<SqlBlock, SqlBlock>() {
707811
// HAVING
708812
val having = node.having
709813
t = if (having != null) visitExprWrapped(having, t concat " HAVING ") else t
814+
// WINDOW
815+
val window = node.window
816+
t = if (window != null) visitWindowClause(window, t concat " ") else t
710817
return t
711818
}
712819

@@ -939,6 +1046,32 @@ public abstract class SqlDialect : AstVisitor<SqlBlock, SqlBlock>() {
9391046
return next!!
9401047
}
9411048

1049+
private fun visitWindowFunctionTypeLeadOrLag(
1050+
prefix: String,
1051+
extent: Expr,
1052+
offset: Long?,
1053+
defaultValue: Expr?,
1054+
nullTreatment: WindowFunctionNullTreatment?,
1055+
tail: SqlBlock
1056+
): SqlBlock {
1057+
var t = tail concat prefix
1058+
t = visitExpr(extent, t)
1059+
offset?.let {
1060+
t = t concat ", $it"
1061+
}
1062+
1063+
defaultValue?.let { defaultValue ->
1064+
t = t concat ", "
1065+
t = visitExpr(defaultValue, t)
1066+
}
1067+
1068+
t = t concat ")"
1069+
nullTreatment?.let { nullTreatment ->
1070+
t = t concat " ${nullTreatment.name()}"
1071+
}
1072+
return t
1073+
}
1074+
9421075
private fun type(symbol: String, vararg args: Int?, gap: Boolean = false): SqlBlock {
9431076
val p = args.filterNotNull()
9441077
val t = when {

partiql-ast/src/main/kotlin/org/partiql/ast/Ast.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import org.partiql.ast.expr.ExprValues
5757
import org.partiql.ast.expr.ExprVarRef
5858
import org.partiql.ast.expr.ExprVariant
5959
import org.partiql.ast.expr.ExprWindow
60+
import org.partiql.ast.expr.ExprWindowFunction
6061
import org.partiql.ast.expr.PathStep
6162
import org.partiql.ast.expr.PathStep.AllFields
6263
import org.partiql.ast.expr.SessionAttribute
@@ -301,6 +302,43 @@ public object Ast {
301302
return ExprWindow(windowFunction, expression, offset, defaultValue, over)
302303
}
303304

305+
@JvmStatic
306+
@Deprecated("This feature is experimental and is subject to change")
307+
public fun exprWindowFunction(
308+
type: WindowFunctionType,
309+
spec: WindowSpecification
310+
): ExprWindowFunction {
311+
return ExprWindowFunction(type, spec)
312+
}
313+
314+
@JvmStatic
315+
@Deprecated("This feature is experimental and is subject to change")
316+
public fun windowSpecification(
317+
existingName: Identifier.Simple?,
318+
partitionClause: List<WindowPartition>?,
319+
orderByClause: OrderBy?
320+
): WindowSpecification {
321+
return WindowSpecification(existingName, partitionClause, orderByClause)
322+
}
323+
324+
@JvmStatic
325+
@Deprecated("This feature is experimental and is subject to change")
326+
public fun windowPartition(columnReference: Identifier): WindowPartition {
327+
return WindowPartition(columnReference)
328+
}
329+
330+
@JvmStatic
331+
@Deprecated("This feature is experimental and is subject to change")
332+
public fun windowClause(definitions: List<WindowClause.Definition>): WindowClause {
333+
return WindowClause(definitions)
334+
}
335+
336+
@JvmStatic
337+
@Deprecated("This feature is experimental and is subject to change")
338+
public fun windowClauseDefinition(name: Identifier.Simple, spec: WindowSpecification): WindowClause.Definition {
339+
return WindowClause.Definition(name, spec)
340+
}
341+
304342
@JvmStatic
305343
@Deprecated("This is replaced by WindowSpecification.")
306344
public fun exprWindowOver(partitions: List<Expr>, sorts: List<Sort>): ExprWindow.Over {

0 commit comments

Comments
 (0)