@@ -25,6 +25,7 @@ use common_expression::types::NumberType;
25
25
use common_expression:: types:: StringType ;
26
26
use common_expression:: vectorize_with_builder_1_arg;
27
27
use common_expression:: vectorize_with_builder_2_arg;
28
+ use common_expression:: vectorize_with_builder_3_arg;
28
29
use common_expression:: vectorize_with_builder_4_arg;
29
30
use common_expression:: FunctionProperty ;
30
31
use common_expression:: FunctionRegistry ;
@@ -111,106 +112,111 @@ pub fn register(registry: &mut FunctionRegistry) {
111
112
) ;
112
113
registry. register_aliases ( "char_length" , & [ "character_length" ] ) ;
113
114
114
- registry. register_3_arg :: < StringType , NumberType < u64 > , StringType , StringType , _ , _ > (
115
+ registry. register_passthrough_nullable_3_arg :: < StringType , NumberType < u64 > , StringType , StringType , _ , _ > (
115
116
"lpad" ,
116
117
FunctionProperty :: default ( ) ,
117
118
|_, _, _| None ,
118
- |str : & [ u8 ] , l : u64 , pad : & [ u8 ] | {
119
- let mut buff: Vec < u8 > = vec ! [ ] ;
120
- if l != 0 {
121
- if l > str. len ( ) as u64 {
122
- let l = l - str. len ( ) as u64 ;
123
- while buff. len ( ) < l as usize {
124
- if buff. len ( ) + pad. len ( ) <= l as usize {
125
- buff. extend_from_slice ( pad) ;
119
+ vectorize_with_builder_3_arg :: < StringType , NumberType < u64 > , StringType , StringType > (
120
+ |s, pad_len, pad, output| {
121
+ let pad_len = pad_len as usize ;
122
+ if pad_len <= s. len ( ) {
123
+ output. put_slice ( & s[ ..pad_len] )
124
+ } else {
125
+ let mut remain_pad_len = pad_len - s. len ( ) ;
126
+ while remain_pad_len > 0 {
127
+ if remain_pad_len < pad. len ( ) {
128
+ output. put_slice ( & pad[ ..remain_pad_len] ) ;
129
+ remain_pad_len = 0 ;
126
130
} else {
127
- buff. extend_from_slice ( & pad[ 0 ..l as usize - buff. len ( ) ] )
131
+ output. put_slice ( pad) ;
132
+ remain_pad_len -= pad. len ( ) ;
128
133
}
129
134
}
130
- buff. extend_from_slice ( str) ;
131
- } else {
132
- buff. extend_from_slice ( & str[ 0 ..l as usize ] ) ;
135
+ output. put_slice ( s) ;
133
136
}
137
+ output. commit_row ( ) ;
138
+ Ok ( ( ) )
134
139
}
135
- buff
136
- } ,
140
+ ) ,
137
141
) ;
138
142
139
143
registry. register_passthrough_nullable_4_arg :: < StringType , NumberType < i64 > , NumberType < i64 > , StringType , StringType , _ , _ > (
140
- "insert" ,
141
- FunctionProperty :: default ( ) ,
142
- |_, _, _, _| None ,
143
- vectorize_with_builder_4_arg :: < StringType , NumberType < i64 > , NumberType < i64 > , StringType , StringType > (
144
- |srcstr, pos, len, substr, builder| {
145
- let mut values: Vec < u8 > = vec ! [ ] ;
146
-
147
- let sl = srcstr. len ( ) as i64 ;
148
- if pos < 1 || pos > sl {
149
- values. extend_from_slice ( srcstr) ;
144
+ "insert" ,
145
+ FunctionProperty :: default ( ) ,
146
+ |_, _, _, _| None ,
147
+ vectorize_with_builder_4_arg :: < StringType , NumberType < i64 > , NumberType < i64 > , StringType , StringType > (
148
+ |srcstr, pos, len, substr, output| {
149
+ let pos = pos as usize ;
150
+ let len = len as usize ;
151
+ if pos < 1 || pos > srcstr. len ( ) {
152
+ output. put_slice ( srcstr) ;
150
153
} else {
151
- let p = pos as usize - 1 ;
152
- values. extend_from_slice ( & srcstr[ 0 ..p] ) ;
153
- values. extend_from_slice ( substr) ;
154
- if len >= 0 && pos + len < sl {
155
- let l = len as usize ;
156
- values. extend_from_slice ( & srcstr[ p + l..] ) ;
154
+ let pos = pos - 1 ;
155
+ output. put_slice ( & srcstr[ 0 ..pos] ) ;
156
+ output. put_slice ( substr) ;
157
+ if pos + len < srcstr. len ( ) {
158
+ output. put_slice ( & srcstr[ ( pos + len) ..] ) ;
157
159
}
158
160
}
159
- builder. put_slice ( & values) ;
160
- builder. commit_row ( ) ;
161
- Ok ( ( ) )
161
+ output. commit_row ( ) ;
162
+ Ok ( ( ) )
162
163
} ) ,
163
- ) ;
164
+ ) ;
164
165
165
- registry. register_3_arg :: < StringType , NumberType < u64 > , StringType , StringType , _ , _ > (
166
+ registry. register_passthrough_nullable_3_arg :: < StringType , NumberType < u64 > , StringType , StringType , _ , _ > (
166
167
"rpad" ,
167
168
FunctionProperty :: default ( ) ,
168
169
|_, _, _| None ,
169
- |str : & [ u8 ] , l : u64 , pad : & [ u8 ] | {
170
- let mut buff: Vec < u8 > = vec ! [ ] ;
171
- if l != 0 {
172
- if l > str. len ( ) as u64 {
173
- buff. extend_from_slice ( str) ;
174
- while buff. len ( ) < l as usize {
175
- if buff. len ( ) + pad. len ( ) <= l as usize {
176
- buff. extend_from_slice ( pad) ;
177
- } else {
178
- buff. extend_from_slice ( & pad[ 0 ..l as usize - buff. len ( ) ] )
179
- }
170
+ vectorize_with_builder_3_arg :: < StringType , NumberType < u64 > , StringType , StringType > (
171
+ |s : & [ u8 ] , pad_len : u64 , pad : & [ u8 ] , output| {
172
+ let pad_len = pad_len as usize ;
173
+ if pad_len <= s. len ( ) {
174
+ output. put_slice ( & s[ ..pad_len] )
175
+ } else {
176
+ output. put_slice ( s) ;
177
+ let mut remain_pad_len = pad_len - s. len ( ) ;
178
+ while remain_pad_len > 0 {
179
+ if remain_pad_len < pad. len ( ) {
180
+ output. put_slice ( & pad[ ..remain_pad_len] ) ;
181
+ remain_pad_len = 0 ;
182
+ } else {
183
+ output. put_slice ( pad) ;
184
+ remain_pad_len -= pad. len ( ) ;
180
185
}
181
- } else {
182
- buff. extend_from_slice ( & str[ 0 ..l as usize ] ) ;
183
186
}
184
187
}
185
- buff
186
- } ,
188
+ output. commit_row ( ) ;
189
+ Ok ( ( ) )
190
+ } ) ,
187
191
) ;
188
192
189
- registry. register_3_arg :: < StringType , StringType , StringType , StringType , _ , _ > (
193
+ registry. register_passthrough_nullable_3_arg :: < StringType , StringType , StringType , StringType , _ , _ > (
190
194
"replace" ,
191
195
FunctionProperty :: default ( ) ,
192
196
|_, _, _| None ,
193
- |str , from , to| {
194
- let mut buf : Vec < u8 > = vec ! [ ] ;
197
+ vectorize_with_builder_3_arg :: < StringType , StringType , StringType , StringType > (
198
+ |str , from , to , output| {
195
199
if from. is_empty ( ) || from == to {
196
- buf. extend_from_slice ( str) ;
197
- return buf;
200
+ output. put_slice ( str) ;
201
+ output. commit_row ( ) ;
202
+ return Ok ( ( ) ) ;
198
203
}
199
204
let mut skip = 0 ;
200
205
for ( p, w) in str. windows ( from. len ( ) ) . enumerate ( ) {
201
206
if w == from {
202
- buf . extend_from_slice ( to) ;
207
+ output . put_slice ( to) ;
203
208
skip = from. len ( ) ;
204
209
} else if p + w. len ( ) == str. len ( ) {
205
- buf . extend_from_slice ( w) ;
210
+ output . put_slice ( w) ;
206
211
} else if skip > 1 {
207
212
skip -= 1 ;
208
213
} else {
209
- buf . extend_from_slice ( & w[ 0 ..1 ] ) ;
214
+ output . put_slice ( & w[ 0 ..1 ] ) ;
210
215
}
211
216
}
212
- buf
213
- } ,
217
+ output. commit_row ( ) ;
218
+ Ok ( ( ) )
219
+ } ) ,
214
220
) ;
215
221
216
222
registry. register_2_arg :: < StringType , StringType , NumberType < i8 > , _ , _ > (
0 commit comments