Changeset: 1dacb0ab9bfb for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1dacb0ab9bfb
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:
Add support for NULL values to protocol 10.
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;
}
@@ -4017,33 +4020,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";
}
@@ -4087,12 +4095,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) {
@@ -4196,16 +4203,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;
@@ -4224,6 +4228,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;
@@ -4253,7 +4272,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
@@ -4589,6 +4589,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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list