Changeset: 8a3d8e27b790 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8a3d8e27b790 Modified Files: clients/mapilib/mapi.c clients/mapilib/mapi.h common/utils/conversion.c common/utils/conversion.h Branch: protocol Log Message:
Add mapi_fetch_field_[type] family of functions to avoid unnecessary string conversion function, and implement mapi_store_bind functions. diffs (truncated from 895 to 300 lines): diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c --- a/clients/mapilib/mapi.c +++ b/clients/mapilib/mapi.c @@ -840,6 +840,7 @@ struct MapiColumn { size_t dynamic_write_bufsiz; char write_buf[COLBUFSIZ]; mapi_converter converter; + binary_sql_type sql_type; }; /* information about bound columns */ @@ -4289,12 +4290,15 @@ read_into_cache(MapiHdl hdl, int lookahe result->fields[i].dynamic_write_buf = NULL; result->fields[i].dynamic_write_bufsiz = 0; result->fields[i].converter = NULL; + result->fields[i].sql_type = SQL_BINARY_UNKNOWN; if (strcasecmp(type_sql_name, "blob") == 0) { + result->fields[i].sql_type = SQL_BINARY_BLOB; result->fields[i].converter = (mapi_converter) mapi_convert_blob; } else if (result->fields[i].null_value == NULL) { result->fields[i].converter = (mapi_converter) mapi_convert_null; } else if (strcasecmp(type_sql_name, "varchar") == 0 || strcasecmp(type_sql_name, "char") == 0) { + result->fields[i].sql_type = SQL_BINARY_VARCHAR; if (typelen > 0) { result->fields[i].converter = (mapi_converter) mapi_convert_varchar; result->fields[i].dynamic_write_bufsiz = result->fields[i].typelen * sizeof(char); @@ -4303,38 +4307,53 @@ read_into_cache(MapiHdl hdl, int lookahe result->fields[i].converter = (mapi_converter) mapi_convert_clob; } } else if (strcasecmp(type_sql_name, "clob") == 0) { + result->fields[i].sql_type = SQL_BINARY_CLOB; // var length strings result->fields[i].converter = (mapi_converter) mapi_convert_clob; } else if (strcasecmp(type_sql_name, "int") == 0 || strcasecmp(type_sql_name, "month_interval") == 0) { + result->fields[i].sql_type = SQL_BINARY_INT; result->fields[i].converter = (mapi_converter) mapi_convert_int; } else if (strcasecmp(type_sql_name, "smallint") == 0) { + result->fields[i].sql_type = SQL_BINARY_SMALLINT; result->fields[i].converter = (mapi_converter) mapi_convert_smallint; } else if (strcasecmp(type_sql_name, "tinyint") == 0) { + result->fields[i].sql_type = SQL_BINARY_TINYINT; result->fields[i].converter = (mapi_converter) mapi_convert_tinyint; } else if (strcasecmp(type_sql_name, "boolean") == 0) { + result->fields[i].sql_type = SQL_BINARY_BOOLEAN; result->fields[i].converter = (mapi_converter) mapi_convert_boolean; } else if (strcasecmp(type_sql_name, "decimal") == 0 || strcasecmp(type_sql_name, "sec_interval") == 0) { + result->fields[i].sql_type = SQL_BINARY_DECIMAL; result->fields[i].converter = (mapi_converter) mapi_convert_decimal; } else if (strcasecmp(type_sql_name, "double") == 0) { + result->fields[i].sql_type = SQL_BINARY_DOUBLE; result->fields[i].converter = (mapi_converter) mapi_convert_double; } else if (strcasecmp(type_sql_name, "date") == 0) { + result->fields[i].sql_type = SQL_BINARY_DATE; result->fields[i].converter = (mapi_converter) mapi_convert_date; } else if (strcasecmp(type_sql_name, "bigint") == 0) { + result->fields[i].sql_type = SQL_BINARY_BIGINT; result->fields[i].converter = (mapi_converter) mapi_convert_bigint; } else if (strcasecmp(type_sql_name, "real") == 0) { + result->fields[i].sql_type = SQL_BINARY_REAL; result->fields[i].converter = (mapi_converter) mapi_convert_real; #ifdef HAVE_HGE } else if (strcasecmp(type_sql_name, "hugeint") == 0) { + result->fields[i].sql_type = SQL_BINARY_HUGEINT; result->fields[i].converter = (mapi_converter) mapi_convert_hugeint; #endif } else if (strcasecmp(type_sql_name, "time") == 0) { + result->fields[i].sql_type = SQL_BINARY_TIME; result->fields[i].converter = (mapi_converter) mapi_convert_time; } else if (strcasecmp(type_sql_name, "timestamp") == 0) { + result->fields[i].sql_type = SQL_BINARY_TIMESTAMP; result->fields[i].converter = (mapi_converter) mapi_convert_timestamp; } else if (strcasecmp(type_sql_name, "timestamptz") == 0) { + result->fields[i].sql_type = SQL_BINARY_TIMESTAMPTZ; result->fields[i].timezone = timezone; result->fields[i].converter = (mapi_converter) mapi_convert_timestamptz; } else if (typelen < 0) { /* any type besides the ones shown above should be converted to strings by the server */ + result->fields[i].sql_type = SQL_BINARY_CLOB; result->fields[i].converter = (mapi_converter) mapi_convert_clob; } else { fprintf(stderr, "Unrecognized sql type: %s\n", type_sql_name); @@ -5347,106 +5366,157 @@ mapi_extend_params(MapiHdl hdl, int minp static MapiMsg store_field(struct MapiResultSet *result, int cr, int fnr, int outtype, void *dst) { - char *val; - - val = result->cache.line[cr].anchors[fnr]; - - if (val == 0) { - return mapi_setError(result->hdl->mid, "Field value undefined or nil", "mapi_store_field", MERROR); - } - - /* auto convert to C-type */ - switch (outtype) { - case MAPI_TINY: - *(signed char *) dst = (signed char) strtol(val, NULL, 0); - break; - case MAPI_UTINY: - *(unsigned char *) dst = (unsigned char) strtoul(val, NULL, 0); - break; - case MAPI_SHORT: - *(short *) dst = (short) strtol(val, NULL, 0); - break; - case MAPI_USHORT: - *(unsigned short *) dst = (unsigned short) strtoul(val, NULL, 0); - break; - case MAPI_NUMERIC: - case MAPI_INT: - *(int *) dst = (int) strtol(val, NULL, 0); - break; - case MAPI_UINT: - *(unsigned int *) dst = (unsigned int) strtoul(val, NULL, 0); - break; - case MAPI_LONG: - *(long *) dst = strtol(val, NULL, 0); - break; - case MAPI_ULONG: - *(unsigned long *) dst = strtoul(val, NULL, 0); - break; + if (result->prot10_resultset) { + /* auto convert to C-type */ + switch (outtype) { + case MAPI_TINY: + return mapi_fetch_field_tinyint(result->hdl, fnr, dst); + case MAPI_UTINY: + return mapi_fetch_field_utinyint(result->hdl, fnr, dst); + case MAPI_SHORT: + return mapi_fetch_field_smallint(result->hdl, fnr, dst); + case MAPI_USHORT: + return mapi_fetch_field_usmallint(result->hdl, fnr, dst); + case MAPI_NUMERIC: + case MAPI_INT: + return mapi_fetch_field_int(result->hdl, fnr, dst); + case MAPI_UINT: + return mapi_fetch_field_uint(result->hdl, fnr, dst); + case MAPI_LONG: + case MAPI_ULONG: + // fixme + case MAPI_LONGLONG: + return mapi_fetch_field_bigint(result->hdl, fnr, dst); + case MAPI_ULONGLONG: + return mapi_fetch_field_ubigint(result->hdl, fnr, dst); + case MAPI_CHAR: { + char *val; + if ((val = mapi_fetch_field(result->hdl, fnr)) == NULL) { + return MERROR; + } + *(char *) dst = *val; + return MOK; + } + case MAPI_FLOAT: + return mapi_fetch_field_real(result->hdl, fnr, dst); + case MAPI_DOUBLE: + return mapi_fetch_field_double(result->hdl, fnr, dst); + case MAPI_DATE: + return mapi_fetch_field_date(result->hdl, fnr, &((MapiDate *) dst)->year, &((MapiDate *) dst)->month, &((MapiDate *) dst)->day); + case MAPI_TIME: { + unsigned int nanoseconds; + return mapi_fetch_field_time(result->hdl, fnr, &((MapiTime *) dst)->hour, &((MapiTime *) dst)->minute, &((MapiTime *) dst)->second, &nanoseconds); + } + case MAPI_DATETIME: + return mapi_fetch_field_timestamp(result->hdl, fnr, &((MapiDateTime *) dst)->year, &((MapiDateTime *) dst)->month, &((MapiDateTime *) dst)->day, &((MapiDateTime *) dst)->hour, &((MapiDateTime *) dst)->minute, &((MapiDateTime *) dst)->second, &((MapiDateTime *) dst)->fraction); + case MAPI_AUTO: + case MAPI_VARCHAR: + default: + *(char **) dst = mapi_fetch_field(result->hdl, fnr); + } + return MERROR; + } else { + char *val; + + val = result->cache.line[cr].anchors[fnr]; + + if (val == 0) { + return mapi_setError(result->hdl->mid, "Field value undefined or nil", "mapi_store_field", MERROR); + } + + /* auto convert to C-type */ + switch (outtype) { + case MAPI_TINY: + *(signed char *) dst = (signed char) strtol(val, NULL, 0); + break; + case MAPI_UTINY: + *(unsigned char *) dst = (unsigned char) strtoul(val, NULL, 0); + break; + case MAPI_SHORT: + *(short *) dst = (short) strtol(val, NULL, 0); + break; + case MAPI_USHORT: + *(unsigned short *) dst = (unsigned short) strtoul(val, NULL, 0); + break; + case MAPI_NUMERIC: + case MAPI_INT: + *(int *) dst = (int) strtol(val, NULL, 0); + break; + case MAPI_UINT: + *(unsigned int *) dst = (unsigned int) strtoul(val, NULL, 0); + break; + case MAPI_LONG: + *(long *) dst = strtol(val, NULL, 0); + break; + case MAPI_ULONG: + *(unsigned long *) dst = strtoul(val, NULL, 0); + break; #ifdef HAVE_STRTOLL - case MAPI_LONGLONG: - *(mapi_int64 *) dst = strtoll(val, NULL, 0); - break; + case MAPI_LONGLONG: + *(mapi_int64 *) dst = strtoll(val, NULL, 0); + break; #endif #ifdef HAVE_STRTOULL - case MAPI_ULONGLONG: - *(mapi_uint64 *) dst = strtoull(val, NULL, 0); - break; + case MAPI_ULONGLONG: + *(mapi_uint64 *) dst = strtoull(val, NULL, 0); + break; #endif - case MAPI_CHAR: - *(char *) dst = *val; - break; + case MAPI_CHAR: + *(char *) dst = *val; + break; #ifdef HAVE_STRTOF - case MAPI_FLOAT: - *(float *) dst = strtof(val, NULL); - break; + case MAPI_FLOAT: + *(float *) dst = strtof(val, NULL); + break; #endif #ifdef HAVE_STRTOD - case MAPI_DOUBLE: - *(double *) dst = strtod(val, NULL); - break; + case MAPI_DOUBLE: + *(double *) dst = strtod(val, NULL); + break; #endif - case MAPI_DATE: - sscanf(val, "%hd-%hu-%hu", - &((MapiDate *) dst)->year, - &((MapiDate *) dst)->month, - &((MapiDate *) dst)->day); - break; - case MAPI_TIME: - sscanf(val, "%hu:%hu:%hu", - &((MapiTime *) dst)->hour, - &((MapiTime *) dst)->minute, - &((MapiTime *) dst)->second); - break; - case MAPI_DATETIME:{ - int n; - - ((MapiDateTime *) dst)->fraction = 0; - sscanf(val, "%hd-%hu-%hu %hu:%hu:%hu%n", - &((MapiDateTime *) dst)->year, - &((MapiDateTime *) dst)->month, - &((MapiDateTime *) dst)->day, - &((MapiDateTime *) dst)->hour, - &((MapiDateTime *) dst)->minute, - &((MapiDateTime *) dst)->second, - &n); - if (val[n] == '.') { - unsigned int fac = 1000000000; - unsigned int nsec = 0; - - for (n++; isdigit((int) (unsigned char) val[n]); n++) { - fac /= 10; - nsec += (val[n] - '0') * fac; + case MAPI_DATE: + sscanf(val, "%hd-%hu-%hu", + &((MapiDate *) dst)->year, + &((MapiDate *) dst)->month, + &((MapiDate *) dst)->day); + break; + case MAPI_TIME: + sscanf(val, "%hu:%hu:%hu", + &((MapiTime *) dst)->hour, + &((MapiTime *) dst)->minute, + &((MapiTime *) dst)->second); + break; + case MAPI_DATETIME:{ + int n; + + ((MapiDateTime *) dst)->fraction = 0; + sscanf(val, "%hd-%hu-%hu %hu:%hu:%hu%n", + &((MapiDateTime *) dst)->year, + &((MapiDateTime *) dst)->month, + &((MapiDateTime *) dst)->day, + &((MapiDateTime *) dst)->hour, + &((MapiDateTime *) dst)->minute, + &((MapiDateTime *) dst)->second, + &n); + if (val[n] == '.') { + unsigned int fac = 1000000000; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list