1- use std:: ffi:: { c_char, c_int, c_ulong, c_void} ;
1+ use std:: ffi:: { c_char, c_int, c_ulong, c_void, CStr } ;
22
3- use taos_error:: Code ;
3+ use taos_error:: { Code , Error as RawError } ;
44use taos_query:: block_in_place_or_global;
5+ use taos_query:: stmt2:: Stmt2Bindable ;
56use taos_query:: util:: generate_req_id;
67use taos_ws:: { Stmt2 , Taos } ;
7- use tracing:: trace;
8+ use tracing:: { error , trace} ;
89
9- use crate :: native:: error:: { TaosError , TaosMaybeError } ;
10+ use crate :: native:: error:: {
11+ clear_error_info, format_errno, set_err_and_get_code, TaosError , TaosMaybeError ,
12+ } ;
1013use crate :: native:: { TaosResult , __taos_async_fn_t, TAOS , TAOS_RES } ;
1114
1215#[ allow( non_camel_case_types) ]
@@ -95,12 +98,42 @@ unsafe fn stmt2_init(taos: *mut TAOS, option: *mut TAOS_STMT2_OPTION) -> TaosRes
9598}
9699
97100#[ no_mangle]
98- pub extern "C" fn taos_stmt2_prepare (
101+ #[ tracing:: instrument( level = "trace" , ret) ]
102+ pub unsafe extern "C" fn taos_stmt2_prepare (
99103 stmt : * mut TAOS_STMT2 ,
100104 sql : * const c_char ,
101105 length : c_ulong ,
102106) -> c_int {
103- todo ! ( )
107+ match ( stmt as * mut TaosMaybeError < Stmt2 > ) . as_mut ( ) {
108+ Some ( maybe_err) => {
109+ let sql = if length > 0 {
110+ std:: str:: from_utf8_unchecked ( std:: slice:: from_raw_parts ( sql as _ , length as _ ) )
111+ } else {
112+ CStr :: from_ptr ( sql) . to_str ( ) . expect (
113+ "taos_stmt2_prepare with a sql len 0 means the input should always be valid utf-8" ,
114+ )
115+ } ;
116+
117+ if let Some ( errno) = maybe_err. errno ( ) {
118+ return format_errno ( errno) ;
119+ }
120+
121+ if let Err ( err) = maybe_err
122+ . deref_mut ( )
123+ . ok_or_else ( || RawError :: from_string ( "data is null" ) )
124+ . and_then ( |stmt2| stmt2. prepare ( sql) )
125+ {
126+ error ! ( "stmt2 prepare error, err: {err:?}" ) ;
127+ maybe_err. with_err ( Some ( TaosError :: new ( err. code ( ) , & err. to_string ( ) ) ) ) ;
128+ set_err_and_get_code ( TaosError :: new ( err. code ( ) , & err. to_string ( ) ) )
129+ } else {
130+ maybe_err. with_err ( None ) ;
131+ clear_error_info ( ) ;
132+ Code :: SUCCESS . into ( )
133+ }
134+ }
135+ None => set_err_and_get_code ( TaosError :: new ( Code :: INVALID_PARA , "stmt is invalid" ) ) ,
136+ }
104137}
105138
106139#[ no_mangle]
@@ -156,12 +189,22 @@ mod tests {
156189 use std:: { mem, ptr} ;
157190
158191 use super :: * ;
159- use crate :: native:: test_connect;
192+ use crate :: native:: { test_connect, test_exec_many } ;
160193
161194 #[ test]
162195 fn test_stmt2 ( ) {
163196 unsafe {
164197 let taos = test_connect ( ) ;
198+ test_exec_many (
199+ taos,
200+ & [
201+ "drop database if exists test_1739274502" ,
202+ "create database test_1739274502" ,
203+ "use test_1739274502" ,
204+ "create table t0 (ts timestamp, c1 int)" ,
205+ ] ,
206+ ) ;
207+
165208 let mut option = TAOS_STMT2_OPTION {
166209 reqid : 1001 ,
167210 singleStbInsert : true ,
@@ -171,6 +214,11 @@ mod tests {
171214 } ;
172215 let stmt2 = taos_stmt2_init ( taos, & mut option) ;
173216 assert ! ( !stmt2. is_null( ) ) ;
217+
218+ let sql = c"insert into t0 values(?, ?)" ;
219+ let len = sql. to_bytes ( ) . len ( ) ;
220+ let code = taos_stmt2_prepare ( stmt2, sql. as_ptr ( ) , len as _ ) ;
221+ assert_eq ! ( code, 0 ) ;
174222 }
175223 }
176224}
0 commit comments