[freetds] blk_in error

ZIGLIO, Frediano, VF-IT Frediano.Ziglio at vodafone.com
Tue Jul 27 05:29:41 EDT 2004


> 
> Thanks Freddy,
> 
> I'll take a look at this tomorrow, if I may (bit busy at the moment)
> 
> is this from CVS / latest snapshot ? 
> 
> Bill
> 

Yes, I put a patch on CVS, mainly (I updated also comment style... not
that important :) )

@@ -409,50 +414,49 @@
        }

        resinfo = tds->res_info;

        if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL) {
                _ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140,
"");
                return CS_FAIL;
        }


-       bindinfo->num_cols = resinfo->num_cols;
        bindinfo->row_size = resinfo->row_size;

-       bindinfo->columns = (TDSCOLUMN **) malloc(resinfo->num_cols *
sizeof(TDSCOLUMN *));
-
        for (i = 0; i < bindinfo->num_cols; i++) {

-               bindinfo->columns[i] = (TDSCOLUMN *)
malloc(sizeof(TDSCOLUMN));
                curcol = bindinfo->columns[i];
-               memset(curcol, '\0', sizeof(TDSCOLUMN));

                curcol->column_type = resinfo->columns[i]->column_type;
                curcol->column_usertype =
resinfo->columns[i]->column_usertype;
                curcol->column_flags =
resinfo->columns[i]->column_flags;
                curcol->column_size = resinfo->columns[i]->column_size;
                curcol->column_varint_size =
resinfo->columns[i]->column_varint_size;
                curcol->column_prec = resinfo->columns[i]->column_prec;
                curcol->column_scale =
resinfo->columns[i]->column_scale;
                curcol->column_namelen =
resinfo->columns[i]->column_namelen;
                curcol->on_server.column_type =
resinfo->columns[i]->on_server.column_type;
                curcol->on_server.column_size =
resinfo->columns[i]->on_server.column_size;
                curcol->char_conv = resinfo->columns[i]->char_conv;
                memcpy(curcol->column_name,
resinfo->columns[i]->column_name, resinfo->columns[i]->column_namelen);
                curcol->column_nullable =
resinfo->columns[i]->column_nullable;
                curcol->column_identity =
resinfo->columns[i]->column_identity;
                curcol->column_timestamp =
resinfo->columns[i]->column_timestamp;

                memcpy(curcol->column_collation,
resinfo->columns[i]->column_collation, 5);

-               curcol->bcp_column_data =
tds_alloc_bcp_column_data(curcol->on_server.column_size);
+               if (is_numeric_type(curcol->column_type)) {
+                       curcol->bcp_column_data =
tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC));
+               } else {
+                       curcol->bcp_column_data =
tds_alloc_bcp_column_data(curcol->on_server.column_size);
+               }
        }

        bindinfo->current_row = tds_alloc_row(bindinfo);

        blkdesc->bindinfo = bindinfo;
        blkdesc->bind_count = CS_UNUSED;

        if (blkdesc->identity_insert_on) {

                if (tds_submit_queryf(tds, "set identity_insert %s on",
blkdesc->tablename) == TDS_FAIL) {

Mainly two difference:
- do not allocated again already allocated data (see tds_alloc_results)
- fix size for numeric (already in dblib)

I looked a bit code and how it works.
For TDS7+
- convert data to bcp_column_data (_blk_get_col_data)
- build record to send (_blk_build_bcp_record)
- put record (_blk_rowxfer_in)
- discard it
Why not sending data directly to wire avoiding buffering all row ??
I don't think null text work... (test do not include this type)

For TDS<7 (it still core)
- add fixed columns to buffer (_blk_add_fixed_columns)
- add variable columns to buffer (_blk_add_variable_columns)
- write buffer to wire
- write all blob data (I really don't understand, I think Sybase bulk
protocol it's very different...)

There is a comment I don't like:
	/*
	 * In TDS 5 we get the column information as a result set from
the "insert bulk" command.
	 * We're going to ignore it.  
	 */

Why ignore it and instead issue a "select * from table where 0=1" ??
Perhaps server already sort variables in fixed/variable order... A test
with proprietary library should help (how it fetch column metadata, does
blk_init send insert bulk, what blk_describe returns and so on).

Another comment

/* this formula taken from sybase manual... */

where did you find this documentation??

Also tds_get_column_declaration (query.c) and
_blk_build_bulk_insert_stmt (blk.c) are quite similar...

Any idea to implement blk_textxfer ?? IMHO we should think how to
implement it cause it can be difficult later...

My opinion it that we should send data just after conversion in order to
remove bcp_column_data stuff. 

Yesterday I cleanup old unused bcp stuff from tds.h. I saw also that
dblib bulk it's similar to ctlib bulk. I think this it's simply
fantastic !!!

freddy77



More information about the FreeTDS mailing list