[freetds] Procedure or function has too many arguments specified
Man Min Yan
manmin_yan at yahoo.com.au
Tue Nov 4 00:56:03 EST 2008
Hi,
I think I have found the cause to this problem. The following patch fixes the problem, but I don't know the code well enough to know whether this is the proper fix or not.
*** mem.c.orig 2008-11-04 16:35:39.000000000 +1100
--- mem.c 2008-11-04 16:23:24.000000000 +1100
***************
*** 99,104 ****
--- 99,105 ----
for (curr = tds->dyns; curr != NULL; curr = curr->next)
if (!strcmp(curr->id, id)) {
/* id already exists! just return it */
+ curr->num_id = 0;
return curr;
}
This is what's causing the problem to occur:
- The algorithm in the tds_get_dynid function in tds/query.c will always return the same 65535 ids in a single session (The code increments the variable inc_num everytime the function is called, but then restricts its value with incr & 0xffff). This means that after the 65536's iteration of a query through the sp_prepare/sp_execute cycle, the id is the same as iteration 1.
- In tds_submit_prepare, the id from tds_get_dynid is passed to tds_alloc_dynamic. When given a previously used id, tds_alloc_dynamic will return the previously allocated structure. However, it doesn't clear its contents (in particular, the num_id variable). This causes the num_id returned from the server to be ignored in tds_process_tokens, in the TDS_PARAM_TOKEN case, where it does
if (tds->internal_sp_called == TDS_SP_PREPARE
&& tds->cur_dyn && ***tds->cur_dyn->num_id == 0*** && curcol->column_cur_size > 0) {
tds->cur_dyn->num_id = *(TDS_INT *) curcol->column_data;
}
This later causes freetds to try to sp_execute the wrong prepared statement.
Man Min
----- Original Message ----
From: Man Min Yan <manmin_yan at yahoo.com.au>
To: freetds at lists.ibiblio.org
Sent: Friday, 17 October, 2008 1:25:27 PM
Subject: [freetds] Procedure or function has too many arguments specified
Hi,
I am getting the above error when trying to execute over 65535 statements (tested with insert, update and select) using DBD::ODBC, unixODBC and freeTDS (both 0.82 stable and 0.83 20081016) talking to SQL Server 2000 and 2005. I can consistently replicate the problem with the script below.
Please note:
- my freetds.conf is configured with 'tds version = 8.0'
- I'm running on f7, with unixODBC 2.2.12-5, DBD::ODBC 1.13
- the script runs fine if I use DBD::ODBC, unixODBC, mysql-connector (sorts of eliminates DBD::ODBC, unixODBC as the culprits)
- the script runs fine if I use DBD::Proxy (eliminates the dbms side as the culprit)
- the script only fails if there is a prepared select present (even if never used).
- it always fails on record 65536 (16-bit number somewhere??)
- I've attached an extract of the freetds dump log for the last couple of records.
Any help in solving this problem would be greatly appreciated. Thanks.
---
#!/usr/local/bin/perl -w
use strict;
use DBI;
# The table 'test_table' has the following structure
# create table test_table (id int not null, value varchar(10))
my $dsn = 'dbi:ODBC:sqlserver'; my $user='xx'; my $pass='xx';
#my $dsn = 'dbi:ODBC:mysql'; my $user='xx'; my $pass='xx';
#my $dsn = 'dbi:Proxy:hostname=myserver;port=40000;dsn=dbi:ODBC:sqlserver'; my $user='xx'; my $pass='xx';
my $dbh = DBI->connect($dsn, $user, $pass,
{
PrintError => 0,
RaiseError => 0,
AutoCommit => 1,
}) or die $DBI::errstr;
$dbh->do('truncate table test_table') or die $dbh->errstr;
#my $updSth = $dbh->prepare('update test_table set value=? where id=?') or die $dbh->errstr;
my $selSth = $dbh->prepare('select * from test_table where id=?') or die $dbh->errstr;
my $insSth = $dbh->prepare('insert into test_table values (?, ?)') or die $dbh->errstr;
$| = 1;
my $maxIteration = 100000;
for (my $i = 1; $i <= $maxIteration; $i++)
{
print "$i\r";
$insSth->execute($i, $i) or die "Fail execute with $i - ", $insSth->errstr;
#$updSth->execute('v' . $i, $i) or die "Fail execute with $i - ", $updSth->errstr;
#$selSth->execute($i) or die "Fail execute with $i - ", $selSth->errstr;
#$selSth->finish();
}
Search 1000's of available singles in your area at the new Yahoo!7 Dating. Get Started http://au.dating.yahoo.com/?cid=53151&pid=1011
More information about the FreeTDS
mailing list