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.dml.SelectStatementContext;
22 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.NumberLiteralPaginationValueSegment;
23 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.PaginationValueSegment;
24 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.ParameterMarkerPaginationValueSegment;
25 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitValueSegment;
26 import org.apache.shardingsphere.sql.parser.sql.common.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 ? 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 return obj instanceof Long ? (long) obj : (int) obj;
59 }
60 if (paginationValueSegment instanceof ExpressionRowNumberValueSegment) {
61 return ((ExpressionRowNumberValueSegment) paginationValueSegment).getValue(params);
62 }
63 return ((NumberLiteralPaginationValueSegment) paginationValueSegment).getValue();
64 }
65
66
67
68
69
70
71 public Optional<PaginationValueSegment> getOffsetSegment() {
72 return Optional.ofNullable(offsetSegment);
73 }
74
75
76
77
78
79
80 public Optional<PaginationValueSegment> getRowCountSegment() {
81 return Optional.ofNullable(rowCountSegment);
82 }
83
84
85
86
87
88
89 public long getActualOffset() {
90 if (null == offsetSegment) {
91 return 0L;
92 }
93 return offsetSegment.isBoundOpened() ? actualOffset - 1 : actualOffset;
94 }
95
96
97
98
99
100
101 public Optional<Long> getActualRowCount() {
102 if (null == rowCountSegment) {
103 return Optional.empty();
104 }
105 return Optional.of(rowCountSegment.isBoundOpened() ? actualRowCount + 1L : actualRowCount);
106 }
107
108
109
110
111
112
113 public Optional<Integer> getOffsetParameterIndex() {
114
115 return offsetSegment instanceof ParameterMarkerPaginationValueSegment ? Optional.of(((ParameterMarkerPaginationValueSegment) offsetSegment).getParameterIndex()) : Optional.empty();
116 }
117
118
119
120
121
122
123 public Optional<Integer> getRowCountParameterIndex() {
124
125 return rowCountSegment instanceof ParameterMarkerPaginationValueSegment
126 ? Optional.of(((ParameterMarkerPaginationValueSegment) rowCountSegment).getParameterIndex())
127 : Optional.empty();
128 }
129
130
131
132
133
134
135 public long getRevisedOffset() {
136 return 0L;
137 }
138
139
140
141
142
143
144
145 public long getRevisedRowCount(final SelectStatementContext selectStatementContext) {
146 if (isMaxRowCount(selectStatementContext)) {
147 return Integer.MAX_VALUE;
148 }
149 return rowCountSegment instanceof LimitValueSegment ? actualOffset + actualRowCount : actualRowCount;
150 }
151
152 private boolean isMaxRowCount(final SelectStatementContext selectStatementContext) {
153 return (!selectStatementContext.getGroupByContext().getItems().isEmpty()
154 || !selectStatementContext.getProjectionsContext().getAggregationProjections().isEmpty()) && !selectStatementContext.isSameGroupByAndOrderByItems();
155 }
156 }