Re: Procedure or function has too many arguments specified

Man Min Yan <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
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 <[email protected]>
To: [email protected]
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.