1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.infra.binder.context.segment.select.pagination;
19
20 import lombok.Getter;
21 import org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
22 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.NumberLiteralPaginationValueSegment;
23 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.PaginationValueSegment;
24 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.ParameterMarkerPaginationValueSegment;
25 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.limit.LimitValueSegment;
26 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.pagination.rownum.ExpressionRowNumberValueSegment;
27
28 import java.util.List;
29 import java.util.Optional;
30
31
32
33
34 public final class PaginationContext {
35
36 @Getter
37 private final boolean hasPagination;
38
39 private final PaginationValueSegment offsetSegment;
40
41 private final PaginationValueSegment rowCountSegment;
42
43 private final Long actualOffset;
44
45 private final Long actualRowCount;
46
47 public PaginationContext(final PaginationValueSegment offsetSegment, final PaginationValueSegment rowCountSegment, final List<Object> params) {
48 hasPagination = null != offsetSegment || null != rowCountSegment;
49 this.offsetSegment = offsetSegment;
50 this.rowCountSegment = rowCountSegment;
51 actualOffset = null == offsetSegment ? Long.valueOf(0L) : getValue(offsetSegment, params);
52 actualRowCount = null == rowCountSegment ? null : getValue(rowCountSegment, params);
53 }
54
55 private Long getValue(final PaginationValueSegment paginationValueSegment, final List<Object> params) {
56 if (paginationValueSegment instanceof ParameterMarkerPaginationValueSegment) {
57 Object obj = null == params || params.isEmpty() ? 0L : params.get(((ParameterMarkerPaginationValueSegment) paginationValueSegment).getParameterIndex());
58 if (null == obj) {
59 return null;
60 }
61 return obj instanceof Long ? (long) obj : (int) obj;
62 }
63 if (paginationValueSegment instanceof ExpressionRowNumberValueSegment) {
64 return ((ExpressionRowNumberValueSegment) paginationValueSegment).getValue(params);
65 }
66 return ((NumberLiteralPaginationValueSegment) paginationValueSegment).getValue();
67 }
68
69
70
71
72
73
74 public Optional<PaginationValueSegment> getOffsetSegment() {
75 return Optional.ofNullable(offsetSegment);
76 }
77
78
79
80
81
82
83 public Optional<PaginationValueSegment> getRowCountSegment() {
84 return Optional.ofNullable(rowCountSegment);
85 }
86
87
88
89
90
91
92 public long getActualOffset() {
93 if (null == offsetSegment) {
94 return 0L;
95 }
96 return offsetSegment.isBoundOpened() ? actualOffset - 1 : actualOffset;
97 }
98
99
100
101
102
103
104 public Optional<Long> getActualRowCount() {
105 if (null == rowCountSegment) {
106 return Optional.empty();
107 }
108 return Optional.of(rowCountSegment.isBoundOpened() ? actualRowCount + 1L : actualRowCount);
109 }
110
111
112
113
114
115
116 public Optional<Integer> getOffsetParameterIndex() {
117
118 return offsetSegment instanceof ParameterMarkerPaginationValueSegment ? Optional.of(((ParameterMarkerPaginationValueSegment) offsetSegment).getParameterIndex()) : Optional.empty();
119 }
120
121
122
123
124
125
126 public Optional<Integer> getRowCountParameterIndex() {
127
128 return rowCountSegment instanceof ParameterMarkerPaginationValueSegment
129 ? Optional.of(((ParameterMarkerPaginationValueSegment) rowCountSegment).getParameterIndex())
130 : Optional.empty();
131 }
132
133
134
135
136
137
138 public long getRevisedOffset() {
139 return 0L;
140 }
141
142
143
144
145
146
147
148 public long getRevisedRowCount(final SelectStatementContext selectStatementContext) {
149 if (isMaxRowCount(selectStatementContext)) {
150 return Integer.MAX_VALUE;
151 }
152 return rowCountSegment instanceof LimitValueSegment ? actualOffset + actualRowCount : actualRowCount;
153 }
154
155 private boolean isMaxRowCount(final SelectStatementContext selectStatementContext) {
156 return (!selectStatementContext.getGroupByContext().getItems().isEmpty()
157 || !selectStatementContext.getProjectionsContext().getAggregationProjections().isEmpty()) && !selectStatementContext.isSameGroupByAndOrderByItems();
158 }
159 }