freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
- From: christos AT zoulas.com (Christos Zoulas)
- To: freetds AT lists.ibiblio.org
- Subject: [freetds] bcp patch
- Date: Sat, 3 Jan 2004 14:38:38 -0500
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:
- [freetds] bcp patch, Christos Zoulas, 01/03/2004
Archive powered by MHonArc 2.6.24.