未验证 提交 af5587bb 编写于 作者: L Liang Zhang 提交者: GitHub

Process LIMIT ALL for PostgreSQL (#4285)

* Process LIMIT ALL for PostgreSQL

* Add test case
上级 5af93dd2
......@@ -24,6 +24,7 @@
<sql-case id="select_pagination_with_limit_with_back_quotes" value="SELECT i.* FROM `t_order` o JOIN `t_order_item` i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.`user_id` IN (?, ?) AND o.`order_id` BETWEEN ? AND ? ORDER BY i.item_id DESC LIMIT ?, ?" db-types="MySQL" />
<sql-case id="select_pagination_with_limit_and_offset_keyword" value="SELECT i.* FROM `t_order` o JOIN `t_order_item` i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.`user_id` IN (?, ?) AND o.`order_id` BETWEEN ? AND ? ORDER BY i.item_id DESC LIMIT ? OFFSET ?" db-types="MySQL" />
<sql-case id="select_pagination_with_offset_and_limit" value="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ? ORDER BY i.item_id DESC OFFSET ? LIMIT ?" db-types="PostgreSQL" />
<sql-case id="select_pagination_with_offset_and_limit_all" value="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ? ORDER BY i.item_id DESC OFFSET ? LIMIT ALL" db-types="PostgreSQL" />
<sql-case id="select_pagination_with_top_for_greater_than" value="SELECT * FROM (SELECT TOP (?) row_number() OVER (ORDER BY i.item_id DESC) AS rownum_, i.item_id, o.order_id as order_id, o.status as status, o.user_id as user_id FROM t_order o JOIN t_order_item i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ?) AS row_ WHERE row_.rownum_ &gt; ?" db-types="SQLServer" />
<sql-case id="select_pagination_with_top_for_greater_than_and_equal" value="SELECT * FROM (SELECT TOP (?) row_number() OVER (ORDER BY i.item_id DESC) AS rownum_, i.item_id, o.order_id as order_id, o.status as status, o.user_id as user_id FROM t_order o JOIN t_order_item i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ?) AS row_ WHERE row_.rownum_ &gt;= ?" db-types="SQLServer" />
<sql-case id="select_pagination_with_row_number_for_greater_than" value="SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT order0_.order_id as order_id, order0_.status as status, order0_.user_id as user_id FROM t_order order0_ JOIN t_order_item i ON order0_.user_id = i.user_id AND order0_.order_id = i.order_id WHERE order0_.user_id IN (?, ?) AND order0_.order_id BETWEEN ? AND ? ORDER BY i.item_id DESC) row_ WHERE rownum &lt;= ?) t WHERE t.rownum_ &gt; ?" db-types="Oracle" />
......
......@@ -150,11 +150,11 @@ havingClause
;
limitClause
: limitRowCountSyntax_ limitOffsetSyntax_?
| limitOffsetSyntax_ limitRowCountSyntax_?
: limitRowCountSyntax limitOffsetSyntax?
| limitOffsetSyntax limitRowCountSyntax?
;
limitRowCountSyntax_
limitRowCountSyntax
: LIMIT (ALL | limitRowCount)
;
......@@ -162,7 +162,7 @@ limitRowCount
: numberLiterals | parameterMarker
;
limitOffsetSyntax_
limitOffsetSyntax
: OFFSET limitOffset (ROW | ROWS)?
;
......
......@@ -406,31 +406,32 @@ public final class PostgreSQLDMLVisitor extends PostgreSQLVisitor {
@Override
public ASTNode visitLimitClause(final LimitClauseContext ctx) {
if (null != ctx.limitRowCountSyntax_() && null != ctx.limitOffsetSyntax_()) {
if (null != ctx.limitRowCountSyntax() && null != ctx.limitOffsetSyntax()) {
return isRowCountBeforeOffset(ctx) ? createLimitSegmentWhenRowCountBeforeOffset(ctx) : createLimitSegmentWhenRowCountAfterOffset(ctx);
}
return createLimitSegmentWhenRowCountOrOffsetAbsent(ctx);
}
private boolean isRowCountBeforeOffset(final LimitClauseContext ctx) {
return ctx.limitRowCountSyntax_().getStart().getStartIndex() < ctx.limitOffsetSyntax_().getStart().getStartIndex();
return ctx.limitRowCountSyntax().getStart().getStartIndex() < ctx.limitOffsetSyntax().getStart().getStartIndex();
}
private LimitSegment createLimitSegmentWhenRowCountBeforeOffset(final LimitClauseContext ctx) {
LimitValueSegment rowCount = (LimitValueSegment) visit(ctx.limitRowCountSyntax_().limitRowCount());
LimitValueSegment offset = (LimitValueSegment) visit(ctx.limitOffsetSyntax_().limitOffset());
LimitValueSegment rowCount = null == ctx.limitRowCountSyntax().limitRowCount() ? null : (LimitValueSegment) visit(ctx.limitRowCountSyntax().limitRowCount());
LimitValueSegment offset = (LimitValueSegment) visit(ctx.limitOffsetSyntax().limitOffset());
return new LimitSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), offset, rowCount);
}
private LimitSegment createLimitSegmentWhenRowCountAfterOffset(final LimitClauseContext ctx) {
LimitValueSegment offset = (LimitValueSegment) visit(ctx.limitOffsetSyntax_().limitOffset());
LimitValueSegment rowCount = (LimitValueSegment) visit(ctx.limitRowCountSyntax_().limitRowCount());
LimitValueSegment offset = (LimitValueSegment) visit(ctx.limitOffsetSyntax().limitOffset());
LimitValueSegment rowCount = null == ctx.limitRowCountSyntax().limitRowCount() ? null : (LimitValueSegment) visit(ctx.limitRowCountSyntax().limitRowCount());
return new LimitSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), offset, rowCount);
}
private LimitSegment createLimitSegmentWhenRowCountOrOffsetAbsent(final LimitClauseContext ctx) {
LimitValueSegment rowCount = null == ctx.limitRowCountSyntax_() ? null : (LimitValueSegment) visit(ctx.limitRowCountSyntax_().limitRowCount());
LimitValueSegment offset = null == ctx.limitOffsetSyntax_() ? null : (LimitValueSegment) visit(ctx.limitOffsetSyntax_().limitOffset());
LimitValueSegment rowCount = null == ctx.limitRowCountSyntax() || null == ctx.limitRowCountSyntax().limitRowCount()
? null : (LimitValueSegment) visit(ctx.limitRowCountSyntax().limitRowCount());
LimitValueSegment offset = null == ctx.limitOffsetSyntax() ? null : (LimitValueSegment) visit(ctx.limitOffsetSyntax().limitOffset());
return new LimitSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), offset, rowCount);
}
......
......@@ -296,6 +296,50 @@
</limit>
</select>
<select sql-case-id="select_pagination_with_offset_and_limit_all" parameters="1, 2, 9, 10, 5">
<table name="t_order" alias="o" start-index="16" stop-index="22" />
<table name="t_order_item" alias="i" start-index="31" stop-index="42" />
<projections start-index="7" stop-index="9">
<shorthand-projection start-index="7" stop-index="9">
<owner name="i" start-index="7" stop-index="7" />
</shorthand-projection>
</projections>
<where parameters-count="5" start-index="99" stop-index="154" literal-stop-index="155">
<and-predicate>
<predicate start-index="105" stop-index="123">
<column-left-value name="user_id" start-index="105" stop-index="113">
<owner name="o" start-index="105" stop-index="105" />
</column-left-value>
<in-right-value>
<parameter-marker-expression value="0" />
<parameter-marker-expression value="1" />
<literal-expression value="1" />
<literal-expression value="2" />
</in-right-value>
</predicate>
<predicate start-index="129" stop-index="154" literal-stop-index="155">
<column-left-value name="order_id" start-index="129" stop-index="138">
<owner name="o" start-index="129" stop-index="129" />
</column-left-value>
<between-right-value>
<between-parameter-marker-expression value="2" />
<between-literal-expression value="9" />
<and-parameter-marker-expression value="3" />
<and-literal-expression value="10" />
</between-right-value>
</predicate>
</and-predicate>
</where>
<order-by>
<column-item name="item_id" order-direction="DESC">
<owner name="i" start-index="165" stop-index="165" literal-start-index="166" literal-stop-index="166" />
</column-item>
</order-by>
<limit start-index="180" stop-index="197" literal-start-index="181" literal-stop-index="198">
<offset value="5" parameter-index="4" start-index="187" stop-index="187" literal-start-index="188" literal-stop-index="188" />
</limit>
</select>
<select sql-case-id="select_pagination_with_top_for_greater_than" parameters="3, 1, 2, 9, 10, 6">
<table name="t_order" alias="o" start-index="167" stop-index="173" />
<table name="t_order_item" alias="i" start-index="182" stop-index="193" />
......
......@@ -294,6 +294,50 @@
</limit>
</select>
<select sql-case-id="select_pagination_with_offset_and_limit_all" parameters="1, 2, 9, 10, 5">
<table name="t_order" alias="o" start-index="16" stop-index="22" />
<table name="t_order_item" alias="i" start-index="31" stop-index="42" />
<projections start-index="7" stop-index="9">
<shorthand-projection start-index="7" stop-index="9">
<owner name="i" start-index="7" stop-index="7" />
</shorthand-projection>
</projections>
<where parameters-count="4" start-index="99" stop-index="154" literal-stop-index="155">
<and-predicate>
<predicate start-index="105" stop-index="123">
<column-left-value name="user_id" start-index="105" stop-index="113">
<owner name="o" start-index="105" stop-index="105" />
</column-left-value>
<in-right-value>
<parameter-marker-expression value="0" />
<parameter-marker-expression value="1" />
<literal-expression value="1" />
<literal-expression value="2" />
</in-right-value>
</predicate>
<predicate start-index="129" stop-index="154" literal-stop-index="155">
<column-left-value name="order_id" start-index="129" stop-index="138">
<owner name="o" start-index="129" stop-index="129" />
</column-left-value>
<between-right-value>
<between-parameter-marker-expression value="2" />
<between-literal-expression value="9" />
<and-parameter-marker-expression value="3" />
<and-literal-expression value="10" />
</between-right-value>
</predicate>
</and-predicate>
</where>
<order-by>
<column-item name="item_id" order-direction="DESC">
<owner name="i" start-index="165" stop-index="165" literal-start-index="166" literal-stop-index="166" />
</column-item>
</order-by>
<limit start-index="180" stop-index="197" literal-start-index="181" literal-stop-index="198">
<offset value="5" parameter-index="4" start-index="187" stop-index="187" literal-start-index="188" literal-stop-index="188" />
</limit>
</select>
<select sql-case-id="select_pagination_with_top_for_greater_than" parameters="3, 1, 2, 9, 10, 6">
<table name="t_order" alias="o" start-index="167" stop-index="173" />
<table name="t_order_item" alias="i" start-index="182" stop-index="193" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册