Skip to content

Commit dadf1f3

Browse files
committed
Revert OFFSET (due to clash with existing SQL Functions)
1 parent 7436cc4 commit dadf1f3

File tree

2 files changed

+92
-49
lines changed

2 files changed

+92
-49
lines changed

sqlest/src/main/scala/sqlest/sql/DB2StatementBuilder.scala

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,19 @@ trait DB2StatementBuilder extends base.StatementBuilder {
5757
}
5858

5959
override def selectSql(select: Select[_, _ <: Relation]): String = {
60-
Seq(
61-
selectWhatSql(select.columns),
62-
selectFromSql(select.from)
63-
) ++ Seq(
64-
selectWhereSql(select.where),
65-
selectStartWithSql(select.startWith),
66-
selectConnectBySql(select.connectBy),
67-
selectGroupBySql(select.groupBy),
68-
selectHavingSql(select.having),
69-
selectOrderBySql(select.orderBy),
70-
selectOffsetSql(select.offset),
71-
selectLimitSql(select.limit),
72-
selectOptimizeSql(select.optimize),
73-
selectUnionSql(select.union)
74-
).flatten mkString (" ")
60+
val offset = select.offset getOrElse 0L
61+
if (offset > 0L) {
62+
rowNumberSelectSql(select, offset, select.limit)
63+
} else {
64+
super.selectSql(select)
65+
}
7566
}
7667

7768
override def selectLimitSql(limit: Option[Long]): Option[String] =
7869
limit map (limit => s"fetch first $limit rows only")
7970

8071
override def selectOffsetSql(offset: Option[Long]): Option[String] =
81-
offset map (offset => s"offset ${literalSql(offset)} rows")
72+
None
8273

8374
override def selectOptimizeSql(optimize: Option[Long]): Option[String] =
8475
optimize map (optimize => s"optimize for $optimize rows")
@@ -91,6 +82,25 @@ trait DB2StatementBuilder extends base.StatementBuilder {
9182
case _ => super.joinSql(relation)
9283
}
9384

85+
def rowNumberSelectSql(select: Select[_, _ <: Relation], offset: Long, limit: Option[Long]): String = {
86+
val subquery = Seq(
87+
s"${selectWhatSql(select.columns)}, row_number() over (${selectOrderBySql(select.orderBy) getOrElse ""}) as rownum",
88+
selectFromSql(select.from)
89+
) ++ Seq(
90+
selectWhereSql(select.where),
91+
selectGroupBySql(select.groupBy)
92+
).flatten mkString " "
93+
94+
val what =
95+
select.columns map (col => identifierSql(col.columnAlias)) mkString ", "
96+
97+
val bounds = limit
98+
.map(limit => s"rownum between ? and ?")
99+
.getOrElse(s"rownum >= ?")
100+
101+
s"with subquery as ($subquery) select $what from subquery where $bounds"
102+
}
103+
94104
override def columnSql(column: Column[_]): String =
95105
column match {
96106
case literalColumn: LiteralColumn[_] if literalColumn.columnType == BooleanColumnType =>
@@ -100,12 +110,38 @@ trait DB2StatementBuilder extends base.StatementBuilder {
100110
case _ => super.columnSql(column)
101111
}
102112

113+
override def selectArgs(select: Select[_, _ <: Relation]): List[LiteralColumn[_]] = {
114+
val offset = select.offset getOrElse 0L
115+
if (offset > 0L) {
116+
rowNumberSelectArgs(select, offset, select.limit)
117+
} else {
118+
super.selectArgs(select)
119+
}
120+
}
121+
103122
override def selectLimitArgs(limit: Option[Long]): List[LiteralColumn[_]] =
104123
Nil
105124

125+
override def selectOffsetArgs(limit: Option[Long]): List[LiteralColumn[_]] =
126+
Nil
127+
106128
override def selectOptimizeArgs(optimize: Option[Long]): List[LiteralColumn[_]] =
107129
Nil
108130

131+
def rowNumberSelectArgs(select: Select[_, _ <: Relation], offset: Long, limit: Option[Long]): List[LiteralColumn[_]] = {
132+
val subqueryArgs =
133+
selectWhatArgs(select.columns) ++
134+
selectOrderByArgs(select.orderBy) ++
135+
selectFromArgs(select.from) ++
136+
selectWhereArgs(select.where)
137+
138+
val boundsArgs = limit
139+
.map(limit => List(LiteralColumn[Long](offset + 1), LiteralColumn[Long](offset + limit)))
140+
.getOrElse(List(LiteralColumn[Long](offset + 1)))
141+
142+
subqueryArgs ++ boundsArgs
143+
}
144+
109145
override def columnArgs(column: Column[_]): List[LiteralColumn[_]] = column match {
110146
case column: LiteralColumn[_] if column.columnType == BooleanColumnType => List(LiteralColumn(0), LiteralColumn(0))
111147
case _ => super.columnArgs(column)

sqlest/src/test/scala/sqlest/sql/DB2StatementBuilderSpec.scala

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,15 @@ class DB2StatementBuilderSpec extends BaseStatementBuilderSpec {
5151
.offset(20)
5252
} should equal(
5353
s"""
54-
|select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2
55-
|from mytable
56-
|where (mytable.col1 = ?)
57-
|offset ? rows
54+
|with subquery as
55+
|(select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2, row_number() over () as rownum
56+
|from mytable
57+
|where (mytable.col1 = ?))
58+
|select mytable_col1, mytable_col2
59+
|from subquery
60+
|where rownum >= ?
5861
""".formatSql,
59-
List(List(123, 20))
62+
List(List(123, 2 * 10 + 1))
6063
)
6164
}
6265

@@ -68,13 +71,15 @@ class DB2StatementBuilderSpec extends BaseStatementBuilderSpec {
6871
.page(2, 10)
6972
} should equal(
7073
s"""
71-
|select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2
72-
|from mytable
73-
|where (mytable.col1 = ?)
74-
|offset ? rows
75-
|fetch first 10 rows only
74+
|with subquery as
75+
|(select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2, row_number() over () as rownum
76+
|from mytable
77+
|where (mytable.col1 = ?))
78+
|select mytable_col1, mytable_col2
79+
|from subquery
80+
|where rownum between ? and ?
7681
""".formatSql,
77-
List(List(123, 2 * 10))
82+
List(List(123, 2 * 10 + 1, 2 * 10 + 10))
7883
)
7984
}
8085

