Skip to content

Commit 0815416

Browse files
committed
refactor(sys): modify stmt2 bind
1 parent baf0997 commit 0815416

File tree

1 file changed

+164
-54
lines changed

1 file changed

+164
-54
lines changed

taos-ws-sys/src/native/stmt2.rs

Lines changed: 164 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct TAOS_STMT2_OPTION {
3030
}
3131

3232
#[repr(C)]
33+
#[derive(Clone, Debug)]
3334
#[allow(non_camel_case_types)]
3435
pub struct TAOS_STMT2_BIND {
3536
pub buffer_type: c_int,
@@ -95,192 +96,194 @@ impl TAOS_STMT2_BIND {
9596
let num = self.num as usize;
9697
let is_nulls = unsafe { slice::from_raw_parts(self.is_null, num) };
9798
let lens = unsafe { slice::from_raw_parts(self.length, num) };
99+
let len = *lens.iter().max().unwrap() as usize;
98100

99-
let mut len = 0;
100-
for l in lens {
101-
len = len.max(*l);
102-
}
101+
trace!("to_column_view, is_nulls: {is_nulls:?}, lens: {lens:?}, max_len: {len}");
103102

104103
match self.ty() {
105104
Ty::Bool => {
105+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const bool, num) };
106106
let mut vals = vec![None; num];
107107
for i in 0..num {
108108
if is_nulls[i] == 0 {
109-
let val = unsafe { *(self.buffer.add(i) as *const _) };
110-
vals[i] = Some(val);
109+
vals[i] = Some(slice[i]);
111110
}
112111
}
113112
ColumnView::from_bools(vals)
114113
}
115114
Ty::TinyInt => {
115+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const i8, num) };
116116
let mut vals = vec![None; num];
117117
for i in 0..num {
118118
if is_nulls[i] == 0 {
119-
let val = unsafe { *(self.buffer.add(i) as *const _) };
120-
vals[i] = Some(val);
119+
vals[i] = Some(slice[i]);
121120
}
122121
}
123122
ColumnView::from_tiny_ints(vals)
124123
}
125124
Ty::SmallInt => {
125+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const i16, num) };
126126
let mut vals = vec![None; num];
127127
for i in 0..num {
128128
if is_nulls[i] == 0 {
129-
let val = unsafe { *(self.buffer.add(i) as *const _) };
130-
vals[i] = Some(val);
129+
vals[i] = Some(slice[i]);
131130
}
132131
}
133132
ColumnView::from_small_ints(vals)
134133
}
135134
Ty::Int => {
135+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const i32, num) };
136136
let mut vals = vec![None; num];
137137
for i in 0..num {
138138
if is_nulls[i] == 0 {
139-
let val = unsafe { *(self.buffer.add(i) as *const _) };
140-
vals[i] = Some(val);
139+
vals[i] = Some(slice[i]);
141140
}
142141
}
143142
ColumnView::from_ints(vals)
144143
}
145144
Ty::BigInt => {
145+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const i64, num) };
146146
let mut vals = vec![None; num];
147147
for i in 0..num {
148148
if is_nulls[i] == 0 {
149-
let val = unsafe { *(self.buffer.add(i) as *const _) };
150-
vals[i] = Some(val);
149+
vals[i] = Some(slice[i]);
151150
}
152151
}
153152
ColumnView::from_big_ints(vals)
154153
}
155154
Ty::UTinyInt => {
155+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u8, num) };
156156
let mut vals = vec![None; num];
157157
for i in 0..num {
158158
if is_nulls[i] == 0 {
159-
let val = unsafe { *(self.buffer.add(i) as *const _) };
160-
vals[i] = Some(val);
159+
vals[i] = Some(slice[i]);
161160
}
162161
}
163162
ColumnView::from_unsigned_tiny_ints(vals)
164163
}
165164
Ty::USmallInt => {
165+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u16, num) };
166166
let mut vals = vec![None; num];
167167
for i in 0..num {
168168
if is_nulls[i] == 0 {
169-
let val = unsafe { *(self.buffer.add(i) as *const _) };
170-
vals[i] = Some(val);
169+
vals[i] = Some(slice[i]);
171170
}
172171
}
173172
ColumnView::from_unsigned_small_ints(vals)
174173
}
175174
Ty::UInt => {
175+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u32, num) };
176176
let mut vals = vec![None; num];
177177
for i in 0..num {
178178
if is_nulls[i] == 0 {
179-
let val = unsafe { *(self.buffer.add(i) as *const _) };
180-
vals[i] = Some(val);
179+
vals[i] = Some(slice[i]);
181180
}
182181
}
183182
ColumnView::from_unsigned_ints(vals)
184183
}
185184
Ty::UBigInt => {
185+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u64, num) };
186186
let mut vals = vec![None; num];
187187
for i in 0..num {
188188
if is_nulls[i] == 0 {
189-
let val = unsafe { *(self.buffer.add(i) as *const _) };
190-
vals[i] = Some(val);
189+
vals[i] = Some(slice[i]);
191190
}
192191
}
193192
ColumnView::from_unsigned_big_ints(vals)
194193
}
195194
Ty::Float => {
195+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const f32, num) };
196196
let mut vals = vec![None; num];
197197
for i in 0..num {
198198
if is_nulls[i] == 0 {
199-
let val = unsafe { *(self.buffer.add(i) as *const _) };
200-
vals[i] = Some(val);
199+
vals[i] = Some(slice[i]);
201200
}
202201
}
203202
ColumnView::from_floats(vals)
204203
}
205204
Ty::Double => {
205+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const f64, num) };
206206
let mut vals = vec![None; num];
207207
for i in 0..num {
208208
if is_nulls[i] == 0 {
209-
let val = unsafe { *(self.buffer.add(i) as *const _) };
210-
vals[i] = Some(val);
209+
vals[i] = Some(slice[i]);
211210
}
212211
}
213212
ColumnView::from_doubles(vals)
214213
}
215214
Ty::Timestamp => {
215+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const i64, num) };
216216
let mut vals = vec![None; num];
217217
for i in 0..num {
218218
if is_nulls[i] == 0 {
219-
let val = unsafe { *(self.buffer.add(i) as *const _) };
220-
vals[i] = Some(val);
219+
vals[i] = Some(slice[i]);
221220
}
222221
}
223222
ColumnView::from_millis_timestamp(vals)
224223
}
225224
Ty::VarChar => {
225+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u8, len * num) };
226226
let mut vals = vec![None; num];
227227
for i in 0..num {
228228
if is_nulls[i] == 0 {
229-
let slice = unsafe {
230-
slice::from_raw_parts(self.buffer.add(i) as *const _, len as _)
231-
};
232-
let val = unsafe { str::from_utf8_unchecked(slice) };
233-
vals[i] = Some(val);
229+
let start = i * len;
230+
let end = start + lens[i] as usize;
231+
let bytes = &slice[start..end];
232+
vals[i] = unsafe { Some(str::from_utf8_unchecked(bytes)) };
234233
}
235234
}
236235
ColumnView::from_varchar::<&str, _, _, _>(vals)
237236
}
238237
Ty::NChar => {
238+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u8, len * num) };
239239
let mut vals = vec![None; num];
240240
for i in 0..num {
241241
if is_nulls[i] == 0 {
242-
let slice = unsafe {
243-
slice::from_raw_parts(self.buffer.add(i) as *const _, len as _)
244-
};
245-
let val = unsafe { str::from_utf8_unchecked(slice) };
246-
vals[i] = Some(val);
242+
let start = i * len;
243+
let end = start + lens[i] as usize;
244+
let bytes = &slice[start..end];
245+
vals[i] = unsafe { Some(str::from_utf8_unchecked(bytes)) };
247246
}
248247
}
249248
ColumnView::from_nchar::<&str, _, _, _>(vals)
250249
}
251250
Ty::Json => {
251+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u8, len * num) };
252252
let mut vals = vec![None; num];
253253
for i in 0..num {
254254
if is_nulls[i] == 0 {
255-
let slice = unsafe {
256-
slice::from_raw_parts(self.buffer.add(i) as *const _, len as _)
257-
};
258-
let val = serde_json::from_slice(slice).unwrap();
259-
vals[i] = Some(val);
255+
let start = i * len;
256+
let end = start + lens[i] as usize;
257+
let bytes = &slice[start..end];
258+
vals[i] = serde_json::from_slice(bytes).unwrap();
260259
}
261260
}
262261
ColumnView::from_json::<&str, _, _, _>(vals)
263262
}
264263
Ty::VarBinary => {
264+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u8, len * num) };
265265
let mut vals = vec![None; num];
266266
for i in 0..num {
267267
if is_nulls[i] == 0 {
268-
let slice = unsafe {
269-
slice::from_raw_parts(self.buffer.add(i) as *const _, len as _)
270-
};
271-
vals[i] = Some(slice);
268+
if is_nulls[i] == 0 {
269+
let start = i * len;
270+
let end = start + lens[i] as usize;
271+
let val = &slice[start..end];
272+
vals[i] = Some(val);
273+
}
272274
}
273275
}
274276
ColumnView::from_bytes::<&[u8], _, _, _>(vals)
275277
}
276278
Ty::Geometry => {
279+
let slice = unsafe { slice::from_raw_parts(self.buffer as *const u8, len * num) };
277280
let mut vals = vec![None; num];
278281
for i in 0..num {
279282
if is_nulls[i] == 0 {
280-
let slice = unsafe {
281-
slice::from_raw_parts(self.buffer.add(i) as *const _, len as _)
282-
};
283-
vals[i] = Some(slice);
283+
let start = i * len;
284+
let end = start + lens[i] as usize;
285+
let val = &slice[start..end];
286+
vals[i] = Some(val);
284287
}
285288
}
286289
ColumnView::from_geobytes::<&[u8], _, _, _>(vals)
@@ -485,6 +488,8 @@ pub unsafe extern "C" fn taos_stmt2_bind_param(
485488
};
486489

487490
let params = bindv.to_bind_params(stmt2);
491+
trace!("taos_stmt2_bind_param, params: {params:?}");
492+
488493
if let Err(err) = stmt2.bind(&params) {
489494
error!("stmt2 bind failed, err: {err:?}");
490495
maybe_err.with_err(Some(TaosError::new(err.code(), &err.to_string())));
@@ -571,15 +576,15 @@ mod tests {
571576
let code = taos_stmt2_prepare(stmt2, sql.as_ptr(), len as _);
572577
assert_eq!(code, 0);
573578

574-
let mut buffer = vec![1739456248];
579+
let mut buffer = vec![1739456248i64];
575580
let mut length = vec![8];
576581
let mut is_null = vec![0];
577582
let ts = TAOS_STMT2_BIND {
578583
buffer_type: Ty::Timestamp as _,
579584
buffer: buffer.as_mut_ptr() as _,
580585
length: length.as_mut_ptr(),
581586
is_null: is_null.as_mut_ptr(),
582-
num: 1,
587+
num: buffer.len() as _,
583588
};
584589

585590
let mut buffer = vec![2];
@@ -590,7 +595,7 @@ mod tests {
590595
buffer: buffer.as_mut_ptr() as _,
591596
length: length.as_mut_ptr(),
592597
is_null: is_null.as_mut_ptr(),
593-
num: 1,
598+
num: buffer.len() as _,
594599
};
595600

596601
let mut col = vec![ts, c1];
@@ -606,4 +611,109 @@ mod tests {
606611
assert_eq!(code, 0);
607612
}
608613
}
614+
615+
#[test]
616+
fn test_taos_stmt2_bind_param() {
617+
unsafe {
618+
let taos = test_connect();
619+
test_exec_many(
620+
taos,
621+
&[
622+
"drop database if exists test_1739502440",
623+
"create database test_1739502440",
624+
"use test_1739502440",
625+
"create table s0 (ts timestamp, c1 int, c2 varchar(20)) tags (t1 int)",
626+
],
627+
);
628+
629+
let mut option = TAOS_STMT2_OPTION {
630+
reqid: 1001,
631+
singleStbInsert: true,
632+
singleTableBindOnce: false,
633+
asyncExecFn: mem::transmute::<*const (), __taos_async_fn_t>(ptr::null()),
634+
userdata: ptr::null_mut(),
635+
};
636+
let stmt2 = taos_stmt2_init(taos, &mut option);
637+
assert!(!stmt2.is_null());
638+
639+
let sql = c"insert into ? using s0 tags(?) values(?, ?, ?)";
640+
let len = sql.to_bytes().len();
641+
let code = taos_stmt2_prepare(stmt2, sql.as_ptr(), len as _);
642+
assert_eq!(code, 0);
643+
644+
let tbname1 = c"d0";
645+
let tbname2 = c"d1";
646+
let mut tbnames = vec![tbname1.as_ptr() as _, tbname2.as_ptr() as _];
647+
648+
let mut buffer = vec![1999];
649+
let mut length = vec![4];
650+
let mut is_null = vec![0];
651+
let t1 = TAOS_STMT2_BIND {
652+
buffer_type: Ty::Int as _,
653+
buffer: buffer.as_mut_ptr() as _,
654+
length: length.as_mut_ptr(),
655+
is_null: is_null.as_mut_ptr(),
656+
num: buffer.len() as _,
657+
};
658+
659+
let mut tag1 = vec![t1];
660+
let mut tag2 = tag1.clone();
661+
let mut tags = vec![tag1.as_mut_ptr(), tag2.as_mut_ptr()];
662+
663+
let mut buffer = vec![
664+
1739521477831i64,
665+
1739521477832,
666+
1739521477833,
667+
1739521477834,
668+
];
669+
let mut length = vec![8, 8, 8, 8];
670+
let mut is_null = vec![0, 0, 0, 0];
671+
let ts = TAOS_STMT2_BIND {
672+
buffer_type: Ty::Timestamp as _,
673+
buffer: buffer.as_mut_ptr() as _,
674+
length: length.as_mut_ptr(),
675+
is_null: is_null.as_mut_ptr(),
676+
num: buffer.len() as _,
677+
};
678+
679+
let mut buffer = vec![1, 2, 3, 4];
680+
let mut length = vec![4, 4, 4, 4];
681+
let mut is_null = vec![0, 0, 0, 0];
682+
let c1 = TAOS_STMT2_BIND {
683+
buffer_type: Ty::Int as _,
684+
buffer: buffer.as_mut_ptr() as _,
685+
length: length.as_mut_ptr(),
686+
is_null: is_null.as_mut_ptr(),
687+
num: buffer.len() as _,
688+
};
689+
690+
let mut buffer = vec![
691+
104u8, 101, 108, 108, 111, 0, 0, 0, 0, 0, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0,
692+
104, 101, 108, 108, 111, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
693+
];
694+
let mut length = vec![5, 5, 10, 0];
695+
let mut is_null = vec![0, 0, 0, 1];
696+
let c2 = TAOS_STMT2_BIND {
697+
buffer_type: Ty::VarChar as _,
698+
buffer: buffer.as_mut_ptr() as _,
699+
length: length.as_mut_ptr(),
700+
is_null: is_null.as_mut_ptr(),
701+
num: length.len() as _,
702+
};
703+
704+
let mut col1 = vec![ts, c1, c2];
705+
let mut col2 = col1.clone();
706+
let mut cols = vec![col1.as_mut_ptr(), col2.as_mut_ptr()];
707+
708+
let mut bindv = TAOS_STMT2_BINDV {
709+
count: tbnames.len() as _,
710+
tbnames: tbnames.as_mut_ptr(),
711+
tags: tags.as_mut_ptr(),
712+
bind_cols: cols.as_mut_ptr(),
713+
};
714+
715+
let code = taos_stmt2_bind_param(stmt2, &mut bindv, -1);
716+
assert_eq!(code, 0);
717+
}
718+
}
609719
}

0 commit comments

Comments
 (0)