23
23
import io .dingodb .codec .KeyValueCodec ;
24
24
import io .dingodb .common .CommonId ;
25
25
import io .dingodb .common .CoprocessorV2 ;
26
+ import io .dingodb .common .log .LogUtils ;
26
27
import io .dingodb .common .type .DingoType ;
27
28
import io .dingodb .common .type .TupleMapping ;
28
29
import io .dingodb .exec .dag .Vertex ;
29
30
import io .dingodb .exec .expr .DingoCompileContext ;
30
31
import io .dingodb .exec .utils .SchemaWrapperUtils ;
32
+ import io .dingodb .exec .utils .relop .RelOpMappingVisitor ;
33
+ import io .dingodb .exec .utils .relop .RelOpSelectionVisitor ;
34
+ import io .dingodb .exec .utils .relop .SelectionFlag ;
35
+ import io .dingodb .exec .utils .relop .SelectionObj ;
31
36
import io .dingodb .expr .coding .CodingFlag ;
32
37
import io .dingodb .expr .coding .RelOpCoder ;
33
38
import io .dingodb .expr .common .type .TupleType ;
34
39
import io .dingodb .expr .rel .RelOp ;
35
40
import io .dingodb .meta .entity .Table ;
36
41
import lombok .Getter ;
42
+ import lombok .extern .slf4j .Slf4j ;
37
43
38
44
import java .io .ByteArrayOutputStream ;
39
45
import java .util .Arrays ;
46
+ import java .util .Comparator ;
47
+ import java .util .HashSet ;
40
48
import java .util .List ;
49
+ import java .util .Set ;
41
50
import java .util .stream .Collectors ;
42
51
import java .util .stream .IntStream ;
43
52
53
+ @ Slf4j
44
54
@ Getter
45
55
public class TxnIndexRangeScanParam extends ScanWithRelOpParam {
46
56
@@ -68,6 +78,8 @@ public class TxnIndexRangeScanParam extends ScanWithRelOpParam {
68
78
protected List <Integer > mapList ;
69
79
@ JsonProperty ("selection" )
70
80
private TupleMapping selection ;
81
+ @ JsonProperty ("isAutoCommit" )
82
+ private final boolean isAutoCommit ;
71
83
72
84
public TxnIndexRangeScanParam (CommonId indexTableId ,
73
85
CommonId tableId ,
@@ -82,9 +94,10 @@ public TxnIndexRangeScanParam(CommonId indexTableId,
82
94
RelOp relOp ,
83
95
boolean pushDown ,
84
96
TupleMapping selection ,
85
- int limit ) {
97
+ int limit ,
98
+ boolean isAutoCommit ) {
86
99
super (tableId , index .tupleType (), keyMapping , relOp , outputSchema ,
87
- pushDown , index .getVersion (), limit , table .getCodecVersion ());
100
+ pushDown , index .getVersion (), limit , table .getCodecVersion (), selection . stream (). boxed (). collect ( Collectors . toList ()) );
88
101
this .indexSchema = index .tupleType ();
89
102
this .indexTableId = indexTableId ;
90
103
this .isLookup = isLookup ;
@@ -94,6 +107,7 @@ public TxnIndexRangeScanParam(CommonId indexTableId,
94
107
this .scanTs = scanTs ;
95
108
this .timeout = timeout ;
96
109
this .selection = selection ;
110
+ this .isAutoCommit = isAutoCommit ;
97
111
this .codec = CodecService .getDefault ().createKeyValueCodec (
98
112
index .getCodecVersion (), index .version , index .tupleType (), index .keyMapping ());
99
113
if (isLookup ) {
@@ -109,16 +123,48 @@ public void init(Vertex vertex) {
109
123
if (relOp == null ) {
110
124
return ;
111
125
}
112
- relOp = relOp .compile (new DingoCompileContext (
126
+ RelOp relOpCompile = relOp .compile (new DingoCompileContext (
113
127
(TupleType ) indexSchema .getType (),
114
128
(TupleType ) vertex .getParasType ().getType ()
115
129
), config );
116
130
if (pushDown ) {
117
131
ByteArrayOutputStream os = new ByteArrayOutputStream ();
118
- if (RelOpCoder .INSTANCE .visit (relOp , os ) == CodingFlag .OK ) {
132
+ if (RelOpCoder .INSTANCE .visit (relOpCompile , os ) == CodingFlag .OK ) {
119
133
List <Integer > selection = IntStream .range (0 , indexSchema .fieldCount ())
120
134
.boxed ()
121
135
.collect (Collectors .toList ());
136
+ Set <Integer > selections = new HashSet <>();
137
+ SelectionObj selectionObj = new SelectionObj (selections , true );
138
+ boolean isSelection = false ;
139
+ if (isAutoCommit () && RelOpSelectionVisitor .INSTANCE .visit (relOp , selectionObj ) == SelectionFlag .OK
140
+ && selectionObj .isProject () && selections .size () != selection .size ()) {
141
+ try {
142
+ selection .clear ();
143
+ selection .addAll (selections );
144
+ selection .sort (Comparator .naturalOrder ());
145
+ relOpCompile = RelOpMappingVisitor .INSTANCE .visit (relOp , selection );
146
+ LogUtils .debug (log , "jobId:{}, new relOp: {}" , vertex .getTask ().getJobId (), relOpCompile );
147
+ isSelection = true ;
148
+ } catch (Exception e ) {
149
+ LogUtils .error (log , e .getMessage (), e );
150
+ selection = IntStream .range (0 , indexSchema .fieldCount ())
151
+ .boxed ()
152
+ .collect (Collectors .toList ());
153
+ }
154
+ } else {
155
+ LogUtils .debug (log , "jobId:{}, origin relOp: {}" , vertex .getTask ().getJobId (), relOp );
156
+ }
157
+ if (isSelection ) {
158
+ relOpCompile = relOpCompile .compile (new DingoCompileContext (
159
+ (TupleType ) indexSchema .select (TupleMapping .of (selection )).getType (),
160
+ (TupleType ) vertex .getParasType ().getType ()
161
+ ), config );
162
+ os = new ByteArrayOutputStream ();
163
+ if (RelOpCoder .INSTANCE .visit (relOpCompile , os ) != CodingFlag .OK ) {
164
+ relOp = relOpCompile ;
165
+ return ;
166
+ }
167
+ }
122
168
TupleMapping keyMapping = indexKeyMapping ();
123
169
TupleMapping outputKeyMapping = TupleMapping .of (new int []{});
124
170
coprocessor = CoprocessorV2 .builder ()
@@ -130,6 +176,7 @@ public void init(Vertex vertex) {
130
176
.build ();
131
177
}
132
178
}
179
+ relOp = relOpCompile ;
133
180
}
134
181
135
182
public TupleMapping indexKeyMapping () {
0 commit comments