Dear MonetDB developers,

as I have been working on interfacing Mapi to C++ in a manner as
lightweight as possible, I have noticed that the parameter binding
interface does not interface to STL strings as seamlessly as it
probably could. Similar considerations might well apply to other
C-based string APIs:

The STL string API provides accessor functions to the string's
char data and its size. To ensure secure programming, the pointer to
the char data has to be const. Yet, the Mapi interface for passing
string parameters expects a writable char pointer. I'm not sure
how future plans for Mapi look like, but currently thsi doesn't
seem necessary to me. I have attached a patch to have Mapi treat the
data as const, which works well for me.

I also noticed that Mapi expects the string size parameter to be
passed by reference. Is this necessary? Having an interface which
supports pass-by-value would facilitate string API integration even
more.

Best regards,

Isidor
--- a/src/mapilib/Mapi.mx
+++ b/src/mapilib/Mapi.mx
@@ -685,7 +685,7 @@ type is described by sqltype.
 
 Bind to a numeric variable, internally represented by MAPI_INT.
 
-...@item MapiMsg mapi_param_string(MapiHdl hdl, int fldnr, int sqltype, char *val, int *sizeptr)
+...@item MapiMsg mapi_param_string(MapiHdl hdl, int fldnr, int sqltype, const char *val, const int *sizeptr)
 
 Bind a string variable, internally represented by MAPI_VARCHAR, to a
 parameter.  The sizeptr parameter points to the length of the string
