freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
- From: "Thompson, Bill D (London)" <ThompBil AT exchange.uk.ml.com>
- To: "'TDS Development Group'" <freetds AT franklin.oit.unc.edu>
- Subject: RE: Parameters, resultinfo, curr_resinfo
- Date: Fri, 22 Nov 2002 08:39:17 -0000
Freddy,
I've had a quick think about your questions, as I think the issues are very
similar to ones I came across with the "compute clause" enhancements.
When I coded this, I came across the problem that I had to maintain
concurrently a (potentially infinite) number of different sets of result
"metadata". For example, a statement like :
select a,b,c,d,e
from table
order by a,b
compute sum(c) by a
compute max(e) by b
....
Could potentially have any number of different compute clauses.
The server returns data as follows:
result metadata for select clause
result metadata for compute clause 1
...
result metadata for compute clause n
data for select clause
data for compute clause n
...
data for select clause
data for compute clause n
...
data for select clause
etc. etc.
the way I coded this was to maintain the "res_info" structure for the select
cluase metadata, but to maintain a separate array of "res_info" type
structurtes for the compute clause metadata. On hitting a particular type of
data row, the pointer "curr_resinfo" would be assigned the address of the
metadata that corresponded to it (either the res_info structure or one of
the compute_info structures).
After the fact, I came to the conclusion that a more elegant way of coding
this would have been to have a linked list of "res_info" structures.
My understanding of how this should work was greatly enhanced by a detailed
reading of the ct-library documentation, particularly the bits that deal
with results processing. In ct-library, every kind of returned data is
dealt with in the same way: ct_results returns you the kind of data you are
dealing with :
CS_ROW_RESULT : select cluse data
CS_COMPUTE_RESULT : compute clause data
CS_STATUS_RESULT : Stored procedure return status data
CS_PARAM_RESULT : Return parameter results
CS_CURSOR_RESULT: cursor row results from a ct_cursor
cursor-open command
You then "describe" "bind" and "fetch" the actual data into your program.
This suggests to me that we should have a "res_info" structure for any type
of data we get back, even if (like status result) we have to "manufacture"
one ourselves. We don't currently do this for the return status of a stored
procedure. I think we should....
The question then arises - "when should we clear down our result information
structures and start again ?"
Again I think the ct-library documentation helps us here. Here's what it
says:
ct_results and logical commands
* ct_results sets *result_type to CS_CMD_DONE to indicate that the
results of a "logical command" have been completely processed.
* A logical command is defined as any command defined via ct_command,
ct_dynamic, or ct_cursor, with the following exceptions:
* Each Transact-SQL select statement that returns columns inside a
stored procedure is a logical command. Other Transact-SQL statements inside
stored procedures do not count as logical commands (including select
statements that assign values to local variables).
* Each Transact-SQL statement executed by a dynamic SQL command is a
distinct logical command.
* Each Transact-SQL statement in a language command is a logical
command.
* A command sent by a client application can execute multiple logical
commands on the server.
* A logical command can generate one or more result sets.
I think an understanding of how the results are fed back to the client is
crucial to understanding how and when we re-initialise oure results
structures. I think we should re-initiase our result info structures for
each logical command , as described above.
I think we're a bit confused about this at present, we call
tds_free_all_results() in two different circumstances. First when we submit
a command, i.e. at the top of tds_submit_query(), tds_submit_prepare(), and
tds_submit_execute(). Second, when we hit a result set, i.e at the top of
tds_process_col_name(), tds7_process_result(), tds_process_result(). We
should think about this a bit deeper...Maybe we should clear down when we
hit an end token, and then allocate a new resinfo structure in the linked
list whenever we hit something that requires one, be that result or compute
metadata, output parameters, return status etc.
Hope this helps a little , and isn't too rambling....
Bill
> -----Original Message-----
> From: Frediano Ziglio [SMTP:freddyz77 AT tin.it]
> Sent: 22 November 2002 07:06
> To: TDS Development Group
> Subject: [freetds] Parameters, resultinfo, curr_resinfo
>
> Now I understood the use of curr_resinfo in TDSSOCKET !!!
> We have three type of result:
> - row
> - parameters (output)
> - compute
> All three type can be stored in a unique structure. This waste a bit of
> memory but is very useful (another similar method is to define a basic
> structure with a type id and defined 3 structures containing this
> structure, something similar to inheritance in OO).
> I have already compiled with "typedef TDSRESULTINFO TDSPARAMINFO" and
> all work correctly!
>
> Other is the use of curr_resinfo. This is the current result info. So I
> can initialize this with param_info/res_info/a compute result/a dynamic
> result and use this structure to write data. This solve the problem were
> to store output parameters.
>
> Future: when we'll implement cursors we must handle different res_info
> for every cursor and every row info should contain compute results...
>
> freddy77
>
>
>
> ---
> You are currently subscribed to freetds as: [thompbil AT exchange.uk.ml.com]
> To unsubscribe, forward this message to
> $subst('Email.Unsub')
-
Parameters, resultinfo, curr_resinfo,
Frediano Ziglio, 11/22/2002
- <Possible follow-up(s)>
- RE: Parameters, resultinfo, curr_resinfo, Thompson, Bill D (London), 11/22/2002
Archive powered by MHonArc 2.6.24.