1- /* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.74 2008/01/13 11:53:16 meskes Exp $ */
1+ /* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.75 2008/01/15 10:31:47 meskes Exp $ */
22
33/*
44 * The aim is to get a simpler inteface to the database routines.
@@ -128,8 +128,8 @@ next_insert(char *text, int pos, bool questionmarks)
128128 int i ;
129129
130130 for (i = p + 1 ; isdigit (text [i ]); i ++ );
131- if (!isalpha (text [i ]) && isascii (text [i ]) && text [i ] != '_' )
132- /* not dollar delimeted quote */
131+ if (!isalpha (text [i ]) && isascii (text [i ]) && text [i ] != '_' )
132+ /* not dollar delimited quote */
133133 return p ;
134134 }
135135 else if (questionmarks && text [p ] == '?' )
@@ -451,7 +451,7 @@ ecpg_store_result(const PGresult *results, int act_field,
451451
452452bool
453453ecpg_store_input (const int lineno , const bool force_indicator , const struct variable * var ,
454- const char * * tobeinserted_p , bool quote )
454+ char * * tobeinserted_p , bool quote )
455455{
456456 char * mallocedval = NULL ;
457457 char * newcopy = NULL ;
@@ -1046,6 +1046,39 @@ free_params(const char **paramValues, int nParams, bool print, int lineno)
10461046 ecpg_free (paramValues );
10471047}
10481048
1049+
1050+ static bool
1051+ insert_tobeinserted (int position , int ph_len , struct statement * stmt , char * tobeinserted )
1052+ {
1053+ char * newcopy ;
1054+
1055+ if (!(newcopy = (char * ) ecpg_alloc (strlen (stmt -> command )
1056+ + strlen (tobeinserted )
1057+ + 1 , stmt -> lineno )))
1058+ {
1059+ ecpg_free (tobeinserted );
1060+ return false;
1061+ }
1062+
1063+ strcpy (newcopy , stmt -> command );
1064+ strcpy (newcopy + position - 1 , tobeinserted );
1065+
1066+ /*
1067+ * The strange thing in the second argument is the rest of the
1068+ * string from the old string
1069+ */
1070+ strcat (newcopy ,
1071+ stmt -> command
1072+ + position
1073+ + ph_len - 1 );
1074+
1075+ ecpg_free (stmt -> command );
1076+ stmt -> command = newcopy ;
1077+
1078+ ecpg_free ((char * ) tobeinserted );
1079+ return true;
1080+ }
1081+
10491082static bool
10501083ecpg_execute (struct statement * stmt )
10511084{
@@ -1069,7 +1102,7 @@ ecpg_execute(struct statement * stmt)
10691102 var = stmt -> inlist ;
10701103 while (var )
10711104 {
1072- const char * tobeinserted ;
1105+ char * tobeinserted ;
10731106 int counter = 1 ;
10741107
10751108 tobeinserted = NULL ;
@@ -1134,11 +1167,51 @@ ecpg_execute(struct statement * stmt)
11341167
11351168 /*
11361169 * now tobeinserted points to an area that contains the next parameter
1170+ * now find the positin in the string where it belongs
1171+ */
1172+ if ((position = next_insert (stmt -> command , position , stmt -> questionmarks ) + 1 ) == 0 )
1173+ {
1174+ /*
1175+ * We have an argument but we dont have the matched up
1176+ * placeholder in the string
1177+ */
1178+ ecpg_raise (stmt -> lineno , ECPG_TOO_MANY_ARGUMENTS ,
1179+ ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS ,
1180+ NULL );
1181+ free_params (paramValues , nParams , false, stmt -> lineno );
1182+ return false;
1183+ }
1184+
1185+ /*
11371186 * if var->type=ECPGt_char_variable we have a dynamic cursor we have
11381187 * to simulate a dynamic cursor because there is no backend
11391188 * functionality for it
11401189 */
1141- if (var -> type != ECPGt_char_variable )
1190+ if (var -> type == ECPGt_char_variable )
1191+ {
1192+ int ph_len = (stmt -> command [position ] == '?' ) ? strlen ("?" ) : strlen ("$1" );
1193+
1194+ if (!insert_tobeinserted (position , ph_len , stmt , tobeinserted ))
1195+ {
1196+ free_params (paramValues , nParams , false, stmt -> lineno );
1197+ return false;
1198+ }
1199+ tobeinserted = NULL ;
1200+ }
1201+ /*
1202+ * if the placeholder is '$0' we have to replace it on the client side
1203+ * this is for places we want to support variables at that are not supported in the backend
1204+ */
1205+ else if (stmt -> command [position ] == '0' )
1206+ {
1207+ if (!insert_tobeinserted (position , 2 , stmt , tobeinserted ))
1208+ {
1209+ free_params (paramValues , nParams , false, stmt -> lineno );
1210+ return false;
1211+ }
1212+ tobeinserted = NULL ;
1213+ }
1214+ else
11421215 {
11431216 nParams ++ ;
11441217 if (!(paramValues = (const char * * ) ecpg_realloc (paramValues , sizeof (const char * ) * nParams , stmt -> lineno )))
@@ -1149,107 +1222,28 @@ ecpg_execute(struct statement * stmt)
11491222
11501223 paramValues [nParams - 1 ] = tobeinserted ;
11511224
1152- if ((position = next_insert (stmt -> command , position , stmt -> questionmarks ) + 1 ) == 0 )
1153- {
1154- /*
1155- * We have an argument but we dont have the matched up
1156- * placeholder in the string
1157- */
1158- ecpg_raise (stmt -> lineno , ECPG_TOO_MANY_ARGUMENTS ,
1159- ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS ,
1160- NULL );
1161- free_params (paramValues , nParams , false, stmt -> lineno );
1162- return false;
1163- }
1164-
11651225 /* let's see if this was an old style placeholder */
1166- if (stmt -> command [position - 1 ] == '?' )
1226+ if (stmt -> command [position ] == '?' )
11671227 {
11681228 /* yes, replace with new style */
11691229 int buffersize = sizeof (int ) * CHAR_BIT * 10 / 3 ; /* a rough guess of the
11701230 * size we need */
1171- char * buffer ,
1172- * newcopy ;
11731231
1174- if (!(buffer = (char * ) ecpg_alloc (buffersize , stmt -> lineno )))
1232+ if (!(tobeinserted = (char * ) ecpg_alloc (buffersize , stmt -> lineno )))
11751233 {
11761234 free_params (paramValues , nParams , false, stmt -> lineno );
11771235 return false;
11781236 }
11791237
1180- snprintf (buffer , buffersize , "$%d" , counter ++ );
1238+ snprintf (tobeinserted , buffersize , "$%d" , counter ++ );
11811239
1182- if (!( newcopy = ( char * ) ecpg_alloc ( strlen ( stmt -> command ) + strlen ( buffer ) + 1 , stmt -> lineno ) ))
1240+ if (!insert_tobeinserted ( position , 2 , stmt , tobeinserted ))
11831241 {
11841242 free_params (paramValues , nParams , false, stmt -> lineno );
1185- ecpg_free (buffer );
11861243 return false;
11871244 }
1188-
1189- strcpy (newcopy , stmt -> command );
1190-
1191- /* set positional parameter */
1192- strcpy (newcopy + position - 1 , buffer );
1193-
1194- /*
1195- * The strange thing in the second argument is the rest of the
1196- * string from the old string
1197- */
1198- strcat (newcopy ,
1199- stmt -> command
1200- + position + 1 );
1201- ecpg_free (buffer );
1202- ecpg_free (stmt -> command );
1203- stmt -> command = newcopy ;
1204- }
1205- }
1206- else
1207- {
1208- char * newcopy ;
1209-
1210- if (!(newcopy = (char * ) ecpg_alloc (strlen (stmt -> command )
1211- + strlen (tobeinserted )
1212- + 1 , stmt -> lineno )))
1213- {
1214- free_params (paramValues , nParams , false, stmt -> lineno );
1215- return false;
1216- }
1217-
1218- strcpy (newcopy , stmt -> command );
1219- if ((position = next_insert (stmt -> command , position , stmt -> questionmarks ) + 1 ) == 0 )
1220- {
1221- /*
1222- * We have an argument but we dont have the matched up string
1223- * in the string
1224- */
1225- ecpg_raise (stmt -> lineno , ECPG_TOO_MANY_ARGUMENTS ,
1226- ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS ,
1227- NULL );
1228- free_params (paramValues , nParams , false, stmt -> lineno );
1229- ecpg_free (newcopy );
1230- return false;
1245+ tobeinserted = NULL ;
12311246 }
1232- else
1233- {
1234- int ph_len = (stmt -> command [position ] == '?' ) ? strlen ("?" ) : strlen ("$1" );
1235-
1236- strcpy (newcopy + position - 1 , tobeinserted );
1237-
1238- /*
1239- * The strange thing in the second argument is the rest of the
1240- * string from the old string
1241- */
1242- strcat (newcopy ,
1243- stmt -> command
1244- + position
1245- + ph_len - 1 );
1246- }
1247-
1248- ecpg_free (stmt -> command );
1249- stmt -> command = newcopy ;
1250-
1251- ecpg_free ((char * ) tobeinserted );
1252- tobeinserted = NULL ;
12531247 }
12541248
12551249 if (desc_counter == 0 )
0 commit comments