@@ -940,8 +940,8 @@ struct MapiBinding {
 
 /* information about statement parameters */
 struct MapiParam {
-	void *inparam;		/* pointer to application variable */
-	int *sizeptr;		/* if string, points to length of string or -1 */
+	const void *inparam;	/* pointer to application variable */
+	const int *sizeptr;	/* if string, points to length of string or -1 */
 	int intype;		/* type of application variable */
 	int outtype;		/* type of value */
 	int precision;
@@ -1220,7 +1220,7 @@ mapi_export MapiMsg mapi_bind_var(MapiHdl hdl, int fnr, int type, void *ptr);
 mapi_export MapiMsg mapi_bind_numeric(MapiHdl hdl, int fnr, int scale, int precision, void *ptr);
 mapi_export MapiMsg mapi_clear_bindings(MapiHdl hdl);
 mapi_export MapiMsg mapi_param_type(MapiHdl hdl, int fnr, int ctype, int sqltype, void *ptr);
-mapi_export MapiMsg mapi_param_string(MapiHdl hdl, int fnr, int sqltype, char *ptr, int *sizeptr);
+mapi_export MapiMsg mapi_param_string(MapiHdl hdl, int fnr, int sqltype, const char *ptr, const int *sizeptr);
 mapi_export MapiMsg mapi_param(MapiHdl hdl, int fnr, char **ptr);
 mapi_export MapiMsg mapi_param_numeric(MapiHdl hdl, int fnr, int scale, int precision, void *ptr);
 mapi_export MapiMsg mapi_clear_params(MapiHdl hdl);
@@ -3072,10 +3072,10 @@ mapi_param_type(MapiHdl hdl, int fnr, int ctype, int sqltype, void *ptr)
 }
 
 MapiMsg
-mapi_param_string(MapiHdl hdl, int fnr, int sqltype, char *ptr, int *sizeptr)
+mapi_param_string(MapiHdl hdl, int fnr, int sqltype, const char *ptr, const int *sizeptr)
 {
 	testParam(hdl, fnr, "mapi_param_type");
-	hdl->params[fnr].inparam = (void *) ptr;
+	hdl->params[fnr].inparam = (const void *) ptr;
 
 	hdl->params[fnr].intype = MAPI_VARCHAR;
 	hdl->params[fnr].sizeptr = sizeptr;
@@ -3313,87 +3313,87 @@ mapi_param_store(MapiHdl hdl)
 			checkSpace(5);
 			strcpy(hdl->query + k, hdl->mid->languageId == LANG_SQL ? "NULL" : "nil");
 		} else {
-			void *src = hdl->params[i].inparam;	/* abbrev */
+			void const *src = hdl->params[i].inparam;	/* abbrev */
 
 			switch (hdl->params[i].intype) {
 			case MAPI_TINY:
 				checkSpace(5);
-				sprintf(hdl->query + k, "%hhd", *(signed char *) src);
+				sprintf(hdl->query + k, "%hhd", *(signed char const *) src);
 				break;
 			case MAPI_UTINY:
 				checkSpace(5);
-				sprintf(hdl->query + k, "%hhu", *(unsigned char *) src);
+				sprintf(hdl->query + k, "%hhu", *(unsigned char const *) src);
 				break;
 			case MAPI_SHORT:
 				checkSpace(10);
-				sprintf(hdl->query + k, "%d", *(short *) src);
+				sprintf(hdl->query + k, "%d", *(short const *) src);
 				break;
 			case MAPI_USHORT:
 				checkSpace(10);
-				sprintf(hdl->query + k, "%hu", *(unsigned short *) src);
+				sprintf(hdl->query + k, "%hu", *(unsigned short const *) src);
 				break;
 			case MAPI_INT:
 				checkSpace(20);
-				sprintf(hdl->query + k, "%d", *(int *) src);
+				sprintf(hdl->query + k, "%d", *(int const *) src);
 				break;
 			case MAPI_UINT:
 				checkSpace(20);
-				sprintf(hdl->query + k, "%u", *(unsigned int *) src);
+				sprintf(hdl->query + k, "%u", *(unsigned int const *) src);
 				break;
 			case MAPI_LONG:
 				checkSpace(20);
-				sprintf(hdl->query + k, "%ld", *(long *) src);
+				sprintf(hdl->query + k, "%ld", *(long const *) src);
 				break;
 			case MAPI_ULONG:
 				checkSpace(20);
-				sprintf(hdl->query + k, "%lu", *(unsigned long *) src);
+				sprintf(hdl->query + k, "%lu", *(unsigned long const *) src);
 				break;
 			case MAPI_LONGLONG:
 				checkSpace(30);
-				sprintf(hdl->query + k, LLFMT, *(mapi_int64 *) src);
+				sprintf(hdl->query + k, LLFMT, *(mapi_int64 const *) src);
 				break;
 			case MAPI_ULONGLONG:
 				checkSpace(30);
-				sprintf(hdl->query + k, ULLFMT, *(mapi_uint64 *) src);
+				sprintf(hdl->query + k, ULLFMT, *(mapi_uint64 const *) src);
 				break;
 			case MAPI_FLOAT:
 				checkSpace(30);
-				sprintf(hdl->query + k, "%.9g", *(float *) src);
+				sprintf(hdl->query + k, "%.9g", *(float const *) src);
 				break;
 			case MAPI_DOUBLE:
 				checkSpace(20);
-				sprintf(hdl->query + k, "%.17g", *(double *) src);
+				sprintf(hdl->query + k, "%.17g", *(double const *) src);
 				break;
 			case MAPI_DATE:
 				checkSpace(50);
 				sprintf(hdl->query + k,
 					"DATE '%04d-%02hu-%02hu'",
-					((MapiDate *) src)->year,
-					((MapiDate *) src)->month,
-					((MapiDate *) src)->day);
+					((MapiDate const *) src)->year,
+					((MapiDate const *) src)->month,
+					((MapiDate const *) src)->day);
 				break;
 			case MAPI_TIME:
 				checkSpace(60);
 				sprintf(hdl->query + k,
 					"TIME '%02hu:%02hu:%02hu'",
-					((MapiTime *) src)->hour,
-					((MapiTime *) src)->minute,
-					((MapiTime *) src)->second);
+					((MapiTime const *) src)->hour,
+					((MapiTime const *) src)->minute,
+					((MapiTime const *) src)->second);
 				break;
 			case MAPI_DATETIME:
 				checkSpace(110);
 				sprintf(hdl->query + k,
 					"TIMESTAMP '%04d-%02hu-%02hu %02hu:%02hu:%02hu.%09u'",
-					((MapiDateTime *) src)->year,
-					((MapiDateTime *) src)->month,
-					((MapiDateTime *) src)->day,
-					((MapiDateTime *) src)->hour,
-					((MapiDateTime *) src)->minute,
-					((MapiDateTime *) src)->second,
-					((MapiDateTime *) src)->fraction);
+					((MapiDateTime const *) src)->year,
+					((MapiDateTime const *) src)->month,
+					((MapiDateTime const *) src)->day,
+					((MapiDateTime const *) src)->hour,
+					((MapiDateTime const *) src)->minute,
+					((MapiDateTime const *) src)->second,
+					((MapiDateTime const *) src)->fraction);
 				break;
 			case MAPI_CHAR:
-				buf[0] = *(char *) src;
+				buf[0] = *(char const *) src;
 				buf[1] = 0;
 				val = mapi_quote(buf, 1);
 				checkSpace(strlen(val) + 3);
@@ -3401,7 +3401,7 @@ mapi_param_store(MapiHdl hdl)
 				free(val);
 				break;
 			case MAPI_VARCHAR:
-				val = mapi_quote((char *) src, hdl->params[i].sizeptr ? *hdl->params[i].sizeptr : -1);
+				val = mapi_quote((char const *) src, hdl->params[i].sizeptr ? *hdl->params[i].sizeptr : -1);
 				checkSpace(strlen(val) + 3);
 				sprintf(hdl->query + k, "'%s'", val);
 				free(val);
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Monetdb-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-developers

Reply via email to