Changeset: 7ad69cae4a83 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7ad69cae4a83 Modified Files: clients/mapiclient/mclient.c clients/mapilib/mapi.c common/stream/stream.c common/stream/stream.h sql/backends/monet5/sql_result.c Branch: protocol Log Message:
merge diffs (284 lines): diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c --- a/clients/mapiclient/mclient.c +++ b/clients/mapiclient/mclient.c @@ -823,7 +823,11 @@ CSVrenderer(MapiHdl hdl) for (i = 0; i < fields; i++) { s = mapi_fetch_field(hdl, i); - buffer_ptr = stpcpy(buffer_ptr, s); + if (s) { + buffer_ptr = stpcpy(buffer_ptr, s); + } else { + buffer_ptr = stpcpy(buffer_ptr, default_nullstring); + } if (i != fields - 1) { *buffer_ptr++ = *sep; diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c --- a/clients/mapilib/mapi.c +++ b/clients/mapilib/mapi.c @@ -829,6 +829,7 @@ struct MapiColumn { int columnlength; int digits; int scale; + void *null_value; char* buffer_ptr; char write_buf[50]; mapi_converter converter; @@ -3993,6 +3994,8 @@ parse_header_line(MapiHdl hdl, char *lin */ static char* mapi_convert_varchar(struct MapiColumn *col) { + if (strcmp(col->buffer_ptr, (char*)col->null_value) == 0) + return NULL; return col->buffer_ptr; } @@ -4018,33 +4021,38 @@ static char* itoa(int i, char b[]){ } static char* mapi_convert_int(struct MapiColumn *col) { - //sprintf(col->write_buf, "%d", *((int*) col->buffer_ptr)); + if (*((int*) col->buffer_ptr) == *((int*)col->null_value)) return NULL; itoa(*((int*) col->buffer_ptr), col->write_buf); return (char*) col->write_buf; } static char* mapi_convert_lng(struct MapiColumn *col) { + if (*((lng*) col->buffer_ptr) == *((lng*)col->null_value)) return NULL; sprintf(col->write_buf, "%lld", *((lng*) col->buffer_ptr)); return (char*) col->write_buf; } static char* mapi_convert_smallint(struct MapiColumn *col) { + if (*((short*) col->buffer_ptr) == *((short*)col->null_value)) return NULL; sprintf(col->write_buf, "%hd", *((short*) col->buffer_ptr)); return (char*) col->write_buf; } static char* mapi_convert_tinyint(struct MapiColumn *col) { + if (*((signed char*) col->buffer_ptr) == *((signed char*)col->null_value)) return NULL; sprintf(col->write_buf, "%hhd", *((signed char*) col->buffer_ptr)); return (char*) col->write_buf; } static char* mapi_convert_double(struct MapiColumn *col) { + if (*((double*) col->buffer_ptr) == *((double*)col->null_value)) return NULL; //sprintf(col->write_buf, "%g", *((double*) col->buffer_ptr)); gcvt(*((double*) col->buffer_ptr), 2, col->write_buf); return (char*) col->write_buf; } static char* mapi_convert_boolean(struct MapiColumn *col) { + if (*((signed char*) col->buffer_ptr) == *((signed char*)col->null_value)) return NULL; if (*((signed char*) col->buffer_ptr) == 1) { return "true"; } @@ -4088,12 +4096,11 @@ static int CUMLEAPDAYS[13] = { static char* mapi_convert_date(struct MapiColumn *col){ int day, month, year; - date n = *((date*) col->buffer_ptr); - if (n == date_nil) { - return "NULL"; - } + if (n == *((date*)col->null_value)) + return NULL; + year = n / 365; day = (n - year * 365) - leapyears(year >= 0 ? year - 1 : year); if (n < 0) { @@ -4197,16 +4204,13 @@ read_into_cache(MapiHdl hdl, int lookahe result->querytype = Q_TABLE; result->tuple_count = 0; result->rows_read = 0; -// result->errorstr = NULL; -// result->cache.line = NULL; -// result->next = NULL; -// result->hdl = hdl; for (i = 0; i < nr_cols; i++) { lng col_info_length; char *table_name, *col_name, *type_sql_name; int typelen; + int null_len; if (!mnstr_readLng(mid->from, &col_info_length)) { return mid->error; @@ -4225,6 +4229,21 @@ read_into_cache(MapiHdl hdl, int lookahe !mnstr_readInt(mid->from, &typelen)) { return mid->error; } + + if (!mnstr_readInt(mid->from, &null_len)) { + return mid->error; + } + assert(null_len > 0); + + result->fields[i].null_value = malloc(sizeof(char) * null_len); + if (!result->fields[i].null_value) { + return mid->error; + } + + if (mnstr_read(mid->from, result->fields[i].null_value, null_len, 1) != 1) { + return mid->error; + } + // fprintf(stderr, "%lld col_info_length=%lld, table_name=%s, col_name=%s, type_sql_name=%s, type_len=%d\n", // i, col_info_length, table_name, col_name, type_sql_name, typelen); result->fields[i].columnname = col_name; @@ -4254,7 +4273,6 @@ read_into_cache(MapiHdl hdl, int lookahe result->fields[i].converter = (mapi_converter) mapi_convert_unknown; // TODO: complain } - // TODO: NULLs } hdl->result = result; hdl->active = result; diff --git a/common/stream/stream.c b/common/stream/stream.c --- a/common/stream/stream.c +++ b/common/stream/stream.c @@ -4590,6 +4590,22 @@ mnstr_writeLng(stream *s, lng val) return s->write(s, (void *) &val, sizeof(val), (size_t) 1) == 1; } +int +mnstr_writeFlt(stream *s, float val) +{ + if (s == NULL || s->errnr) + return 0; + return s->write(s, (void *) &val, sizeof(val), (size_t) 1) == 1; +} + +int +mnstr_writeDbl(stream *s, double val) +{ + if (s == NULL || s->errnr) + return 0; + return s->write(s, (void *) &val, sizeof(val), (size_t) 1) == 1; +} + #ifdef HAVE_HGE int diff --git a/common/stream/stream.h b/common/stream/stream.h --- a/common/stream/stream.h +++ b/common/stream/stream.h @@ -8,7 +8,7 @@ #ifndef _STREAM_H_ #define _STREAM_H_ - + /* * File: stream.h * Auteur: Niels J. Nes @@ -114,6 +114,10 @@ stream_export int mnstr_writeInt(stream stream_export int mnstr_readLng(stream *s, lng *val); stream_export int mnstr_writeLng(stream *s, lng val); + +int mnstr_writeFlt(stream *s, float val); +int mnstr_writeDbl(stream *s, double val); + #ifdef HAVE_HGE stream_export int mnstr_readHge(stream *s, hge *val); stream_export int mnstr_writeHge(stream *s, hge val); diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c --- a/sql/backends/monet5/sql_result.c +++ b/sql/backends/monet5/sql_result.c @@ -9,6 +9,7 @@ /* * author N.J. Nes */ + #include "monetdb_config.h" #include "sql_result.h" @@ -1865,7 +1866,7 @@ static int write_str_term(stream* s, str static int mvc_export_resultset_prot10(res_table* t, stream* s, stream *c, size_t bsize) { BAT *order; lng count; - size_t i; + size_t i, j; size_t row = 0; size_t srow = 0; size_t varsized = 0; @@ -1898,6 +1899,8 @@ static int mvc_export_resultset_prot10(r res_col *c = t->cols + i; int mtype = c->type.type->localtype; int typelen = ATOMsize(mtype); + int nil_len = -1; + int retval = -1; iterators[i] = bat_iterator(BATdescriptor(c->b)); if (strcasecmp(c->type.type->sqlname, "decimal") == 0) { @@ -1930,6 +1933,7 @@ static int mvc_export_resultset_prot10(r return -1; } if (res == MAL_SUCCEED) { + mtype = TYPE_dbl; typelen = sizeof(dbl); BBPunfix(iterators[i].b->batCacheid); iterators[i].b = BATdescriptor(result); @@ -1943,8 +1947,10 @@ static int mvc_export_resultset_prot10(r assert(mtype == TYPE_str); typelen = -1; varsized++; + nil_len = strlen(str_nil) + 1; } else { fixed_lengths += typelen; + nil_len = typelen; } if (!mnstr_writeLng(s, (lng)(strlen(c->tn) + strlen(c->name) + strlen(c->type.type->sqlname) + sizeof(int) + 3)) || @@ -1952,7 +1958,45 @@ static int mvc_export_resultset_prot10(r !mnstr_writeInt(s, typelen)) { return -1; } - // FIXME: null values + // write NULL values for this column to the stream + // NULL values are encoded as <size:int> <NULL value> (<size> is always <typelen> for fixed size columns) + if (!mnstr_writeInt(s, nil_len)) { + return -1; + } + + switch(ATOMstorage(mtype)) { + case TYPE_str: + retval = 1; + for(j = 0; j < nil_len; j++) { + retval = retval && mnstr_writeBte(s, str_nil[j]); + } + break; + case TYPE_bit: + case TYPE_bte: + retval = mnstr_writeBte(s, bte_nil); + break; + case TYPE_sht: + retval = mnstr_writeSht(s, sht_nil); + break; + case TYPE_int: + retval = mnstr_writeInt(s, int_nil); + break; + case TYPE_lng: + retval = mnstr_writeLng(s, lng_nil); + break; + case TYPE_flt: + retval = mnstr_writeFlt(s, flt_nil); + break; + case TYPE_dbl: + retval = mnstr_writeDbl(s, dbl_nil); + break; + default: + assert(0); + return -1; + } + if (!retval) { + return -1; + } } mnstr_flush(s); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list