@@ -488,6 +488,23 @@ sprintf_float_value(char *ptr, float value, const char *delim)
488488 sprintf (ptr , "%.15g%s" , value , delim );
489489}
490490
491+ static char *
492+ convert_bytea_to_string (char * from_data , int from_len , int lineno )
493+ {
494+ char * to_data ;
495+ int to_len = ecpg_hex_enc_len (from_len ) + 4 + 1 ; /* backslash + 'x' + quote + quote */
496+
497+ to_data = ecpg_alloc (to_len , lineno );
498+ if (!to_data )
499+ return NULL ;
500+
501+ strcpy (to_data , "'\\x" );
502+ ecpg_hex_encode (from_data , from_len , to_data + 3 );
503+ strcpy (to_data + 3 + ecpg_hex_enc_len (from_len ), "\'" );
504+
505+ return to_data ;
506+ }
507+
491508bool
492509ecpg_store_input (const int lineno , const bool force_indicator , const struct variable * var ,
493510 char * * tobeinserted_p , bool quote )
@@ -1433,6 +1450,36 @@ ecpg_build_params(struct statement *stmt)
14331450 */
14341451 else if (stmt -> command [position ] == '0' )
14351452 {
1453+ if (stmt -> statement_type == ECPGst_prepare ||
1454+ stmt -> statement_type == ECPGst_exec_with_exprlist )
1455+ {
1456+ /* Add double quote both side for embedding statement name. */
1457+ char * str = ecpg_alloc (strlen (tobeinserted ) + 2 + 1 , stmt -> lineno );
1458+ sprintf (str , "\"%s\"" , tobeinserted );
1459+ ecpg_free (tobeinserted );
1460+ tobeinserted = str ;
1461+ }
1462+ if (!insert_tobeinserted (position , 2 , stmt , tobeinserted ))
1463+ {
1464+ ecpg_free_params (stmt , false);
1465+ return false;
1466+ }
1467+ tobeinserted = NULL ;
1468+ }
1469+ else if (stmt -> statement_type == ECPGst_exec_with_exprlist )
1470+ {
1471+
1472+ if (binary_format )
1473+ {
1474+ char * p = convert_bytea_to_string (tobeinserted , binary_length , stmt -> lineno );
1475+ if (!p )
1476+ {
1477+ ecpg_free_params (stmt , false);
1478+ return false;
1479+ }
1480+ tobeinserted = p ;
1481+ }
1482+
14361483 if (!insert_tobeinserted (position , 2 , stmt , tobeinserted ))
14371484 {
14381485 ecpg_free_params (stmt , false);
@@ -1493,8 +1540,12 @@ ecpg_build_params(struct statement *stmt)
14931540 var = var -> next ;
14941541 }
14951542
1496- /* Check if there are unmatched things left. */
1497- if (next_insert (stmt -> command , position , stmt -> questionmarks , std_strings ) >= 0 )
1543+ /*
1544+ * Check if there are unmatched things left.
1545+ * PREPARE AS has no parameter. Check other statement.
1546+ */
1547+ if (stmt -> statement_type != ECPGst_prepare &&
1548+ next_insert (stmt -> command , position , stmt -> questionmarks , std_strings ) >= 0 )
14981549 {
14991550 ecpg_raise (stmt -> lineno , ECPG_TOO_FEW_ARGUMENTS ,
15001551 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS , NULL );
@@ -1560,8 +1611,18 @@ ecpg_execute(struct statement *stmt)
15601611 (const int * ) stmt -> paramlengths ,
15611612 (const int * ) stmt -> paramformats ,
15621613 0 );
1614+
15631615 ecpg_log ("ecpg_execute on line %d: using PQexecParams\n" , stmt -> lineno );
15641616 }
1617+
1618+ if (stmt -> statement_type == ECPGst_prepare )
1619+ {
1620+ if (! ecpg_register_prepared_stmt (stmt ))
1621+ {
1622+ ecpg_free_params (stmt , true);
1623+ return false;
1624+ }
1625+ }
15651626 }
15661627
15671628 ecpg_free_params (stmt , true);
@@ -1874,6 +1935,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
18741935 enum ECPGttype type ;
18751936 struct variable * * list ;
18761937 char * prepname ;
1938+ bool is_prepared_name_set ;
18771939
18781940 * stmt_out = NULL ;
18791941
@@ -1975,6 +2037,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
19752037 return false;
19762038 }
19772039 }
2040+ /* name of PREPARE AS will be set in loop of inlist */
19782041
19792042 stmt -> connection = con ;
19802043 stmt -> lineno = lineno ;
@@ -2004,6 +2067,8 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
20042067 *------
20052068 */
20062069
2070+ is_prepared_name_set = false;
2071+
20072072 list = & (stmt -> inlist );
20082073
20092074 type = va_arg (args , enum ECPGttype );
@@ -2092,6 +2157,12 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
20922157 * list = var ;
20932158 else
20942159 ptr -> next = var ;
2160+
2161+ if (!is_prepared_name_set && stmt -> statement_type == ECPGst_prepare )
2162+ {
2163+ stmt -> name = ecpg_strdup (var -> value , lineno );
2164+ is_prepared_name_set = true;
2165+ }
20952166 }
20962167
20972168 type = va_arg (args , enum ECPGttype );
@@ -2105,6 +2176,13 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
21052176 return false;
21062177 }
21072178
2179+ if (!is_prepared_name_set && stmt -> statement_type == ECPGst_prepare )
2180+ {
2181+ ecpg_raise (lineno , ECPG_TOO_FEW_ARGUMENTS , ECPG_SQLSTATE_ECPG_INTERNAL_ERROR , (con ) ? con -> name : ecpg_gettext ("<empty>" ));
2182+ ecpg_do_epilogue (stmt );
2183+ return false;
2184+ }
2185+
21082186 /* initialize auto_mem struct */
21092187 ecpg_clear_auto_mem ();
21102188
0 commit comments