@@ -87,14 +92,15 @@ class DB2StatementBuilderSpec extends BaseStatementBuilderSpec {
8792
.page(2, 10)
8893
} should equal(
8994
s"""
90-
|select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2
91-
|from mytable
92-
|where (mytable.col1 = ?)
93-
|order by mytable.col1
94-
|offset ? rows
95-
|fetch first 10 rows only
95+
|with subquery as
96+
|(select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2, row_number() over (order by mytable.col1) as rownum
97+
|from mytable
98+
|where (mytable.col1 = ?))
99+
|select mytable_col1, mytable_col2
100+
|from subquery
101+
|where rownum between ? and ?
96102
""".formatSql,
97-
List(List(123, 2 * 10))
103+
List(List(123, 2 * 10 + 1, 2 * 10 + 10))
98104
)
99105
}
100106

@@ -166,15 +172,15 @@ class DB2StatementBuilderSpec extends BaseStatementBuilderSpec {
166172
.optimize(10)
167173
} should equal(
168174
s"""
169-
|select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2
170-
|from mytable
171-
|where (mytable.col1 = ?)
172-
|order by mytable.col1
173-
|offset ? rows
174-
|fetch first 10 rows only
175-
|optimize for 10 rows
175+
|with subquery as
176+
|(select mytable.col1 as mytable_col1, mytable.col2 as mytable_col2, row_number() over (order by mytable.col1) as rownum
177+
|from mytable
178+
|where (mytable.col1 = ?))
179+
|select mytable_col1, mytable_col2
180+
|from subquery
181+
|where rownum between ? and ?
176182
""".formatSql,
177-
List(List(123, 10))
183+
List(List(123, 11, 20))
178184
)
179185
}
180186

@@ -187,14 +193,15 @@ class DB2StatementBuilderSpec extends BaseStatementBuilderSpec {
187193
.page(15, 16)
188194
} should equal(
189195
s"""
190-
|select 1 as a, sum(cast(? as integer)) as b, (3 + ?) as c
191-
|from one inner join two on ((? = ?) and (? <> ?))
192-
|where ((? = ?) and (? <> ?))
193-
|order by ?, ? desc
194-
|offset ? rows
195-
|fetch first 16 rows only
196+
|with subquery as
197+
|(select 1 as a, sum(cast(? as integer)) as b, (3 + ?) as c, row_number() over (order by ?, ? desc) as rownum
198+
|from one inner join two on ((? = ?) and (? <> ?))
199+
|where ((? = ?) and (? <> ?)))
200+
|select a, b, c
201+
|from subquery
202+
|where rownum between ? and ?
196203
""".formatSql,
197-
List(List(2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 * 16))
204+
List(List(2, 4, 13, 14, 5, 6, 7, 8, 9, 10, 11, 12, 15 * 16 + 1, 15 * 16 + 16))
198205
)
199206
}
200207

0 commit comments

Comments
 (0)