[freetds] bcp patch
Christos Zoulas
christos at zoulas.com
Sat Jan 3 14:38:38 EST 2004
Hello and Happy New Year,
The following patches fix all bcp issues with null and empty columns
in both native and delimited formats. This is done by setting the
data_size to -1 for null columns, so that empty columns can be
represented as having 0 length.
Enjoy,
christos
--- src/dblib/bcp.c.orig 2003-12-24 13:53:04.000000000 -0500
+++ src/dblib/bcp.c 2004-01-03 14:31:45.000000000 -0500
@@ -587,7 +587,7 @@
/* null columns have zero output */
if (tds_get_null(resinfo->current_row, bcpcol->tab_colnum - 1))
- bcpcol->data_size = 0;
+ bcpcol->data_size = -1;
else
bcpcol->data_size = curcol->column_cur_size;
@@ -732,7 +732,10 @@
* For null columns, the above work to determine the output buffer size is moot,
* because bcpcol->data_size is zero, so dbconvert() won't write anything, and returns zero.
*/
- buflen = dbconvert(dbproc,
+ if (bcpcol->data_size == -1)
+ buflen = -1;
+ else
+ buflen = dbconvert(dbproc,
bcpcol->db_type,
bcpcol->data, bcpcol->data_size, hostcol->datatype, outbuf, destlen);
@@ -782,7 +785,8 @@
buflen = buflen > hostcol->column_len ? hostcol->column_len : buflen;
}
- fwrite(outbuf, buflen, 1, hostfile);
+ if (buflen > 0)
+ fwrite(outbuf, buflen, 1, hostfile);
free(outbuf);
@@ -868,9 +872,10 @@
break;
}
- if (collen == 0)
+ if (collen == -1) {
data_is_null = 1;
-
+ collen = 0;
+ }
}
/* if (Max) column length specified take that into consideration. */
@@ -923,7 +928,9 @@
tdsdump_log(TDS_DBG_FUNC, "_bcp_measure_terminated_field returned -1!\n");
/* FIXME emit message? _bcp_err_handler(dbproc, SYBEMEM); */
return (FAIL);
- }
+ } else if (collen == 0)
+ data_is_null = 1;
+
tdsdump_log(TDS_DBG_FUNC, "_bcp_measure_terminated_field returned %d\n", collen);
/*
@@ -969,6 +976,21 @@
* because English dates expressed as UTF-8 strings are indistinguishable from the ASCII.
*/
} else { /* unterminated field */
+ bcpcol = dbproc->bcp.db_columns[hostcol->tab_colnum - 1];
+ if (collen == 0 && (is_nullable_type(bcpcol->db_type)
+ || bcpcol->db_nullable)) {
+ TDS_SMALLINT len;
+ if (fread(&len, sizeof(len), 1, hostfile) != 1) {
+ if (i != 0)
+ _bcp_err_handler(dbproc, SYBEBCRE);
+ return (FAIL);
+ }
+ collen = len;
+ if (collen == -1) {
+ collen = 0;
+ data_is_null = 1;
+ }
+ }
coldata = (BYTE *) calloc(1, 1 + collen);
if (coldata == NULL) {
*row_error = TRUE;
@@ -1001,7 +1023,7 @@
*/
if (hostcol->tab_colnum) {
if (data_is_null) {
- bcpcol->data_size = 0;
+ bcpcol->data_size = -1;
} else {
desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
@@ -1046,7 +1068,7 @@
bcpcol->data_size = converted_data_size;
}
}
- if (bcpcol->data_size == 0) { /* Are we trying to insert a NULL ? */
+ if (bcpcol->data_size == -1) { /* Are we trying to insert a NULL ? */
if (!bcpcol->db_nullable) {
/* too bad if the column is not nullable */
hostcol->column_error = HOST_COL_NULL_ERROR;
@@ -1165,7 +1187,7 @@
if (!is_nullable_type(bcpcol->db_type) && !(bcpcol->db_nullable)) {
- if (!(bcpcol->db_nullable) && bcpcol->data_size == 0) {
+ if (!(bcpcol->db_nullable) && bcpcol->data_size == -1) {
_bcp_err_handler(dbproc, SYBEBCNN);
return FAIL;
}
@@ -1235,7 +1257,7 @@
/* but if its a NOT NULL column, and we have no data */
/* throw an error */
- if (!(bcpcol->db_nullable) && bcpcol->data_size == 0) {
+ if (!(bcpcol->db_nullable) && bcpcol->data_size == -1) {
_bcp_err_handler(dbproc, SYBEBCNN);
return FAIL;
}
@@ -2508,7 +2530,7 @@
if (hostcol->tab_colnum) {
if (data_is_null) {
- bcpcol->data_size = 0;
+ bcpcol->data_size = -1;
} else {
desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
@@ -2526,7 +2548,7 @@
if (hostcol->tab_colnum) {
if (data_is_null) {
- bcpcol->data_size = 0;
+ bcpcol->data_size = -1;
} else {
desttype = tds_get_conversion_type(bcpcol->db_type, bcpcol->db_length);
@@ -2542,7 +2564,7 @@
}
}
- if (bcpcol->data_size == 0) { /* Are we trying to insert a NULL? */
+ if (bcpcol->data_size == -1) { /* Are we trying to insert a NULL? */
if (!bcpcol->db_nullable) {
/* too bad if the column is not nullable */
_bcp_err_handler(dbproc, SYBEBCNN);
--- src/tds/write.c.orig 2003-12-22 16:54:53.000000000 -0500
+++ src/tds/write.c 2004-01-02 17:32:36.000000000 -0500
@@ -270,7 +270,7 @@
TDS_TINYINT numeric_size;
- if (bcpcol->data_size == 0) {
+ if (bcpcol->data_size == -1) {
/*
* Insert a NULL. If the column is not nullable, it should be dealt with
* in _bcp_read_hostfile() or _bcp_get_prog_data().
@@ -290,7 +290,7 @@
}
return TDS_SUCCEED;
}
- assert(bcpcol->data_size > 0);
+ assert(bcpcol->data_size >= 0);
switch (bcpcol->db_varint_size) {
case 4:
More information about the FreeTDS
mailing list