@@ -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