Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
296e7ba2
Commit
296e7ba2
authored
May 08, 2001
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ODBC source code cleanup patch. Should match rest of PostgreSQL code better.
parent
062a79a9
Changes
24
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
990 additions
and
1182 deletions
+990
-1182
src/interfaces/odbc/bind.c
src/interfaces/odbc/bind.c
+45
-44
src/interfaces/odbc/columninfo.c
src/interfaces/odbc/columninfo.c
+13
-12
src/interfaces/odbc/connection.c
src/interfaces/odbc/connection.c
+79
-68
src/interfaces/odbc/convert.c
src/interfaces/odbc/convert.c
+97
-112
src/interfaces/odbc/dlg_specific.c
src/interfaces/odbc/dlg_specific.c
+24
-38
src/interfaces/odbc/drvconn.c
src/interfaces/odbc/drvconn.c
+14
-23
src/interfaces/odbc/environ.c
src/interfaces/odbc/environ.c
+17
-22
src/interfaces/odbc/execute.c
src/interfaces/odbc/execute.c
+35
-66
src/interfaces/odbc/gpps.c
src/interfaces/odbc/gpps.c
+27
-46
src/interfaces/odbc/info.c
src/interfaces/odbc/info.c
+103
-144
src/interfaces/odbc/lobj.c
src/interfaces/odbc/lobj.c
+11
-19
src/interfaces/odbc/misc.c
src/interfaces/odbc/misc.c
+33
-21
src/interfaces/odbc/multibyte.c
src/interfaces/odbc/multibyte.c
+22
-19
src/interfaces/odbc/options.c
src/interfaces/odbc/options.c
+45
-62
src/interfaces/odbc/parse.c
src/interfaces/odbc/parse.c
+28
-60
src/interfaces/odbc/pgtypes.c
src/interfaces/odbc/pgtypes.c
+81
-62
src/interfaces/odbc/psqlodbc.c
src/interfaces/odbc/psqlodbc.c
+16
-15
src/interfaces/odbc/qresult.c
src/interfaces/odbc/qresult.c
+72
-57
src/interfaces/odbc/results.c
src/interfaces/odbc/results.c
+76
-123
src/interfaces/odbc/setup.c
src/interfaces/odbc/setup.c
+60
-65
src/interfaces/odbc/socket.c
src/interfaces/odbc/socket.c
+15
-14
src/interfaces/odbc/statement.c
src/interfaces/odbc/statement.c
+57
-74
src/interfaces/odbc/tuple.c
src/interfaces/odbc/tuple.c
+12
-7
src/interfaces/odbc/tuplelist.c
src/interfaces/odbc/tuplelist.c
+8
-9
No files found.
src/interfaces/odbc/bind.c
View file @
296e7ba2
/* Module: bind.c
/*-------
* Module: bind.c
*
*
* Description: This module contains routines related to binding
* Description: This module contains routines related to binding
* columns and parameters.
* columns and parameters.
...
@@ -9,7 +10,7 @@
...
@@ -9,7 +10,7 @@
* SQLParamOptions(NI)
* SQLParamOptions(NI)
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -33,8 +34,8 @@
...
@@ -33,8 +34,8 @@
#include "sqlext.h"
#include "sqlext.h"
#endif
#endif
/* Bind parameters on a statement handle */
/* Bind parameters on a statement handle */
RETCODE
SQL_API
RETCODE
SQL_API
SQLBindParameter
(
SQLBindParameter
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -112,8 +113,8 @@ SQLBindParameter(
...
@@ -112,8 +113,8 @@ SQLBindParameter(
}
}
}
}
ipar
--
;
/* use zero based column numbers for the
/* use zero based column numbers for the below part */
* below part */
ipar
--
;
/* store the given info */
/* store the given info */
stmt
->
parameters
[
ipar
].
buflen
=
cbValueMax
;
stmt
->
parameters
[
ipar
].
buflen
=
cbValueMax
;
...
@@ -158,7 +159,6 @@ SQLBindParameter(
...
@@ -158,7 +159,6 @@ SQLBindParameter(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
/* Associate a user-supplied buffer with a database column. */
/* Associate a user-supplied buffer with a database column. */
RETCODE
SQL_API
RETCODE
SQL_API
...
@@ -197,7 +197,6 @@ SQLBindCol(
...
@@ -197,7 +197,6 @@ SQLBindCol(
/* If the bookmark column is being bound, then just save it */
/* If the bookmark column is being bound, then just save it */
if
(
icol
==
0
)
if
(
icol
==
0
)
{
{
if
(
rgbValue
==
NULL
)
if
(
rgbValue
==
NULL
)
{
{
stmt
->
bookmark
.
buffer
=
NULL
;
stmt
->
bookmark
.
buffer
=
NULL
;
...
@@ -220,10 +219,12 @@ SQLBindCol(
...
@@ -220,10 +219,12 @@ SQLBindCol(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* allocate enough bindings if not already done */
/*
/* Most likely, execution of a statement would have setup the */
* Allocate enough bindings if not already done.
/* necessary bindings. But some apps call BindCol before any */
* Most likely, execution of a statement would have setup the
/* statement is executed. */
* necessary bindings. But some apps call BindCol before any
* statement is executed.
*/
if
(
icol
>
stmt
->
bindings_allocated
)
if
(
icol
>
stmt
->
bindings_allocated
)
extend_bindings
(
stmt
,
icol
);
extend_bindings
(
stmt
,
icol
);
...
@@ -236,8 +237,8 @@ SQLBindCol(
...
@@ -236,8 +237,8 @@ SQLBindCol(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
icol
--
;
/* use zero based col numbers from here
/* use zero based col numbers from here out */
* out */
icol
--
;
/* Reset for SQLGetData */
/* Reset for SQLGetData */
stmt
->
bindings
[
icol
].
data_left
=
-
1
;
stmt
->
bindings
[
icol
].
data_left
=
-
1
;
...
@@ -264,15 +265,15 @@ SQLBindCol(
...
@@ -264,15 +265,15 @@ SQLBindCol(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
/* Returns the description of a parameter marker. */
/* This function is listed as not being supported by SQLGetFunctions() because it is */
/* used to describe "parameter markers" (not bound parameters), in which case, */
/* the dbms should return info on the markers. Since Postgres doesn't support that, */
/* it is best to say this function is not supported and let the application assume a */
/* data type (most likely varchar). */
/*
* Returns the description of a parameter marker.
* This function is listed as not being supported by SQLGetFunctions() because it is
* used to describe "parameter markers" (not bound parameters), in which case,
* the dbms should return info on the markers. Since Postgres doesn't support that,
* it is best to say this function is not supported and let the application assume a
* data type (most likely varchar).
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLDescribeParam
(
SQLDescribeParam
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -323,10 +324,8 @@ SQLDescribeParam(
...
@@ -323,10 +324,8 @@ SQLDescribeParam(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
/* Sets multiple values (arrays) for the set of parameter markers. */
/* Sets multiple values (arrays) for the set of parameter markers. */
RETCODE
SQL_API
RETCODE
SQL_API
SQLParamOptions
(
SQLParamOptions
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -341,15 +340,16 @@ SQLParamOptions(
...
@@ -341,15 +340,16 @@ SQLParamOptions(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* - - - - - - - - - */
/* This function should really talk to the dbms to determine the number of */
/*
/* "parameter markers" (not bound parameters) in the statement. But, since */
* This function should really talk to the dbms to determine the number of
/* Postgres doesn't support that, the driver should just count the number of markers */
* "parameter markers" (not bound parameters) in the statement. But, since
/* and return that. The reason the driver just can't say this function is unsupported */
* Postgres doesn't support that, the driver should just count the number of markers
/* like it does for SQLDescribeParam is that some applications don't care and try */
* and return that. The reason the driver just can't say this function is unsupported
/* to call it anyway. */
* like it does for SQLDescribeParam is that some applications don't care and try
/* If the statement does not have parameters, it should just return 0. */
* to call it anyway.
* If the statement does not have parameters, it should just return 0.
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLNumParams
(
SQLNumParams
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -387,10 +387,8 @@ SQLNumParams(
...
@@ -387,10 +387,8 @@ SQLNumParams(
}
}
else
else
{
{
for
(
i
=
0
;
i
<
strlen
(
stmt
->
statement
);
i
++
)
for
(
i
=
0
;
i
<
strlen
(
stmt
->
statement
);
i
++
)
{
{
if
(
stmt
->
statement
[
i
]
==
'?'
&&
!
in_quote
)
if
(
stmt
->
statement
[
i
]
==
'?'
&&
!
in_quote
)
(
*
pcpar
)
++
;
(
*
pcpar
)
++
;
else
else
...
@@ -399,12 +397,12 @@ SQLNumParams(
...
@@ -399,12 +397,12 @@ SQLNumParams(
in_quote
=
(
in_quote
?
FALSE
:
TRUE
);
in_quote
=
(
in_quote
?
FALSE
:
TRUE
);
}
}
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
}
}
/********************************************************************
/*
* Bindings Implementation
* Bindings Implementation
*/
*/
BindInfoClass
*
BindInfoClass
*
...
@@ -428,6 +426,7 @@ create_empty_bindings(int num_columns)
...
@@ -428,6 +426,7 @@ create_empty_bindings(int num_columns)
return
new_bindings
;
return
new_bindings
;
}
}
void
void
extend_bindings
(
StatementClass
*
stmt
,
int
num_columns
)
extend_bindings
(
StatementClass
*
stmt
,
int
num_columns
)
{
{
...
@@ -437,11 +436,12 @@ extend_bindings(StatementClass *stmt, int num_columns)
...
@@ -437,11 +436,12 @@ extend_bindings(StatementClass *stmt, int num_columns)
mylog
(
"%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d
\n
"
,
func
,
stmt
,
stmt
->
bindings_allocated
,
num_columns
);
mylog
(
"%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d
\n
"
,
func
,
stmt
,
stmt
->
bindings_allocated
,
num_columns
);
/* if we have too few, allocate room for more, and copy the old */
/*
/* entries into the new structure */
* if we have too few, allocate room for more, and copy the old
* entries into the new structure
*/
if
(
stmt
->
bindings_allocated
<
num_columns
)
if
(
stmt
->
bindings_allocated
<
num_columns
)
{
{
new_bindings
=
create_empty_bindings
(
num_columns
);
new_bindings
=
create_empty_bindings
(
num_columns
);
if
(
!
new_bindings
)
if
(
!
new_bindings
)
{
{
...
@@ -466,11 +466,12 @@ extend_bindings(StatementClass *stmt, int num_columns)
...
@@ -466,11 +466,12 @@ extend_bindings(StatementClass *stmt, int num_columns)
stmt
->
bindings
=
new_bindings
;
stmt
->
bindings
=
new_bindings
;
stmt
->
bindings_allocated
=
num_columns
;
stmt
->
bindings_allocated
=
num_columns
;
}
}
/* There is no reason to zero out extra bindings if there are */
/*
/* more than needed. If an app has allocated extra bindings, */
* There is no reason to zero out extra bindings if there are
/* let it worry about it by unbinding those columns. */
* more than needed. If an app has allocated extra bindings,
* let it worry about it by unbinding those columns.
*/
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
/* SQLExecDirect(...) # returns 5 cols */
/* SQLExecDirect(...) # returns 5 cols */
...
...
src/interfaces/odbc/columninfo.c
View file @
296e7ba2
/* Module: columninfo.c
/*-------
* Module: columninfo.c
*
*
* Description: This module contains routines related to
* Description: This module contains routines related to
* reading and storing the field information from a query.
* reading and storing the field information from a query.
...
@@ -8,7 +9,7 @@
...
@@ -8,7 +9,7 @@
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#include "columninfo.h"
#include "columninfo.h"
...
@@ -37,6 +38,7 @@ CI_Constructor()
...
@@ -37,6 +38,7 @@ CI_Constructor()
return
rv
;
return
rv
;
}
}
void
void
CI_Destructor
(
ColumnInfoClass
*
self
)
CI_Destructor
(
ColumnInfoClass
*
self
)
{
{
...
@@ -45,10 +47,12 @@ CI_Destructor(ColumnInfoClass *self)
...
@@ -45,10 +47,12 @@ CI_Destructor(ColumnInfoClass *self)
free
(
self
);
free
(
self
);
}
}
/* Read in field descriptions.
If self is not null, then also store the information.
/*
If self is null, then just read, don't store.
* Read in field descriptions.
*/
* If self is not null, then also store the information.
* If self is null, then just read, don't store.
*/
char
char
CI_read_fields
(
ColumnInfoClass
*
self
,
ConnectionClass
*
conn
)
CI_read_fields
(
ColumnInfoClass
*
self
,
ConnectionClass
*
conn
)
{
{
...
@@ -71,14 +75,12 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
...
@@ -71,14 +75,12 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
mylog
(
"num_fields = %d
\n
"
,
new_num_fields
);
mylog
(
"num_fields = %d
\n
"
,
new_num_fields
);
if
(
self
)
if
(
self
)
{
/* according to that allocate memory */
/* according to that allocate memory */
CI_set_num_fields
(
self
,
new_num_fields
);
CI_set_num_fields
(
self
,
new_num_fields
);
}
/* now read in the descriptions */
/* now read in the descriptions */
for
(
lf
=
0
;
lf
<
new_num_fields
;
lf
++
)
for
(
lf
=
0
;
lf
<
new_num_fields
;
lf
++
)
{
{
SOCK_get_string
(
sock
,
new_field_name
,
2
*
MAX_COLUMN_LEN
);
SOCK_get_string
(
sock
,
new_field_name
,
2
*
MAX_COLUMN_LEN
);
new_adtid
=
(
Oid
)
SOCK_get_int
(
sock
,
4
);
new_adtid
=
(
Oid
)
SOCK_get_int
(
sock
,
4
);
new_adtsize
=
(
Int2
)
SOCK_get_int
(
sock
,
2
);
new_adtsize
=
(
Int2
)
SOCK_get_int
(
sock
,
2
);
...
@@ -86,7 +88,6 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
...
@@ -86,7 +88,6 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
/* If 6.4 protocol, then read the atttypmod field */
/* If 6.4 protocol, then read the atttypmod field */
if
(
PG_VERSION_GE
(
conn
,
6
.
4
))
if
(
PG_VERSION_GE
(
conn
,
6
.
4
))
{
{
mylog
(
"READING ATTTYPMOD
\n
"
);
mylog
(
"READING ATTTYPMOD
\n
"
);
new_atttypmod
=
(
Int4
)
SOCK_get_int
(
sock
,
4
);
new_atttypmod
=
(
Int4
)
SOCK_get_int
(
sock
,
4
);
...
@@ -107,7 +108,6 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
...
@@ -107,7 +108,6 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
}
}
void
void
CI_free_memory
(
ColumnInfoClass
*
self
)
CI_free_memory
(
ColumnInfoClass
*
self
)
{
{
...
@@ -143,6 +143,7 @@ CI_free_memory(ColumnInfoClass *self)
...
@@ -143,6 +143,7 @@ CI_free_memory(ColumnInfoClass *self)
self
->
atttypmod
=
NULL
;
self
->
atttypmod
=
NULL
;
}
}
void
void
CI_set_num_fields
(
ColumnInfoClass
*
self
,
int
new_num_fields
)
CI_set_num_fields
(
ColumnInfoClass
*
self
,
int
new_num_fields
)
{
{
...
@@ -158,11 +159,11 @@ CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
...
@@ -158,11 +159,11 @@ CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
self
->
atttypmod
=
(
Int4
*
)
malloc
(
sizeof
(
Int4
)
*
self
->
num_fields
);
self
->
atttypmod
=
(
Int4
*
)
malloc
(
sizeof
(
Int4
)
*
self
->
num_fields
);
}
}
void
void
CI_set_field_info
(
ColumnInfoClass
*
self
,
int
field_num
,
char
*
new_name
,
CI_set_field_info
(
ColumnInfoClass
*
self
,
int
field_num
,
char
*
new_name
,
Oid
new_adtid
,
Int2
new_adtsize
,
Int4
new_atttypmod
)
Oid
new_adtid
,
Int2
new_adtsize
,
Int4
new_atttypmod
)
{
{
/* check bounds */
/* check bounds */
if
((
field_num
<
0
)
||
(
field_num
>=
self
->
num_fields
))
if
((
field_num
<
0
)
||
(
field_num
>=
self
->
num_fields
))
return
;
return
;
...
...
src/interfaces/odbc/connection.c
View file @
296e7ba2
/* Module: connection.c
/*------
* Module: connection.c
*
*
* Description: This module contains routines related to
* Description: This module contains routines related to
* connecting to and disconnecting from the Postgres DBMS.
* connecting to and disconnecting from the Postgres DBMS.
...
@@ -9,7 +10,7 @@
...
@@ -9,7 +10,7 @@
* SQLBrowseConnect(NI)
* SQLBrowseConnect(NI)
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
/* Multibyte support Eiji Tokuya 2001-03-15 */
...
@@ -83,8 +84,6 @@ SQLAllocConnect(
...
@@ -83,8 +84,6 @@ SQLAllocConnect(
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLConnect
(
SQLConnect
(
HDBC
hdbc
,
HDBC
hdbc
,
...
@@ -140,7 +139,6 @@ SQLConnect(
...
@@ -140,7 +139,6 @@ SQLConnect(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLBrowseConnect
(
SQLBrowseConnect
(
...
@@ -158,7 +156,6 @@ SQLBrowseConnect(
...
@@ -158,7 +156,6 @@ SQLBrowseConnect(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
/* Drop any hstmts open on hdbc and disconnect from database */
/* Drop any hstmts open on hdbc and disconnect from database */
RETCODE
SQL_API
RETCODE
SQL_API
...
@@ -199,8 +196,6 @@ SQLDisconnect(
...
@@ -199,8 +196,6 @@ SQLDisconnect(
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLFreeConnect
(
SQLFreeConnect
(
HDBC
hdbc
)
HDBC
hdbc
)
...
@@ -235,11 +230,8 @@ SQLFreeConnect(
...
@@ -235,11 +230,8 @@ SQLFreeConnect(
/*
/*
*
* IMPLEMENTATION CONNECTION CLASS
* IMPLEMENTATION CONNECTION CLASS
*/
*
*/
ConnectionClass
*
ConnectionClass
*
CC_Constructor
()
CC_Constructor
()
{
{
...
@@ -249,7 +241,6 @@ CC_Constructor()
...
@@ -249,7 +241,6 @@ CC_Constructor()
if
(
rv
!=
NULL
)
if
(
rv
!=
NULL
)
{
{
rv
->
henv
=
NULL
;
/* not yet associated with an environment */
rv
->
henv
=
NULL
;
/* not yet associated with an environment */
rv
->
errormsg
=
NULL
;
rv
->
errormsg
=
NULL
;
...
@@ -301,7 +292,6 @@ CC_Constructor()
...
@@ -301,7 +292,6 @@ CC_Constructor()
char
char
CC_Destructor
(
ConnectionClass
*
self
)
CC_Destructor
(
ConnectionClass
*
self
)
{
{
mylog
(
"enter CC_Destructor, self=%u
\n
"
,
self
);
mylog
(
"enter CC_Destructor, self=%u
\n
"
,
self
);
if
(
self
->
status
==
CONN_EXECUTING
)
if
(
self
->
status
==
CONN_EXECUTING
)
...
@@ -343,6 +333,7 @@ CC_Destructor(ConnectionClass *self)
...
@@ -343,6 +333,7 @@ CC_Destructor(ConnectionClass *self)
return
1
;
return
1
;
}
}
/* Return how many cursors are opened on this connection */
/* Return how many cursors are opened on this connection */
int
int
CC_cursor_count
(
ConnectionClass
*
self
)
CC_cursor_count
(
ConnectionClass
*
self
)
...
@@ -365,6 +356,7 @@ CC_cursor_count(ConnectionClass *self)
...
@@ -365,6 +356,7 @@ CC_cursor_count(ConnectionClass *self)
return
count
;
return
count
;
}
}
void
void
CC_clear_error
(
ConnectionClass
*
self
)
CC_clear_error
(
ConnectionClass
*
self
)
{
{
...
@@ -373,8 +365,11 @@ CC_clear_error(ConnectionClass *self)
...
@@ -373,8 +365,11 @@ CC_clear_error(ConnectionClass *self)
self
->
errormsg_created
=
FALSE
;
self
->
errormsg_created
=
FALSE
;
}
}
/* Used to cancel a transaction */
/* We are almost always in the middle of a transaction. */
/*
* Used to cancel a transaction.
* We are almost always in the middle of a transaction.
*/
char
char
CC_abort
(
ConnectionClass
*
self
)
CC_abort
(
ConnectionClass
*
self
)
{
{
...
@@ -399,6 +394,7 @@ CC_abort(ConnectionClass *self)
...
@@ -399,6 +394,7 @@ CC_abort(ConnectionClass *self)
return
TRUE
;
return
TRUE
;
}
}
/* This is called by SQLDisconnect also */
/* This is called by SQLDisconnect also */
char
char
CC_cleanup
(
ConnectionClass
*
self
)
CC_cleanup
(
ConnectionClass
*
self
)
...
@@ -434,7 +430,6 @@ CC_cleanup(ConnectionClass *self)
...
@@ -434,7 +430,6 @@ CC_cleanup(ConnectionClass *self)
stmt
=
self
->
stmts
[
i
];
stmt
=
self
->
stmts
[
i
];
if
(
stmt
)
if
(
stmt
)
{
{
stmt
->
hdbc
=
NULL
;
/* prevent any more dbase interactions */
stmt
->
hdbc
=
NULL
;
/* prevent any more dbase interactions */
SC_Destructor
(
stmt
);
SC_Destructor
(
stmt
);
...
@@ -456,6 +451,7 @@ CC_cleanup(ConnectionClass *self)
...
@@ -456,6 +451,7 @@ CC_cleanup(ConnectionClass *self)
return
TRUE
;
return
TRUE
;
}
}
int
int
CC_set_translation
(
ConnectionClass
*
self
)
CC_set_translation
(
ConnectionClass
*
self
)
{
{
...
@@ -499,6 +495,7 @@ CC_set_translation(ConnectionClass *self)
...
@@ -499,6 +495,7 @@ CC_set_translation(ConnectionClass *self)
return
TRUE
;
return
TRUE
;
}
}
char
char
CC_connect
(
ConnectionClass
*
self
,
char
do_password
)
CC_connect
(
ConnectionClass
*
self
,
char
do_password
)
{
{
...
@@ -521,7 +518,6 @@ CC_connect(ConnectionClass *self, char do_password)
...
@@ -521,7 +518,6 @@ CC_connect(ConnectionClass *self, char do_password)
else
else
{
{
qlog
(
"Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d
\n
"
,
qlog
(
"Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d
\n
"
,
POSTGRESDRIVERVERSION
,
POSTGRESDRIVERVERSION
,
globals
.
fetch_max
,
globals
.
fetch_max
,
...
@@ -646,14 +642,13 @@ CC_connect(ConnectionClass *self, char do_password)
...
@@ -646,14 +642,13 @@ CC_connect(ConnectionClass *self, char do_password)
mylog
(
"gonna do authentication
\n
"
);
mylog
(
"gonna do authentication
\n
"
);
/*
*************************************************** */
/*
/* Now get the authentication request from backend */
* Now get the authentication request from backend
/* ***************************************************
*/
*/
if
(
!
PROTOCOL_62
(
ci
))
if
(
!
PROTOCOL_62
(
ci
))
do
do
{
{
if
(
do_password
)
if
(
do_password
)
beresp
=
'R'
;
beresp
=
'R'
;
else
else
...
@@ -743,8 +738,10 @@ CC_connect(ConnectionClass *self, char do_password)
...
@@ -743,8 +738,10 @@ CC_connect(ConnectionClass *self, char do_password)
CC_clear_error
(
self
);
/* clear any password error */
CC_clear_error
(
self
);
/* clear any password error */
/* send an empty query in order to find out whether the specified */
/*
/* database really exists on the server machine */
* send an empty query in order to find out whether the specified
* database really exists on the server machine
*/
mylog
(
"sending an empty query...
\n
"
);
mylog
(
"sending an empty query...
\n
"
);
res
=
CC_send_query
(
self
,
" "
,
NULL
);
res
=
CC_send_query
(
self
,
" "
,
NULL
);
...
@@ -764,9 +761,9 @@ CC_connect(ConnectionClass *self, char do_password)
...
@@ -764,9 +761,9 @@ CC_connect(ConnectionClass *self, char do_password)
CC_set_translation
(
self
);
CC_set_translation
(
self
);
/*
*********************************************/
/*
/******* Send any initial settings *********/
* Send any initial settings
/*********************************************
*/
*/
/*
/*
* Since these functions allocate statements, and since the connection
* Since these functions allocate statements, and since the connection
...
@@ -789,6 +786,7 @@ CC_connect(ConnectionClass *self, char do_password)
...
@@ -789,6 +786,7 @@ CC_connect(ConnectionClass *self, char do_password)
}
}
char
char
CC_add_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
)
CC_add_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
)
{
{
...
@@ -821,6 +819,7 @@ CC_add_statement(ConnectionClass *self, StatementClass *stmt)
...
@@ -821,6 +819,7 @@ CC_add_statement(ConnectionClass *self, StatementClass *stmt)
return
TRUE
;
return
TRUE
;
}
}
char
char
CC_remove_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
)
CC_remove_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
)
{
{
...
@@ -838,9 +837,11 @@ CC_remove_statement(ConnectionClass *self, StatementClass *stmt)
...
@@ -838,9 +837,11 @@ CC_remove_statement(ConnectionClass *self, StatementClass *stmt)
return
FALSE
;
return
FALSE
;
}
}
/* Create a more informative error message by concatenating the connection
error message with its socket error message.
/*
*/
* Create a more informative error message by concatenating the connection
* error message with its socket error message.
*/
char
*
char
*
CC_create_errormsg
(
ConnectionClass
*
self
)
CC_create_errormsg
(
ConnectionClass
*
self
)
{
{
...
@@ -897,14 +898,15 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
...
@@ -897,14 +898,15 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
}
}
/* The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
/*
the same existing QResultClass (this occurs when the tuple cache is depleted and
* The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
needs to be re-filled).
* the same existing QResultClass (this occurs when the tuple cache is depleted and
* needs to be re-filled).
The "cursor" is used by SQLExecute to associate a statement handle as the cursor name
*
(i.e., C3326857) for SQL select statements. This cursor is then used in future
* The "cursor" is used by SQLExecute to associate a statement handle as the cursor name
'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
* (i.e., C3326857) for SQL select statements. This cursor is then used in future
*/
* 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
*/
QResultClass
*
QResultClass
*
CC_send_query
(
ConnectionClass
*
self
,
char
*
query
,
QueryInfo
*
qi
)
CC_send_query
(
ConnectionClass
*
self
,
char
*
query
,
QueryInfo
*
qi
)
{
{
...
@@ -915,10 +917,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
...
@@ -915,10 +917,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
SocketClass
*
sock
=
self
->
sock
;
SocketClass
*
sock
=
self
->
sock
;
/* ERROR_MSG_LENGTH is suffcient */
/* ERROR_MSG_LENGTH is suffcient */
static
char
msgbuffer
[
ERROR_MSG_LENGTH
+
1
];
static
char
msgbuffer
[
ERROR_MSG_LENGTH
+
1
];
char
cmdbuffer
[
ERROR_MSG_LENGTH
+
1
];
/* QR_set_command() dups
/* QR_set_command() dups this string so doesn't need static */
* this string so dont
char
cmdbuffer
[
ERROR_MSG_LENGTH
+
1
];
* need static */
mylog
(
"send_query(): conn=%u, query='%s'
\n
"
,
self
,
query
);
mylog
(
"send_query(): conn=%u, query='%s'
\n
"
,
self
,
query
);
qlog
(
"conn=%u, query='%s'
\n
"
,
self
,
query
);
qlog
(
"conn=%u, query='%s'
\n
"
,
self
,
query
);
...
@@ -1004,7 +1004,6 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
...
@@ -1004,7 +1004,6 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
}
}
else
else
{
{
char
clear
=
0
;
char
clear
=
0
;
mylog
(
"send_query: ok - 'C' - %s
\n
"
,
cmdbuffer
);
mylog
(
"send_query: ok - 'C' - %s
\n
"
,
cmdbuffer
);
...
@@ -1203,6 +1202,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
...
@@ -1203,6 +1202,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
}
}
}
}
int
int
CC_send_function
(
ConnectionClass
*
self
,
int
fnid
,
void
*
result_buf
,
int
*
actual_result_len
,
int
result_is_int
,
LO_ARG
*
args
,
int
nargs
)
CC_send_function
(
ConnectionClass
*
self
,
int
fnid
,
void
*
result_buf
,
int
*
actual_result_len
,
int
result_is_int
,
LO_ARG
*
args
,
int
nargs
)
{
{
...
@@ -1241,7 +1241,6 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
...
@@ -1241,7 +1241,6 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
for
(
i
=
0
;
i
<
nargs
;
++
i
)
for
(
i
=
0
;
i
<
nargs
;
++
i
)
{
{
mylog
(
" arg[%d]: len = %d, isint = %d, integer = %d, ptr = %u
\n
"
,
i
,
args
[
i
].
len
,
args
[
i
].
isint
,
args
[
i
].
u
.
integer
,
args
[
i
].
u
.
ptr
);
mylog
(
" arg[%d]: len = %d, isint = %d, integer = %d, ptr = %u
\n
"
,
i
,
args
[
i
].
len
,
args
[
i
].
isint
,
args
[
i
].
u
.
integer
,
args
[
i
].
u
.
ptr
);
SOCK_put_int
(
sock
,
args
[
i
].
len
,
4
);
SOCK_put_int
(
sock
,
args
[
i
].
len
,
4
);
...
@@ -1373,9 +1372,10 @@ CC_send_settings(ConnectionClass *self)
...
@@ -1373,9 +1372,10 @@ CC_send_settings(ConnectionClass *self)
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
/* This function must use the local odbc API functions since the odbc state
/*
has not transitioned to "connected" yet.
* This function must use the local odbc API functions since the odbc state
*/
* has not transitioned to "connected" yet.
*/
result
=
SQLAllocStmt
(
self
,
&
hstmt
);
result
=
SQLAllocStmt
(
self
,
&
hstmt
);
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
...
@@ -1457,10 +1457,12 @@ CC_send_settings(ConnectionClass *self)
...
@@ -1457,10 +1457,12 @@ CC_send_settings(ConnectionClass *self)
return
status
;
return
status
;
}
}
/* This function is just a hack to get the oid of our Large Object oid type.
If a real Large Object oid type is made part of Postgres, this function
/*
will go away and the define 'PG_TYPE_LO' will be updated.
* This function is just a hack to get the oid of our Large Object oid type.
*/
* If a real Large Object oid type is made part of Postgres, this function
* will go away and the define 'PG_TYPE_LO' will be updated.
*/
void
void
CC_lookup_lo
(
ConnectionClass
*
self
)
CC_lookup_lo
(
ConnectionClass
*
self
)
{
{
...
@@ -1471,9 +1473,10 @@ CC_lookup_lo(ConnectionClass *self)
...
@@ -1471,9 +1473,10 @@ CC_lookup_lo(ConnectionClass *self)
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
/* This function must use the local odbc API functions since the odbc state
/*
has not transitioned to "connected" yet.
* This function must use the local odbc API functions since the odbc state
*/
* has not transitioned to "connected" yet.
*/
result
=
SQLAllocStmt
(
self
,
&
hstmt
);
result
=
SQLAllocStmt
(
self
,
&
hstmt
);
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
return
;
return
;
...
@@ -1506,10 +1509,12 @@ CC_lookup_lo(ConnectionClass *self)
...
@@ -1506,10 +1509,12 @@ CC_lookup_lo(ConnectionClass *self)
result
=
SQLFreeStmt
(
hstmt
,
SQL_DROP
);
result
=
SQLFreeStmt
(
hstmt
,
SQL_DROP
);
}
}
/* This function initializes the version of PostgreSQL from
connInfo.protocol that we're connected to.
/*
h-inoue 01-2-2001
* This function initializes the version of PostgreSQL from
*/
* connInfo.protocol that we're connected to.
* h-inoue 01-2-2001
*/
void
void
CC_initialize_pg_version
(
ConnectionClass
*
self
)
CC_initialize_pg_version
(
ConnectionClass
*
self
)
{
{
...
@@ -1534,10 +1539,12 @@ CC_initialize_pg_version(ConnectionClass *self)
...
@@ -1534,10 +1539,12 @@ CC_initialize_pg_version(ConnectionClass *self)
}
}
}
}
/* This function gets the version of PostgreSQL that we're connected to.
This is used to return the correct info in SQLGetInfo
/*
DJP - 25-1-2001
* This function gets the version of PostgreSQL that we're connected to.
*/
* This is used to return the correct info in SQLGetInfo
* DJP - 25-1-2001
*/
void
void
CC_lookup_pg_version
(
ConnectionClass
*
self
)
CC_lookup_pg_version
(
ConnectionClass
*
self
)
{
{
...
@@ -1551,9 +1558,10 @@ CC_lookup_pg_version(ConnectionClass *self)
...
@@ -1551,9 +1558,10 @@ CC_lookup_pg_version(ConnectionClass *self)
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
/* This function must use the local odbc API functions since the odbc state
/*
has not transitioned to "connected" yet.
* This function must use the local odbc API functions since the odbc state
*/
* has not transitioned to "connected" yet.
*/
result
=
SQLAllocStmt
(
self
,
&
hstmt
);
result
=
SQLAllocStmt
(
self
,
&
hstmt
);
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
return
;
return
;
...
@@ -1581,8 +1589,10 @@ CC_lookup_pg_version(ConnectionClass *self)
...
@@ -1581,8 +1589,10 @@ CC_lookup_pg_version(ConnectionClass *self)
return
;
return
;
}
}
/* Extract the Major and Minor numbers from the string. */
/*
/* This assumes the string starts 'Postgresql X.X' */
* Extract the Major and Minor numbers from the string.
* This assumes the string starts 'Postgresql X.X'
*/
strcpy
(
szVersion
,
"0.0"
);
strcpy
(
szVersion
,
"0.0"
);
if
(
sscanf
(
self
->
pg_version
,
"%*s %d.%d"
,
&
major
,
&
minor
)
>=
2
)
if
(
sscanf
(
self
->
pg_version
,
"%*s %d.%d"
,
&
major
,
&
minor
)
>=
2
)
{
{
...
@@ -1600,6 +1610,7 @@ CC_lookup_pg_version(ConnectionClass *self)
...
@@ -1600,6 +1610,7 @@ CC_lookup_pg_version(ConnectionClass *self)
result
=
SQLFreeStmt
(
hstmt
,
SQL_DROP
);
result
=
SQLFreeStmt
(
hstmt
,
SQL_DROP
);
}
}
void
void
CC_log_error
(
char
*
func
,
char
*
desc
,
ConnectionClass
*
self
)
CC_log_error
(
char
*
func
,
char
*
desc
,
ConnectionClass
*
self
)
{
{
...
...
src/interfaces/odbc/convert.c
View file @
296e7ba2
/* Module: convert.c
/*-------
* Module: convert.c
*
*
* Description: This module contains routines related to
* Description: This module contains routines related to
* converting parameters and columns into requested data types.
* converting parameters and columns into requested data types.
...
@@ -12,7 +13,7 @@
...
@@ -12,7 +13,7 @@
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
/* Multibyte support Eiji Tokuya 2001-03-15 */
...
@@ -64,9 +65,9 @@ typedef signed char SCHAR;
...
@@ -64,9 +65,9 @@ typedef signed char SCHAR;
extern
GLOBAL_VALUES
globals
;
extern
GLOBAL_VALUES
globals
;
/*
How to map ODBC scalar functions {fn func(args)} to Postgres
/*
*
This is just a simple substitution
*
How to map ODBC scalar functions {fn func(args)} to Postgres.
*
List augmented from
*
This is just a simple substitution. List augmented from:
* http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm
* http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm
* - thomas 2000-04-03
* - thomas 2000-04-03
*/
*/
...
@@ -141,21 +142,24 @@ unsigned int conv_from_octal(unsigned char *s);
...
@@ -141,21 +142,24 @@ unsigned int conv_from_octal(unsigned char *s);
unsigned
int
conv_from_hex
(
unsigned
char
*
s
);
unsigned
int
conv_from_hex
(
unsigned
char
*
s
);
char
*
conv_to_octal
(
unsigned
char
val
);
char
*
conv_to_octal
(
unsigned
char
val
);
/******** A Guide for date/time/timestamp conversions **************
/*---------
* A Guide for date/time/timestamp conversions
*
* field_type fCType Output
* ---------- ------ ----------
* PG_TYPE_DATE SQL_C_DEFAULT SQL_C_DATE
* PG_TYPE_DATE SQL_C_DATE SQL_C_DATE
* PG_TYPE_DATE SQL_C_TIMESTAMP SQL_C_TIMESTAMP (time = 0 (midnight))
* PG_TYPE_TIME SQL_C_DEFAULT SQL_C_TIME
* PG_TYPE_TIME SQL_C_TIME SQL_C_TIME
* PG_TYPE_TIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP (date = current date)
* PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP
* PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated)
* PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated)
* PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP
*---------
*/
field_type fCType Output
---------- ------ ----------
PG_TYPE_DATE SQL_C_DEFAULT SQL_C_DATE
PG_TYPE_DATE SQL_C_DATE SQL_C_DATE
PG_TYPE_DATE SQL_C_TIMESTAMP SQL_C_TIMESTAMP (time = 0 (midnight))
PG_TYPE_TIME SQL_C_DEFAULT SQL_C_TIME
PG_TYPE_TIME SQL_C_TIME SQL_C_TIME
PG_TYPE_TIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP (date = current date)
PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP
PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated)
PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated)
PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP
******************************************************************************/
/* This is called by SQLFetch() */
/* This is called by SQLFetch() */
...
@@ -168,6 +172,7 @@ copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *val
...
@@ -168,6 +172,7 @@ copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *val
(
SDWORD
)
bic
->
buflen
,
(
SDWORD
*
)
bic
->
used
);
(
SDWORD
)
bic
->
buflen
,
(
SDWORD
*
)
bic
->
used
);
}
}
/* This is called by SQLGetData() */
/* This is called by SQLGetData() */
int
int
copy_and_convert_field
(
StatementClass
*
stmt
,
Int4
field_type
,
void
*
value
,
Int2
fCType
,
copy_and_convert_field
(
StatementClass
*
stmt
,
Int4
field_type
,
void
*
value
,
Int2
fCType
,
...
@@ -187,17 +192,18 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -187,17 +192,18 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
int
result
=
COPY_OK
;
int
result
=
COPY_OK
;
char
tempBuf
[
TEXT_FIELD_SIZE
+
5
];
char
tempBuf
[
TEXT_FIELD_SIZE
+
5
];
/* rgbValueOffset is *ONLY* for character and binary data */
/*---------
/* pcbValueOffset is for computing any pcbValue location */
* rgbValueOffset is *ONLY* for character and binary data.
* pcbValueOffset is for computing any pcbValue location
*---------
*/
if
(
bind_size
>
0
)
if
(
bind_size
>
0
)
{
{
pcbValueOffset
=
rgbValueOffset
=
(
bind_size
*
bind_row
);
pcbValueOffset
=
rgbValueOffset
=
(
bind_size
*
bind_row
);
}
}
else
else
{
{
pcbValueOffset
=
bind_row
*
sizeof
(
SDWORD
);
pcbValueOffset
=
bind_row
*
sizeof
(
SDWORD
);
rgbValueOffset
=
bind_row
*
cbValueMax
;
rgbValueOffset
=
bind_row
*
cbValueMax
;
...
@@ -215,14 +221,15 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -215,14 +221,15 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
if
(
!
value
)
if
(
!
value
)
{
{
/* handle a null just by returning SQL_NULL_DATA in pcbValue, */
/*
/* and doing nothing to the buffer. */
* handle a null just by returning SQL_NULL_DATA in pcbValue,
* and doing nothing to the buffer.
*/
if
(
pcbValue
)
if
(
pcbValue
)
*
(
SDWORD
*
)
((
char
*
)
pcbValue
+
pcbValueOffset
)
=
SQL_NULL_DATA
;
*
(
SDWORD
*
)
((
char
*
)
pcbValue
+
pcbValueOffset
)
=
SQL_NULL_DATA
;
return
COPY_OK
;
return
COPY_OK
;
}
}
if
(
stmt
->
hdbc
->
DataSourceToDriver
!=
NULL
)
if
(
stmt
->
hdbc
->
DataSourceToDriver
!=
NULL
)
{
{
int
length
=
strlen
(
value
);
int
length
=
strlen
(
value
);
...
@@ -234,17 +241,15 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -234,17 +241,15 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
NULL
,
0
,
NULL
);
NULL
,
0
,
NULL
);
}
}
/*
/********************************************************************
* First convert any specific postgres types into more
First convert any specific postgres types into more
* useable data.
useable data.
*
* NOTE: Conversions from PG char/varchar of a date/time/timestamp
NOTE: Conversions from PG char/varchar of a date/time/timestamp
* value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported
value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported
*/
*********************************************************************/
switch
(
field_type
)
switch
(
field_type
)
{
{
/*
/*
* $$$ need to add parsing for date/time/timestamp strings in
* $$$ need to add parsing for date/time/timestamp strings in
* PG_TYPE_CHAR,VARCHAR $$$
* PG_TYPE_CHAR,VARCHAR $$$
...
@@ -261,13 +266,13 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -261,13 +266,13 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
case
PG_TYPE_DATETIME
:
case
PG_TYPE_DATETIME
:
case
PG_TYPE_TIMESTAMP
:
case
PG_TYPE_TIMESTAMP
:
if
(
strnicmp
(
value
,
"invalid"
,
7
)
!=
0
)
if
(
strnicmp
(
value
,
"invalid"
,
7
)
!=
0
)
{
sscanf
(
value
,
"%4d-%2d-%2d %2d:%2d:%2d"
,
&
st
.
y
,
&
st
.
m
,
&
st
.
d
,
&
st
.
hh
,
&
st
.
mm
,
&
st
.
ss
);
sscanf
(
value
,
"%4d-%2d-%2d %2d:%2d:%2d"
,
&
st
.
y
,
&
st
.
m
,
&
st
.
d
,
&
st
.
hh
,
&
st
.
mm
,
&
st
.
ss
);
}
else
else
{
/* The timestamp is invalid so set
{
* something conspicuous, like the epoch */
/*
* The timestamp is invalid so set
* something conspicuous, like the epoch
*/
t
=
0
;
t
=
0
;
tim
=
localtime
(
&
t
);
tim
=
localtime
(
&
t
);
st
.
m
=
tim
->
tm_mon
+
1
;
st
.
m
=
tim
->
tm_mon
+
1
;
...
@@ -369,15 +374,11 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -369,15 +374,11 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
mylog
(
"copy_and_convert, SQL_C_DEFAULT: fCType = %d
\n
"
,
fCType
);
mylog
(
"copy_and_convert, SQL_C_DEFAULT: fCType = %d
\n
"
,
fCType
);
}
}
rgbValueBindRow
=
(
char
*
)
rgbValue
+
rgbValueOffset
;
rgbValueBindRow
=
(
char
*
)
rgbValue
+
rgbValueOffset
;
if
(
fCType
==
SQL_C_CHAR
)
if
(
fCType
==
SQL_C_CHAR
)
{
{
/* Special character formatting as required */
/* Special character formatting as required */
/*
/*
* These really should return error if cbValueMax is not big
* These really should return error if cbValueMax is not big
* enough.
* enough.
...
@@ -456,7 +457,6 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -456,7 +457,6 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
if
(
cbValueMax
>
0
)
if
(
cbValueMax
>
0
)
{
{
copy_len
=
(
len
>=
cbValueMax
)
?
cbValueMax
-
1
:
len
;
copy_len
=
(
len
>=
cbValueMax
)
?
cbValueMax
-
1
:
len
;
/* Copy the data */
/* Copy the data */
...
@@ -483,7 +483,6 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -483,7 +483,6 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
}
}
else
else
{
{
/*
/*
* for SQL_C_CHAR, it's probably ok to leave currency symbols in.
* for SQL_C_CHAR, it's probably ok to leave currency symbols in.
* But to convert to numeric types, it is necessary to get rid of
* But to convert to numeric types, it is necessary to get rid of
...
@@ -633,7 +632,6 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -633,7 +632,6 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
if
(
stmt
->
current_col
>=
0
)
if
(
stmt
->
current_col
>=
0
)
{
{
/* No more data left for this column */
/* No more data left for this column */
if
(
stmt
->
bindings
[
stmt
->
current_col
].
data_left
==
0
)
if
(
stmt
->
bindings
[
stmt
->
current_col
].
data_left
==
0
)
return
COPY_NO_DATA_FOUND
;
return
COPY_NO_DATA_FOUND
;
...
@@ -690,10 +688,11 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
...
@@ -690,10 +688,11 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
}
}
/* This function inserts parameters into an SQL statements.
/*
It will also modify a SELECT statement for use with declare/fetch cursors.
* This function inserts parameters into an SQL statements.
This function no longer does any dynamic memory allocation!
* It will also modify a SELECT statement for use with declare/fetch cursors.
*/
* This function no longer does any dynamic memory allocation!
*/
int
int
copy_statement_with_parameters
(
StatementClass
*
stmt
)
copy_statement_with_parameters
(
StatementClass
*
stmt
)
{
{
...
@@ -760,7 +759,6 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -760,7 +759,6 @@ copy_statement_with_parameters(StatementClass *stmt)
for
(
opos
=
0
;
opos
<
oldstmtlen
;
opos
++
)
for
(
opos
=
0
;
opos
<
oldstmtlen
;
opos
++
)
{
{
/* Squeeze carriage-return/linefeed pairs to linefeed only */
/* Squeeze carriage-return/linefeed pairs to linefeed only */
if
(
old_statement
[
opos
]
==
'\r'
&&
opos
+
1
<
oldstmtlen
&&
if
(
old_statement
[
opos
]
==
'\r'
&&
opos
+
1
<
oldstmtlen
&&
old_statement
[
opos
+
1
]
==
'\n'
)
old_statement
[
opos
+
1
]
==
'\n'
)
...
@@ -782,10 +780,8 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -782,10 +780,8 @@ copy_statement_with_parameters(StatementClass *stmt)
#ifdef MULTIBYTE
#ifdef MULTIBYTE
char
*
end
=
multibyte_strchr
(
begin
,
'}'
);
char
*
end
=
multibyte_strchr
(
begin
,
'}'
);
#else
#else
char
*
end
=
strchr
(
begin
,
'}'
);
char
*
end
=
strchr
(
begin
,
'}'
);
#endif
#endif
if
(
!
end
)
if
(
!
end
)
...
@@ -807,12 +803,9 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -807,12 +803,9 @@ copy_statement_with_parameters(StatementClass *stmt)
}
}
opos
+=
end
-
begin
+
1
;
opos
+=
end
-
begin
+
1
;
*
end
=
'}'
;
*
end
=
'}'
;
continue
;
continue
;
}
}
/*
/*
* Can you have parameter markers inside of quotes? I dont think
* Can you have parameter markers inside of quotes? I dont think
* so. All the queries I've seen expect the driver to put quotes
* so. All the queries I've seen expect the driver to put quotes
...
@@ -829,12 +822,9 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -829,12 +822,9 @@ copy_statement_with_parameters(StatementClass *stmt)
continue
;
continue
;
}
}
/*
* Its a '?' parameter alright
/****************************************************/
*/
/* Its a '?' parameter alright */
/****************************************************/
param_number
++
;
param_number
++
;
if
(
param_number
>=
stmt
->
parameters_allocated
)
if
(
param_number
>=
stmt
->
parameters_allocated
)
...
@@ -906,7 +896,6 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -906,7 +896,6 @@ copy_statement_with_parameters(StatementClass *stmt)
param_string
[
0
]
=
'\0'
;
param_string
[
0
]
=
'\0'
;
cbuf
[
0
]
=
'\0'
;
cbuf
[
0
]
=
'\0'
;
/* Convert input C type to a neutral format */
/* Convert input C type to a neutral format */
switch
(
param_ctype
)
switch
(
param_ctype
)
{
{
...
@@ -1113,13 +1102,10 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -1113,13 +1102,10 @@ copy_statement_with_parameters(StatementClass *stmt)
if
(
stmt
->
parameters
[
param_number
].
data_at_exec
)
if
(
stmt
->
parameters
[
param_number
].
data_at_exec
)
{
{
lobj_oid
=
stmt
->
parameters
[
param_number
].
lobj_oid
;
lobj_oid
=
stmt
->
parameters
[
param_number
].
lobj_oid
;
}
}
else
else
{
{
/* begin transaction if needed */
/* begin transaction if needed */
if
(
!
CC_is_in_trans
(
stmt
->
hdbc
))
if
(
!
CC_is_in_trans
(
stmt
->
hdbc
))
{
{
...
@@ -1264,15 +1250,12 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -1264,15 +1250,12 @@ copy_statement_with_parameters(StatementClass *stmt)
new_statement
[
npos
++
]
=
'\''
;
/* Close Quote */
new_statement
[
npos
++
]
=
'\''
;
/* Close Quote */
break
;
break
;
}
}
}
/* end, for */
}
/* end, for */
/* make sure new_statement is always null-terminated */
/* make sure new_statement is always null-terminated */
new_statement
[
npos
]
=
'\0'
;
new_statement
[
npos
]
=
'\0'
;
if
(
stmt
->
hdbc
->
DriverToDataSource
!=
NULL
)
if
(
stmt
->
hdbc
->
DriverToDataSource
!=
NULL
)
{
{
int
length
=
strlen
(
new_statement
);
int
length
=
strlen
(
new_statement
);
...
@@ -1284,10 +1267,10 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -1284,10 +1267,10 @@ copy_statement_with_parameters(StatementClass *stmt)
NULL
,
0
,
NULL
);
NULL
,
0
,
NULL
);
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
char
*
char
*
mapFunction
(
char
*
func
)
mapFunction
(
char
*
func
)
{
{
...
@@ -1300,7 +1283,10 @@ mapFunction(char *func)
...
@@ -1300,7 +1283,10 @@ mapFunction(char *func)
return
NULL
;
return
NULL
;
}
}
/* convert_escape()
/*
* convert_escape()
*
* This function returns a pointer to static memory!
* This function returns a pointer to static memory!
*/
*/
char
*
char
*
...
@@ -1330,7 +1316,6 @@ convert_escape(char *value)
...
@@ -1330,7 +1316,6 @@ convert_escape(char *value)
}
}
else
if
(
strcmp
(
key
,
"fn"
)
==
0
)
else
if
(
strcmp
(
key
,
"fn"
)
==
0
)
{
{
/*
/*
* Function invocation Separate off the func name, skipping
* Function invocation Separate off the func name, skipping
* trailing whitespace.
* trailing whitespace.
...
@@ -1381,7 +1366,6 @@ convert_escape(char *value)
...
@@ -1381,7 +1366,6 @@ convert_escape(char *value)
}
}
return
escape
;
return
escape
;
}
}
...
@@ -1405,9 +1389,10 @@ convert_money(char *s)
...
@@ -1405,9 +1389,10 @@ convert_money(char *s)
}
}
/*
/* This function parses a character string for date/time info and fills in SIMPLE_TIME */
* This function parses a character string for date/time info and fills in SIMPLE_TIME
/* It does not zero out SIMPLE_TIME in case it is desired to initialize it with a value */
* It does not zero out SIMPLE_TIME in case it is desired to initialize it with a value
*/
char
char
parse_datetime
(
char
*
buf
,
SIMPLE_TIME
*
st
)
parse_datetime
(
char
*
buf
,
SIMPLE_TIME
*
st
)
{
{
...
@@ -1465,6 +1450,7 @@ parse_datetime(char *buf, SIMPLE_TIME *st)
...
@@ -1465,6 +1450,7 @@ parse_datetime(char *buf, SIMPLE_TIME *st)
return
FALSE
;
return
FALSE
;
}
}
/* Change linefeed to carriage-return/linefeed */
/* Change linefeed to carriage-return/linefeed */
int
int
convert_linefeeds
(
char
*
si
,
char
*
dst
,
size_t
max
)
convert_linefeeds
(
char
*
si
,
char
*
dst
,
size_t
max
)
...
@@ -1493,9 +1479,11 @@ convert_linefeeds(char *si, char *dst, size_t max)
...
@@ -1493,9 +1479,11 @@ convert_linefeeds(char *si, char *dst, size_t max)
return
out
;
return
out
;
}
}
/* Change carriage-return/linefeed to just linefeed
Plus, escape any special characters.
/*
*/
* Change carriage-return/linefeed to just linefeed
* Plus, escape any special characters.
*/
char
*
char
*
convert_special_chars
(
char
*
si
,
char
*
dst
,
int
used
)
convert_special_chars
(
char
*
si
,
char
*
dst
,
int
used
)
{
{
...
@@ -1537,6 +1525,7 @@ convert_special_chars(char *si, char *dst, int used)
...
@@ -1537,6 +1525,7 @@ convert_special_chars(char *si, char *dst, int used)
return
p
;
return
p
;
}
}
/* !!! Need to implement this function !!! */
/* !!! Need to implement this function !!! */
int
int
convert_pgbinary_to_char
(
char
*
value
,
char
*
rgbValue
,
int
cbValueMax
)
convert_pgbinary_to_char
(
char
*
value
,
char
*
rgbValue
,
int
cbValueMax
)
...
@@ -1547,6 +1536,7 @@ convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax)
...
@@ -1547,6 +1536,7 @@ convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax)
return
0
;
return
0
;
}
}
unsigned
int
unsigned
int
conv_from_octal
(
unsigned
char
*
s
)
conv_from_octal
(
unsigned
char
*
s
)
{
{
...
@@ -1560,6 +1550,7 @@ conv_from_octal(unsigned char *s)
...
@@ -1560,6 +1550,7 @@ conv_from_octal(unsigned char *s)
}
}
unsigned
int
unsigned
int
conv_from_hex
(
unsigned
char
*
s
)
conv_from_hex
(
unsigned
char
*
s
)
{
{
...
@@ -1569,7 +1560,6 @@ conv_from_hex(unsigned char *s)
...
@@ -1569,7 +1560,6 @@ conv_from_hex(unsigned char *s)
for
(
i
=
1
;
i
<=
2
;
i
++
)
for
(
i
=
1
;
i
<=
2
;
i
++
)
{
{
if
(
s
[
i
]
>=
'a'
&&
s
[
i
]
<=
'f'
)
if
(
s
[
i
]
>=
'a'
&&
s
[
i
]
<=
'f'
)
val
=
s
[
i
]
-
'a'
+
10
;
val
=
s
[
i
]
-
'a'
+
10
;
else
if
(
s
[
i
]
>=
'A'
&&
s
[
i
]
<=
'F'
)
else
if
(
s
[
i
]
>=
'A'
&&
s
[
i
]
<=
'F'
)
...
@@ -1583,6 +1573,7 @@ conv_from_hex(unsigned char *s)
...
@@ -1583,6 +1573,7 @@ conv_from_hex(unsigned char *s)
return
y
;
return
y
;
}
}
/* convert octal escapes to bytes */
/* convert octal escapes to bytes */
int
int
convert_from_pgbinary
(
unsigned
char
*
value
,
unsigned
char
*
rgbValue
,
int
cbValueMax
)
convert_from_pgbinary
(
unsigned
char
*
value
,
unsigned
char
*
rgbValue
,
int
cbValueMax
)
...
@@ -1629,6 +1620,7 @@ conv_to_octal(unsigned char val)
...
@@ -1629,6 +1620,7 @@ conv_to_octal(unsigned char val)
return
x
;
return
x
;
}
}
/* convert non-ascii bytes to octal escape sequences */
/* convert non-ascii bytes to octal escape sequences */
int
int
convert_to_pgbinary
(
unsigned
char
*
in
,
char
*
out
,
int
len
)
convert_to_pgbinary
(
unsigned
char
*
in
,
char
*
out
,
int
len
)
...
@@ -1636,7 +1628,6 @@ convert_to_pgbinary(unsigned char *in, char *out, int len)
...
@@ -1636,7 +1628,6 @@ convert_to_pgbinary(unsigned char *in, char *out, int len)
int
i
,
int
i
,
o
=
0
;
o
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
for
(
i
=
0
;
i
<
len
;
i
++
)
{
{
mylog
(
"convert_to_pgbinary: in[%d] = %d, %c
\n
"
,
i
,
in
[
i
],
in
[
i
]);
mylog
(
"convert_to_pgbinary: in[%d] = %d, %c
\n
"
,
i
,
in
[
i
],
in
[
i
]);
...
@@ -1647,7 +1638,6 @@ convert_to_pgbinary(unsigned char *in, char *out, int len)
...
@@ -1647,7 +1638,6 @@ convert_to_pgbinary(unsigned char *in, char *out, int len)
strcpy
(
&
out
[
o
],
conv_to_octal
(
in
[
i
]));
strcpy
(
&
out
[
o
],
conv_to_octal
(
in
[
i
]));
o
+=
5
;
o
+=
5
;
}
}
}
}
mylog
(
"convert_to_pgbinary: returning %d, out='%.*s'
\n
"
,
o
,
o
,
out
);
mylog
(
"convert_to_pgbinary: returning %d, out='%.*s'
\n
"
,
o
,
o
,
out
);
...
@@ -1705,21 +1695,22 @@ decode(char *in, char *out)
...
@@ -1705,21 +1695,22 @@ decode(char *in, char *out)
}
}
/*-------
/* 1. get oid (from 'value')
* 1. get oid (from 'value')
2. open the large object
* 2. open the large object
3. read from the large object (handle multiple GetData)
* 3. read from the large object (handle multiple GetData)
4. close when read less than requested? -OR-
* 4. close when read less than requested? -OR-
lseek/read each time
* lseek/read each time
handle case where application receives truncated and
* handle case where application receives truncated and
decides not to continue reading.
* decides not to continue reading.
*
CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only
* CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only
data type currently mapped to a PG_TYPE_LO. But, if any other types
* data type currently mapped to a PG_TYPE_LO. But, if any other types
are desired to map to a large object (PG_TYPE_LO), then that would
* are desired to map to a large object (PG_TYPE_LO), then that would
need to be handled here. For example, LONGVARCHAR could possibly be
* need to be handled here. For example, LONGVARCHAR could possibly be
mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now.
* mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now.
*/
*-------
*/
int
int
convert_lo
(
StatementClass
*
stmt
,
void
*
value
,
Int2
fCType
,
PTR
rgbValue
,
convert_lo
(
StatementClass
*
stmt
,
void
*
value
,
Int2
fCType
,
PTR
rgbValue
,
SDWORD
cbValueMax
,
SDWORD
*
pcbValue
)
SDWORD
cbValueMax
,
SDWORD
*
pcbValue
)
...
@@ -1731,7 +1722,7 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
...
@@ -1731,7 +1722,7 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
BindInfoClass
*
bindInfo
=
NULL
;
BindInfoClass
*
bindInfo
=
NULL
;
/* If using SQLGetData, then current_col will be set */
/* If using SQLGetData, then current_col will be set */
if
(
stmt
->
current_col
>=
0
)
if
(
stmt
->
current_col
>=
0
)
{
{
bindInfo
=
&
stmt
->
bindings
[
stmt
->
current_col
];
bindInfo
=
&
stmt
->
bindings
[
stmt
->
current_col
];
...
@@ -1745,7 +1736,6 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
...
@@ -1745,7 +1736,6 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
if
(
!
bindInfo
||
bindInfo
->
data_left
==
-
1
)
if
(
!
bindInfo
||
bindInfo
->
data_left
==
-
1
)
{
{
/* begin transaction if needed */
/* begin transaction if needed */
if
(
!
CC_is_in_trans
(
stmt
->
hdbc
))
if
(
!
CC_is_in_trans
(
stmt
->
hdbc
))
{
{
...
@@ -1784,7 +1774,6 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
...
@@ -1784,7 +1774,6 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
retval
=
lo_lseek
(
stmt
->
hdbc
,
stmt
->
lobj_fd
,
0L
,
SEEK_END
);
retval
=
lo_lseek
(
stmt
->
hdbc
,
stmt
->
lobj_fd
,
0L
,
SEEK_END
);
if
(
retval
>=
0
)
if
(
retval
>=
0
)
{
{
left
=
lo_tell
(
stmt
->
hdbc
,
stmt
->
lobj_fd
);
left
=
lo_tell
(
stmt
->
hdbc
,
stmt
->
lobj_fd
);
if
(
bindInfo
)
if
(
bindInfo
)
bindInfo
->
data_left
=
left
;
bindInfo
->
data_left
=
left
;
...
@@ -1849,11 +1838,9 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
...
@@ -1849,11 +1838,9 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
if
(
pcbValue
)
if
(
pcbValue
)
*
pcbValue
=
left
<
0
?
SQL_NO_TOTAL
:
left
;
*
pcbValue
=
left
<
0
?
SQL_NO_TOTAL
:
left
;
if
(
bindInfo
&&
bindInfo
->
data_left
>
0
)
if
(
bindInfo
&&
bindInfo
->
data_left
>
0
)
bindInfo
->
data_left
-=
retval
;
bindInfo
->
data_left
-=
retval
;
if
(
!
bindInfo
||
bindInfo
->
data_left
==
0
)
if
(
!
bindInfo
||
bindInfo
->
data_left
==
0
)
{
{
lo_close
(
stmt
->
hdbc
,
stmt
->
lobj_fd
);
lo_close
(
stmt
->
hdbc
,
stmt
->
lobj_fd
);
...
@@ -1886,7 +1873,5 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
...
@@ -1886,7 +1873,5 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
stmt
->
lobj_fd
=
-
1
;
/* prevent further reading */
stmt
->
lobj_fd
=
-
1
;
/* prevent further reading */
}
}
return
result
;
return
result
;
}
}
src/interfaces/odbc/dlg_specific.c
View file @
296e7ba2
/* Module: dlg_specific.c
/*-------
* Module: dlg_specific.c
*
*
* Description: This module contains any specific code for handling
* Description: This module contains any specific code for handling
* dialog boxes such as driver/datasource options. Both the
* dialog boxes such as driver/datasource options. Both the
...
@@ -12,7 +13,7 @@
...
@@ -12,7 +13,7 @@
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
/* Multibyte support Eiji Tokuya 2001-03-15 */
...
@@ -50,11 +51,11 @@
...
@@ -50,11 +51,11 @@
extern
GLOBAL_VALUES
globals
;
extern
GLOBAL_VALUES
globals
;
#ifdef WIN32
#ifdef WIN32
void
void
SetDlgStuff
(
HWND
hdlg
,
ConnInfo
*
ci
)
SetDlgStuff
(
HWND
hdlg
,
ConnInfo
*
ci
)
{
{
/*
/*
* If driver attribute NOT present, then set the datasource name and
* If driver attribute NOT present, then set the datasource name and
* description
* description
...
@@ -72,6 +73,7 @@ SetDlgStuff(HWND hdlg, ConnInfo *ci)
...
@@ -72,6 +73,7 @@ SetDlgStuff(HWND hdlg, ConnInfo *ci)
SetDlgItemText
(
hdlg
,
IDC_PORT
,
ci
->
port
);
SetDlgItemText
(
hdlg
,
IDC_PORT
,
ci
->
port
);
}
}
void
void
GetDlgStuff
(
HWND
hdlg
,
ConnInfo
*
ci
)
GetDlgStuff
(
HWND
hdlg
,
ConnInfo
*
ci
)
{
{
...
@@ -85,7 +87,6 @@ GetDlgStuff(HWND hdlg, ConnInfo *ci)
...
@@ -85,7 +87,6 @@ GetDlgStuff(HWND hdlg, ConnInfo *ci)
}
}
int
CALLBACK
int
CALLBACK
driver_optionsProc
(
HWND
hdlg
,
driver_optionsProc
(
HWND
hdlg
,
WORD
wMsg
,
WORD
wMsg
,
...
@@ -141,7 +142,6 @@ driver_optionsProc(HWND hdlg,
...
@@ -141,7 +142,6 @@ driver_optionsProc(HWND hdlg,
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
{
{
case
IDOK
:
case
IDOK
:
globals
.
commlog
=
IsDlgButtonChecked
(
hdlg
,
DRV_COMMLOG
);
globals
.
commlog
=
IsDlgButtonChecked
(
hdlg
,
DRV_COMMLOG
);
globals
.
disable_optimizer
=
IsDlgButtonChecked
(
hdlg
,
DRV_OPTIMIZER
);
globals
.
disable_optimizer
=
IsDlgButtonChecked
(
hdlg
,
DRV_OPTIMIZER
);
globals
.
ksqo
=
IsDlgButtonChecked
(
hdlg
,
DRV_KSQO
);
globals
.
ksqo
=
IsDlgButtonChecked
(
hdlg
,
DRV_KSQO
);
...
@@ -228,12 +228,12 @@ driver_optionsProc(HWND hdlg,
...
@@ -228,12 +228,12 @@ driver_optionsProc(HWND hdlg,
break
;
break
;
}
}
}
}
return
FALSE
;
return
FALSE
;
}
}
int
CALLBACK
int
CALLBACK
ds_optionsProc
(
HWND
hdlg
,
ds_optionsProc
(
HWND
hdlg
,
WORD
wMsg
,
WORD
wMsg
,
...
@@ -267,11 +267,9 @@ ds_optionsProc(HWND hdlg,
...
@@ -267,11 +267,9 @@ ds_optionsProc(HWND hdlg,
else
if
(
strncmp
(
ci
->
protocol
,
PG63
,
strlen
(
PG63
))
==
0
)
else
if
(
strncmp
(
ci
->
protocol
,
PG63
,
strlen
(
PG63
))
==
0
)
CheckDlgButton
(
hdlg
,
DS_PG63
,
1
);
CheckDlgButton
(
hdlg
,
DS_PG63
,
1
);
else
else
/* latest */
/* latest */
CheckDlgButton
(
hdlg
,
DS_PG64
,
1
);
CheckDlgButton
(
hdlg
,
DS_PG64
,
1
);
CheckDlgButton
(
hdlg
,
DS_SHOWOIDCOLUMN
,
atoi
(
ci
->
show_oid_column
));
CheckDlgButton
(
hdlg
,
DS_SHOWOIDCOLUMN
,
atoi
(
ci
->
show_oid_column
));
CheckDlgButton
(
hdlg
,
DS_FAKEOIDINDEX
,
atoi
(
ci
->
fake_oid_index
));
CheckDlgButton
(
hdlg
,
DS_FAKEOIDINDEX
,
atoi
(
ci
->
fake_oid_index
));
CheckDlgButton
(
hdlg
,
DS_ROWVERSIONING
,
atoi
(
ci
->
row_versioning
));
CheckDlgButton
(
hdlg
,
DS_ROWVERSIONING
,
atoi
(
ci
->
row_versioning
));
...
@@ -283,7 +281,6 @@ ds_optionsProc(HWND hdlg,
...
@@ -283,7 +281,6 @@ ds_optionsProc(HWND hdlg,
SetDlgItemText
(
hdlg
,
DS_CONNSETTINGS
,
ci
->
conn_settings
);
SetDlgItemText
(
hdlg
,
DS_CONNSETTINGS
,
ci
->
conn_settings
);
break
;
break
;
case
WM_COMMAND
:
case
WM_COMMAND
:
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
{
{
...
@@ -292,9 +289,7 @@ ds_optionsProc(HWND hdlg,
...
@@ -292,9 +289,7 @@ ds_optionsProc(HWND hdlg,
EnableWindow
(
GetDlgItem
(
hdlg
,
DS_FAKEOIDINDEX
),
IsDlgButtonChecked
(
hdlg
,
DS_SHOWOIDCOLUMN
));
EnableWindow
(
GetDlgItem
(
hdlg
,
DS_FAKEOIDINDEX
),
IsDlgButtonChecked
(
hdlg
,
DS_SHOWOIDCOLUMN
));
return
TRUE
;
return
TRUE
;
case
IDOK
:
case
IDOK
:
ci
=
(
ConnInfo
*
)
GetWindowLong
(
hdlg
,
DWL_USER
);
ci
=
(
ConnInfo
*
)
GetWindowLong
(
hdlg
,
DWL_USER
);
mylog
(
"IDOK: got ci = %u
\n
"
,
ci
);
mylog
(
"IDOK: got ci = %u
\n
"
,
ci
);
...
@@ -307,7 +302,7 @@ ds_optionsProc(HWND hdlg,
...
@@ -307,7 +302,7 @@ ds_optionsProc(HWND hdlg,
else
if
(
IsDlgButtonChecked
(
hdlg
,
DS_PG63
))
else
if
(
IsDlgButtonChecked
(
hdlg
,
DS_PG63
))
strcpy
(
ci
->
protocol
,
PG63
);
strcpy
(
ci
->
protocol
,
PG63
);
else
else
/* latest */
/* latest */
strcpy
(
ci
->
protocol
,
PG64
);
strcpy
(
ci
->
protocol
,
PG64
);
sprintf
(
ci
->
show_system_tables
,
"%d"
,
IsDlgButtonChecked
(
hdlg
,
DS_SHOWSYSTEMTABLES
));
sprintf
(
ci
->
show_system_tables
,
"%d"
,
IsDlgButtonChecked
(
hdlg
,
DS_SHOWSYSTEMTABLES
));
...
@@ -321,7 +316,6 @@ ds_optionsProc(HWND hdlg,
...
@@ -321,7 +316,6 @@ ds_optionsProc(HWND hdlg,
/* Datasource Connection Settings */
/* Datasource Connection Settings */
GetDlgItemText
(
hdlg
,
DS_CONNSETTINGS
,
ci
->
conn_settings
,
sizeof
(
ci
->
conn_settings
));
GetDlgItemText
(
hdlg
,
DS_CONNSETTINGS
,
ci
->
conn_settings
,
sizeof
(
ci
->
conn_settings
));
/* fall through */
/* fall through */
case
IDCANCEL
:
case
IDCANCEL
:
...
@@ -335,6 +329,7 @@ ds_optionsProc(HWND hdlg,
...
@@ -335,6 +329,7 @@ ds_optionsProc(HWND hdlg,
#endif
/* WIN32 */
#endif
/* WIN32 */
void
void
makeConnectString
(
char
*
connect_string
,
ConnInfo
*
ci
)
makeConnectString
(
char
*
connect_string
,
ConnInfo
*
ci
)
{
{
...
@@ -365,10 +360,10 @@ makeConnectString(char *connect_string, ConnInfo *ci)
...
@@ -365,10 +360,10 @@ makeConnectString(char *connect_string, ConnInfo *ci)
encoded_conn_settings
);
encoded_conn_settings
);
}
}
void
void
copyAttributes
(
ConnInfo
*
ci
,
char
*
attribute
,
char
*
value
)
copyAttributes
(
ConnInfo
*
ci
,
char
*
attribute
,
char
*
value
)
{
{
if
(
stricmp
(
attribute
,
"DSN"
)
==
0
)
if
(
stricmp
(
attribute
,
"DSN"
)
==
0
)
strcpy
(
ci
->
dsn
,
value
);
strcpy
(
ci
->
dsn
,
value
);
...
@@ -415,9 +410,9 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value)
...
@@ -415,9 +410,9 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value)
}
}
mylog
(
"copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s', conn_settings='%s')
\n
"
,
ci
->
dsn
,
ci
->
server
,
ci
->
database
,
ci
->
username
,
ci
->
password
,
ci
->
port
,
ci
->
onlyread
,
ci
->
protocol
,
ci
->
conn_settings
);
mylog
(
"copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s', conn_settings='%s')
\n
"
,
ci
->
dsn
,
ci
->
server
,
ci
->
database
,
ci
->
username
,
ci
->
password
,
ci
->
port
,
ci
->
onlyread
,
ci
->
protocol
,
ci
->
conn_settings
);
}
}
void
void
getDSNdefaults
(
ConnInfo
*
ci
)
getDSNdefaults
(
ConnInfo
*
ci
)
{
{
...
@@ -450,8 +445,10 @@ getDSNinfo(ConnInfo *ci, char overwrite)
...
@@ -450,8 +445,10 @@ getDSNinfo(ConnInfo *ci, char overwrite)
char
*
DSN
=
ci
->
dsn
;
char
*
DSN
=
ci
->
dsn
;
char
encoded_conn_settings
[
LARGE_REGISTRY_LEN
];
char
encoded_conn_settings
[
LARGE_REGISTRY_LEN
];
/* If a driver keyword was present, then dont use a DSN and return. */
/*
/* If DSN is null and no driver, then use the default datasource. */
* If a driver keyword was present, then dont use a DSN and return.
* If DSN is null and no driver, then use the default datasource.
*/
if
(
DSN
[
0
]
==
'\0'
)
if
(
DSN
[
0
]
==
'\0'
)
{
{
if
(
ci
->
driver
[
0
]
!=
'\0'
)
if
(
ci
->
driver
[
0
]
!=
'\0'
)
...
@@ -514,11 +511,9 @@ getDSNinfo(ConnInfo *ci, char overwrite)
...
@@ -514,11 +511,9 @@ getDSNinfo(ConnInfo *ci, char overwrite)
if
(
ci
->
translation_option
[
0
]
==
'\0'
||
overwrite
)
if
(
ci
->
translation_option
[
0
]
==
'\0'
||
overwrite
)
SQLGetPrivateProfileString
(
DSN
,
INI_TRANSLATIONOPTION
,
""
,
ci
->
translation_option
,
sizeof
(
ci
->
translation_option
),
ODBC_INI
);
SQLGetPrivateProfileString
(
DSN
,
INI_TRANSLATIONOPTION
,
""
,
ci
->
translation_option
,
sizeof
(
ci
->
translation_option
),
ODBC_INI
);
/* Allow override of odbcinst.ini parameters here */
/* Allow override of odbcinst.ini parameters here */
getGlobalDefaults
(
DSN
,
ODBC_INI
,
TRUE
);
getGlobalDefaults
(
DSN
,
ODBC_INI
,
TRUE
);
qlog
(
"DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'
\n
"
,
qlog
(
"DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'
\n
"
,
DSN
,
DSN
,
ci
->
server
,
ci
->
server
,
...
@@ -546,7 +541,6 @@ getDSNinfo(ConnInfo *ci, char overwrite)
...
@@ -546,7 +541,6 @@ getDSNinfo(ConnInfo *ci, char overwrite)
qlog
(
" translation_dll='%s',translation_option='%s'
\n
"
,
qlog
(
" translation_dll='%s',translation_option='%s'
\n
"
,
ci
->
translation_dll
,
ci
->
translation_dll
,
ci
->
translation_option
);
ci
->
translation_option
);
}
}
...
@@ -626,15 +620,15 @@ writeDSNinfo(ConnInfo *ci)
...
@@ -626,15 +620,15 @@ writeDSNinfo(ConnInfo *ci)
}
}
/* This function reads the ODBCINST.INI portion of
/*
the registry and gets any driver defaults.
* This function reads the ODBCINST.INI portion of
*/
* the registry and gets any driver defaults.
*/
void
void
getGlobalDefaults
(
char
*
section
,
char
*
filename
,
char
override
)
getGlobalDefaults
(
char
*
section
,
char
*
filename
,
char
override
)
{
{
char
temp
[
256
];
char
temp
[
256
];
/* Fetch Count is stored in driver section */
/* Fetch Count is stored in driver section */
SQLGetPrivateProfileString
(
section
,
INI_FETCH
,
""
,
SQLGetPrivateProfileString
(
section
,
INI_FETCH
,
""
,
temp
,
sizeof
(
temp
),
filename
);
temp
,
sizeof
(
temp
),
filename
);
...
@@ -648,7 +642,6 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -648,7 +642,6 @@ getGlobalDefaults(char *section, char *filename, char override)
else
if
(
!
override
)
else
if
(
!
override
)
globals
.
fetch_max
=
FETCH_MAX
;
globals
.
fetch_max
=
FETCH_MAX
;
/* Socket Buffersize is stored in driver section */
/* Socket Buffersize is stored in driver section */
SQLGetPrivateProfileString
(
section
,
INI_SOCKET
,
""
,
SQLGetPrivateProfileString
(
section
,
INI_SOCKET
,
""
,
temp
,
sizeof
(
temp
),
filename
);
temp
,
sizeof
(
temp
),
filename
);
...
@@ -657,7 +650,6 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -657,7 +650,6 @@ getGlobalDefaults(char *section, char *filename, char override)
else
if
(
!
override
)
else
if
(
!
override
)
globals
.
socket_buffersize
=
SOCK_BUFFER_SIZE
;
globals
.
socket_buffersize
=
SOCK_BUFFER_SIZE
;
/* Debug is stored in the driver section */
/* Debug is stored in the driver section */
SQLGetPrivateProfileString
(
section
,
INI_DEBUG
,
""
,
SQLGetPrivateProfileString
(
section
,
INI_DEBUG
,
""
,
temp
,
sizeof
(
temp
),
filename
);
temp
,
sizeof
(
temp
),
filename
);
...
@@ -666,7 +658,6 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -666,7 +658,6 @@ getGlobalDefaults(char *section, char *filename, char override)
else
if
(
!
override
)
else
if
(
!
override
)
globals
.
debug
=
DEFAULT_DEBUG
;
globals
.
debug
=
DEFAULT_DEBUG
;
/* CommLog is stored in the driver section */
/* CommLog is stored in the driver section */
SQLGetPrivateProfileString
(
section
,
INI_COMMLOG
,
""
,
SQLGetPrivateProfileString
(
section
,
INI_COMMLOG
,
""
,
temp
,
sizeof
(
temp
),
filename
);
temp
,
sizeof
(
temp
),
filename
);
...
@@ -675,7 +666,6 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -675,7 +666,6 @@ getGlobalDefaults(char *section, char *filename, char override)
else
if
(
!
override
)
else
if
(
!
override
)
globals
.
commlog
=
DEFAULT_COMMLOG
;
globals
.
commlog
=
DEFAULT_COMMLOG
;
/* Optimizer is stored in the driver section only */
/* Optimizer is stored in the driver section only */
SQLGetPrivateProfileString
(
section
,
INI_OPTIMIZER
,
""
,
SQLGetPrivateProfileString
(
section
,
INI_OPTIMIZER
,
""
,
temp
,
sizeof
(
temp
),
filename
);
temp
,
sizeof
(
temp
),
filename
);
...
@@ -734,8 +724,6 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -734,8 +724,6 @@ getGlobalDefaults(char *section, char *filename, char override)
else
if
(
!
override
)
else
if
(
!
override
)
globals
.
cancel_as_freestmt
=
DEFAULT_CANCELASFREESTMT
;
globals
.
cancel_as_freestmt
=
DEFAULT_CANCELASFREESTMT
;
/* UseDeclareFetch is stored in the driver section only */
/* UseDeclareFetch is stored in the driver section only */
SQLGetPrivateProfileString
(
section
,
INI_USEDECLAREFETCH
,
""
,
SQLGetPrivateProfileString
(
section
,
INI_USEDECLAREFETCH
,
""
,
temp
,
sizeof
(
temp
),
filename
);
temp
,
sizeof
(
temp
),
filename
);
...
@@ -744,7 +732,6 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -744,7 +732,6 @@ getGlobalDefaults(char *section, char *filename, char override)
else
if
(
!
override
)
else
if
(
!
override
)
globals
.
use_declarefetch
=
DEFAULT_USEDECLAREFETCH
;
globals
.
use_declarefetch
=
DEFAULT_USEDECLAREFETCH
;
/* Max Varchar Size */
/* Max Varchar Size */
SQLGetPrivateProfileString
(
section
,
INI_MAXVARCHARSIZE
,
""
,
SQLGetPrivateProfileString
(
section
,
INI_MAXVARCHARSIZE
,
""
,
temp
,
sizeof
(
temp
),
filename
);
temp
,
sizeof
(
temp
),
filename
);
...
@@ -804,7 +791,6 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -804,7 +791,6 @@ getGlobalDefaults(char *section, char *filename, char override)
/* Dont allow override of an override! */
/* Dont allow override of an override! */
if
(
!
override
)
if
(
!
override
)
{
{
/*
/*
* ConnSettings is stored in the driver section and per datasource
* ConnSettings is stored in the driver section and per datasource
* for override
* for override
...
@@ -831,14 +817,14 @@ getGlobalDefaults(char *section, char *filename, char override)
...
@@ -831,14 +817,14 @@ getGlobalDefaults(char *section, char *filename, char override)
strcpy
(
globals
.
protocol
,
temp
);
strcpy
(
globals
.
protocol
,
temp
);
else
else
strcpy
(
globals
.
protocol
,
DEFAULT_PROTOCOL
);
strcpy
(
globals
.
protocol
,
DEFAULT_PROTOCOL
);
}
}
}
}
/* This function writes any global parameters (that can be manipulated)
/*
to the ODBCINST.INI portion of the registry
* This function writes any global parameters (that can be manipulated)
*/
* to the ODBCINST.INI portion of the registry
*/
void
void
updateGlobals
(
void
)
updateGlobals
(
void
)
{
{
...
...
src/interfaces/odbc/drvconn.c
View file @
296e7ba2
/* Module: drvconn.c
/*-------
* Module: drvconn.c
*
*
* Description: This module contains only routines related to
* Description: This module contains only routines related to
* implementing SQLDriverConnect.
* implementing SQLDriverConnect.
...
@@ -8,7 +9,7 @@
...
@@ -8,7 +9,7 @@
* API functions: SQLDriverConnect
* API functions: SQLDriverConnect
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -110,9 +111,11 @@ SQLDriverConnect(
...
@@ -110,9 +111,11 @@ SQLDriverConnect(
/* Parse the connect string and fill in conninfo for this hdbc. */
/* Parse the connect string and fill in conninfo for this hdbc. */
dconn_get_connect_attributes
(
connStrIn
,
ci
);
dconn_get_connect_attributes
(
connStrIn
,
ci
);
/* If the ConnInfo in the hdbc is missing anything, */
/*
/* this function will fill them in from the registry (assuming */
* If the ConnInfo in the hdbc is missing anything,
/* of course there is a DSN given -- if not, it does nothing!) */
* this function will fill them in from the registry (assuming
* of course there is a DSN given -- if not, it does nothing!)
*/
getDSNinfo
(
ci
,
CONN_DONT_OVERWRITE
);
getDSNinfo
(
ci
,
CONN_DONT_OVERWRITE
);
/* Fill in any default parameters if they are not there. */
/* Fill in any default parameters if they are not there. */
...
@@ -147,7 +150,6 @@ dialog:
...
@@ -147,7 +150,6 @@ dialog:
ci
->
port
[
0
]
==
'\0'
||
ci
->
port
[
0
]
==
'\0'
||
password_required
)
password_required
)
{
{
dialog_result
=
dconn_DoDialog
(
hwnd
,
ci
);
dialog_result
=
dconn_DoDialog
(
hwnd
,
ci
);
if
(
dialog_result
!=
SQL_SUCCESS
)
if
(
dialog_result
!=
SQL_SUCCESS
)
return
dialog_result
;
return
dialog_result
;
...
@@ -173,12 +175,11 @@ dialog:
...
@@ -173,12 +175,11 @@ dialog:
ci
->
database
[
0
]
==
'\0'
||
ci
->
database
[
0
]
==
'\0'
||
ci
->
port
[
0
]
==
'\0'
)
ci
->
port
[
0
]
==
'\0'
)
{
{
/*
(password_required && ci->password[0] == '\0')) */
/*
(password_required && ci->password[0] == '\0')) */
return
SQL_NO_DATA_FOUND
;
return
SQL_NO_DATA_FOUND
;
}
}
/* do the actual connect */
/* do the actual connect */
retval
=
CC_connect
(
conn
,
password_required
);
retval
=
CC_connect
(
conn
,
password_required
);
if
(
retval
<
0
)
if
(
retval
<
0
)
...
@@ -206,9 +207,9 @@ dialog:
...
@@ -206,9 +207,9 @@ dialog:
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/*
********************************************/
/*
/* Create the Output Connection String */
* Create the Output Connection String
/********************************************
*/
*/
result
=
SQL_SUCCESS
;
result
=
SQL_SUCCESS
;
makeConnectString
(
connStrOut
,
ci
);
makeConnectString
(
connStrOut
,
ci
);
...
@@ -216,7 +217,6 @@ dialog:
...
@@ -216,7 +217,6 @@ dialog:
if
(
szConnStrOut
)
if
(
szConnStrOut
)
{
{
/*
/*
* Return the completed string to the caller. The correct method
* Return the completed string to the caller. The correct method
* is to only construct the connect string if a dialog was put up,
* is to only construct the connect string if a dialog was put up,
...
@@ -247,6 +247,7 @@ dialog:
...
@@ -247,6 +247,7 @@ dialog:
return
result
;
return
result
;
}
}
#ifdef WIN32
#ifdef WIN32
RETCODE
RETCODE
dconn_DoDialog
(
HWND
hwnd
,
ConnInfo
*
ci
)
dconn_DoDialog
(
HWND
hwnd
,
ConnInfo
*
ci
)
...
@@ -296,7 +297,6 @@ dconn_FDriverConnectProc(
...
@@ -296,7 +297,6 @@ dconn_FDriverConnectProc(
SetWindowLong
(
hdlg
,
DWL_USER
,
lParam
);
/* Save the ConnInfo for
SetWindowLong
(
hdlg
,
DWL_USER
,
lParam
);
/* Save the ConnInfo for
* the "OK" */
* the "OK" */
SetDlgStuff
(
hdlg
,
ci
);
SetDlgStuff
(
hdlg
,
ci
);
if
(
ci
->
database
[
0
]
==
'\0'
)
if
(
ci
->
database
[
0
]
==
'\0'
)
...
@@ -309,38 +309,29 @@ dconn_FDriverConnectProc(
...
@@ -309,38 +309,29 @@ dconn_FDriverConnectProc(
SetFocus
(
GetDlgItem
(
hdlg
,
IDC_USER
));
SetFocus
(
GetDlgItem
(
hdlg
,
IDC_USER
));
else
if
(
ci
->
focus_password
)
else
if
(
ci
->
focus_password
)
SetFocus
(
GetDlgItem
(
hdlg
,
IDC_PASSWORD
));
SetFocus
(
GetDlgItem
(
hdlg
,
IDC_PASSWORD
));
break
;
break
;
case
WM_COMMAND
:
case
WM_COMMAND
:
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
{
{
case
IDOK
:
case
IDOK
:
ci
=
(
ConnInfo
*
)
GetWindowLong
(
hdlg
,
DWL_USER
);
ci
=
(
ConnInfo
*
)
GetWindowLong
(
hdlg
,
DWL_USER
);
GetDlgStuff
(
hdlg
,
ci
);
GetDlgStuff
(
hdlg
,
ci
);
case
IDCANCEL
:
case
IDCANCEL
:
EndDialog
(
hdlg
,
GET_WM_COMMAND_ID
(
wParam
,
lParam
)
==
IDOK
);
EndDialog
(
hdlg
,
GET_WM_COMMAND_ID
(
wParam
,
lParam
)
==
IDOK
);
return
TRUE
;
return
TRUE
;
case
IDC_DRIVER
:
case
IDC_DRIVER
:
DialogBoxParam
(
s_hModule
,
MAKEINTRESOURCE
(
DLG_OPTIONS_DRV
),
DialogBoxParam
(
s_hModule
,
MAKEINTRESOURCE
(
DLG_OPTIONS_DRV
),
hdlg
,
driver_optionsProc
,
(
LPARAM
)
NULL
);
hdlg
,
driver_optionsProc
,
(
LPARAM
)
NULL
);
break
;
break
;
case
IDC_DATASOURCE
:
case
IDC_DATASOURCE
:
ci
=
(
ConnInfo
*
)
GetWindowLong
(
hdlg
,
DWL_USER
);
ci
=
(
ConnInfo
*
)
GetWindowLong
(
hdlg
,
DWL_USER
);
DialogBoxParam
(
s_hModule
,
MAKEINTRESOURCE
(
DLG_OPTIONS_DS
),
DialogBoxParam
(
s_hModule
,
MAKEINTRESOURCE
(
DLG_OPTIONS_DS
),
hdlg
,
ds_optionsProc
,
(
LPARAM
)
ci
);
hdlg
,
ds_optionsProc
,
(
LPARAM
)
ci
);
break
;
break
;
}
}
}
}
...
@@ -350,6 +341,7 @@ dconn_FDriverConnectProc(
...
@@ -350,6 +341,7 @@ dconn_FDriverConnectProc(
#endif
/* WIN32 */
#endif
/* WIN32 */
void
void
dconn_get_connect_attributes
(
UCHAR
FAR
*
connect_string
,
ConnInfo
*
ci
)
dconn_get_connect_attributes
(
UCHAR
FAR
*
connect_string
,
ConnInfo
*
ci
)
{
{
...
@@ -393,6 +385,5 @@ dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
...
@@ -393,6 +385,5 @@ dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
}
}
free
(
our_connect_string
);
free
(
our_connect_string
);
}
}
src/interfaces/odbc/environ.c
View file @
296e7ba2
/* Module: environ.c
/*-------
* Module: environ.c
*
*
* Description: This module contains routines related to
* Description: This module contains routines related to
* the environment, such as storing connection handles,
* the environment, such as storing connection handles,
...
@@ -9,7 +10,7 @@
...
@@ -9,7 +10,7 @@
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#include "environ.h"
#include "environ.h"
...
@@ -54,6 +55,7 @@ SQLAllocEnv(HENV FAR *phenv)
...
@@ -54,6 +55,7 @@ SQLAllocEnv(HENV FAR *phenv)
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLFreeEnv
(
HENV
henv
)
SQLFreeEnv
(
HENV
henv
)
{
{
...
@@ -73,8 +75,8 @@ SQLFreeEnv(HENV henv)
...
@@ -73,8 +75,8 @@ SQLFreeEnv(HENV henv)
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* Returns the next SQL error information. */
/* Returns the next SQL error information. */
RETCODE
SQL_API
RETCODE
SQL_API
SQLError
(
SQLError
(
HENV
henv
,
HENV
henv
,
...
@@ -208,24 +210,19 @@ SQLError(
...
@@ -208,24 +210,19 @@ SQLError(
case
STMT_INVALID_CURSOR_POSITION
:
case
STMT_INVALID_CURSOR_POSITION
:
strcpy
(
szSqlState
,
"S1109"
);
strcpy
(
szSqlState
,
"S1109"
);
break
;
break
;
case
STMT_VALUE_OUT_OF_RANGE
:
case
STMT_VALUE_OUT_OF_RANGE
:
strcpy
(
szSqlState
,
"22003"
);
strcpy
(
szSqlState
,
"22003"
);
break
;
break
;
case
STMT_OPERATION_INVALID
:
case
STMT_OPERATION_INVALID
:
strcpy
(
szSqlState
,
"S1011"
);
strcpy
(
szSqlState
,
"S1011"
);
break
;
break
;
case
STMT_EXEC_ERROR
:
case
STMT_EXEC_ERROR
:
default:
default:
strcpy
(
szSqlState
,
"S1000"
);
strcpy
(
szSqlState
,
"S1000"
);
/* also a general error */
/* also a general error */
break
;
break
;
}
}
mylog
(
" szSqlState = '%s', szError='%s'
\n
"
,
szSqlState
,
szErrorMsg
);
mylog
(
" szSqlState = '%s', szError='%s'
\n
"
,
szSqlState
,
szErrorMsg
);
}
}
else
else
{
{
...
@@ -237,10 +234,11 @@ SQLError(
...
@@ -237,10 +234,11 @@ SQLError(
szErrorMsg
[
0
]
=
'\0'
;
szErrorMsg
[
0
]
=
'\0'
;
mylog
(
" returning NO_DATA_FOUND
\n
"
);
mylog
(
" returning NO_DATA_FOUND
\n
"
);
return
SQL_NO_DATA_FOUND
;
return
SQL_NO_DATA_FOUND
;
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
else
if
(
SQL_NULL_HDBC
!=
hdbc
)
else
if
(
SQL_NULL_HDBC
!=
hdbc
)
{
{
...
@@ -310,7 +308,6 @@ SQLError(
...
@@ -310,7 +308,6 @@ SQLError(
break
;
break
;
case
CONN_TRANSACT_IN_PROGRES
:
case
CONN_TRANSACT_IN_PROGRES
:
strcpy
(
szSqlState
,
"S1010"
);
strcpy
(
szSqlState
,
"S1010"
);
/*
/*
* when the user tries to switch commit mode in a
* when the user tries to switch commit mode in a
* transaction
* transaction
...
@@ -324,18 +321,15 @@ SQLError(
...
@@ -324,18 +321,15 @@ SQLError(
case
STMT_NOT_IMPLEMENTED_ERROR
:
case
STMT_NOT_IMPLEMENTED_ERROR
:
strcpy
(
szSqlState
,
"S1C00"
);
strcpy
(
szSqlState
,
"S1C00"
);
break
;
break
;
case
CONN_VALUE_OUT_OF_RANGE
:
case
CONN_VALUE_OUT_OF_RANGE
:
case
STMT_VALUE_OUT_OF_RANGE
:
case
STMT_VALUE_OUT_OF_RANGE
:
strcpy
(
szSqlState
,
"22003"
);
strcpy
(
szSqlState
,
"22003"
);
break
;
break
;
default:
default:
strcpy
(
szSqlState
,
"S1000"
);
strcpy
(
szSqlState
,
"S1000"
);
/* general error */
/* general error */
break
;
break
;
}
}
}
}
else
else
{
{
...
@@ -349,8 +343,8 @@ SQLError(
...
@@ -349,8 +343,8 @@ SQLError(
return
SQL_NO_DATA_FOUND
;
return
SQL_NO_DATA_FOUND
;
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
else
if
(
SQL_NULL_HENV
!=
henv
)
else
if
(
SQL_NULL_HENV
!=
henv
)
{
{
...
@@ -419,15 +413,10 @@ SQLError(
...
@@ -419,15 +413,10 @@ SQLError(
}
}
/*********************************************************************/
/*
/*
* EnvironmentClass implementation
* EnvironmentClass implementation
*/
*/
EnvironmentClass
*
EnvironmentClass
*
EN_Constructor
(
void
)
EN_Constructor
(
void
)
{
{
EnvironmentClass
*
rv
;
EnvironmentClass
*
rv
;
...
@@ -451,8 +440,10 @@ EN_Destructor(EnvironmentClass *self)
...
@@ -451,8 +440,10 @@ EN_Destructor(EnvironmentClass *self)
mylog
(
"in EN_Destructor, self=%u
\n
"
,
self
);
mylog
(
"in EN_Destructor, self=%u
\n
"
,
self
);
/* the error messages are static strings distributed throughout */
/*
/* the source--they should not be freed */
* the error messages are static strings distributed throughout
* the source--they should not be freed
*/
/* Free any connections belonging to this environment */
/* Free any connections belonging to this environment */
for
(
lf
=
0
;
lf
<
MAX_CONNECTIONS
;
lf
++
)
for
(
lf
=
0
;
lf
<
MAX_CONNECTIONS
;
lf
++
)
...
@@ -466,6 +457,7 @@ EN_Destructor(EnvironmentClass *self)
...
@@ -466,6 +457,7 @@ EN_Destructor(EnvironmentClass *self)
return
rv
;
return
rv
;
}
}
char
char
EN_get_error
(
EnvironmentClass
*
self
,
int
*
number
,
char
**
message
)
EN_get_error
(
EnvironmentClass
*
self
,
int
*
number
,
char
**
message
)
{
{
...
@@ -481,6 +473,7 @@ EN_get_error(EnvironmentClass *self, int *number, char **message)
...
@@ -481,6 +473,7 @@ EN_get_error(EnvironmentClass *self, int *number, char **message)
return
0
;
return
0
;
}
}
char
char
EN_add_connection
(
EnvironmentClass
*
self
,
ConnectionClass
*
conn
)
EN_add_connection
(
EnvironmentClass
*
self
,
ConnectionClass
*
conn
)
{
{
...
@@ -504,6 +497,7 @@ EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
...
@@ -504,6 +497,7 @@ EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
return
FALSE
;
return
FALSE
;
}
}
char
char
EN_remove_connection
(
EnvironmentClass
*
self
,
ConnectionClass
*
conn
)
EN_remove_connection
(
EnvironmentClass
*
self
,
ConnectionClass
*
conn
)
{
{
...
@@ -519,6 +513,7 @@ EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
...
@@ -519,6 +513,7 @@ EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
return
FALSE
;
return
FALSE
;
}
}
void
void
EN_log_error
(
char
*
func
,
char
*
desc
,
EnvironmentClass
*
self
)
EN_log_error
(
char
*
func
,
char
*
desc
,
EnvironmentClass
*
self
)
{
{
...
...
src/interfaces/odbc/execute.c
View file @
296e7ba2
/* Module: execute.c
/*-------
* Module: execute.c
*
*
* Description: This module contains routines related to
* Description: This module contains routines related to
* preparing and executing an SQL statement.
* preparing and executing an SQL statement.
...
@@ -9,7 +10,7 @@
...
@@ -9,7 +10,7 @@
* SQLCancel, SQLNativeSql, SQLParamData, SQLPutData
* SQLCancel, SQLNativeSql, SQLParamData, SQLPutData
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -126,14 +127,10 @@ SQLPrepare(HSTMT hstmt,
...
@@ -126,14 +127,10 @@ SQLPrepare(HSTMT hstmt,
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */
/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */
RETCODE
SQL_API
RETCODE
SQL_API
SQLExecDirect
(
SQLExecDirect
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -155,8 +152,10 @@ SQLExecDirect(
...
@@ -155,8 +152,10 @@ SQLExecDirect(
if
(
stmt
->
statement
)
if
(
stmt
->
statement
)
free
(
stmt
->
statement
);
free
(
stmt
->
statement
);
/* keep a copy of the un-parametrized statement, in case */
/*
/* they try to execute this statement again */
* keep a copy of the un-parametrized statement, in case
* they try to execute this statement again
*/
stmt
->
statement
=
make_string
(
szSqlStr
,
cbSqlStr
,
NULL
);
stmt
->
statement
=
make_string
(
szSqlStr
,
cbSqlStr
,
NULL
);
if
(
!
stmt
->
statement
)
if
(
!
stmt
->
statement
)
{
{
...
@@ -170,9 +169,11 @@ SQLExecDirect(
...
@@ -170,9 +169,11 @@ SQLExecDirect(
stmt
->
prepare
=
FALSE
;
stmt
->
prepare
=
FALSE
;
/* If an SQLPrepare was performed prior to this, but was left in */
/*
/* the premature state because an error occurred prior to SQLExecute */
* If an SQLPrepare was performed prior to this, but was left in
/* then set the statement to finished so it can be recycled. */
* the premature state because an error occurred prior to SQLExecute
* then set the statement to finished so it can be recycled.
*/
if
(
stmt
->
status
==
STMT_PREMATURE
)
if
(
stmt
->
status
==
STMT_PREMATURE
)
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
...
@@ -195,6 +196,7 @@ SQLExecDirect(
...
@@ -195,6 +196,7 @@ SQLExecDirect(
return
result
;
return
result
;
}
}
/* Execute a prepared SQL statement */
/* Execute a prepared SQL statement */
RETCODE
SQL_API
RETCODE
SQL_API
SQLExecute
(
SQLExecute
(
...
@@ -206,7 +208,6 @@ SQLExecute(
...
@@ -206,7 +208,6 @@ SQLExecute(
int
i
,
int
i
,
retval
;
retval
;
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
if
(
!
stmt
)
if
(
!
stmt
)
...
@@ -280,7 +281,6 @@ SQLExecute(
...
@@ -280,7 +281,6 @@ SQLExecute(
if
((
stmt
->
prepare
&&
stmt
->
status
!=
STMT_READY
)
||
if
((
stmt
->
prepare
&&
stmt
->
status
!=
STMT_READY
)
||
(
stmt
->
status
!=
STMT_ALLOCATED
&&
stmt
->
status
!=
STMT_READY
))
(
stmt
->
status
!=
STMT_ALLOCATED
&&
stmt
->
status
!=
STMT_READY
))
{
{
stmt
->
errornumber
=
STMT_STATUS_ERROR
;
stmt
->
errornumber
=
STMT_STATUS_ERROR
;
stmt
->
errormsg
=
"The handle does not point to a statement that is ready to be executed"
;
stmt
->
errormsg
=
"The handle does not point to a statement that is ready to be executed"
;
SC_log_error
(
func
,
""
,
stmt
);
SC_log_error
(
func
,
""
,
stmt
);
...
@@ -288,7 +288,6 @@ SQLExecute(
...
@@ -288,7 +288,6 @@ SQLExecute(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* Check if statement has any data-at-execute parameters when it is not in SC_pre_execute. */
/* Check if statement has any data-at-execute parameters when it is not in SC_pre_execute. */
if
(
!
stmt
->
pre_executing
)
if
(
!
stmt
->
pre_executing
)
{
{
...
@@ -336,15 +335,10 @@ SQLExecute(
...
@@ -336,15 +335,10 @@ SQLExecute(
mylog
(
" stmt_with_params = '%s'
\n
"
,
stmt
->
stmt_with_params
);
mylog
(
" stmt_with_params = '%s'
\n
"
,
stmt
->
stmt_with_params
);
return
SC_execute
(
stmt
);
return
SC_execute
(
stmt
);
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLTransact
(
SQLTransact
(
HENV
henv
,
HENV
henv
,
...
@@ -380,7 +374,6 @@ SQLTransact(
...
@@ -380,7 +374,6 @@ SQLTransact(
if
(
conn
&&
conn
->
henv
==
henv
)
if
(
conn
&&
conn
->
henv
==
henv
)
if
(
SQLTransact
(
henv
,
(
HDBC
)
conn
,
fType
)
!=
SQL_SUCCESS
)
if
(
SQLTransact
(
henv
,
(
HDBC
)
conn
,
fType
)
!=
SQL_SUCCESS
)
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
...
@@ -388,15 +381,9 @@ SQLTransact(
...
@@ -388,15 +381,9 @@ SQLTransact(
conn
=
(
ConnectionClass
*
)
hdbc
;
conn
=
(
ConnectionClass
*
)
hdbc
;
if
(
fType
==
SQL_COMMIT
)
if
(
fType
==
SQL_COMMIT
)
{
stmt_string
=
"COMMIT"
;
stmt_string
=
"COMMIT"
;
}
else
if
(
fType
==
SQL_ROLLBACK
)
else
if
(
fType
==
SQL_ROLLBACK
)
{
stmt_string
=
"ROLLBACK"
;
stmt_string
=
"ROLLBACK"
;
}
else
else
{
{
conn
->
errornumber
=
CONN_INVALID_ARGUMENT_NO
;
conn
->
errornumber
=
CONN_INVALID_ARGUMENT_NO
;
...
@@ -408,7 +395,6 @@ SQLTransact(
...
@@ -408,7 +395,6 @@ SQLTransact(
/* If manual commit and in transaction, then proceed. */
/* If manual commit and in transaction, then proceed. */
if
(
!
CC_is_in_autocommit
(
conn
)
&&
CC_is_in_trans
(
conn
))
if
(
!
CC_is_in_autocommit
(
conn
)
&&
CC_is_in_trans
(
conn
))
{
{
mylog
(
"SQLTransact: sending on conn %d '%s'
\n
"
,
conn
,
stmt_string
);
mylog
(
"SQLTransact: sending on conn %d '%s'
\n
"
,
conn
,
stmt_string
);
res
=
CC_send_query
(
conn
,
stmt_string
,
NULL
);
res
=
CC_send_query
(
conn
,
stmt_string
,
NULL
);
...
@@ -433,7 +419,6 @@ SQLTransact(
...
@@ -433,7 +419,6 @@ SQLTransact(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLCancel
(
SQLCancel
(
...
@@ -464,8 +449,6 @@ SQLCancel(
...
@@ -464,8 +449,6 @@ SQLCancel(
*/
*/
if
(
stmt
->
data_at_exec
<
0
)
if
(
stmt
->
data_at_exec
<
0
)
{
{
/*
/*
* MAJOR HACK for Windows to reset the driver manager's cursor
* MAJOR HACK for Windows to reset the driver manager's cursor
* state: Because of what seems like a bug in the Odbc driver
* state: Because of what seems like a bug in the Odbc driver
...
@@ -507,14 +490,14 @@ SQLCancel(
...
@@ -507,14 +490,14 @@ SQLCancel(
stmt
->
put_data
=
FALSE
;
stmt
->
put_data
=
FALSE
;
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
/* Returns the SQL string as modified by the driver. */
/*
/* Currently, just copy the input string without modification */
* Returns the SQL string as modified by the driver.
/* observing buffer limits and truncation. */
* Currently, just copy the input string without modification
* observing buffer limits and truncation.
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLNativeSql
(
SQLNativeSql
(
HDBC
hdbc
,
HDBC
hdbc
,
...
@@ -564,11 +547,11 @@ SQLNativeSql(
...
@@ -564,11 +547,11 @@ SQLNativeSql(
return
result
;
return
result
;
}
}
/* - - - - - - - - - */
/* Supplies parameter data at execution time. Used in conjuction with */
/* SQLPutData. */
/*
* Supplies parameter data at execution time.
* Used in conjuction with SQLPutData.
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLParamData
(
SQLParamData
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -636,11 +619,9 @@ SQLParamData(
...
@@ -636,11 +619,9 @@ SQLParamData(
CC_set_no_trans
(
stmt
->
hdbc
);
CC_set_no_trans
(
stmt
->
hdbc
);
}
}
stmt
->
lobj_fd
=
-
1
;
stmt
->
lobj_fd
=
-
1
;
}
}
/* Done, now copy the params and then execute the statement */
/* Done, now copy the params and then execute the statement */
if
(
stmt
->
data_at_exec
==
0
)
if
(
stmt
->
data_at_exec
==
0
)
{
{
...
@@ -675,11 +656,11 @@ SQLParamData(
...
@@ -675,11 +656,11 @@ SQLParamData(
return
SQL_NEED_DATA
;
return
SQL_NEED_DATA
;
}
}
/* - - - - - - - - - */
/* Supplies parameter data at execution time. Used in conjunction with */
/* SQLParamData. */
/*
* Supplies parameter data at execution time.
* Used in conjunction with SQLParamData.
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLPutData
(
SQLPutData
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -701,7 +682,6 @@ SQLPutData(
...
@@ -701,7 +682,6 @@ SQLPutData(
return
SQL_INVALID_HANDLE
;
return
SQL_INVALID_HANDLE
;
}
}
if
(
stmt
->
current_exec_param
<
0
)
if
(
stmt
->
current_exec_param
<
0
)
{
{
stmt
->
errornumber
=
STMT_SEQUENCE_ERROR
;
stmt
->
errornumber
=
STMT_SEQUENCE_ERROR
;
...
@@ -714,7 +694,6 @@ SQLPutData(
...
@@ -714,7 +694,6 @@ SQLPutData(
if
(
!
stmt
->
put_data
)
if
(
!
stmt
->
put_data
)
{
/* first call */
{
/* first call */
mylog
(
"SQLPutData: (1) cbValue = %d
\n
"
,
cbValue
);
mylog
(
"SQLPutData: (1) cbValue = %d
\n
"
,
cbValue
);
stmt
->
put_data
=
TRUE
;
stmt
->
put_data
=
TRUE
;
...
@@ -733,11 +712,9 @@ SQLPutData(
...
@@ -733,11 +712,9 @@ SQLPutData(
if
(
cbValue
==
SQL_NULL_DATA
)
if
(
cbValue
==
SQL_NULL_DATA
)
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
/* Handle Long Var Binary with Large Objects */
/* Handle Long Var Binary with Large Objects */
if
(
current_param
->
SQLType
==
SQL_LONGVARBINARY
)
if
(
current_param
->
SQLType
==
SQL_LONGVARBINARY
)
{
{
/* begin transaction if needed */
/* begin transaction if needed */
if
(
!
CC_is_in_trans
(
stmt
->
hdbc
))
if
(
!
CC_is_in_trans
(
stmt
->
hdbc
))
{
{
...
@@ -775,8 +752,10 @@ SQLPutData(
...
@@ -775,8 +752,10 @@ SQLPutData(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* major hack -- to allow convert to see somethings there */
/*
/* have to modify convert to handle this better */
* major hack -- to allow convert to see somethings there
* have to modify convert to handle this better
*/
current_param
->
EXEC_buffer
=
(
char
*
)
&
current_param
->
lobj_oid
;
current_param
->
EXEC_buffer
=
(
char
*
)
&
current_param
->
lobj_oid
;
/* store the fd */
/* store the fd */
...
@@ -791,11 +770,10 @@ SQLPutData(
...
@@ -791,11 +770,10 @@ SQLPutData(
retval
=
lo_write
(
stmt
->
hdbc
,
stmt
->
lobj_fd
,
rgbValue
,
cbValue
);
retval
=
lo_write
(
stmt
->
hdbc
,
stmt
->
lobj_fd
,
rgbValue
,
cbValue
);
mylog
(
"lo_write: cbValue=%d, wrote %d bytes
\n
"
,
cbValue
,
retval
);
mylog
(
"lo_write: cbValue=%d, wrote %d bytes
\n
"
,
cbValue
,
retval
);
}
}
else
else
{
/* for handling fields */
{
/* for handling fields */
if
(
cbValue
==
SQL_NTS
)
if
(
cbValue
==
SQL_NTS
)
{
{
current_param
->
EXEC_buffer
=
strdup
(
rgbValue
);
current_param
->
EXEC_buffer
=
strdup
(
rgbValue
);
...
@@ -841,25 +819,21 @@ SQLPutData(
...
@@ -841,25 +819,21 @@ SQLPutData(
}
}
}
}
}
}
else
else
{
/* calling SQLPutData more than once */
{
/* calling SQLPutData more than once */
mylog
(
"SQLPutData: (>1) cbValue = %d
\n
"
,
cbValue
);
mylog
(
"SQLPutData: (>1) cbValue = %d
\n
"
,
cbValue
);
if
(
current_param
->
SQLType
==
SQL_LONGVARBINARY
)
if
(
current_param
->
SQLType
==
SQL_LONGVARBINARY
)
{
{
/* the large object fd is in EXEC_buffer */
/* the large object fd is in EXEC_buffer */
retval
=
lo_write
(
stmt
->
hdbc
,
stmt
->
lobj_fd
,
rgbValue
,
cbValue
);
retval
=
lo_write
(
stmt
->
hdbc
,
stmt
->
lobj_fd
,
rgbValue
,
cbValue
);
mylog
(
"lo_write(2): cbValue = %d, wrote %d bytes
\n
"
,
cbValue
,
retval
);
mylog
(
"lo_write(2): cbValue = %d, wrote %d bytes
\n
"
,
cbValue
,
retval
);
*
current_param
->
EXEC_used
+=
cbValue
;
*
current_param
->
EXEC_used
+=
cbValue
;
}
}
else
else
{
{
buffer
=
current_param
->
EXEC_buffer
;
buffer
=
current_param
->
EXEC_buffer
;
if
(
cbValue
==
SQL_NTS
)
if
(
cbValue
==
SQL_NTS
)
...
@@ -880,11 +854,9 @@ SQLPutData(
...
@@ -880,11 +854,9 @@ SQLPutData(
/* reassign buffer incase realloc moved it */
/* reassign buffer incase realloc moved it */
current_param
->
EXEC_buffer
=
buffer
;
current_param
->
EXEC_buffer
=
buffer
;
}
}
else
if
(
cbValue
>
0
)
else
if
(
cbValue
>
0
)
{
{
old_pos
=
*
current_param
->
EXEC_used
;
old_pos
=
*
current_param
->
EXEC_used
;
*
current_param
->
EXEC_used
+=
cbValue
;
*
current_param
->
EXEC_used
+=
cbValue
;
...
@@ -906,17 +878,14 @@ SQLPutData(
...
@@ -906,17 +878,14 @@ SQLPutData(
/* reassign buffer incase realloc moved it */
/* reassign buffer incase realloc moved it */
current_param
->
EXEC_buffer
=
buffer
;
current_param
->
EXEC_buffer
=
buffer
;
}
}
else
else
{
{
SC_log_error
(
func
,
"bad cbValue"
,
stmt
);
SC_log_error
(
func
,
"bad cbValue"
,
stmt
);
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
}
}
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
src/interfaces/odbc/gpps.c
View file @
296e7ba2
/* GetPrivateProfileString()
/*-------
* GetPrivateProfileString()
*
*
* approximate implementation of
* approximate implementation of
* Windows NT System Services version of GetPrivateProfileString()
* Windows NT System Services version of GetPrivateProfileString()
...
@@ -15,6 +16,7 @@
...
@@ -15,6 +16,7 @@
* are allowed (that is an anachronism anyway)
* are allowed (that is an anachronism anyway)
* Added code to search for ODBC_INI file in users home directory on
* Added code to search for ODBC_INI file in users home directory on
* Unix
* Unix
*-------
*/
*/
#ifndef WIN32
#ifndef WIN32
...
@@ -110,7 +112,6 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -110,7 +112,6 @@ GetPrivateProfileString(char *theSection, /* section name */
aFile
=
(
FILE
*
)
(
buf
?
fopen
(
buf
,
PG_BINARY_R
)
:
NULL
);
aFile
=
(
FILE
*
)
(
buf
?
fopen
(
buf
,
PG_BINARY_R
)
:
NULL
);
}
}
aLength
=
(
theDefault
==
NULL
)
?
0
:
strlen
(
theDefault
);
aLength
=
(
theDefault
==
NULL
)
?
0
:
strlen
(
theDefault
);
if
(
theReturnBufferLength
==
0
||
theReturnBuffer
==
NULL
)
if
(
theReturnBufferLength
==
0
||
theReturnBuffer
==
NULL
)
...
@@ -123,7 +124,6 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -123,7 +124,6 @@ GetPrivateProfileString(char *theSection, /* section name */
if
(
aFile
==
NULL
)
if
(
aFile
==
NULL
)
{
{
/* no ini file specified, return the default */
/* no ini file specified, return the default */
++
aLength
;
/* room for NULL char */
++
aLength
;
/* room for NULL char */
aLength
=
theReturnBufferLength
<
aLength
?
aLength
=
theReturnBufferLength
<
aLength
?
theReturnBufferLength
:
aLength
;
theReturnBufferLength
:
aLength
;
...
@@ -132,7 +132,6 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -132,7 +132,6 @@ GetPrivateProfileString(char *theSection, /* section name */
return
aLength
-
1
;
return
aLength
-
1
;
}
}
while
(
fgets
(
aLine
,
sizeof
(
aLine
),
aFile
)
!=
NULL
)
while
(
fgets
(
aLine
,
sizeof
(
aLine
),
aFile
)
!=
NULL
)
{
{
aLineLength
=
strlen
(
aLine
);
aLineLength
=
strlen
(
aLine
);
...
@@ -147,7 +146,6 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -147,7 +146,6 @@ GetPrivateProfileString(char *theSection, /* section name */
break
;
break
;
case
'['
:
/* section marker */
case
'['
:
/* section marker */
if
((
aString
=
strchr
(
aLine
,
']'
)))
if
((
aString
=
strchr
(
aLine
,
']'
)))
{
{
aStart
=
aLine
+
1
;
aStart
=
aLine
+
1
;
...
@@ -159,30 +157,25 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -159,30 +157,25 @@ GetPrivateProfileString(char *theSection, /* section name */
*
(
aString
+
1
)
=
'\0'
;
*
(
aString
+
1
)
=
'\0'
;
/* accept as matched if NULL key or exact match */
/* accept as matched if NULL key or exact match */
if
(
!
theSection
||
!
strcmp
(
aStart
,
theSection
))
if
(
!
theSection
||
!
strcmp
(
aStart
,
theSection
))
aSectionFound
=
TRUE
;
aSectionFound
=
TRUE
;
else
else
aSectionFound
=
FALSE
;
aSectionFound
=
FALSE
;
}
}
break
;
break
;
default:
default:
/* try to match value keys if in proper section */
/* try to match value keys if in proper section */
if
(
aSectionFound
)
if
(
aSectionFound
)
{
{
/* try to match requested key */
/* try to match requested key */
if
((
aString
=
aValue
=
strchr
(
aLine
,
'='
)))
if
((
aString
=
aValue
=
strchr
(
aLine
,
'='
)))
{
{
*
aValue
=
'\0'
;
*
aValue
=
'\0'
;
++
aValue
;
++
aValue
;
/* strip leading blanks in value field */
/* strip leading blanks in value field */
while
(
*
aValue
==
' '
&&
aValue
<
aLine
+
sizeof
(
aLine
))
while
(
*
aValue
==
' '
&&
aValue
<
aLine
+
sizeof
(
aLine
))
*
aValue
++
=
'\0'
;
*
aValue
++
=
'\0'
;
if
(
aValue
>=
aLine
+
sizeof
(
aLine
))
if
(
aValue
>=
aLine
+
sizeof
(
aLine
))
...
@@ -196,7 +189,6 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -196,7 +189,6 @@ GetPrivateProfileString(char *theSection, /* section name */
aStart
++
;
aStart
++
;
/* strip trailing blanks from key */
/* strip trailing blanks from key */
if
(
aString
)
if
(
aString
)
{
{
while
(
--
aString
>=
aStart
&&
*
aString
==
' '
)
while
(
--
aString
>=
aStart
&&
*
aString
==
' '
)
...
@@ -204,16 +196,13 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -204,16 +196,13 @@ GetPrivateProfileString(char *theSection, /* section name */
}
}
/* see if key is matched */
/* see if key is matched */
if
(
theKey
==
NULL
||
!
strcmp
(
theKey
,
aStart
))
if
(
theKey
==
NULL
||
!
strcmp
(
theKey
,
aStart
))
{
{
/* matched -- first, terminate value part */
/* matched -- first, terminate value part */
aKeyFound
=
TRUE
;
aKeyFound
=
TRUE
;
aLength
=
strlen
(
aValue
);
aLength
=
strlen
(
aValue
);
/* remove trailing blanks from aValue if any */
/* remove trailing blanks from aValue if any */
aString
=
aValue
+
aLength
-
1
;
aString
=
aValue
+
aLength
-
1
;
while
(
--
aString
>
aValue
&&
*
aString
==
' '
)
while
(
--
aString
>
aValue
&&
*
aString
==
' '
)
...
@@ -223,7 +212,6 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -223,7 +212,6 @@ GetPrivateProfileString(char *theSection, /* section name */
}
}
/* unquote value if quoted */
/* unquote value if quoted */
if
(
aLength
>=
2
&&
aValue
[
0
]
==
'"'
&&
if
(
aLength
>=
2
&&
aValue
[
0
]
==
'"'
&&
aValue
[
aLength
-
1
]
==
'"'
)
aValue
[
aLength
-
1
]
==
'"'
)
{
{
...
@@ -236,7 +224,6 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -236,7 +224,6 @@ GetPrivateProfileString(char *theSection, /* section name */
else
else
{
{
/* single quotes allowed also... */
/* single quotes allowed also... */
if
(
aLength
>=
2
&&
aValue
[
0
]
==
'\''
&&
if
(
aLength
>=
2
&&
aValue
[
0
]
==
'\''
&&
aValue
[
aLength
-
1
]
==
'\''
)
aValue
[
aLength
-
1
]
==
'\''
)
{
{
...
@@ -247,13 +234,11 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -247,13 +234,11 @@ GetPrivateProfileString(char *theSection, /* section name */
}
}
/* compute maximum length copyable */
/* compute maximum length copyable */
aLineLength
=
(
aLength
<
aLineLength
=
(
aLength
<
theReturnBufferLength
-
aReturnLength
)
?
aLength
:
theReturnBufferLength
-
aReturnLength
)
?
aLength
:
theReturnBufferLength
-
aReturnLength
;
theReturnBufferLength
-
aReturnLength
;
/* do the copy to return buffer */
/* do the copy to return buffer */
if
(
aLineLength
)
if
(
aLineLength
)
{
{
strncpy
(
&
theReturnBuffer
[
aReturnLength
],
strncpy
(
&
theReturnBuffer
[
aReturnLength
],
...
@@ -270,11 +255,9 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -270,11 +255,9 @@ GetPrivateProfileString(char *theSection, /* section name */
fclose
(
aFile
);
fclose
(
aFile
);
aFile
=
NULL
;
aFile
=
NULL
;
}
}
return
aReturnLength
>
0
?
aReturnLength
-
1
:
0
;
return
aReturnLength
>
0
?
aReturnLength
-
1
:
0
;
}
}
}
}
break
;
break
;
}
}
}
}
...
@@ -283,7 +266,8 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -283,7 +266,8 @@ GetPrivateProfileString(char *theSection, /* section name */
fclose
(
aFile
);
fclose
(
aFile
);
if
(
!
aKeyFound
)
if
(
!
aKeyFound
)
{
/* key wasn't found return default */
{
/* key wasn't found return default */
++
aLength
;
/* room for NULL char */
++
aLength
;
/* room for NULL char */
aLength
=
theReturnBufferLength
<
aLength
?
aLength
=
theReturnBufferLength
<
aLength
?
theReturnBufferLength
:
aLength
;
theReturnBufferLength
:
aLength
;
...
@@ -294,6 +278,7 @@ GetPrivateProfileString(char *theSection, /* section name */
...
@@ -294,6 +278,7 @@ GetPrivateProfileString(char *theSection, /* section name */
return
aReturnLength
>
0
?
aReturnLength
-
1
:
0
;
return
aReturnLength
>
0
?
aReturnLength
-
1
:
0
;
}
}
DWORD
DWORD
WritePrivateProfileString
(
char
*
theSection
,
/* section name */
WritePrivateProfileString
(
char
*
theSection
,
/* section name */
char
*
theKey
,
/* write key name */
char
*
theKey
,
/* write key name */
...
@@ -304,8 +289,10 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -304,8 +289,10 @@ WritePrivateProfileString(char *theSection, /* section name */
return
0
;
return
0
;
}
}
#if 0
#if 0
/* Ok. What the hell's the default behaviour for a null input buffer, and null
/*
* Ok. What the hell's the default behaviour for a null input buffer, and null
* section name. For now if either are null I ignore the request, until
* section name. For now if either are null I ignore the request, until
* I find out different.
* I find out different.
*/
*/
...
@@ -353,11 +340,12 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -353,11 +340,12 @@ WritePrivateProfileString(char *theSection, /* section name */
if (ptr == NULL || *ptr == '\0')
if (ptr == NULL || *ptr == '\0')
ptr = "/home";
ptr = "/home";
/* This doesn't make it so we find an ini file but allows normal */
/*
/* processing to continue further on down. The likelihood is that */
* This doesn't make it so we find an ini file but allows normal
/* the file won't be found and thus the default value will be */
* processing to continue further on down. The likelihood is that
/* returned. */
* the file won't be found and thus the default value will be
/* */
* returned.
*/
if (MAXPGPATH - 1 < strlen(ptr) + j)
if (MAXPGPATH - 1 < strlen(ptr) + j)
{
{
if (MAXPGPATH - 1 < strlen(ptr))
if (MAXPGPATH - 1 < strlen(ptr))
...
@@ -368,9 +356,10 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -368,9 +356,10 @@ WritePrivateProfileString(char *theSection, /* section name */
sprintf(buf, "%s/%s", ptr, theIniFileName);
sprintf(buf, "%s/%s", ptr, theIniFileName);
/* This code makes it so that a file in the users home dir */
/*
/* overrides a the "default" file as passed in */
* This code makes it so that a file in the users home dir
/* */
* overrides a the "default" file as passed in
*/
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
if (!aFile)
if (!aFile)
{
{
...
@@ -380,13 +369,13 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -380,13 +369,13 @@ WritePrivateProfileString(char *theSection, /* section name */
return 0;
return 0;
}
}
aLength = strlen(theBuffer);
aLength = strlen(theBuffer);
/* We have to search for theKey, because if it already */
/*
/* exists we have to overwrite it. If it doesn't exist */
* We have to search for theKey, because if it already
/* we just write a new line to the file. */
* exists we have to overwrite it. If it doesn't exist
/* */
* we just write a new line to the file.
*/
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
{
{
aLineLength = strlen(aLine);
aLineLength = strlen(aLine);
...
@@ -401,7 +390,6 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -401,7 +390,6 @@ WritePrivateProfileString(char *theSection, /* section name */
break;
break;
case '[': /* section marker */
case '[': /* section marker */
if ((aString = strchr(aLine, ']')))
if ((aString = strchr(aLine, ']')))
{
{
*aString = '\0';
*aString = '\0';
...
@@ -411,13 +399,10 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -411,13 +399,10 @@ WritePrivateProfileString(char *theSection, /* section name */
if (!strcmp(aLine + 1, theSection))
if (!strcmp(aLine + 1, theSection))
aSectionFound = TRUE;
aSectionFound = TRUE;
}
}
break;
break;
default:
default:
/* try to match value keys if in proper section */
/* try to match value keys if in proper section */
if (aSectionFound)
if (aSectionFound)
{
{
/* try to match requested key */
/* try to match requested key */
...
@@ -428,7 +413,6 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -428,7 +413,6 @@ WritePrivateProfileString(char *theSection, /* section name */
++aValue;
++aValue;
/* strip leading blanks in value field */
/* strip leading blanks in value field */
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
*aValue++ = '\0';
*aValue++ = '\0';
if (aValue >= aLine + sizeof(aLine))
if (aValue >= aLine + sizeof(aLine))
...
@@ -438,7 +422,6 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -438,7 +422,6 @@ WritePrivateProfileString(char *theSection, /* section name */
aValue = "";
aValue = "";
/* strip trailing blanks from key */
/* strip trailing blanks from key */
if (aString)
if (aString)
{
{
while (--aString >= aLine && *aString == ' ')
while (--aString >= aLine && *aString == ' ')
...
@@ -446,7 +429,6 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -446,7 +429,6 @@ WritePrivateProfileString(char *theSection, /* section name */
}
}
/* see if key is matched */
/* see if key is matched */
if (!strcmp(theKey, aLine))
if (!strcmp(theKey, aLine))
{
{
keyFound = TRUE;
keyFound = TRUE;
...
@@ -460,7 +442,6 @@ WritePrivateProfileString(char *theSection, /* section name */
...
@@ -460,7 +442,6 @@ WritePrivateProfileString(char *theSection, /* section name */
}
}
}
}
}
}
break;
break;
}
}
}
}
...
...
src/interfaces/odbc/info.c
View file @
296e7ba2
/* Module: info.c
/*--------
* Module: info.c
*
*
* Description: This module contains routines related to
* Description: This module contains routines related to
* ODBC informational functions.
* ODBC informational functions.
...
@@ -12,7 +13,7 @@
...
@@ -12,7 +13,7 @@
* SQLTablePrivileges(NI), SQLColumnPrivileges(NI)
* SQLTablePrivileges(NI), SQLColumnPrivileges(NI)
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
--------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -56,8 +57,6 @@
...
@@ -56,8 +57,6 @@
extern
GLOBAL_VALUES
globals
;
extern
GLOBAL_VALUES
globals
;
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLGetInfo
(
SQLGetInfo
(
HDBC
hdbc
,
HDBC
hdbc
,
...
@@ -154,7 +153,6 @@ SQLGetInfo(
...
@@ -154,7 +153,6 @@ SQLGetInfo(
break
;
break
;
case
SQL_CORRELATION_NAME
:
/* ODBC 1.0 */
case
SQL_CORRELATION_NAME
:
/* ODBC 1.0 */
/*
/*
* Saying no correlation name makes Query not work right.
* Saying no correlation name makes Query not work right.
* value = SQL_CN_NONE;
* value = SQL_CN_NONE;
...
@@ -182,11 +180,10 @@ SQLGetInfo(
...
@@ -182,11 +180,10 @@ SQLGetInfo(
break
;
break
;
case
SQL_DATABASE_NAME
:
/* Support for old ODBC 1.0 Apps */
case
SQL_DATABASE_NAME
:
/* Support for old ODBC 1.0 Apps */
/*
/*
* Returning the database name causes problems in MS Query. It
* Returning the database name causes problems in MS Query. It
* generates query like: "SELECT DISTINCT a FROM byronn
crap
3
* generates query like: "SELECT DISTINCT a FROM byronn
bad
3
*
crap
3"
*
bad
3"
*
*
* p = CC_get_database(conn);
* p = CC_get_database(conn);
*/
*/
...
@@ -198,7 +195,6 @@ SQLGetInfo(
...
@@ -198,7 +195,6 @@ SQLGetInfo(
break
;
break
;
case
SQL_DBMS_VER
:
/* ODBC 1.0 */
case
SQL_DBMS_VER
:
/* ODBC 1.0 */
/*
/*
* The ODBC spec wants ##.##.#### ...whatever... so prepend
* The ODBC spec wants ##.##.#### ...whatever... so prepend
* the driver
* the driver
...
@@ -256,7 +252,6 @@ SQLGetInfo(
...
@@ -256,7 +252,6 @@ SQLGetInfo(
break
;
break
;
case
SQL_IDENTIFIER_CASE
:
/* ODBC 1.0 */
case
SQL_IDENTIFIER_CASE
:
/* ODBC 1.0 */
/*
/*
* are identifiers case-sensitive (yes, but only when quoted.
* are identifiers case-sensitive (yes, but only when quoted.
* If not quoted, they default to lowercase)
* If not quoted, they default to lowercase)
...
@@ -275,7 +270,6 @@ SQLGetInfo(
...
@@ -275,7 +270,6 @@ SQLGetInfo(
break
;
break
;
case
SQL_LIKE_ESCAPE_CLAUSE
:
/* ODBC 2.0 */
case
SQL_LIKE_ESCAPE_CLAUSE
:
/* ODBC 2.0 */
/*
/*
* is there a character that escapes '%' and '_' in a LIKE
* is there a character that escapes '%' and '_' in a LIKE
* clause? not as far as I can tell
* clause? not as far as I can tell
...
@@ -356,18 +350,18 @@ SQLGetInfo(
...
@@ -356,18 +350,18 @@ SQLGetInfo(
case
SQL_MAX_ROW_SIZE
:
/* ODBC 2.0 */
case
SQL_MAX_ROW_SIZE
:
/* ODBC 2.0 */
len
=
4
;
len
=
4
;
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
{
/* Large Rowa in 7.1+ */
{
/* Large Rowa in 7.1+ */
value
=
MAX_ROW_SIZE
;
value
=
MAX_ROW_SIZE
;
}
}
else
else
{
/* Without the Toaster we're limited to
{
*
the blocksize */
/* Without the Toaster we're limited to
the blocksize */
value
=
BLCKSZ
;
value
=
BLCKSZ
;
}
}
break
;
break
;
case
SQL_MAX_ROW_SIZE_INCLUDES_LONG
:
/* ODBC 2.0 */
case
SQL_MAX_ROW_SIZE_INCLUDES_LONG
:
/* ODBC 2.0 */
/*
/*
* does the preceding value include LONGVARCHAR and
* does the preceding value include LONGVARCHAR and
* LONGVARBINARY fields? Well, it does include longvarchar,
* LONGVARBINARY fields? Well, it does include longvarchar,
...
@@ -379,15 +373,14 @@ SQLGetInfo(
...
@@ -379,15 +373,14 @@ SQLGetInfo(
case
SQL_MAX_STATEMENT_LEN
:
/* ODBC 2.0 */
case
SQL_MAX_STATEMENT_LEN
:
/* ODBC 2.0 */
/* maybe this should be 0? */
/* maybe this should be 0? */
len
=
4
;
len
=
4
;
/* Long Queries in 7.0+ */
if
(
PG_VERSION_GE
(
conn
,
7
.
0
))
if
(
PG_VERSION_GE
(
conn
,
7
.
0
))
{
/* Long Queries in 7.0+ */
value
=
MAX_STATEMENT_LEN
;
value
=
MAX_STATEMENT_LEN
;
}
/* Prior to 7.0 we used 2*BLCKSZ */
else
if
(
PG_VERSION_GE
(
conn
,
6
.
5
))
/* Prior to 7.0 we used
else
if
(
PG_VERSION_GE
(
conn
,
6
.
5
))
* 2*BLCKSZ */
value
=
(
2
*
BLCKSZ
);
value
=
(
2
*
BLCKSZ
);
else
else
/* Prior to 6.5 we used BLCKSZ */
/* Prior to 6.5 we used BLCKSZ */
value
=
BLCKSZ
;
value
=
BLCKSZ
;
break
;
break
;
...
@@ -417,9 +410,8 @@ SQLGetInfo(
...
@@ -417,9 +410,8 @@ SQLGetInfo(
break
;
break
;
case
SQL_NEED_LONG_DATA_LEN
:
/* ODBC 2.0 */
case
SQL_NEED_LONG_DATA_LEN
:
/* ODBC 2.0 */
/*
/*
* Dont need the length, SQLPutData can handle any size and
* Don
'
t need the length, SQLPutData can handle any size and
* multiple calls
* multiple calls
*/
*/
p
=
"N"
;
p
=
"N"
;
...
@@ -463,7 +455,8 @@ SQLGetInfo(
...
@@ -463,7 +455,8 @@ SQLGetInfo(
case
SQL_OJ_CAPABILITIES
:
/* ODBC 2.01 */
case
SQL_OJ_CAPABILITIES
:
/* ODBC 2.01 */
len
=
4
;
len
=
4
;
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
{
/* OJs in 7.1+ */
{
/* OJs in 7.1+ */
value
=
(
SQL_OJ_LEFT
|
value
=
(
SQL_OJ_LEFT
|
SQL_OJ_RIGHT
|
SQL_OJ_RIGHT
|
SQL_OJ_FULL
|
SQL_OJ_FULL
|
...
@@ -473,9 +466,8 @@ SQLGetInfo(
...
@@ -473,9 +466,8 @@ SQLGetInfo(
SQL_OJ_ALL_COMPARISON_OPS
);
SQL_OJ_ALL_COMPARISON_OPS
);
}
}
else
else
{
/* OJs not in <7.1 */
/* OJs not in <7.1 */
value
=
0
;
value
=
0
;
}
break
;
break
;
case
SQL_ORDER_BY_COLUMNS_IN_SELECT
:
/* ODBC 2.0 */
case
SQL_ORDER_BY_COLUMNS_IN_SELECT
:
/* ODBC 2.0 */
...
@@ -484,13 +476,11 @@ SQLGetInfo(
...
@@ -484,13 +476,11 @@ SQLGetInfo(
case
SQL_OUTER_JOINS
:
/* ODBC 1.0 */
case
SQL_OUTER_JOINS
:
/* ODBC 1.0 */
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
{
/* OJs in 7.1+ */
/* OJs in 7.1+ */
p
=
"Y"
;
p
=
"Y"
;
}
else
else
{
/* OJs not in <7.1 */
/* OJs not in <7.1 */
p
=
"N"
;
p
=
"N"
;
}
break
;
break
;
case
SQL_OWNER_TERM
:
/* ODBC 1.0 */
case
SQL_OWNER_TERM
:
/* ODBC 1.0 */
...
@@ -547,7 +537,6 @@ SQLGetInfo(
...
@@ -547,7 +537,6 @@ SQLGetInfo(
break
;
break
;
case
SQL_ROW_UPDATES
:
/* ODBC 1.0 */
case
SQL_ROW_UPDATES
:
/* ODBC 1.0 */
/*
/*
* Driver doesn't support keyset-driven or mixed cursors, so
* Driver doesn't support keyset-driven or mixed cursors, so
* not much point in saying row updates are supported
* not much point in saying row updates are supported
...
@@ -635,7 +624,6 @@ SQLGetInfo(
...
@@ -635,7 +624,6 @@ SQLGetInfo(
break
;
break
;
case
SQL_TXN_CAPABLE
:
/* ODBC 1.0 */
case
SQL_TXN_CAPABLE
:
/* ODBC 1.0 */
/*
/*
* Postgres can deal with create or drop table statements in a
* Postgres can deal with create or drop table statements in a
* transaction
* transaction
...
@@ -677,7 +665,8 @@ SQLGetInfo(
...
@@ -677,7 +665,8 @@ SQLGetInfo(
* what length would be required if a real buffer had been passed in.
* what length would be required if a real buffer had been passed in.
*/
*/
if
(
p
)
if
(
p
)
{
/* char/binary data */
{
/* char/binary data */
len
=
strlen
(
p
);
len
=
strlen
(
p
);
if
(
rgbInfoValue
)
if
(
rgbInfoValue
)
...
@@ -692,13 +681,11 @@ SQLGetInfo(
...
@@ -692,13 +681,11 @@ SQLGetInfo(
}
}
}
}
}
}
else
else
{
/* numeric data */
{
/* numeric data */
if
(
rgbInfoValue
)
if
(
rgbInfoValue
)
{
{
if
(
len
==
2
)
if
(
len
==
2
)
*
((
WORD
*
)
rgbInfoValue
)
=
(
WORD
)
value
;
*
((
WORD
*
)
rgbInfoValue
)
=
(
WORD
)
value
;
else
if
(
len
==
4
)
else
if
(
len
==
4
)
...
@@ -712,8 +699,6 @@ SQLGetInfo(
...
@@ -712,8 +699,6 @@ SQLGetInfo(
return
result
;
return
result
;
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLGetTypeInfo
(
SQLGetTypeInfo
(
...
@@ -725,7 +710,7 @@ SQLGetTypeInfo(
...
@@ -725,7 +710,7 @@ SQLGetTypeInfo(
TupleNode
*
row
;
TupleNode
*
row
;
int
i
;
int
i
;
/* Int4 type; */
/* Int4 type; */
Int4
pgType
;
Int4
pgType
;
Int2
sqlType
;
Int2
sqlType
;
...
@@ -737,7 +722,6 @@ SQLGetTypeInfo(
...
@@ -737,7 +722,6 @@ SQLGetTypeInfo(
return
SQL_INVALID_HANDLE
;
return
SQL_INVALID_HANDLE
;
}
}
stmt
->
manual_result
=
TRUE
;
stmt
->
manual_result
=
TRUE
;
stmt
->
result
=
QR_Constructor
();
stmt
->
result
=
QR_Constructor
();
if
(
!
stmt
->
result
)
if
(
!
stmt
->
result
)
...
@@ -801,7 +785,6 @@ SQLGetTypeInfo(
...
@@ -801,7 +785,6 @@ SQLGetTypeInfo(
}
}
}
}
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
stmt
->
currTuple
=
-
1
;
stmt
->
currTuple
=
-
1
;
stmt
->
rowset_start
=
-
1
;
stmt
->
rowset_start
=
-
1
;
...
@@ -810,7 +793,6 @@ SQLGetTypeInfo(
...
@@ -810,7 +793,6 @@ SQLGetTypeInfo(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLGetFunctions
(
SQLGetFunctions
(
...
@@ -824,7 +806,6 @@ SQLGetFunctions(
...
@@ -824,7 +806,6 @@ SQLGetFunctions(
if
(
fFunction
==
SQL_API_ALL_FUNCTIONS
)
if
(
fFunction
==
SQL_API_ALL_FUNCTIONS
)
{
{
if
(
globals
.
lie
)
if
(
globals
.
lie
)
{
{
int
i
;
int
i
;
...
@@ -910,13 +891,10 @@ SQLGetFunctions(
...
@@ -910,13 +891,10 @@ SQLGetFunctions(
}
}
else
else
{
{
if
(
globals
.
lie
)
if
(
globals
.
lie
)
*
pfExists
=
TRUE
;
*
pfExists
=
TRUE
;
else
else
{
{
switch
(
fFunction
)
switch
(
fFunction
)
{
{
case
SQL_API_SQLALLOCCONNECT
:
case
SQL_API_SQLALLOCCONNECT
:
...
@@ -1094,12 +1072,10 @@ SQLGetFunctions(
...
@@ -1094,12 +1072,10 @@ SQLGetFunctions(
}
}
}
}
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLTables
(
SQLTables
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -1161,13 +1137,12 @@ SQLTables(
...
@@ -1161,13 +1137,12 @@ SQLTables(
}
}
tbl_stmt
=
(
StatementClass
*
)
htbl_stmt
;
tbl_stmt
=
(
StatementClass
*
)
htbl_stmt
;
/* ********************************************************************** */
/*
/* Create the query to find out the tables */
* Create the query to find out the tables
/* ********************************************************************** */
*/
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
{
/* view is represented by its relkind
{
*
since 7.1 */
/* view is represented by its relkind
since 7.1 */
strcpy
(
tables_query
,
"select relname, usename, relkind from pg_class, pg_user"
);
strcpy
(
tables_query
,
"select relname, usename, relkind from pg_class, pg_user"
);
strcat
(
tables_query
,
" where relkind in ('r', 'v')"
);
strcat
(
tables_query
,
" where relkind in ('r', 'v')"
);
}
}
...
@@ -1180,15 +1155,12 @@ SQLTables(
...
@@ -1180,15 +1155,12 @@ SQLTables(
my_strcat
(
tables_query
,
" and usename like '%.*s'"
,
szTableOwner
,
cbTableOwner
);
my_strcat
(
tables_query
,
" and usename like '%.*s'"
,
szTableOwner
,
cbTableOwner
);
my_strcat
(
tables_query
,
" and relname like '%.*s'"
,
szTableName
,
cbTableName
);
my_strcat
(
tables_query
,
" and relname like '%.*s'"
,
szTableName
,
cbTableName
);
/* Parse the extra systable prefix */
/* Parse the extra systable prefix */
strcpy
(
prefixes
,
globals
.
extra_systable_prefixes
);
strcpy
(
prefixes
,
globals
.
extra_systable_prefixes
);
i
=
0
;
i
=
0
;
prefix
[
i
]
=
strtok
(
prefixes
,
";"
);
prefix
[
i
]
=
strtok
(
prefixes
,
";"
);
while
(
prefix
[
i
]
&&
i
<
32
)
while
(
prefix
[
i
]
&&
i
<
32
)
{
prefix
[
++
i
]
=
strtok
(
NULL
,
";"
);
prefix
[
++
i
]
=
strtok
(
NULL
,
";"
);
}
/* Parse the desired table types to return */
/* Parse the desired table types to return */
show_system_tables
=
FALSE
;
show_system_tables
=
FALSE
;
...
@@ -1216,7 +1188,6 @@ SQLTables(
...
@@ -1216,7 +1188,6 @@ SQLTables(
show_regular_tables
=
TRUE
;
show_regular_tables
=
TRUE
;
else
if
(
strstr
(
table_type
[
i
],
"VIEW"
))
else
if
(
strstr
(
table_type
[
i
],
"VIEW"
))
show_views
=
TRUE
;
show_views
=
TRUE
;
i
++
;
i
++
;
}
}
}
}
...
@@ -1243,21 +1214,17 @@ SQLTables(
...
@@ -1243,21 +1214,17 @@ SQLTables(
strcat
(
tables_query
,
prefix
[
i
]);
strcat
(
tables_query
,
prefix
[
i
]);
i
++
;
i
++
;
}
}
strcat
(
tables_query
,
"'"
);
strcat
(
tables_query
,
"'"
);
}
}
/* match users */
/* match users */
if
(
PG_VERSION_LT
(
conn
,
7
.
1
))
/* filter out large objects in
if
(
PG_VERSION_LT
(
conn
,
7
.
1
))
*
older versions */
/* filter out large objects in
older versions */
strcat
(
tables_query
,
" and relname !~ '^xinv[0-9]+'"
);
strcat
(
tables_query
,
" and relname !~ '^xinv[0-9]+'"
);
strcat
(
tables_query
,
" and usesysid = relowner"
);
strcat
(
tables_query
,
" and usesysid = relowner"
);
strcat
(
tables_query
,
" order by relname"
);
strcat
(
tables_query
,
" order by relname"
);
/* ********************************************************************** */
result
=
SQLExecDirect
(
htbl_stmt
,
tables_query
,
strlen
(
tables_query
));
result
=
SQLExecDirect
(
htbl_stmt
,
tables_query
,
strlen
(
tables_query
));
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
{
{
...
@@ -1330,7 +1297,6 @@ SQLTables(
...
@@ -1330,7 +1297,6 @@ SQLTables(
result
=
SQLFetch
(
htbl_stmt
);
result
=
SQLFetch
(
htbl_stmt
);
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
{
{
/*
/*
* Determine if this table name is a system table. If treating
* Determine if this table name is a system table. If treating
* system tables as regular tables, then no need to do this test.
* system tables as regular tables, then no need to do this test.
...
@@ -1338,12 +1304,12 @@ SQLTables(
...
@@ -1338,12 +1304,12 @@ SQLTables(
systable
=
FALSE
;
systable
=
FALSE
;
if
(
!
atoi
(
ci
->
show_system_tables
))
if
(
!
atoi
(
ci
->
show_system_tables
))
{
{
if
(
strncmp
(
table_name
,
POSTGRES_SYS_PREFIX
,
strlen
(
POSTGRES_SYS_PREFIX
))
==
0
)
if
(
strncmp
(
table_name
,
POSTGRES_SYS_PREFIX
,
strlen
(
POSTGRES_SYS_PREFIX
))
==
0
)
systable
=
TRUE
;
systable
=
TRUE
;
else
else
{
/* Check extra system table prefixes */
{
/* Check extra system table prefixes */
i
=
0
;
i
=
0
;
while
(
prefix
[
i
])
while
(
prefix
[
i
])
{
{
...
@@ -1359,8 +1325,8 @@ SQLTables(
...
@@ -1359,8 +1325,8 @@ SQLTables(
}
}
/* Determine if the table name is a view */
/* Determine if the table name is a view */
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
/* view is represented by its
if
(
PG_VERSION_GE
(
conn
,
7
.
1
))
*
relkind since 7.1 */
/* view is represented by its
relkind since 7.1 */
view
=
(
relkind_or_hasrules
[
0
]
==
'v'
);
view
=
(
relkind_or_hasrules
[
0
]
==
'v'
);
else
else
view
=
(
relkind_or_hasrules
[
0
]
==
'1'
);
view
=
(
relkind_or_hasrules
[
0
]
==
'1'
);
...
@@ -1379,16 +1345,18 @@ SQLTables(
...
@@ -1379,16 +1345,18 @@ SQLTables(
(
view
&&
show_views
)
||
(
view
&&
show_views
)
||
(
regular_table
&&
show_regular_tables
))
(
regular_table
&&
show_regular_tables
))
{
{
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
5
-
1
)
*
sizeof
(
TupleField
));
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
5
-
1
)
*
sizeof
(
TupleField
));
set_tuplefield_string
(
&
row
->
tuple
[
0
],
""
);
set_tuplefield_string
(
&
row
->
tuple
[
0
],
""
);
/* I have to hide the table owner from Access, otherwise it */
/*
/* insists on referring to the table as 'owner.table'. */
* I have to hide the table owner from Access, otherwise it
/* (this is valid according to the ODBC SQL grammar, but */
* insists on referring to the table as 'owner.table'.
/* Postgres won't support it.) */
* (this is valid according to the ODBC SQL grammar, but
/* set_tuplefield_string(&row->tuple[1], table_owner); */
* Postgres won't support it.)
*
* set_tuplefield_string(&row->tuple[1], table_owner);
*/
mylog
(
"SQLTables: table_name = '%s'
\n
"
,
table_name
);
mylog
(
"SQLTables: table_name = '%s'
\n
"
,
table_name
);
...
@@ -1410,8 +1378,10 @@ SQLTables(
...
@@ -1410,8 +1378,10 @@ SQLTables(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* also, things need to think that this statement is finished so */
/*
/* the results can be retrieved. */
* also, things need to think that this statement is finished so
* the results can be retrieved.
*/
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
/* set up the current tuple pointer for SQLFetch */
/* set up the current tuple pointer for SQLFetch */
...
@@ -1425,8 +1395,6 @@ SQLTables(
...
@@ -1425,8 +1395,6 @@ SQLTables(
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLColumns
(
SQLColumns
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -1479,13 +1447,10 @@ SQLColumns(
...
@@ -1479,13 +1447,10 @@ SQLColumns(
conn
=
(
ConnectionClass
*
)
(
stmt
->
hdbc
);
conn
=
(
ConnectionClass
*
)
(
stmt
->
hdbc
);
ci
=
&
stmt
->
hdbc
->
connInfo
;
ci
=
&
stmt
->
hdbc
->
connInfo
;
/* ********************************************************************** */
/*
/*
* Create the query to find out the columns (Note: pre 6.3 did not
* Create the query to find out the columns (Note: pre 6.3 did not
* have the atttypmod field)
* have the atttypmod field)
*/
*/
/* ********************************************************************** */
sprintf
(
columns_query
,
"select u.usename, c.relname, a.attname, a.atttypid"
sprintf
(
columns_query
,
"select u.usename, c.relname, a.attname, a.atttypid"
", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules"
", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules"
" from pg_user u, pg_class c, pg_attribute a, pg_type t"
" from pg_user u, pg_class c, pg_attribute a, pg_type t"
...
@@ -1497,10 +1462,11 @@ SQLColumns(
...
@@ -1497,10 +1462,11 @@ SQLColumns(
my_strcat
(
columns_query
,
" and u.usename like '%.*s'"
,
szTableOwner
,
cbTableOwner
);
my_strcat
(
columns_query
,
" and u.usename like '%.*s'"
,
szTableOwner
,
cbTableOwner
);
my_strcat
(
columns_query
,
" and a.attname like '%.*s'"
,
szColumnName
,
cbColumnName
);
my_strcat
(
columns_query
,
" and a.attname like '%.*s'"
,
szColumnName
,
cbColumnName
);
/* give the output in the order the columns were defined */
/*
/* when the table was created */
* give the output in the order the columns were defined
* when the table was created
*/
strcat
(
columns_query
,
" order by attnum"
);
strcat
(
columns_query
,
" order by attnum"
);
/* ********************************************************************** */
result
=
SQLAllocStmt
(
stmt
->
hdbc
,
&
hcol_stmt
);
result
=
SQLAllocStmt
(
stmt
->
hdbc
,
&
hcol_stmt
);
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
...
@@ -1673,10 +1639,8 @@ SQLColumns(
...
@@ -1673,10 +1639,8 @@ SQLColumns(
QR_set_field_info
(
stmt
->
result
,
12
,
"DISPLAY_SIZE"
,
PG_TYPE_INT4
,
4
);
QR_set_field_info
(
stmt
->
result
,
12
,
"DISPLAY_SIZE"
,
PG_TYPE_INT4
,
4
);
QR_set_field_info
(
stmt
->
result
,
13
,
"FIELD_TYPE"
,
PG_TYPE_INT4
,
4
);
QR_set_field_info
(
stmt
->
result
,
13
,
"FIELD_TYPE"
,
PG_TYPE_INT4
,
4
);
result
=
SQLFetch
(
hcol_stmt
);
result
=
SQLFetch
(
hcol_stmt
);
/*
/*
* Only show oid if option AND there are other columns AND it's not
* Only show oid if option AND there are other columns AND it's not
* being called by SQLStatistics . Always show OID if it's a system
* being called by SQLStatistics . Always show OID if it's a system
...
@@ -1685,12 +1649,10 @@ SQLColumns(
...
@@ -1685,12 +1649,10 @@ SQLColumns(
if
(
result
!=
SQL_ERROR
&&
!
stmt
->
internal
)
if
(
result
!=
SQL_ERROR
&&
!
stmt
->
internal
)
{
{
if
(
relhasrules
[
0
]
!=
'1'
&&
if
(
relhasrules
[
0
]
!=
'1'
&&
(
atoi
(
ci
->
show_oid_column
)
||
(
atoi
(
ci
->
show_oid_column
)
||
strncmp
(
table_name
,
POSTGRES_SYS_PREFIX
,
strlen
(
POSTGRES_SYS_PREFIX
))
==
0
))
strncmp
(
table_name
,
POSTGRES_SYS_PREFIX
,
strlen
(
POSTGRES_SYS_PREFIX
))
==
0
))
{
{
/* For OID fields */
/* For OID fields */
the_type
=
PG_TYPE_OID
;
the_type
=
PG_TYPE_OID
;
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
...
@@ -1718,7 +1680,6 @@ SQLColumns(
...
@@ -1718,7 +1680,6 @@ SQLColumns(
QR_add_tuple
(
stmt
->
result
,
row
);
QR_add_tuple
(
stmt
->
result
,
row
);
}
}
}
}
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
...
@@ -1776,11 +1737,9 @@ SQLColumns(
...
@@ -1776,11 +1737,9 @@ SQLColumns(
}
}
}
}
if
((
field_type
==
PG_TYPE_VARCHAR
)
||
if
((
field_type
==
PG_TYPE_VARCHAR
)
||
(
field_type
==
PG_TYPE_BPCHAR
))
(
field_type
==
PG_TYPE_BPCHAR
))
{
{
useStaticPrecision
=
FALSE
;
useStaticPrecision
=
FALSE
;
if
(
mod_length
>=
4
)
if
(
mod_length
>=
4
)
...
@@ -1827,8 +1786,10 @@ SQLColumns(
...
@@ -1827,8 +1786,10 @@ SQLColumns(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* Put the row version column at the end so it might not be */
/*
/* mistaken for a key field. */
* Put the row version column at the end so it might not be
* mistaken for a key field.
*/
if
(
relhasrules
[
0
]
!=
'1'
&&
!
stmt
->
internal
&&
atoi
(
ci
->
row_versioning
))
if
(
relhasrules
[
0
]
!=
'1'
&&
!
stmt
->
internal
&&
atoi
(
ci
->
row_versioning
))
{
{
/* For Row Versioning fields */
/* For Row Versioning fields */
...
@@ -1855,8 +1816,10 @@ SQLColumns(
...
@@ -1855,8 +1816,10 @@ SQLColumns(
QR_add_tuple
(
stmt
->
result
,
row
);
QR_add_tuple
(
stmt
->
result
,
row
);
}
}
/* also, things need to think that this statement is finished so */
/*
/* the results can be retrieved. */
* also, things need to think that this statement is finished so
* the results can be retrieved.
*/
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
/* set up the current tuple pointer for SQLFetch */
/* set up the current tuple pointer for SQLFetch */
...
@@ -1869,6 +1832,7 @@ SQLColumns(
...
@@ -1869,6 +1832,7 @@ SQLColumns(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLSpecialColumns
(
SQLSpecialColumns
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -1892,8 +1856,6 @@ SQLSpecialColumns(
...
@@ -1892,8 +1856,6 @@ SQLSpecialColumns(
RETCODE
result
;
RETCODE
result
;
char
relhasrules
[
MAX_INFO_STRING
];
char
relhasrules
[
MAX_INFO_STRING
];
mylog
(
"%s: entering...stmt=%u
\n
"
,
func
,
stmt
);
mylog
(
"%s: entering...stmt=%u
\n
"
,
func
,
stmt
);
if
(
!
stmt
)
if
(
!
stmt
)
...
@@ -1905,10 +1867,9 @@ SQLSpecialColumns(
...
@@ -1905,10 +1867,9 @@ SQLSpecialColumns(
stmt
->
manual_result
=
TRUE
;
stmt
->
manual_result
=
TRUE
;
/*
/* ********************************************************************** */
* Create the query to find out if this is a view or not...
/* Create the query to find out if this is a view or not... */
*/
/* ********************************************************************** */
sprintf
(
columns_query
,
"select c.relhasrules "
sprintf
(
columns_query
,
"select c.relhasrules "
"from pg_user u, pg_class c where "
"from pg_user u, pg_class c where "
"u.usesysid = c.relowner"
);
"u.usesysid = c.relowner"
);
...
@@ -1988,7 +1949,6 @@ SQLSpecialColumns(
...
@@ -1988,7 +1949,6 @@ SQLSpecialColumns(
}
}
else
if
(
fColType
==
SQL_ROWVER
)
else
if
(
fColType
==
SQL_ROWVER
)
{
{
Int2
the_type
=
PG_TYPE_INT4
;
Int2
the_type
=
PG_TYPE_INT4
;
if
(
atoi
(
ci
->
row_versioning
))
if
(
atoi
(
ci
->
row_versioning
))
...
@@ -2009,8 +1969,6 @@ SQLSpecialColumns(
...
@@ -2009,8 +1969,6 @@ SQLSpecialColumns(
}
}
}
}
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
stmt
->
currTuple
=
-
1
;
stmt
->
currTuple
=
-
1
;
stmt
->
rowset_start
=
-
1
;
stmt
->
rowset_start
=
-
1
;
...
@@ -2020,6 +1978,7 @@ SQLSpecialColumns(
...
@@ -2020,6 +1978,7 @@ SQLSpecialColumns(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLStatistics
(
SQLStatistics
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -2104,9 +2063,10 @@ SQLStatistics(
...
@@ -2104,9 +2063,10 @@ SQLStatistics(
QR_set_field_info
(
stmt
->
result
,
11
,
"PAGES"
,
PG_TYPE_INT4
,
4
);
QR_set_field_info
(
stmt
->
result
,
11
,
"PAGES"
,
PG_TYPE_INT4
,
4
);
QR_set_field_info
(
stmt
->
result
,
12
,
"FILTER_CONDITION"
,
PG_TYPE_TEXT
,
MAX_INFO_STRING
);
QR_set_field_info
(
stmt
->
result
,
12
,
"FILTER_CONDITION"
,
PG_TYPE_TEXT
,
MAX_INFO_STRING
);
/*
/* only use the table name... the owner should be redundant, and */
* only use the table name... the owner should be redundant, and
/* we never use qualifiers. */
* we never use qualifiers.
*/
table_name
=
make_string
(
szTableName
,
cbTableName
,
NULL
);
table_name
=
make_string
(
szTableName
,
cbTableName
,
NULL
);
if
(
!
table_name
)
if
(
!
table_name
)
{
{
...
@@ -2116,8 +2076,10 @@ SQLStatistics(
...
@@ -2116,8 +2076,10 @@ SQLStatistics(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* we need to get a list of the field names first, */
/*
/* so we can return them later. */
* we need to get a list of the field names first,
* so we can return them later.
*/
result
=
SQLAllocStmt
(
stmt
->
hdbc
,
&
hcol_stmt
);
result
=
SQLAllocStmt
(
stmt
->
hdbc
,
&
hcol_stmt
);
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
{
{
...
@@ -2172,6 +2134,7 @@ SQLStatistics(
...
@@ -2172,6 +2134,7 @@ SQLStatistics(
result
=
SQLFetch
(
hcol_stmt
);
result
=
SQLFetch
(
hcol_stmt
);
}
}
if
(
result
!=
SQL_NO_DATA_FOUND
||
total_columns
==
0
)
if
(
result
!=
SQL_NO_DATA_FOUND
||
total_columns
==
0
)
{
{
stmt
->
errormsg
=
SC_create_errormsg
(
hcol_stmt
);
/* "Couldn't get column
stmt
->
errormsg
=
SC_create_errormsg
(
hcol_stmt
);
/* "Couldn't get column
...
@@ -2205,14 +2168,15 @@ SQLStatistics(
...
@@ -2205,14 +2168,15 @@ SQLStatistics(
result
=
SQLExecDirect
(
hindx_stmt
,
index_query
,
strlen
(
index_query
));
result
=
SQLExecDirect
(
hindx_stmt
,
index_query
,
strlen
(
index_query
));
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
if
((
result
!=
SQL_SUCCESS
)
&&
(
result
!=
SQL_SUCCESS_WITH_INFO
))
{
{
stmt
->
errormsg
=
SC_create_errormsg
(
hindx_stmt
);
/* "Couldn't execute
/*
* index query
* "Couldn't execute index query (w/SQLExecDirect) in
* (w/SQLExecDirect) in
* SQLStatistics.";
* SQLStatistics."; */
*/
stmt
->
errormsg
=
SC_create_errormsg
(
hindx_stmt
);
stmt
->
errornumber
=
indx_stmt
->
errornumber
;
stmt
->
errornumber
=
indx_stmt
->
errornumber
;
SQLFreeStmt
(
hindx_stmt
,
SQL_DROP
);
SQLFreeStmt
(
hindx_stmt
,
SQL_DROP
);
goto
SEEYA
;
goto
SEEYA
;
}
}
/* bind the index name column */
/* bind the index name column */
...
@@ -2314,7 +2278,6 @@ SQLStatistics(
...
@@ -2314,7 +2278,6 @@ SQLStatistics(
result
=
SQLFetch
(
hindx_stmt
);
result
=
SQLFetch
(
hindx_stmt
);
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
{
{
/* If only requesting unique indexs, then just return those. */
/* If only requesting unique indexs, then just return those. */
if
(
fUnique
==
SQL_INDEX_ALL
||
if
(
fUnique
==
SQL_INDEX_ALL
||
(
fUnique
==
SQL_INDEX_UNIQUE
&&
atoi
(
isunique
)))
(
fUnique
==
SQL_INDEX_UNIQUE
&&
atoi
(
isunique
)))
...
@@ -2323,7 +2286,6 @@ SQLStatistics(
...
@@ -2323,7 +2286,6 @@ SQLStatistics(
/* add a row in this table for each field in the index */
/* add a row in this table for each field in the index */
while
(
i
<
16
&&
fields_vector
[
i
]
!=
0
)
while
(
i
<
16
&&
fields_vector
[
i
]
!=
0
)
{
{
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
13
-
1
)
*
sizeof
(
TupleField
));
(
13
-
1
)
*
sizeof
(
TupleField
));
...
@@ -2380,8 +2342,8 @@ SQLStatistics(
...
@@ -2380,8 +2342,8 @@ SQLStatistics(
}
}
if
(
result
!=
SQL_NO_DATA_FOUND
)
if
(
result
!=
SQL_NO_DATA_FOUND
)
{
{
stmt
->
errormsg
=
SC_create_errormsg
(
hindx_stmt
);
/* "SQLFetch failed in
/* "SQLFetch failed in SQLStatistics."; */
* SQLStatistics."; */
stmt
->
errormsg
=
SC_create_errormsg
(
hindx_stmt
);
stmt
->
errornumber
=
indx_stmt
->
errornumber
;
stmt
->
errornumber
=
indx_stmt
->
errornumber
;
SQLFreeStmt
(
hindx_stmt
,
SQL_DROP
);
SQLFreeStmt
(
hindx_stmt
,
SQL_DROP
);
goto
SEEYA
;
goto
SEEYA
;
...
@@ -2389,8 +2351,10 @@ SQLStatistics(
...
@@ -2389,8 +2351,10 @@ SQLStatistics(
SQLFreeStmt
(
hindx_stmt
,
SQL_DROP
);
SQLFreeStmt
(
hindx_stmt
,
SQL_DROP
);
/* also, things need to think that this statement is finished so */
/*
/* the results can be retrieved. */
* also, things need to think that this statement is finished so
* the results can be retrieved.
*/
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
/* set up the current tuple pointer for SQLFetch */
/* set up the current tuple pointer for SQLFetch */
...
@@ -2418,6 +2382,7 @@ SEEYA:
...
@@ -2418,6 +2382,7 @@ SEEYA:
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLColumnPrivileges
(
SQLColumnPrivileges
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -2434,14 +2399,16 @@ SQLColumnPrivileges(
...
@@ -2434,14 +2399,16 @@ SQLColumnPrivileges(
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
/* Neither Access or Borland care about this. */
/* Neither Access or Borland care about this. */
SC_log_error
(
func
,
"Function not implemented"
,
(
StatementClass
*
)
hstmt
);
SC_log_error
(
func
,
"Function not implemented"
,
(
StatementClass
*
)
hstmt
);
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* SQLPrimaryKeys()
/*
* SQLPrimaryKeys()
*
* Retrieve the primary key columns for the specified table.
* Retrieve the primary key columns for the specified table.
*/
*/
RETCODE
SQL_API
RETCODE
SQL_API
...
@@ -2572,7 +2539,6 @@ SQLPrimaryKeys(
...
@@ -2572,7 +2539,6 @@ SQLPrimaryKeys(
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
while
((
result
==
SQL_SUCCESS
)
||
(
result
==
SQL_SUCCESS_WITH_INFO
))
{
{
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
result_cols
-
1
)
*
sizeof
(
TupleField
));
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
result_cols
-
1
)
*
sizeof
(
TupleField
));
set_tuplefield_null
(
&
row
->
tuple
[
0
]);
set_tuplefield_null
(
&
row
->
tuple
[
0
]);
...
@@ -2608,8 +2574,10 @@ SQLPrimaryKeys(
...
@@ -2608,8 +2574,10 @@ SQLPrimaryKeys(
SQLFreeStmt
(
htbl_stmt
,
SQL_DROP
);
SQLFreeStmt
(
htbl_stmt
,
SQL_DROP
);
/* also, things need to think that this statement is finished so */
/*
/* the results can be retrieved. */
* also, things need to think that this statement is finished so
* the results can be retrieved.
*/
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
/* set up the current tuple pointer for SQLFetch */
/* set up the current tuple pointer for SQLFetch */
...
@@ -2621,6 +2589,7 @@ SQLPrimaryKeys(
...
@@ -2621,6 +2589,7 @@ SQLPrimaryKeys(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLForeignKeys
(
SQLForeignKeys
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -2667,15 +2636,12 @@ SQLForeignKeys(
...
@@ -2667,15 +2636,12 @@ SQLForeignKeys(
#if (ODBCVER >= 0x0300)
#if (ODBCVER >= 0x0300)
SWORD
defer_type
;
SWORD
defer_type
;
#endif
#endif
char
pkey
[
MAX_INFO_STRING
];
char
pkey
[
MAX_INFO_STRING
];
Int2
result_cols
;
Int2
result_cols
;
mylog
(
"%s: entering...stmt=%u
\n
"
,
func
,
stmt
);
mylog
(
"%s: entering...stmt=%u
\n
"
,
func
,
stmt
);
if
(
!
stmt
)
if
(
!
stmt
)
{
{
SC_log_error
(
func
,
""
,
NULL
);
SC_log_error
(
func
,
""
,
NULL
);
...
@@ -2723,8 +2689,10 @@ SQLForeignKeys(
...
@@ -2723,8 +2689,10 @@ SQLForeignKeys(
QR_set_field_info
(
stmt
->
result
,
14
,
"DEFERRABILITY"
,
PG_TYPE_INT2
,
2
);
QR_set_field_info
(
stmt
->
result
,
14
,
"DEFERRABILITY"
,
PG_TYPE_INT2
,
2
);
#endif
/* ODBCVER >= 0x0300 */
#endif
/* ODBCVER >= 0x0300 */
/* also, things need to think that this statement is finished so */
/*
/* the results can be retrieved. */
* also, things need to think that this statement is finished so
* the results can be retrieved.
*/
stmt
->
status
=
STMT_FINISHED
;
stmt
->
status
=
STMT_FINISHED
;
/* set up the current tuple pointer for SQLFetch */
/* set up the current tuple pointer for SQLFetch */
...
@@ -2898,7 +2866,6 @@ SQLForeignKeys(
...
@@ -2898,7 +2866,6 @@ SQLForeignKeys(
while
(
result
==
SQL_SUCCESS
)
while
(
result
==
SQL_SUCCESS
)
{
{
/* Compute the number of keyparts. */
/* Compute the number of keyparts. */
num_keys
=
(
trig_nargs
-
4
)
/
2
;
num_keys
=
(
trig_nargs
-
4
)
/
2
;
...
@@ -2913,7 +2880,6 @@ SQLForeignKeys(
...
@@ -2913,7 +2880,6 @@ SQLForeignKeys(
/* If there is a pk table specified, then check it. */
/* If there is a pk table specified, then check it. */
if
(
pk_table_needed
[
0
]
!=
'\0'
)
if
(
pk_table_needed
[
0
]
!=
'\0'
)
{
{
/* If it doesn't match, then continue */
/* If it doesn't match, then continue */
if
(
strcmp
(
pk_table
,
pk_table_needed
))
if
(
strcmp
(
pk_table
,
pk_table_needed
))
{
{
...
@@ -2932,7 +2898,6 @@ SQLForeignKeys(
...
@@ -2932,7 +2898,6 @@ SQLForeignKeys(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/* Check that the key listed is the primary key */
/* Check that the key listed is the primary key */
keyresult
=
SQLFetch
(
hpkey_stmt
);
keyresult
=
SQLFetch
(
hpkey_stmt
);
...
@@ -2949,7 +2914,6 @@ SQLForeignKeys(
...
@@ -2949,7 +2914,6 @@ SQLForeignKeys(
num_keys
=
0
;
num_keys
=
0
;
break
;
break
;
}
}
/* Get to next primary key */
/* Get to next primary key */
for
(
k
=
0
;
k
<
2
;
k
++
)
for
(
k
=
0
;
k
<
2
;
k
++
)
pkey_ptr
+=
strlen
(
pkey_ptr
)
+
1
;
pkey_ptr
+=
strlen
(
pkey_ptr
)
+
1
;
...
@@ -3002,7 +2966,6 @@ SQLForeignKeys(
...
@@ -3002,7 +2966,6 @@ SQLForeignKeys(
for
(
k
=
0
;
k
<
num_keys
;
k
++
)
for
(
k
=
0
;
k
<
num_keys
;
k
++
)
{
{
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
result_cols
-
1
)
*
sizeof
(
TupleField
));
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
result_cols
-
1
)
*
sizeof
(
TupleField
));
mylog
(
"%s: pk_table = '%s', pkey_ptr = '%s'
\n
"
,
func
,
pk_table
,
pkey_ptr
);
mylog
(
"%s: pk_table = '%s', pkey_ptr = '%s'
\n
"
,
func
,
pk_table
,
pkey_ptr
);
...
@@ -3050,7 +3013,6 @@ SQLForeignKeys(
...
@@ -3050,7 +3013,6 @@ SQLForeignKeys(
*/
*/
else
if
(
pk_table_needed
[
0
]
!=
'\0'
)
else
if
(
pk_table_needed
[
0
]
!=
'\0'
)
{
{
sprintf
(
tables_query
,
"SELECT pg_trigger.tgargs, "
sprintf
(
tables_query
,
"SELECT pg_trigger.tgargs, "
" pg_trigger.tgnargs, "
" pg_trigger.tgnargs, "
" pg_trigger.tgdeferrable, "
" pg_trigger.tgdeferrable, "
...
@@ -3172,7 +3134,6 @@ SQLForeignKeys(
...
@@ -3172,7 +3134,6 @@ SQLForeignKeys(
while
(
result
==
SQL_SUCCESS
)
while
(
result
==
SQL_SUCCESS
)
{
{
/* Calculate the number of key parts */
/* Calculate the number of key parts */
num_keys
=
(
trig_nargs
-
4
)
/
2
;;
num_keys
=
(
trig_nargs
-
4
)
/
2
;;
...
@@ -3216,7 +3177,6 @@ SQLForeignKeys(
...
@@ -3216,7 +3177,6 @@ SQLForeignKeys(
for
(
i
=
0
;
i
<
5
;
i
++
)
for
(
i
=
0
;
i
<
5
;
i
++
)
pkey_ptr
+=
strlen
(
pkey_ptr
)
+
1
;
pkey_ptr
+=
strlen
(
pkey_ptr
)
+
1
;
/* Get to first foreign table */
/* Get to first foreign table */
fk_table
=
trig_args
;
fk_table
=
trig_args
;
fk_table
+=
strlen
(
fk_table
)
+
1
;
fk_table
+=
strlen
(
fk_table
)
+
1
;
...
@@ -3228,7 +3188,6 @@ SQLForeignKeys(
...
@@ -3228,7 +3188,6 @@ SQLForeignKeys(
for
(
k
=
0
;
k
<
num_keys
;
k
++
)
for
(
k
=
0
;
k
<
num_keys
;
k
++
)
{
{
mylog
(
"pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'
\n
"
,
pkey_ptr
,
fk_table
,
fkey_ptr
);
mylog
(
"pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'
\n
"
,
pkey_ptr
,
fk_table
,
fkey_ptr
);
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
result_cols
-
1
)
*
sizeof
(
TupleField
));
row
=
(
TupleNode
*
)
malloc
(
sizeof
(
TupleNode
)
+
(
result_cols
-
1
)
*
sizeof
(
TupleField
));
...
@@ -3270,7 +3229,6 @@ SQLForeignKeys(
...
@@ -3270,7 +3229,6 @@ SQLForeignKeys(
fkey_ptr
+=
strlen
(
fkey_ptr
)
+
1
;
fkey_ptr
+=
strlen
(
fkey_ptr
)
+
1
;
}
}
}
}
result
=
SQLFetch
(
htbl_stmt
);
result
=
SQLFetch
(
htbl_stmt
);
}
}
}
}
...
@@ -3290,7 +3248,6 @@ SQLForeignKeys(
...
@@ -3290,7 +3248,6 @@ SQLForeignKeys(
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLProcedureColumns
(
SQLProcedureColumns
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -3311,6 +3268,7 @@ SQLProcedureColumns(
...
@@ -3311,6 +3268,7 @@ SQLProcedureColumns(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLProcedures
(
SQLProcedures
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -3329,6 +3287,7 @@ SQLProcedures(
...
@@ -3329,6 +3287,7 @@ SQLProcedures(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
RETCODE
SQL_API
RETCODE
SQL_API
SQLTablePrivileges
(
SQLTablePrivileges
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
...
src/interfaces/odbc/lobj.c
View file @
296e7ba2
/* Module: lobj.c
/*--------
* Module: lobj.c
*
*
* Description: This module contains routines related to manipulating
* Description: This module contains routines related to manipulating
* large objects.
* large objects.
...
@@ -8,13 +9,14 @@
...
@@ -8,13 +9,14 @@
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
--------
*/
*/
#include "lobj.h"
#include "lobj.h"
#include "psqlodbc.h"
#include "psqlodbc.h"
#include "connection.h"
#include "connection.h"
Oid
Oid
lo_creat
(
ConnectionClass
*
conn
,
int
mode
)
lo_creat
(
ConnectionClass
*
conn
,
int
mode
)
{
{
...
@@ -30,10 +32,9 @@ lo_creat(ConnectionClass *conn, int mode)
...
@@ -30,10 +32,9 @@ lo_creat(ConnectionClass *conn, int mode)
return
0
;
/* invalid oid */
return
0
;
/* invalid oid */
else
else
return
retval
;
return
retval
;
}
}
int
int
lo_open
(
ConnectionClass
*
conn
,
int
lobjId
,
int
mode
)
lo_open
(
ConnectionClass
*
conn
,
int
lobjId
,
int
mode
)
{
{
...
@@ -41,7 +42,6 @@ lo_open(ConnectionClass *conn, int lobjId, int mode)
...
@@ -41,7 +42,6 @@ lo_open(ConnectionClass *conn, int lobjId, int mode)
int
result_len
;
int
result_len
;
LO_ARG
argv
[
2
];
LO_ARG
argv
[
2
];
argv
[
0
].
isint
=
1
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
len
=
4
;
argv
[
0
].
len
=
4
;
argv
[
0
].
u
.
integer
=
lobjId
;
argv
[
0
].
u
.
integer
=
lobjId
;
...
@@ -59,6 +59,7 @@ lo_open(ConnectionClass *conn, int lobjId, int mode)
...
@@ -59,6 +59,7 @@ lo_open(ConnectionClass *conn, int lobjId, int mode)
return
fd
;
return
fd
;
}
}
int
int
lo_close
(
ConnectionClass
*
conn
,
int
fd
)
lo_close
(
ConnectionClass
*
conn
,
int
fd
)
{
{
...
@@ -66,17 +67,14 @@ lo_close(ConnectionClass *conn, int fd)
...
@@ -66,17 +67,14 @@ lo_close(ConnectionClass *conn, int fd)
int
retval
,
int
retval
,
result_len
;
result_len
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
len
=
4
;
argv
[
0
].
len
=
4
;
argv
[
0
].
u
.
integer
=
fd
;
argv
[
0
].
u
.
integer
=
fd
;
if
(
!
CC_send_function
(
conn
,
LO_CLOSE
,
&
retval
,
&
result_len
,
1
,
argv
,
1
))
if
(
!
CC_send_function
(
conn
,
LO_CLOSE
,
&
retval
,
&
result_len
,
1
,
argv
,
1
))
return
-
1
;
return
-
1
;
else
else
return
retval
;
return
retval
;
}
}
...
@@ -86,7 +84,6 @@ lo_read(ConnectionClass *conn, int fd, char *buf, int len)
...
@@ -86,7 +84,6 @@ lo_read(ConnectionClass *conn, int fd, char *buf, int len)
LO_ARG
argv
[
2
];
LO_ARG
argv
[
2
];
int
result_len
;
int
result_len
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
len
=
4
;
argv
[
0
].
len
=
4
;
argv
[
0
].
u
.
integer
=
fd
;
argv
[
0
].
u
.
integer
=
fd
;
...
@@ -97,11 +94,11 @@ lo_read(ConnectionClass *conn, int fd, char *buf, int len)
...
@@ -97,11 +94,11 @@ lo_read(ConnectionClass *conn, int fd, char *buf, int len)
if
(
!
CC_send_function
(
conn
,
LO_READ
,
(
int
*
)
buf
,
&
result_len
,
0
,
argv
,
2
))
if
(
!
CC_send_function
(
conn
,
LO_READ
,
(
int
*
)
buf
,
&
result_len
,
0
,
argv
,
2
))
return
-
1
;
return
-
1
;
else
else
return
result_len
;
return
result_len
;
}
}
int
int
lo_write
(
ConnectionClass
*
conn
,
int
fd
,
char
*
buf
,
int
len
)
lo_write
(
ConnectionClass
*
conn
,
int
fd
,
char
*
buf
,
int
len
)
{
{
...
@@ -109,7 +106,6 @@ lo_write(ConnectionClass *conn, int fd, char *buf, int len)
...
@@ -109,7 +106,6 @@ lo_write(ConnectionClass *conn, int fd, char *buf, int len)
int
retval
,
int
retval
,
result_len
;
result_len
;
if
(
len
<=
0
)
if
(
len
<=
0
)
return
0
;
return
0
;
...
@@ -123,11 +119,11 @@ lo_write(ConnectionClass *conn, int fd, char *buf, int len)
...
@@ -123,11 +119,11 @@ lo_write(ConnectionClass *conn, int fd, char *buf, int len)
if
(
!
CC_send_function
(
conn
,
LO_WRITE
,
&
retval
,
&
result_len
,
1
,
argv
,
2
))
if
(
!
CC_send_function
(
conn
,
LO_WRITE
,
&
retval
,
&
result_len
,
1
,
argv
,
2
))
return
-
1
;
return
-
1
;
else
else
return
retval
;
return
retval
;
}
}
int
int
lo_lseek
(
ConnectionClass
*
conn
,
int
fd
,
int
offset
,
int
whence
)
lo_lseek
(
ConnectionClass
*
conn
,
int
fd
,
int
offset
,
int
whence
)
{
{
...
@@ -135,7 +131,6 @@ lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
...
@@ -135,7 +131,6 @@ lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
int
retval
,
int
retval
,
result_len
;
result_len
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
len
=
4
;
argv
[
0
].
len
=
4
;
argv
[
0
].
u
.
integer
=
fd
;
argv
[
0
].
u
.
integer
=
fd
;
...
@@ -150,11 +145,11 @@ lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
...
@@ -150,11 +145,11 @@ lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
if
(
!
CC_send_function
(
conn
,
LO_LSEEK
,
&
retval
,
&
result_len
,
1
,
argv
,
3
))
if
(
!
CC_send_function
(
conn
,
LO_LSEEK
,
&
retval
,
&
result_len
,
1
,
argv
,
3
))
return
-
1
;
return
-
1
;
else
else
return
retval
;
return
retval
;
}
}
int
int
lo_tell
(
ConnectionClass
*
conn
,
int
fd
)
lo_tell
(
ConnectionClass
*
conn
,
int
fd
)
{
{
...
@@ -162,18 +157,17 @@ lo_tell(ConnectionClass *conn, int fd)
...
@@ -162,18 +157,17 @@ lo_tell(ConnectionClass *conn, int fd)
int
retval
,
int
retval
,
result_len
;
result_len
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
len
=
4
;
argv
[
0
].
len
=
4
;
argv
[
0
].
u
.
integer
=
fd
;
argv
[
0
].
u
.
integer
=
fd
;
if
(
!
CC_send_function
(
conn
,
LO_TELL
,
&
retval
,
&
result_len
,
1
,
argv
,
1
))
if
(
!
CC_send_function
(
conn
,
LO_TELL
,
&
retval
,
&
result_len
,
1
,
argv
,
1
))
return
-
1
;
return
-
1
;
else
else
return
retval
;
return
retval
;
}
}
int
int
lo_unlink
(
ConnectionClass
*
conn
,
Oid
lobjId
)
lo_unlink
(
ConnectionClass
*
conn
,
Oid
lobjId
)
{
{
...
@@ -181,14 +175,12 @@ lo_unlink(ConnectionClass *conn, Oid lobjId)
...
@@ -181,14 +175,12 @@ lo_unlink(ConnectionClass *conn, Oid lobjId)
int
retval
,
int
retval
,
result_len
;
result_len
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
isint
=
1
;
argv
[
0
].
len
=
4
;
argv
[
0
].
len
=
4
;
argv
[
0
].
u
.
integer
=
lobjId
;
argv
[
0
].
u
.
integer
=
lobjId
;
if
(
!
CC_send_function
(
conn
,
LO_UNLINK
,
&
retval
,
&
result_len
,
1
,
argv
,
1
))
if
(
!
CC_send_function
(
conn
,
LO_UNLINK
,
&
retval
,
&
result_len
,
1
,
argv
,
1
))
return
-
1
;
return
-
1
;
else
else
return
retval
;
return
retval
;
}
}
src/interfaces/odbc/misc.c
View file @
296e7ba2
/* Module: misc.c
/*-------
* Module: misc.c
*
*
* Description: This module contains miscellaneous routines
* Description: This module contains miscellaneous routines
* such as for debugging/logging and string functions.
* such as for debugging/logging and string functions.
...
@@ -8,7 +9,7 @@
...
@@ -8,7 +9,7 @@
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#include <stdio.h>
#include <stdio.h>
...
@@ -31,6 +32,7 @@
...
@@ -31,6 +32,7 @@
extern
GLOBAL_VALUES
globals
;
extern
GLOBAL_VALUES
globals
;
void
generate_filename
(
char
*
,
char
*
,
char
*
);
void
generate_filename
(
char
*
,
char
*
,
char
*
);
void
void
generate_filename
(
char
*
dirname
,
char
*
prefix
,
char
*
filename
)
generate_filename
(
char
*
dirname
,
char
*
prefix
,
char
*
filename
)
{
{
...
@@ -56,8 +58,8 @@ generate_filename(char *dirname, char *prefix, char *filename)
...
@@ -56,8 +58,8 @@ generate_filename(char *dirname, char *prefix, char *filename)
return
;
return
;
}
}
#ifdef MY_LOG
#ifdef MY_LOG
void
void
mylog
(
char
*
fmt
,...)
mylog
(
char
*
fmt
,...)
{
{
...
@@ -83,12 +85,10 @@ mylog(char *fmt,...)
...
@@ -83,12 +85,10 @@ mylog(char *fmt,...)
va_end
(
args
);
va_end
(
args
);
}
}
}
}
#endif
#endif
#ifdef Q_LOG
#ifdef Q_LOG
void
void
qlog
(
char
*
fmt
,...)
qlog
(
char
*
fmt
,...)
{
{
...
@@ -114,7 +114,6 @@ qlog(char *fmt,...)
...
@@ -114,7 +114,6 @@ qlog(char *fmt,...)
va_end
(
args
);
va_end
(
args
);
}
}
}
}
#endif
#endif
/* Undefine these because windows.h will redefine and cause a warning */
/* Undefine these because windows.h will redefine and cause a warning */
...
@@ -137,7 +136,10 @@ qlog(char *fmt,...)
...
@@ -137,7 +136,10 @@ qlog(char *fmt,...)
#endif
#endif
/* returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied (not including null term) */
/*
* returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied
* (not including null term)
*/
int
int
my_strcpy
(
char
*
dst
,
int
dst_len
,
char
*
src
,
int
src_len
)
my_strcpy
(
char
*
dst
,
int
dst_len
,
char
*
src
,
int
src_len
)
{
{
...
@@ -154,7 +156,6 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
...
@@ -154,7 +156,6 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
if
(
src_len
<=
0
)
if
(
src_len
<=
0
)
return
STRCPY_FAIL
;
return
STRCPY_FAIL
;
else
else
{
{
if
(
src_len
<
dst_len
)
if
(
src_len
<
dst_len
)
...
@@ -173,10 +174,13 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
...
@@ -173,10 +174,13 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
return
strlen
(
dst
);
return
strlen
(
dst
);
}
}
/* strncpy copies up to len characters, and doesn't terminate */
/* the destination string if src has len characters or more. */
/*
/* instead, I want it to copy up to len-1 characters and always */
* strncpy copies up to len characters, and doesn't terminate
/* terminate the destination string. */
* the destination string if src has len characters or more.
* instead, I want it to copy up to len-1 characters and always
* terminate the destination string.
*/
char
*
char
*
strncpy_null
(
char
*
dst
,
const
char
*
src
,
int
len
)
strncpy_null
(
char
*
dst
,
const
char
*
src
,
int
len
)
{
{
...
@@ -185,7 +189,6 @@ strncpy_null(char *dst, const char *src, int len)
...
@@ -185,7 +189,6 @@ strncpy_null(char *dst, const char *src, int len)
if
(
NULL
!=
dst
)
if
(
NULL
!=
dst
)
{
{
/* Just in case, check for special lengths */
/* Just in case, check for special lengths */
if
(
len
==
SQL_NULL_DATA
)
if
(
len
==
SQL_NULL_DATA
)
{
{
...
@@ -204,9 +207,14 @@ strncpy_null(char *dst, const char *src, int len)
...
@@ -204,9 +207,14 @@ strncpy_null(char *dst, const char *src, int len)
return
dst
;
return
dst
;
}
}
/* Create a null terminated string (handling the SQL_NTS thing): */
/* 1. If buf is supplied, place the string in there (assumes enough space) and return buf. */
/*------
/* 2. If buf is not supplied, malloc space and return this string */
* Create a null terminated string (handling the SQL_NTS thing):
* 1. If buf is supplied, place the string in there
* (assumes enough space) and return buf.
* 2. If buf is not supplied, malloc space and return this string
*------
*/
char
*
char
*
make_string
(
char
*
s
,
int
len
,
char
*
buf
)
make_string
(
char
*
s
,
int
len
,
char
*
buf
)
{
{
...
@@ -234,14 +242,16 @@ make_string(char *s, int len, char *buf)
...
@@ -234,14 +242,16 @@ make_string(char *s, int len, char *buf)
return
NULL
;
return
NULL
;
}
}
/* Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing. */
/* "fmt" must contain somewhere in it the single form '%.*s' */
/*
/* This is heavily used in creating queries for info routines (SQLTables, SQLColumns). */
* Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing.
/* This routine could be modified to use vsprintf() to handle multiple arguments. */
* "fmt" must contain somewhere in it the single form '%.*s'.
* This is heavily used in creating queries for info routines (SQLTables, SQLColumns).
* This routine could be modified to use vsprintf() to handle multiple arguments.
*/
char
*
char
*
my_strcat
(
char
*
buf
,
char
*
fmt
,
char
*
s
,
int
len
)
my_strcat
(
char
*
buf
,
char
*
fmt
,
char
*
s
,
int
len
)
{
{
if
(
s
&&
(
len
>
0
||
(
len
==
SQL_NTS
&&
strlen
(
s
)
>
0
)))
if
(
s
&&
(
len
>
0
||
(
len
==
SQL_NTS
&&
strlen
(
s
)
>
0
)))
{
{
int
length
=
(
len
>
0
)
?
len
:
strlen
(
s
);
int
length
=
(
len
>
0
)
?
len
:
strlen
(
s
);
...
@@ -254,6 +264,7 @@ my_strcat(char *buf, char *fmt, char *s, int len)
...
@@ -254,6 +264,7 @@ my_strcat(char *buf, char *fmt, char *s, int len)
return
NULL
;
return
NULL
;
}
}
void
void
remove_newlines
(
char
*
string
)
remove_newlines
(
char
*
string
)
{
{
...
@@ -267,6 +278,7 @@ remove_newlines(char *string)
...
@@ -267,6 +278,7 @@ remove_newlines(char *string)
}
}
}
}
char
*
char
*
trim
(
char
*
s
)
trim
(
char
*
s
)
{
{
...
...
src/interfaces/odbc/multibyte.c
View file @
296e7ba2
/*
/*
--------
* Module : multibyte.c
* Module : multibyte.c
*
*
* Description: Mlutibyte related additional function.
* Description: Mlutibyte related additional function.
*
*
* Create 2001-03-03 Eiji Tokuya
* Create 2001-03-03 Eiji Tokuya
*
*
--------
*/
*/
#include <string.h>
#include <string.h>
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
int
multibyte_client_encoding
;
/* Multibyte Client Encoding. */
int
multibyte_client_encoding
;
/* Multibyte Client Encoding. */
int
multibyte_status
;
/* Multibyte Odds and ends character. */
int
multibyte_status
;
/* Multibyte Odds and ends character. */
unsigned
char
*
unsigned
char
*
multibyte_strchr
(
unsigned
char
*
s
,
unsigned
char
c
)
multibyte_strchr
(
unsigned
char
*
s
,
unsigned
char
c
)
{
{
...
@@ -36,7 +37,6 @@ multibyte_strchr(unsigned char *s, unsigned char c)
...
@@ -36,7 +37,6 @@ multibyte_strchr(unsigned char *s, unsigned char c)
}
}
break
;
break
;
/* Chinese Big5 Support. */
/* Chinese Big5 Support. */
case
BIG5
:
case
BIG5
:
{
{
...
@@ -59,12 +59,14 @@ multibyte_strchr(unsigned char *s, unsigned char c)
...
@@ -59,12 +59,14 @@ multibyte_strchr(unsigned char *s, unsigned char c)
return
(
s
+
i
);
return
(
s
+
i
);
}
}
void
void
multibyte_init
(
void
)
multibyte_init
(
void
)
{
{
multibyte_status
=
0
;
multibyte_status
=
0
;
}
}
unsigned
char
*
unsigned
char
*
check_client_encoding
(
unsigned
char
*
str
)
check_client_encoding
(
unsigned
char
*
str
)
{
{
...
@@ -81,19 +83,21 @@ check_client_encoding(unsigned char *str)
...
@@ -81,19 +83,21 @@ check_client_encoding(unsigned char *str)
return
(
"OHTER"
);
return
(
"OHTER"
);
}
}
/*
/*--------
* Multibyte Status Function.
* Multibyte Status Function.
* Input char
* Input char
* Output 0 : 1 Byte Character.
* Output 0 : 1 Byte Character.
* 1 : MultibyteCharacter Last Byte.
* 1 : MultibyteCharacter Last Byte.
* N : MultibyteCharacter Fast or Middle Byte.
* N : MultibyteCharacter Fast or Middle Byte.
*--------
*/
*/
int
int
multibyte_char_check
(
unsigned
char
s
)
multibyte_char_check
(
unsigned
char
s
)
{
{
switch
(
multibyte_client_encoding
)
switch
(
multibyte_client_encoding
)
{
{
/* Japanese Shift-JIS(CP932) Support. */
/* Japanese Shift-JIS(CP932) Support. */
case
SJIS
:
case
SJIS
:
{
{
if
(
multibyte_status
<
2
&&
s
>
0x80
&&
!
(
s
>
0x9f
&&
s
<
0xE0
))
if
(
multibyte_status
<
2
&&
s
>
0x80
&&
!
(
s
>
0x9f
&&
s
<
0xE0
))
...
@@ -105,8 +109,7 @@ multibyte_char_check(unsigned char s)
...
@@ -105,8 +109,7 @@ multibyte_char_check(unsigned char s)
}
}
break
;
break
;
/* Chinese Big5(CP950) Support. */
/* Chinese Big5(CP950) Support. */
case
BIG5
:
case
BIG5
:
{
{
if
(
multibyte_status
<
2
&&
s
>
0xA0
)
if
(
multibyte_status
<
2
&&
s
>
0xA0
)
...
...
src/interfaces/odbc/options.c
View file @
296e7ba2
/* Module: options.c
/*--------
* Module: options.c
*
*
* Description: This module contains routines for getting/setting
* Description: This module contains routines for getting/setting
* connection and statement options.
* connection and statement options.
...
@@ -9,7 +10,7 @@
...
@@ -9,7 +10,7 @@
* SQLGetStmtOption
* SQLGetStmtOption
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
--------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -43,7 +44,6 @@ RETCODE set_statement_option(ConnectionClass *conn,
...
@@ -43,7 +44,6 @@ RETCODE set_statement_option(ConnectionClass *conn,
UDWORD
vParam
);
UDWORD
vParam
);
RETCODE
RETCODE
set_statement_option
(
ConnectionClass
*
conn
,
set_statement_option
(
ConnectionClass
*
conn
,
StatementClass
*
stmt
,
StatementClass
*
stmt
,
...
@@ -53,7 +53,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -53,7 +53,6 @@ set_statement_option(ConnectionClass *conn,
static
char
*
func
=
"set_statement_option"
;
static
char
*
func
=
"set_statement_option"
;
char
changed
=
FALSE
;
char
changed
=
FALSE
;
switch
(
fOption
)
switch
(
fOption
)
{
{
case
SQL_ASYNC_ENABLE
:
/* ignored */
case
SQL_ASYNC_ENABLE
:
/* ignored */
...
@@ -68,12 +67,10 @@ set_statement_option(ConnectionClass *conn,
...
@@ -68,12 +67,10 @@ set_statement_option(ConnectionClass *conn,
break
;
break
;
case
SQL_CONCURRENCY
:
case
SQL_CONCURRENCY
:
/*
/*
* positioned update isn't supported so cursor concurrency is
* positioned update isn't supported so cursor concurrency is
* read-only
* read-only
*/
*/
if
(
conn
)
if
(
conn
)
conn
->
stmtOptions
.
scroll_concurrency
=
vParam
;
conn
->
stmtOptions
.
scroll_concurrency
=
vParam
;
if
(
stmt
)
if
(
stmt
)
...
@@ -104,7 +101,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -104,7 +101,6 @@ set_statement_option(ConnectionClass *conn,
*/
*/
case
SQL_CURSOR_TYPE
:
case
SQL_CURSOR_TYPE
:
/*
/*
* if declare/fetch, then type can only be forward. otherwise,
* if declare/fetch, then type can only be forward. otherwise,
* it can only be forward or static.
* it can only be forward or static.
...
@@ -113,18 +109,15 @@ set_statement_option(ConnectionClass *conn,
...
@@ -113,18 +109,15 @@ set_statement_option(ConnectionClass *conn,
if
(
globals
.
lie
)
if
(
globals
.
lie
)
{
{
if
(
conn
)
if
(
conn
)
conn
->
stmtOptions
.
cursor_type
=
vParam
;
conn
->
stmtOptions
.
cursor_type
=
vParam
;
if
(
stmt
)
if
(
stmt
)
stmt
->
options
.
cursor_type
=
vParam
;
stmt
->
options
.
cursor_type
=
vParam
;
}
}
else
else
{
{
if
(
globals
.
use_declarefetch
)
if
(
globals
.
use_declarefetch
)
{
{
if
(
conn
)
if
(
conn
)
conn
->
stmtOptions
.
cursor_type
=
SQL_CURSOR_FORWARD_ONLY
;
conn
->
stmtOptions
.
cursor_type
=
SQL_CURSOR_FORWARD_ONLY
;
if
(
stmt
)
if
(
stmt
)
...
@@ -137,7 +130,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -137,7 +130,6 @@ set_statement_option(ConnectionClass *conn,
{
{
if
(
vParam
==
SQL_CURSOR_FORWARD_ONLY
||
vParam
==
SQL_CURSOR_STATIC
)
if
(
vParam
==
SQL_CURSOR_FORWARD_ONLY
||
vParam
==
SQL_CURSOR_STATIC
)
{
{
if
(
conn
)
if
(
conn
)
conn
->
stmtOptions
.
cursor_type
=
vParam
;
/* valid type */
conn
->
stmtOptions
.
cursor_type
=
vParam
;
/* valid type */
if
(
stmt
)
if
(
stmt
)
...
@@ -145,7 +137,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -145,7 +137,6 @@ set_statement_option(ConnectionClass *conn,
}
}
else
else
{
{
if
(
conn
)
if
(
conn
)
conn
->
stmtOptions
.
cursor_type
=
SQL_CURSOR_STATIC
;
conn
->
stmtOptions
.
cursor_type
=
SQL_CURSOR_STATIC
;
if
(
stmt
)
if
(
stmt
)
...
@@ -167,11 +158,17 @@ set_statement_option(ConnectionClass *conn,
...
@@ -167,11 +158,17 @@ set_statement_option(ConnectionClass *conn,
break
;
break
;
/*
/*-------
* if (globals.lie) stmt->keyset_size = vParam; else {
* if (globals.lie)
* stmt->keyset_size = vParam;
* else
* {
* stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
* stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
* stmt->errormsg = "Driver does not support keyset size
* stmt->errormsg = "Driver does not support keyset size option";
* option"; SC_log_error(func, "", stmt); return SQL_ERROR; }
* SC_log_error(func, "", stmt);
* return SQL_ERROR;
* }
*-------
*/
*/
case
SQL_MAX_LENGTH
:
/* ignored, but saved */
case
SQL_MAX_LENGTH
:
/* ignored, but saved */
...
@@ -194,12 +191,12 @@ set_statement_option(ConnectionClass *conn,
...
@@ -194,12 +191,12 @@ set_statement_option(ConnectionClass *conn,
mylog
(
"SetStmtOption: SQL_NOSCAN, vParam = %d
\n
"
,
vParam
);
mylog
(
"SetStmtOption: SQL_NOSCAN, vParam = %d
\n
"
,
vParam
);
break
;
break
;
case
SQL_QUERY_TIMEOUT
:
/* ignored */
case
SQL_QUERY_TIMEOUT
:
/* ignored */
mylog
(
"SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d
\n
"
,
vParam
);
mylog
(
"SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d
\n
"
,
vParam
);
/* "0" returned in SQLGetStmtOption */
/* "0" returned in SQLGetStmtOption */
break
;
break
;
case
SQL_RETRIEVE_DATA
:
/* ignored, but saved */
case
SQL_RETRIEVE_DATA
:
/* ignored, but saved */
mylog
(
"SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d
\n
"
,
vParam
);
mylog
(
"SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d
\n
"
,
vParam
);
if
(
conn
)
if
(
conn
)
conn
->
stmtOptions
.
retrieve_data
=
vParam
;
conn
->
stmtOptions
.
retrieve_data
=
vParam
;
...
@@ -210,7 +207,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -210,7 +207,6 @@ set_statement_option(ConnectionClass *conn,
case
SQL_ROWSET_SIZE
:
case
SQL_ROWSET_SIZE
:
mylog
(
"SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d
\n
"
,
vParam
);
mylog
(
"SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d
\n
"
,
vParam
);
/*
/*
* Save old rowset size for SQLExtendedFetch purposes If the
* Save old rowset size for SQLExtendedFetch purposes If the
* rowset_size is being changed since the last call to fetch
* rowset_size is being changed since the last call to fetch
...
@@ -230,7 +226,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -230,7 +226,6 @@ set_statement_option(ConnectionClass *conn,
conn
->
stmtOptions
.
rowset_size
=
vParam
;
conn
->
stmtOptions
.
rowset_size
=
vParam
;
if
(
stmt
)
if
(
stmt
)
stmt
->
options
.
rowset_size
=
vParam
;
stmt
->
options
.
rowset_size
=
vParam
;
break
;
break
;
case
SQL_SIMULATE_CURSOR
:
/* NOT SUPPORTED */
case
SQL_SIMULATE_CURSOR
:
/* NOT SUPPORTED */
...
@@ -249,7 +244,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -249,7 +244,6 @@ set_statement_option(ConnectionClass *conn,
return
SQL_ERROR
;
return
SQL_ERROR
;
case
SQL_USE_BOOKMARKS
:
case
SQL_USE_BOOKMARKS
:
if
(
stmt
)
if
(
stmt
)
stmt
->
options
.
use_bookmarks
=
vParam
;
stmt
->
options
.
use_bookmarks
=
vParam
;
if
(
conn
)
if
(
conn
)
...
@@ -298,7 +292,6 @@ set_statement_option(ConnectionClass *conn,
...
@@ -298,7 +292,6 @@ set_statement_option(ConnectionClass *conn,
}
}
/* Implements only SQL_AUTOCOMMIT */
/* Implements only SQL_AUTOCOMMIT */
RETCODE
SQL_API
RETCODE
SQL_API
SQLSetConnectOption
(
SQLSetConnectOption
(
...
@@ -320,10 +313,8 @@ SQLSetConnectOption(
...
@@ -320,10 +313,8 @@ SQLSetConnectOption(
return
SQL_INVALID_HANDLE
;
return
SQL_INVALID_HANDLE
;
}
}
switch
(
fOption
)
switch
(
fOption
)
{
{
/*
/*
* Statement Options (apply to all stmts on the connection and
* Statement Options (apply to all stmts on the connection and
* become defaults for new stmts)
* become defaults for new stmts)
...
@@ -362,15 +353,14 @@ SQLSetConnectOption(
...
@@ -362,15 +353,14 @@ SQLSetConnectOption(
break
;
break
;
/**********************************/
/*
/***** Connection Options *******/
* Connection Options
/*********************************
*/
*/
case
SQL_ACCESS_MODE
:
/* ignored */
case
SQL_ACCESS_MODE
:
/* ignored */
break
;
break
;
case
SQL_AUTOCOMMIT
:
case
SQL_AUTOCOMMIT
:
if
(
CC_is_in_trans
(
conn
))
if
(
CC_is_in_trans
(
conn
))
{
{
conn
->
errormsg
=
"Cannot switch commit mode while a transaction is in progress"
;
conn
->
errormsg
=
"Cannot switch commit mode while a transaction is in progress"
;
...
@@ -397,13 +387,12 @@ SQLSetConnectOption(
...
@@ -397,13 +387,12 @@ SQLSetConnectOption(
CC_log_error
(
func
,
""
,
conn
);
CC_log_error
(
func
,
""
,
conn
);
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
break
;
break
;
case
SQL_CURRENT_QUALIFIER
:
/* ignored */
case
SQL_CURRENT_QUALIFIER
:
/* ignored */
break
;
break
;
case
SQL_LOGIN_TIMEOUT
:
/* ignored */
case
SQL_LOGIN_TIMEOUT
:
/* ignored */
break
;
break
;
case
SQL_PACKET_SIZE
:
/* ignored */
case
SQL_PACKET_SIZE
:
/* ignored */
...
@@ -412,7 +401,7 @@ SQLSetConnectOption(
...
@@ -412,7 +401,7 @@ SQLSetConnectOption(
case
SQL_QUIET_MODE
:
/* ignored */
case
SQL_QUIET_MODE
:
/* ignored */
break
;
break
;
case
SQL_TXN_ISOLATION
:
/* ignored */
case
SQL_TXN_ISOLATION
:
/* ignored */
break
;
break
;
/* These options should be handled by driver manager */
/* These options should be handled by driver manager */
...
@@ -434,7 +423,6 @@ SQLSetConnectOption(
...
@@ -434,7 +423,6 @@ SQLSetConnectOption(
CC_log_error
(
func
,
option
,
conn
);
CC_log_error
(
func
,
option
,
conn
);
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
}
}
if
(
changed
)
if
(
changed
)
...
@@ -447,7 +435,6 @@ SQLSetConnectOption(
...
@@ -447,7 +435,6 @@ SQLSetConnectOption(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
/* This function just can tell you whether you are in Autcommit mode or not */
/* This function just can tell you whether you are in Autcommit mode or not */
RETCODE
SQL_API
RETCODE
SQL_API
...
@@ -484,7 +471,7 @@ SQLGetConnectOption(
...
@@ -484,7 +471,7 @@ SQLGetConnectOption(
break
;
break
;
case
SQL_LOGIN_TIMEOUT
:
/* NOT SUPPORTED */
case
SQL_LOGIN_TIMEOUT
:
/* NOT SUPPORTED */
*
((
UDWORD
*
)
pvParam
)
=
0
;
*
((
UDWORD
*
)
pvParam
)
=
0
;
break
;
break
;
...
@@ -496,7 +483,7 @@ SQLGetConnectOption(
...
@@ -496,7 +483,7 @@ SQLGetConnectOption(
*
((
UDWORD
*
)
pvParam
)
=
(
UDWORD
)
NULL
;
*
((
UDWORD
*
)
pvParam
)
=
(
UDWORD
)
NULL
;
break
;
break
;
case
SQL_TXN_ISOLATION
:
/* NOT SUPPORTED */
case
SQL_TXN_ISOLATION
:
/* NOT SUPPORTED */
*
((
UDWORD
*
)
pvParam
)
=
SQL_TXN_SERIALIZABLE
;
*
((
UDWORD
*
)
pvParam
)
=
SQL_TXN_SERIALIZABLE
;
break
;
break
;
...
@@ -520,13 +507,11 @@ SQLGetConnectOption(
...
@@ -520,13 +507,11 @@ SQLGetConnectOption(
return
SQL_ERROR
;
return
SQL_ERROR
;
break
;
break
;
}
}
}
}
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLSetStmtOption
(
SQLSetStmtOption
(
...
@@ -539,10 +524,11 @@ SQLSetStmtOption(
...
@@ -539,10 +524,11 @@ SQLSetStmtOption(
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
/* thought we could fake Access out by just returning SQL_SUCCESS */
/*
/* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
* Though we could fake Access out by just returning SQL_SUCCESS
/* and expects the driver to reduce it to the real value */
* all the time, but it tries to set a huge value for SQL_MAX_LENGTH
* and expects the driver to reduce it to the real value.
*/
if
(
!
stmt
)
if
(
!
stmt
)
{
{
SC_log_error
(
func
,
""
,
NULL
);
SC_log_error
(
func
,
""
,
NULL
);
...
@@ -553,8 +539,6 @@ SQLSetStmtOption(
...
@@ -553,8 +539,6 @@ SQLSetStmtOption(
}
}
/* - - - - - - - - - */
RETCODE
SQL_API
RETCODE
SQL_API
SQLGetStmtOption
(
SQLGetStmtOption
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -567,10 +551,11 @@ SQLGetStmtOption(
...
@@ -567,10 +551,11 @@ SQLGetStmtOption(
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
/* thought we could fake Access out by just returning SQL_SUCCESS */
/*
/* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
* thought we could fake Access out by just returning SQL_SUCCESS
/* and expects the driver to reduce it to the real value */
* all the time, but it tries to set a huge value for SQL_MAX_LENGTH
* and expects the driver to reduce it to the real value
*/
if
(
!
stmt
)
if
(
!
stmt
)
{
{
SC_log_error
(
func
,
""
,
NULL
);
SC_log_error
(
func
,
""
,
NULL
);
...
@@ -689,5 +674,3 @@ SQLGetStmtOption(
...
@@ -689,5 +674,3 @@ SQLGetStmtOption(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* - - - - - - - - - */
src/interfaces/odbc/parse.c
View file @
296e7ba2
/* Module: parse.c
/*--------
* Module: parse.c
*
*
* Description: This module contains routines related to parsing SQL
statements.
* Description: This module contains routines related to parsing SQL
* This can be useful for two reasons:
*
statements.
This can be useful for two reasons:
*
*
* 1. So the query does not actually have to be executed to return data about it
* 1. So the query does not actually have to be executed
* to return data about it
*
*
* 2. To be able to return information about precision, nullability, aliases, etc.
* 2. To be able to return information about precision,
* in the functions SQLDescribeCol and SQLColAttributes. Currently, Postgres
* nullability, aliases, etc. in the functions
* doesn't return any information about these things in a query.
* SQLDescribeCol and SQLColAttributes. Currently,
* Postgres doesn't return any information about
* these things in a query.
*
*
* Classes: none
* Classes: none
*
*
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
--------
*/
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
/* Multibyte support Eiji Tokuya 2001-03-15 */
...
@@ -50,6 +54,7 @@ char *getNextToken(char *s, char *token, int smax, char *delim, char *quote,
...
@@ -50,6 +54,7 @@ char *getNextToken(char *s, char *token, int smax, char *delim, char *quote,
void
getColInfo
(
COL_INFO
*
col_info
,
FIELD_INFO
*
fi
,
int
k
);
void
getColInfo
(
COL_INFO
*
col_info
,
FIELD_INFO
*
fi
,
int
k
);
char
searchColInfo
(
COL_INFO
*
col_info
,
FIELD_INFO
*
fi
);
char
searchColInfo
(
COL_INFO
*
col_info
,
FIELD_INFO
*
fi
);
char
*
char
*
getNextToken
(
char
*
s
,
char
*
token
,
int
smax
,
char
*
delim
,
char
*
quote
,
char
*
dquote
,
char
*
numeric
)
getNextToken
(
char
*
s
,
char
*
token
,
int
smax
,
char
*
delim
,
char
*
quote
,
char
*
dquote
,
char
*
numeric
)
{
{
...
@@ -87,7 +92,6 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
...
@@ -87,7 +92,6 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
while
(
!
isspace
((
unsigned
char
)
s
[
i
])
&&
s
[
i
]
!=
','
&&
while
(
!
isspace
((
unsigned
char
)
s
[
i
])
&&
s
[
i
]
!=
','
&&
s
[
i
]
!=
'\0'
&&
out
!=
smax
)
s
[
i
]
!=
'\0'
&&
out
!=
smax
)
{
{
/* Handle quoted stuff */
/* Handle quoted stuff */
if
(
out
==
0
&&
(
s
[
i
]
==
'\"'
||
s
[
i
]
==
'\''
))
if
(
out
==
0
&&
(
s
[
i
]
==
'\"'
||
s
[
i
]
==
'\''
))
{
{
...
@@ -225,13 +229,13 @@ getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k)
...
@@ -225,13 +229,13 @@ getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k)
fi
->
display_size
=
atoi
(
QR_get_value_manual
(
col_info
->
result
,
k
,
12
));
fi
->
display_size
=
atoi
(
QR_get_value_manual
(
col_info
->
result
,
k
,
12
));
}
}
char
char
searchColInfo
(
COL_INFO
*
col_info
,
FIELD_INFO
*
fi
)
searchColInfo
(
COL_INFO
*
col_info
,
FIELD_INFO
*
fi
)
{
{
int
k
,
cmp
;
int
k
,
cmp
;
char
*
col
;
char
*
col
;
for
(
k
=
0
;
k
<
QR_get_num_tuples
(
col_info
->
result
);
k
++
)
for
(
k
=
0
;
k
<
QR_get_num_tuples
(
col_info
->
result
);
k
++
)
{
{
col
=
QR_get_value_manual
(
col_info
->
result
,
k
,
3
);
col
=
QR_get_value_manual
(
col_info
->
result
,
k
,
3
);
...
@@ -289,7 +293,6 @@ parse_statement(StatementClass *stmt)
...
@@ -289,7 +293,6 @@ parse_statement(StatementClass *stmt)
StatementClass
*
col_stmt
;
StatementClass
*
col_stmt
;
RETCODE
result
;
RETCODE
result
;
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
ptr
=
stmt
->
statement
;
ptr
=
stmt
->
statement
;
...
@@ -301,7 +304,6 @@ parse_statement(StatementClass *stmt)
...
@@ -301,7 +304,6 @@ parse_statement(StatementClass *stmt)
while
((
ptr
=
getNextToken
(
ptr
,
token
,
sizeof
(
token
),
&
delim
,
&
quote
,
&
dquote
,
&
numeric
))
!=
NULL
)
while
((
ptr
=
getNextToken
(
ptr
,
token
,
sizeof
(
token
),
&
delim
,
&
quote
,
&
dquote
,
&
numeric
))
!=
NULL
)
{
{
unquoted
=
!
(
quote
||
dquote
);
unquoted
=
!
(
quote
||
dquote
);
mylog
(
"unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'
\n
"
,
unquoted
,
quote
,
dquote
,
numeric
,
delim
,
token
,
ptr
);
mylog
(
"unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'
\n
"
,
unquoted
,
quote
,
dquote
,
numeric
,
delim
,
token
,
ptr
);
...
@@ -345,7 +347,6 @@ parse_statement(StatementClass *stmt)
...
@@ -345,7 +347,6 @@ parse_statement(StatementClass *stmt)
!
stricmp
(
token
,
"group"
)
||
!
stricmp
(
token
,
"group"
)
||
!
stricmp
(
token
,
"having"
)))
!
stricmp
(
token
,
"having"
)))
{
{
in_select
=
FALSE
;
in_select
=
FALSE
;
in_from
=
FALSE
;
in_from
=
FALSE
;
in_where
=
TRUE
;
in_where
=
TRUE
;
...
@@ -356,7 +357,6 @@ parse_statement(StatementClass *stmt)
...
@@ -356,7 +357,6 @@ parse_statement(StatementClass *stmt)
if
(
in_select
)
if
(
in_select
)
{
{
if
(
in_distinct
)
if
(
in_distinct
)
{
{
mylog
(
"in distinct
\n
"
);
mylog
(
"in distinct
\n
"
);
...
@@ -378,7 +378,8 @@ parse_statement(StatementClass *stmt)
...
@@ -378,7 +378,8 @@ parse_statement(StatementClass *stmt)
}
}
if
(
in_expr
||
in_func
)
if
(
in_expr
||
in_func
)
{
/* just eat the expression */
{
/* just eat the expression */
mylog
(
"in_expr=%d or func=%d
\n
"
,
in_expr
,
in_func
);
mylog
(
"in_expr=%d or func=%d
\n
"
,
in_expr
,
in_func
);
if
(
quote
||
dquote
)
if
(
quote
||
dquote
)
continue
;
continue
;
...
@@ -389,7 +390,6 @@ parse_statement(StatementClass *stmt)
...
@@ -389,7 +390,6 @@ parse_statement(StatementClass *stmt)
in_expr
=
FALSE
;
in_expr
=
FALSE
;
in_field
=
FALSE
;
in_field
=
FALSE
;
}
}
else
if
(
token
[
0
]
==
'('
)
else
if
(
token
[
0
]
==
'('
)
{
{
blevel
++
;
blevel
++
;
...
@@ -414,7 +414,6 @@ parse_statement(StatementClass *stmt)
...
@@ -414,7 +414,6 @@ parse_statement(StatementClass *stmt)
if
(
!
in_field
)
if
(
!
in_field
)
{
{
if
(
!
token
[
0
])
if
(
!
token
[
0
])
continue
;
continue
;
...
@@ -462,7 +461,6 @@ parse_statement(StatementClass *stmt)
...
@@ -462,7 +461,6 @@ parse_statement(StatementClass *stmt)
blevel
=
1
;
blevel
=
1
;
continue
;
continue
;
}
}
else
else
{
{
strcpy
(
fi
[
stmt
->
nfld
]
->
name
,
token
);
strcpy
(
fi
[
stmt
->
nfld
]
->
name
,
token
);
...
@@ -478,9 +476,9 @@ parse_statement(StatementClass *stmt)
...
@@ -478,9 +476,9 @@ parse_statement(StatementClass *stmt)
continue
;
continue
;
}
}
/*
*************************/
/*
/* We are in a field now */
* We are in a field now
/*************************
*/
*/
if
(
in_dot
)
if
(
in_dot
)
{
{
stmt
->
nfld
--
;
stmt
->
nfld
--
;
...
@@ -494,7 +492,6 @@ parse_statement(StatementClass *stmt)
...
@@ -494,7 +492,6 @@ parse_statement(StatementClass *stmt)
mylog
(
"in_dot: got comma
\n
"
);
mylog
(
"in_dot: got comma
\n
"
);
in_field
=
FALSE
;
in_field
=
FALSE
;
}
}
continue
;
continue
;
}
}
...
@@ -547,12 +544,10 @@ parse_statement(StatementClass *stmt)
...
@@ -547,12 +544,10 @@ parse_statement(StatementClass *stmt)
fi
[
stmt
->
nfld
-
1
]
->
expr
=
TRUE
;
fi
[
stmt
->
nfld
-
1
]
->
expr
=
TRUE
;
fi
[
stmt
->
nfld
-
1
]
->
name
[
0
]
=
'\0'
;
fi
[
stmt
->
nfld
-
1
]
->
name
[
0
]
=
'\0'
;
mylog
(
"*** setting expression
\n
"
);
mylog
(
"*** setting expression
\n
"
);
}
}
if
(
in_from
)
if
(
in_from
)
{
{
if
(
!
in_table
)
if
(
!
in_table
)
{
{
if
(
!
token
[
0
])
if
(
!
token
[
0
])
...
@@ -603,17 +598,15 @@ parse_statement(StatementClass *stmt)
...
@@ -603,17 +598,15 @@ parse_statement(StatementClass *stmt)
}
}
}
}
/*
/*************************************************/
* Resolve any possible field names with tables
/* Resolve any possible field names with tables */
*/
/*************************************************/
parse
=
TRUE
;
parse
=
TRUE
;
/* Resolve field names with tables */
/* Resolve field names with tables */
for
(
i
=
0
;
i
<
stmt
->
nfld
;
i
++
)
for
(
i
=
0
;
i
<
stmt
->
nfld
;
i
++
)
{
{
if
(
fi
[
i
]
->
func
||
fi
[
i
]
->
expr
||
fi
[
i
]
->
numeric
)
if
(
fi
[
i
]
->
func
||
fi
[
i
]
->
expr
||
fi
[
i
]
->
numeric
)
{
{
fi
[
i
]
->
ti
=
NULL
;
fi
[
i
]
->
ti
=
NULL
;
...
@@ -621,7 +614,6 @@ parse_statement(StatementClass *stmt)
...
@@ -621,7 +614,6 @@ parse_statement(StatementClass *stmt)
parse
=
FALSE
;
parse
=
FALSE
;
continue
;
continue
;
}
}
else
if
(
fi
[
i
]
->
quote
)
else
if
(
fi
[
i
]
->
quote
)
{
/* handle as text */
{
/* handle as text */
fi
[
i
]
->
ti
=
NULL
;
fi
[
i
]
->
ti
=
NULL
;
...
@@ -629,7 +621,6 @@ parse_statement(StatementClass *stmt)
...
@@ -629,7 +621,6 @@ parse_statement(StatementClass *stmt)
fi
[
i
]
->
precision
=
0
;
fi
[
i
]
->
precision
=
0
;
continue
;
continue
;
}
}
/* it's a dot, resolve to table or alias */
/* it's a dot, resolve to table or alias */
else
if
(
fi
[
i
]
->
dot
[
0
])
else
if
(
fi
[
i
]
->
dot
[
0
])
{
{
...
@@ -665,15 +656,13 @@ parse_statement(StatementClass *stmt)
...
@@ -665,15 +656,13 @@ parse_statement(StatementClass *stmt)
mylog
(
"Table %d: name='%s', alias='%s'
\n
"
,
i
,
ti
[
i
]
->
name
,
ti
[
i
]
->
alias
);
mylog
(
"Table %d: name='%s', alias='%s'
\n
"
,
i
,
ti
[
i
]
->
name
,
ti
[
i
]
->
alias
);
/******************************************************/
/*
/* Now save the SQLColumns Info for the parse tables */
* Now save the SQLColumns Info for the parse tables
/******************************************************/
*/
/* Call SQLColumns for each table and store the result */
/* Call SQLColumns for each table and store the result */
for
(
i
=
0
;
i
<
stmt
->
ntab
;
i
++
)
for
(
i
=
0
;
i
<
stmt
->
ntab
;
i
++
)
{
{
/* See if already got it */
/* See if already got it */
char
found
=
FALSE
;
char
found
=
FALSE
;
...
@@ -689,7 +678,6 @@ parse_statement(StatementClass *stmt)
...
@@ -689,7 +678,6 @@ parse_statement(StatementClass *stmt)
if
(
!
found
)
if
(
!
found
)
{
{
mylog
(
"PARSE: Getting SQLColumns for table[%d]='%s'
\n
"
,
i
,
ti
[
i
]
->
name
);
mylog
(
"PARSE: Getting SQLColumns for table[%d]='%s'
\n
"
,
i
,
ti
[
i
]
->
name
);
result
=
SQLAllocStmt
(
stmt
->
hdbc
,
&
hcol_stmt
);
result
=
SQLAllocStmt
(
stmt
->
hdbc
,
&
hcol_stmt
);
...
@@ -713,7 +701,6 @@ parse_statement(StatementClass *stmt)
...
@@ -713,7 +701,6 @@ parse_statement(StatementClass *stmt)
mylog
(
" Success
\n
"
);
mylog
(
" Success
\n
"
);
if
(
!
(
conn
->
ntables
%
COL_INCR
))
if
(
!
(
conn
->
ntables
%
COL_INCR
))
{
{
mylog
(
"PARSE: Allocing col_info at ntables=%d
\n
"
,
conn
->
ntables
);
mylog
(
"PARSE: Allocing col_info at ntables=%d
\n
"
,
conn
->
ntables
);
conn
->
col_info
=
(
COL_INFO
**
)
realloc
(
conn
->
col_info
,
(
conn
->
ntables
+
COL_INCR
)
*
sizeof
(
COL_INFO
*
));
conn
->
col_info
=
(
COL_INFO
**
)
realloc
(
conn
->
col_info
,
(
conn
->
ntables
+
COL_INCR
)
*
sizeof
(
COL_INFO
*
));
...
@@ -762,18 +749,13 @@ parse_statement(StatementClass *stmt)
...
@@ -762,18 +749,13 @@ parse_statement(StatementClass *stmt)
mylog
(
"associate col_info: i=%d, k=%d
\n
"
,
i
,
k
);
mylog
(
"associate col_info: i=%d, k=%d
\n
"
,
i
,
k
);
}
}
mylog
(
"Done SQLColumns
\n
"
);
mylog
(
"Done SQLColumns
\n
"
);
/******************************************************/
/*
/* Now resolve the fields to point to column info */
* Now resolve the fields to point to column info
/******************************************************/
*/
for
(
i
=
0
;
i
<
stmt
->
nfld
;)
for
(
i
=
0
;
i
<
stmt
->
nfld
;)
{
{
/* Dont worry about functions or quotes */
/* Dont worry about functions or quotes */
if
(
fi
[
i
]
->
func
||
fi
[
i
]
->
quote
||
fi
[
i
]
->
numeric
)
if
(
fi
[
i
]
->
func
||
fi
[
i
]
->
quote
||
fi
[
i
]
->
numeric
)
{
{
...
@@ -784,7 +766,6 @@ parse_statement(StatementClass *stmt)
...
@@ -784,7 +766,6 @@ parse_statement(StatementClass *stmt)
/* Stars get expanded to all fields in the table */
/* Stars get expanded to all fields in the table */
else
if
(
fi
[
i
]
->
name
[
0
]
==
'*'
)
else
if
(
fi
[
i
]
->
name
[
0
]
==
'*'
)
{
{
char
do_all_tables
;
char
do_all_tables
;
int
total_cols
,
int
total_cols
,
old_alloc
,
old_alloc
,
...
@@ -810,7 +791,6 @@ parse_statement(StatementClass *stmt)
...
@@ -810,7 +791,6 @@ parse_statement(StatementClass *stmt)
increased_cols
=
total_cols
-
1
;
increased_cols
=
total_cols
-
1
;
/* Allocate some more field pointers if necessary */
/* Allocate some more field pointers if necessary */
/*------------------------------------------------------------- */
old_alloc
=
((
stmt
->
nfld
-
1
)
/
FLD_INCR
+
1
)
*
FLD_INCR
;
old_alloc
=
((
stmt
->
nfld
-
1
)
/
FLD_INCR
+
1
)
*
FLD_INCR
;
new_size
=
stmt
->
nfld
+
increased_cols
;
new_size
=
stmt
->
nfld
+
increased_cols
;
...
@@ -830,8 +810,6 @@ parse_statement(StatementClass *stmt)
...
@@ -830,8 +810,6 @@ parse_statement(StatementClass *stmt)
stmt
->
fi
=
fi
;
stmt
->
fi
=
fi
;
}
}
/*------------------------------------------------------------- */
/*
/*
* copy any other fields (if there are any) up past the
* copy any other fields (if there are any) up past the
* expansion
* expansion
...
@@ -843,21 +821,16 @@ parse_statement(StatementClass *stmt)
...
@@ -843,21 +821,16 @@ parse_statement(StatementClass *stmt)
}
}
mylog
(
"done copying fields
\n
"
);
mylog
(
"done copying fields
\n
"
);
/*------------------------------------------------------------- */
/* Set the new number of fields */
/* Set the new number of fields */
stmt
->
nfld
+=
increased_cols
;
stmt
->
nfld
+=
increased_cols
;
mylog
(
"stmt->nfld now at %d
\n
"
,
stmt
->
nfld
);
mylog
(
"stmt->nfld now at %d
\n
"
,
stmt
->
nfld
);
/*------------------------------------------------------------- */
/* copy the new field info */
/* copy the new field info */
do_all_tables
=
(
fi
[
i
]
->
ti
?
FALSE
:
TRUE
);
do_all_tables
=
(
fi
[
i
]
->
ti
?
FALSE
:
TRUE
);
for
(
k
=
0
;
k
<
(
do_all_tables
?
stmt
->
ntab
:
1
);
k
++
)
for
(
k
=
0
;
k
<
(
do_all_tables
?
stmt
->
ntab
:
1
);
k
++
)
{
{
TABLE_INFO
*
the_ti
=
do_all_tables
?
ti
[
k
]
:
fi
[
i
]
->
ti
;
TABLE_INFO
*
the_ti
=
do_all_tables
?
ti
[
k
]
:
fi
[
i
]
->
ti
;
cols
=
QR_get_num_tuples
(
the_ti
->
col_info
->
result
);
cols
=
QR_get_num_tuples
(
the_ti
->
col_info
->
result
);
...
@@ -890,8 +863,6 @@ parse_statement(StatementClass *stmt)
...
@@ -890,8 +863,6 @@ parse_statement(StatementClass *stmt)
i
+=
cols
;
i
+=
cols
;
mylog
(
"i now at %d
\n
"
,
i
);
mylog
(
"i now at %d
\n
"
,
i
);
}
}
/*------------------------------------------------------------- */
}
}
/*
/*
...
@@ -901,7 +872,6 @@ parse_statement(StatementClass *stmt)
...
@@ -901,7 +872,6 @@ parse_statement(StatementClass *stmt)
*/
*/
else
if
(
fi
[
i
]
->
ti
)
else
if
(
fi
[
i
]
->
ti
)
{
{
if
(
!
searchColInfo
(
fi
[
i
]
->
ti
->
col_info
,
fi
[
i
]))
if
(
!
searchColInfo
(
fi
[
i
]
->
ti
->
col_info
,
fi
[
i
]))
parse
=
FALSE
;
parse
=
FALSE
;
...
@@ -925,13 +895,11 @@ parse_statement(StatementClass *stmt)
...
@@ -925,13 +895,11 @@ parse_statement(StatementClass *stmt)
}
}
}
}
if
(
!
parse
)
if
(
!
parse
)
stmt
->
parse_status
=
STMT_PARSE_INCOMPLETE
;
stmt
->
parse_status
=
STMT_PARSE_INCOMPLETE
;
else
else
stmt
->
parse_status
=
STMT_PARSE_COMPLETE
;
stmt
->
parse_status
=
STMT_PARSE_COMPLETE
;
mylog
(
"done parse_statement: parse=%d, parse_status=%d
\n
"
,
parse
,
stmt
->
parse_status
);
mylog
(
"done parse_statement: parse=%d, parse_status=%d
\n
"
,
parse
,
stmt
->
parse_status
);
return
parse
;
return
parse
;
}
}
src/interfaces/odbc/pgtypes.c
View file @
296e7ba2
/* Module: pgtypes.c
/*--------
* Module: pgtypes.c
*
*
* Description: This module contains routines for getting information
* Description: This module contains routines for getting information
* about the supported Postgres data types. Only the function
* about the supported Postgres data types. Only the
* pgtype_to_sqltype() returns an unknown condition. All other
* function pgtype_to_sqltype() returns an unknown condition.
* functions return a suitable default so that even data types that
* All other functions return a suitable default so that
* are not directly supported can be used (it is handled as char data).
* even data types that are not directly supported can be
* used (it is handled as char data).
*
*
* Classes: n/a
* Classes: n/a
*
*
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
--------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -40,15 +42,18 @@ extern GLOBAL_VALUES globals;
...
@@ -40,15 +42,18 @@ extern GLOBAL_VALUES globals;
Int4
getCharPrecision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
);
Int4
getCharPrecision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
);
/*
* these are the types we support. all of the pgtype_ functions should
* return values for each one of these.
* Even types not directly supported are handled as character types
* so all types should work (points, etc.)
*/
/*
these are the types we support. all of the pgtype_ functions should */
/*
/* return values for each one of these. */
* ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all
/* Even types not directly supported are handled as character types
* the SQL TYPES are reported and mapped to a corresponding Postgres Type
so all types should work (points, etc.)
*/
*/
/* ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all
the SQL TYPES are reported and mapped to a corresponding Postgres Type
*/
/*
/*
Int4 pgtypes_defined[] = {
Int4 pgtypes_defined[] = {
PG_TYPE_CHAR,
PG_TYPE_CHAR,
...
@@ -102,6 +107,7 @@ Int2 sqlTypes[] = {
...
@@ -102,6 +107,7 @@ Int2 sqlTypes[] = {
0
0
};
};
Int4
Int4
sqltype_to_pgtype
(
SWORD
fSqlType
)
sqltype_to_pgtype
(
SWORD
fSqlType
)
{
{
...
@@ -109,7 +115,6 @@ sqltype_to_pgtype(SWORD fSqlType)
...
@@ -109,7 +115,6 @@ sqltype_to_pgtype(SWORD fSqlType)
switch
(
fSqlType
)
switch
(
fSqlType
)
{
{
case
SQL_BINARY
:
case
SQL_BINARY
:
pgType
=
PG_TYPE_BYTEA
;
pgType
=
PG_TYPE_BYTEA
;
break
;
break
;
...
@@ -185,15 +190,19 @@ sqltype_to_pgtype(SWORD fSqlType)
...
@@ -185,15 +190,19 @@ sqltype_to_pgtype(SWORD fSqlType)
return
pgType
;
return
pgType
;
}
}
/* There are two ways of calling this function:
1. When going through the supported PG types (SQLGetTypeInfo)
2. When taking any type id (SQLColumns, SQLGetData)
The first type will always work because all the types defined are returned here.
/*
The second type will return a default based on global parameter when it does not
* There are two ways of calling this function:
know. This allows for supporting
*
types that are unknown. All other pg routines in here return a suitable default.
* 1. When going through the supported PG types (SQLGetTypeInfo)
*/
*
* 2. When taking any type id (SQLColumns, SQLGetData)
*
* The first type will always work because all the types defined are returned here.
* The second type will return a default based on global parameter when it does not
* know. This allows for supporting
* types that are unknown. All other pg routines in here return a suitable default.
*/
Int2
Int2
pgtype_to_sqltype
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_to_sqltype
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -253,20 +262,20 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
...
@@ -253,20 +262,20 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
return
globals
.
bools_as_char
?
SQL_CHAR
:
SQL_BIT
;
return
globals
.
bools_as_char
?
SQL_CHAR
:
SQL_BIT
;
default:
default:
/*
/*
* first, check to see if 'type' is in list. If not, look up
* first, check to see if 'type' is in list. If not, look up
* with query. Add oid, name to list. If it's already in
* with query. Add oid, name to list. If it's already in
* list, just return.
* list, just return.
*/
*/
if
(
type
==
stmt
->
hdbc
->
lobj_type
)
/* hack until permanent
/* hack until permanent type is available */
* type is available */
if
(
type
==
stmt
->
hdbc
->
lobj_type
)
return
SQL_LONGVARBINARY
;
return
SQL_LONGVARBINARY
;
return
globals
.
unknowns_as_longvarchar
?
SQL_LONGVARCHAR
:
SQL_VARCHAR
;
return
globals
.
unknowns_as_longvarchar
?
SQL_LONGVARCHAR
:
SQL_VARCHAR
;
}
}
}
}
Int2
Int2
pgtype_to_ctype
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_to_ctype
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -305,15 +314,15 @@ pgtype_to_ctype(StatementClass *stmt, Int4 type)
...
@@ -305,15 +314,15 @@ pgtype_to_ctype(StatementClass *stmt, Int4 type)
return
SQL_C_BINARY
;
return
SQL_C_BINARY
;
default:
default:
/* hack until permanent type is available */
if
(
type
==
stmt
->
hdbc
->
lobj_type
)
/* hack until permanent
if
(
type
==
stmt
->
hdbc
->
lobj_type
)
* type is available */
return
SQL_C_BINARY
;
return
SQL_C_BINARY
;
return
SQL_C_CHAR
;
return
SQL_C_CHAR
;
}
}
}
}
char
*
char
*
pgtype_to_name
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_to_name
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -369,8 +378,8 @@ pgtype_to_name(StatementClass *stmt, Int4 type)
...
@@ -369,8 +378,8 @@ pgtype_to_name(StatementClass *stmt, Int4 type)
return
PG_TYPE_LO_NAME
;
return
PG_TYPE_LO_NAME
;
default:
default:
if
(
type
==
stmt
->
hdbc
->
lobj_type
)
/* hack until permanent
/* hack until permanent type is available */
* type is available */
if
(
type
==
stmt
->
hdbc
->
lobj_type
)
return
PG_TYPE_LO_NAME
;
return
PG_TYPE_LO_NAME
;
/*
/*
...
@@ -381,6 +390,7 @@ pgtype_to_name(StatementClass *stmt, Int4 type)
...
@@ -381,6 +390,7 @@ pgtype_to_name(StatementClass *stmt, Int4 type)
}
}
}
}
static
Int2
static
Int2
getNumericScale
(
StatementClass
*
stmt
,
Int4
type
,
int
col
)
getNumericScale
(
StatementClass
*
stmt
,
Int4
type
,
int
col
)
{
{
...
@@ -417,6 +427,7 @@ getNumericScale(StatementClass *stmt, Int4 type, int col)
...
@@ -417,6 +427,7 @@ getNumericScale(StatementClass *stmt, Int4 type, int col)
PG_NUMERIC_MAX_SCALE
);
PG_NUMERIC_MAX_SCALE
);
}
}
static
Int4
static
Int4
getNumericPrecision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
)
getNumericPrecision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
)
{
{
...
@@ -453,6 +464,7 @@ getNumericPrecision(StatementClass *stmt, Int4 type, int col)
...
@@ -453,6 +464,7 @@ getNumericPrecision(StatementClass *stmt, Int4 type, int col)
PG_NUMERIC_MAX_PRECISION
);
PG_NUMERIC_MAX_PRECISION
);
}
}
Int4
Int4
getCharPrecision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
getCharPrecision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
{
{
...
@@ -524,19 +536,19 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
...
@@ -524,19 +536,19 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
return
p
;
return
p
;
}
}
/* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will
override this length with the atttypmod length from pg_attribute .
If col >= 0, then will attempt to get the info from the result set.
/*
This is used for functions SQLDescribeCol and SQLColAttributes.
* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will
*/
* override this length with the atttypmod length from pg_attribute .
*
* If col >= 0, then will attempt to get the info from the result set.
* This is used for functions SQLDescribeCol and SQLColAttributes.
*/
Int4
Int4
pgtype_precision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
pgtype_precision
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
{
{
switch
(
type
)
switch
(
type
)
{
{
case
PG_TYPE_CHAR
:
case
PG_TYPE_CHAR
:
return
1
;
return
1
;
case
PG_TYPE_CHAR2
:
case
PG_TYPE_CHAR2
:
...
@@ -597,10 +609,10 @@ pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
...
@@ -597,10 +609,10 @@ pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
}
}
}
}
Int4
Int4
pgtype_display_size
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
pgtype_display_size
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
{
{
switch
(
type
)
switch
(
type
)
{
{
case
PG_TYPE_INT2
:
case
PG_TYPE_INT2
:
...
@@ -634,16 +646,16 @@ pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown
...
@@ -634,16 +646,16 @@ pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown
}
}
}
}
/* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
override this length with the atttypmod length from pg_attribute
/*
*/
* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
* override this length with the atttypmod length from pg_attribute
*/
Int4
Int4
pgtype_length
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
pgtype_length
(
StatementClass
*
stmt
,
Int4
type
,
int
col
,
int
handle_unknown_size_as
)
{
{
switch
(
type
)
switch
(
type
)
{
{
case
PG_TYPE_INT2
:
case
PG_TYPE_INT2
:
return
2
;
return
2
;
...
@@ -674,19 +686,18 @@ pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_
...
@@ -674,19 +686,18 @@ pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_
case
PG_TYPE_TIMESTAMP
:
case
PG_TYPE_TIMESTAMP
:
return
16
;
return
16
;
/* Character types (and NUMERIC) use the default precision */
/* Character types (and NUMERIC) use the default precision */
default:
default:
return
pgtype_precision
(
stmt
,
type
,
col
,
handle_unknown_size_as
);
return
pgtype_precision
(
stmt
,
type
,
col
,
handle_unknown_size_as
);
}
}
}
}
Int2
Int2
pgtype_scale
(
StatementClass
*
stmt
,
Int4
type
,
int
col
)
pgtype_scale
(
StatementClass
*
stmt
,
Int4
type
,
int
col
)
{
{
switch
(
type
)
switch
(
type
)
{
{
case
PG_TYPE_INT2
:
case
PG_TYPE_INT2
:
case
PG_TYPE_OID
:
case
PG_TYPE_OID
:
case
PG_TYPE_XID
:
case
PG_TYPE_XID
:
...
@@ -729,24 +740,24 @@ pgtype_radix(StatementClass *stmt, Int4 type)
...
@@ -729,24 +740,24 @@ pgtype_radix(StatementClass *stmt, Int4 type)
case
PG_TYPE_MONEY
:
case
PG_TYPE_MONEY
:
case
PG_TYPE_FLOAT8
:
case
PG_TYPE_FLOAT8
:
return
10
;
return
10
;
default:
default:
return
-
1
;
return
-
1
;
}
}
}
}
Int2
Int2
pgtype_nullable
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_nullable
(
StatementClass
*
stmt
,
Int4
type
)
{
{
return
SQL_NULLABLE
;
/* everything should be nullable */
return
SQL_NULLABLE
;
/* everything should be nullable */
}
}
Int2
Int2
pgtype_auto_increment
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_auto_increment
(
StatementClass
*
stmt
,
Int4
type
)
{
{
switch
(
type
)
switch
(
type
)
{
{
case
PG_TYPE_INT2
:
case
PG_TYPE_INT2
:
case
PG_TYPE_OID
:
case
PG_TYPE_OID
:
case
PG_TYPE_XID
:
case
PG_TYPE_XID
:
...
@@ -770,6 +781,7 @@ pgtype_auto_increment(StatementClass *stmt, Int4 type)
...
@@ -770,6 +781,7 @@ pgtype_auto_increment(StatementClass *stmt, Int4 type)
}
}
}
}
Int2
Int2
pgtype_case_sensitive
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_case_sensitive
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -792,6 +804,7 @@ pgtype_case_sensitive(StatementClass *stmt, Int4 type)
...
@@ -792,6 +804,7 @@ pgtype_case_sensitive(StatementClass *stmt, Int4 type)
}
}
}
}
Int2
Int2
pgtype_money
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_money
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -804,6 +817,7 @@ pgtype_money(StatementClass *stmt, Int4 type)
...
@@ -804,6 +817,7 @@ pgtype_money(StatementClass *stmt, Int4 type)
}
}
}
}
Int2
Int2
pgtype_searchable
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_searchable
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -825,6 +839,7 @@ pgtype_searchable(StatementClass *stmt, Int4 type)
...
@@ -825,6 +839,7 @@ pgtype_searchable(StatementClass *stmt, Int4 type)
}
}
}
}
Int2
Int2
pgtype_unsigned
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_unsigned
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -848,12 +863,12 @@ pgtype_unsigned(StatementClass *stmt, Int4 type)
...
@@ -848,12 +863,12 @@ pgtype_unsigned(StatementClass *stmt, Int4 type)
}
}
}
}
char
*
char
*
pgtype_literal_prefix
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_literal_prefix
(
StatementClass
*
stmt
,
Int4
type
)
{
{
switch
(
type
)
switch
(
type
)
{
{
case
PG_TYPE_INT2
:
case
PG_TYPE_INT2
:
case
PG_TYPE_OID
:
case
PG_TYPE_OID
:
case
PG_TYPE_XID
:
case
PG_TYPE_XID
:
...
@@ -869,12 +884,12 @@ pgtype_literal_prefix(StatementClass *stmt, Int4 type)
...
@@ -869,12 +884,12 @@ pgtype_literal_prefix(StatementClass *stmt, Int4 type)
}
}
}
}
char
*
char
*
pgtype_literal_suffix
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_literal_suffix
(
StatementClass
*
stmt
,
Int4
type
)
{
{
switch
(
type
)
switch
(
type
)
{
{
case
PG_TYPE_INT2
:
case
PG_TYPE_INT2
:
case
PG_TYPE_OID
:
case
PG_TYPE_OID
:
case
PG_TYPE_XID
:
case
PG_TYPE_XID
:
...
@@ -890,6 +905,7 @@ pgtype_literal_suffix(StatementClass *stmt, Int4 type)
...
@@ -890,6 +905,7 @@ pgtype_literal_suffix(StatementClass *stmt, Int4 type)
}
}
}
}
char
*
char
*
pgtype_create_params
(
StatementClass
*
stmt
,
Int4
type
)
pgtype_create_params
(
StatementClass
*
stmt
,
Int4
type
)
{
{
...
@@ -906,8 +922,10 @@ pgtype_create_params(StatementClass *stmt, Int4 type)
...
@@ -906,8 +922,10 @@ pgtype_create_params(StatementClass *stmt, Int4 type)
Int2
Int2
sqltype_to_default_ctype
(
Int2
sqltype
)
sqltype_to_default_ctype
(
Int2
sqltype
)
{
{
/* from the table on page 623 of ODBC 2.0 Programmer's Reference */
/*
/* (Appendix D) */
* from the table on page 623 of ODBC 2.0 Programmer's Reference
* (Appendix D)
*/
switch
(
sqltype
)
switch
(
sqltype
)
{
{
case
SQL_CHAR
:
case
SQL_CHAR
:
...
@@ -951,7 +969,8 @@ sqltype_to_default_ctype(Int2 sqltype)
...
@@ -951,7 +969,8 @@ sqltype_to_default_ctype(Int2 sqltype)
case
SQL_TIMESTAMP
:
case
SQL_TIMESTAMP
:
return
SQL_C_TIMESTAMP
;
return
SQL_C_TIMESTAMP
;
default:
/* should never happen */
default:
/* should never happen */
return
SQL_C_CHAR
;
return
SQL_C_CHAR
;
}
}
}
}
...
...
src/interfaces/odbc/psqlodbc.c
View file @
296e7ba2
/* Module: psqlodbc.c
/*--------
* Module: psqlodbc.c
*
*
* Description: This module contains the main entry point (DllMain)
for the library.
* Description: This module contains the main entry point (DllMain)
*
It also contains functions to get and set global variables for the
*
for the library. It also contains functions to get
* driver in the registry.
*
and set global variables for the
driver in the registry.
*
*
* Classes: n/a
* Classes: n/a
*
*
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
--------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -59,7 +60,6 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
...
@@ -59,7 +60,6 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
if
(
LOBYTE
(
wsaData
.
wVersion
)
!=
1
||
if
(
LOBYTE
(
wsaData
.
wVersion
)
!=
1
||
HIBYTE
(
wsaData
.
wVersion
)
!=
1
)
HIBYTE
(
wsaData
.
wVersion
)
!=
1
)
{
{
WSACleanup
();
WSACleanup
();
return
FALSE
;
return
FALSE
;
}
}
...
@@ -71,9 +71,7 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
...
@@ -71,9 +71,7 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
break
;
break
;
case
DLL_PROCESS_DETACH
:
case
DLL_PROCESS_DETACH
:
WSACleanup
();
WSACleanup
();
return
TRUE
;
return
TRUE
;
case
DLL_THREAD_DETACH
:
case
DLL_THREAD_DETACH
:
...
@@ -111,7 +109,8 @@ init(void)
...
@@ -111,7 +109,8 @@ init(void)
#else
/* not __GNUC__ */
#else
/* not __GNUC__ */
/* These two functions do shared library initialziation on UNIX, well at least
/*
* These two functions do shared library initialziation on UNIX, well at least
* on Linux. I don't know about other systems.
* on Linux. I don't know about other systems.
*/
*/
BOOL
BOOL
...
@@ -131,12 +130,14 @@ _fini(void)
...
@@ -131,12 +130,14 @@ _fini(void)
#endif
/* not WIN32 */
#endif
/* not WIN32 */
/* This function is used to cause the Driver Manager to
call functions by number rather than name, which is faster.
/*
The ordinal value of this function must be 199 to have the
* This function is used to cause the Driver Manager to
Driver Manager do this. Also, the ordinal values of the
* call functions by number rather than name, which is faster.
functions must match the value of fFunction in SQLGetFunctions()
* The ordinal value of this function must be 199 to have the
*/
* Driver Manager do this. Also, the ordinal values of the
* functions must match the value of fFunction in SQLGetFunctions()
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLDummyOrdinal
(
void
)
SQLDummyOrdinal
(
void
)
{
{
...
...
src/interfaces/odbc/qresult.c
View file @
296e7ba2
/* Module: qresult.c
/*---------
* Module: qresult.c
*
*
* Description: This module contains functions related to
* Description: This module contains functions related to
* managing result information (i.e, fetching rows from the backend,
* managing result information (i.e, fetching rows
* managing the tuple cache, etc.) and retrieving it.
* from the backend, managing the tuple cache, etc.)
* Depending on the situation, a QResultClass will hold either data
* and retrieving it. Depending on the situation, a
* from the backend or a manually built result (see "qresult.h" to
* QResultClass will hold either data from the backend
* see which functions/macros are for manual or backend results.
* or a manually built result (see "qresult.h" to
* For manually built results, the QResultClass simply points to
* see which functions/macros are for manual or backend
* TupleList and ColumnInfo structures, which actually hold the data.
* results. For manually built results, the
* QResultClass simply points to TupleList and
* ColumnInfo structures, which actually hold the data.
*
*
* Classes: QResultClass (Functions prefix: "QR_")
* Classes: QResultClass (Functions prefix: "QR_")
*
*
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
---------
*/
*/
#include "qresult.h"
#include "qresult.h"
...
@@ -31,8 +34,11 @@
...
@@ -31,8 +34,11 @@
extern
GLOBAL_VALUES
globals
;
extern
GLOBAL_VALUES
globals
;
/* Used for building a Manual Result only */
/* All info functions call this function to create the manual result set. */
/*
* Used for building a Manual Result only
* All info functions call this function to create the manual result set.
*/
void
void
QR_set_num_fields
(
QResultClass
*
self
,
int
new_num_fields
)
QR_set_num_fields
(
QResultClass
*
self
,
int
new_num_fields
)
{
{
...
@@ -47,34 +53,38 @@ QR_set_num_fields(QResultClass *self, int new_num_fields)
...
@@ -47,34 +53,38 @@ QR_set_num_fields(QResultClass *self, int new_num_fields)
mylog
(
"exit QR_set_num_fields
\n
"
);
mylog
(
"exit QR_set_num_fields
\n
"
);
}
}
void
void
QR_set_position
(
QResultClass
*
self
,
int
pos
)
QR_set_position
(
QResultClass
*
self
,
int
pos
)
{
{
self
->
tupleField
=
self
->
backend_tuples
+
((
self
->
base
+
pos
)
*
self
->
num_fields
);
self
->
tupleField
=
self
->
backend_tuples
+
((
self
->
base
+
pos
)
*
self
->
num_fields
);
}
}
void
void
QR_set_cache_size
(
QResultClass
*
self
,
int
cache_size
)
QR_set_cache_size
(
QResultClass
*
self
,
int
cache_size
)
{
{
self
->
cache_size
=
cache_size
;
self
->
cache_size
=
cache_size
;
}
}
void
void
QR_set_rowset_size
(
QResultClass
*
self
,
int
rowset_size
)
QR_set_rowset_size
(
QResultClass
*
self
,
int
rowset_size
)
{
{
self
->
rowset_size
=
rowset_size
;
self
->
rowset_size
=
rowset_size
;
}
}
void
void
QR_inc_base
(
QResultClass
*
self
,
int
base_inc
)
QR_inc_base
(
QResultClass
*
self
,
int
base_inc
)
{
{
self
->
base
+=
base_inc
;
self
->
base
+=
base_inc
;
}
}
/************************************/
/* CLASS QResult */
/************************************/
/*
* CLASS QResult
*/
QResultClass
*
QResultClass
*
QR_Constructor
(
void
)
QR_Constructor
(
void
)
{
{
...
@@ -111,13 +121,13 @@ QR_Constructor(void)
...
@@ -111,13 +121,13 @@ QR_Constructor(void)
rv
->
cache_size
=
globals
.
fetch_max
;
rv
->
cache_size
=
globals
.
fetch_max
;
rv
->
rowset_size
=
1
;
rv
->
rowset_size
=
1
;
}
}
mylog
(
"exit QR_Constructor
\n
"
);
mylog
(
"exit QR_Constructor
\n
"
);
return
rv
;
return
rv
;
}
}
void
void
QR_Destructor
(
QResultClass
*
self
)
QR_Destructor
(
QResultClass
*
self
)
{
{
...
@@ -127,8 +137,10 @@ QR_Destructor(QResultClass *self)
...
@@ -127,8 +137,10 @@ QR_Destructor(QResultClass *self)
if
(
self
->
manual_tuples
)
if
(
self
->
manual_tuples
)
TL_Destructor
(
self
->
manual_tuples
);
TL_Destructor
(
self
->
manual_tuples
);
/* If conn is defined, then we may have used "backend_tuples", */
/*
/* so in case we need to, free it up. Also, close the cursor. */
* If conn is defined, then we may have used "backend_tuples",
* so in case we need to, free it up. Also, close the cursor.
*/
if
(
self
->
conn
&&
self
->
conn
->
sock
&&
CC_is_in_trans
(
self
->
conn
))
if
(
self
->
conn
&&
self
->
conn
->
sock
&&
CC_is_in_trans
(
self
->
conn
))
QR_close
(
self
);
/* close the cursor if there is one */
QR_close
(
self
);
/* close the cursor if there is one */
...
@@ -153,9 +165,9 @@ QR_Destructor(QResultClass *self)
...
@@ -153,9 +165,9 @@ QR_Destructor(QResultClass *self)
free
(
self
);
free
(
self
);
mylog
(
"QResult: exit DESTRUCTOR
\n
"
);
mylog
(
"QResult: exit DESTRUCTOR
\n
"
);
}
}
void
void
QR_set_command
(
QResultClass
*
self
,
char
*
msg
)
QR_set_command
(
QResultClass
*
self
,
char
*
msg
)
{
{
...
@@ -165,6 +177,7 @@ QR_set_command(QResultClass *self, char *msg)
...
@@ -165,6 +177,7 @@ QR_set_command(QResultClass *self, char *msg)
self
->
command
=
msg
?
strdup
(
msg
)
:
NULL
;
self
->
command
=
msg
?
strdup
(
msg
)
:
NULL
;
}
}
void
void
QR_set_notice
(
QResultClass
*
self
,
char
*
msg
)
QR_set_notice
(
QResultClass
*
self
,
char
*
msg
)
{
{
...
@@ -174,6 +187,7 @@ QR_set_notice(QResultClass *self, char *msg)
...
@@ -174,6 +187,7 @@ QR_set_notice(QResultClass *self, char *msg)
self
->
notice
=
msg
?
strdup
(
msg
)
:
NULL
;
self
->
notice
=
msg
?
strdup
(
msg
)
:
NULL
;
}
}
void
void
QR_free_memory
(
QResultClass
*
self
)
QR_free_memory
(
QResultClass
*
self
)
{
{
...
@@ -187,7 +201,6 @@ QR_free_memory(QResultClass *self)
...
@@ -187,7 +201,6 @@ QR_free_memory(QResultClass *self)
if
(
self
->
backend_tuples
)
if
(
self
->
backend_tuples
)
{
{
for
(
row
=
0
;
row
<
fcount
;
row
++
)
for
(
row
=
0
;
row
<
fcount
;
row
++
)
{
{
mylog
(
"row = %d, num_fields = %d
\n
"
,
row
,
num_fields
);
mylog
(
"row = %d, num_fields = %d
\n
"
,
row
,
num_fields
);
...
@@ -211,17 +224,20 @@ QR_free_memory(QResultClass *self)
...
@@ -211,17 +224,20 @@ QR_free_memory(QResultClass *self)
mylog
(
"QResult: free memory out
\n
"
);
mylog
(
"QResult: free memory out
\n
"
);
}
}
/* This function is called by send_query() */
/* This function is called by send_query() */
char
char
QR_fetch_tuples
(
QResultClass
*
self
,
ConnectionClass
*
conn
,
char
*
cursor
)
QR_fetch_tuples
(
QResultClass
*
self
,
ConnectionClass
*
conn
,
char
*
cursor
)
{
{
int
tuple_size
;
int
tuple_size
;
/* If called from send_query the first time (conn != NULL), */
/*
/* then set the inTuples state, */
* If called from send_query the first time (conn != NULL),
/* and read the tuples. If conn is NULL, */
* then set the inTuples state,
/* it implies that we are being called from next_tuple(), */
* and read the tuples. If conn is NULL,
/* like to get more rows so don't call next_tuple again! */
* it implies that we are being called from next_tuple(),
* like to get more rows so don't call next_tuple again!
*/
if
(
conn
!=
NULL
)
if
(
conn
!=
NULL
)
{
{
self
->
conn
=
conn
;
self
->
conn
=
conn
;
...
@@ -242,8 +258,11 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
...
@@ -242,8 +258,11 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
self
->
cursor
=
strdup
(
cursor
);
self
->
cursor
=
strdup
(
cursor
);
}
}
/* Read the field attributes. */
/*
/* $$$$ Should do some error control HERE! $$$$ */
* Read the field attributes.
*
* $$$$ Should do some error control HERE! $$$$
*/
if
(
CI_read_fields
(
self
->
fields
,
self
->
conn
))
if
(
CI_read_fields
(
self
->
fields
,
self
->
conn
))
{
{
self
->
status
=
PGRES_FIELDS_OK
;
self
->
status
=
PGRES_FIELDS_OK
;
...
@@ -275,7 +294,6 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
...
@@ -275,7 +294,6 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
self
->
inTuples
=
TRUE
;
self
->
inTuples
=
TRUE
;
/* Force a read to occur in next_tuple */
/* Force a read to occur in next_tuple */
self
->
fcount
=
tuple_size
+
1
;
self
->
fcount
=
tuple_size
+
1
;
self
->
fetch_count
=
tuple_size
+
1
;
self
->
fetch_count
=
tuple_size
+
1
;
...
@@ -285,9 +303,10 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
...
@@ -285,9 +303,10 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
}
}
else
else
{
{
/*
/* Always have to read the field attributes. */
* Always have to read the field attributes.
/* But we dont have to reallocate memory for them! */
* But we dont have to reallocate memory for them!
*/
if
(
!
CI_read_fields
(
NULL
,
self
->
conn
))
if
(
!
CI_read_fields
(
NULL
,
self
->
conn
))
{
{
...
@@ -299,8 +318,11 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
...
@@ -299,8 +318,11 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
}
}
}
}
/* Close the cursor and end the transaction (if no cursors left) */
/* We only close cursor/end the transaction if a cursor was used. */
/*
* Close the cursor and end the transaction (if no cursors left)
* We only close cursor/end the transaction if a cursor was used.
*/
int
int
QR_close
(
QResultClass
*
self
)
QR_close
(
QResultClass
*
self
)
{
{
...
@@ -346,12 +368,12 @@ QR_close(QResultClass *self)
...
@@ -346,12 +368,12 @@ QR_close(QResultClass *self)
}
}
QR_Destructor
(
res
);
QR_Destructor
(
res
);
}
}
}
}
return
TRUE
;
return
TRUE
;
}
}
/* This function is called by fetch_tuples() AND SQLFetch() */
/* This function is called by fetch_tuples() AND SQLFetch() */
int
int
QR_next_tuple
(
QResultClass
*
self
)
QR_next_tuple
(
QResultClass
*
self
)
...
@@ -360,7 +382,7 @@ QR_next_tuple(QResultClass *self)
...
@@ -360,7 +382,7 @@ QR_next_tuple(QResultClass *self)
QResultClass
*
res
;
QResultClass
*
res
;
SocketClass
*
sock
;
SocketClass
*
sock
;
/* Speed up access */
/* Speed up access */
int
fetch_count
=
self
->
fetch_count
;
int
fetch_count
=
self
->
fetch_count
;
int
fcount
=
self
->
fcount
;
int
fcount
=
self
->
fcount
;
int
fetch_size
,
int
fetch_size
,
...
@@ -370,30 +392,31 @@ QR_next_tuple(QResultClass *self)
...
@@ -370,30 +392,31 @@ QR_next_tuple(QResultClass *self)
TupleField
*
the_tuples
=
self
->
backend_tuples
;
TupleField
*
the_tuples
=
self
->
backend_tuples
;
/* ERROR_MSG_LENGTH is sufficient */
/* ERROR_MSG_LENGTH is sufficient */
static
char
msgbuffer
[
ERROR_MSG_LENGTH
+
1
];
static
char
msgbuffer
[
ERROR_MSG_LENGTH
+
1
];
char
cmdbuffer
[
ERROR_MSG_LENGTH
+
1
];
/* QR_set_command() dups
/* QR_set_command() dups this string so doesn't need static */
* this string so dont
char
cmdbuffer
[
ERROR_MSG_LENGTH
+
1
];
* need static */
char
fetch
[
128
];
char
fetch
[
128
];
QueryInfo
qi
;
QueryInfo
qi
;
if
(
fetch_count
<
fcount
)
if
(
fetch_count
<
fcount
)
{
/* return a row from cache */
{
/* return a row from cache */
mylog
(
"next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d
\n
"
,
fetch_count
,
fcount
);
mylog
(
"next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d
\n
"
,
fetch_count
,
fcount
);
self
->
tupleField
=
the_tuples
+
(
fetch_count
*
self
->
num_fields
);
/* next row */
self
->
tupleField
=
the_tuples
+
(
fetch_count
*
self
->
num_fields
);
/* next row */
self
->
fetch_count
++
;
self
->
fetch_count
++
;
return
TRUE
;
return
TRUE
;
}
}
else
if
(
self
->
fcount
<
self
->
cache_size
)
else
if
(
self
->
fcount
<
self
->
cache_size
)
{
/* last row from cache */
{
/* last row from cache */
/* We are done because we didn't even get CACHE_SIZE tuples */
/* We are done because we didn't even get CACHE_SIZE tuples */
mylog
(
"next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d
\n
"
,
fcount
,
fetch_count
);
mylog
(
"next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d
\n
"
,
fcount
,
fetch_count
);
self
->
tupleField
=
NULL
;
self
->
tupleField
=
NULL
;
self
->
status
=
PGRES_END_TUPLES
;
self
->
status
=
PGRES_END_TUPLES
;
return
-
1
;
/* end of tuples */
/* end of tuples */
return
-
1
;
}
}
else
else
{
{
/*
/*
* See if we need to fetch another group of rows. We may be being
* See if we need to fetch another group of rows. We may be being
* called from send_query(), and if so, don't send another fetch,
* called from send_query(), and if so, don't send another fetch,
...
@@ -403,7 +426,6 @@ QR_next_tuple(QResultClass *self)
...
@@ -403,7 +426,6 @@ QR_next_tuple(QResultClass *self)
if
(
!
self
->
inTuples
)
if
(
!
self
->
inTuples
)
{
{
if
(
!
globals
.
use_declarefetch
)
if
(
!
globals
.
use_declarefetch
)
{
{
mylog
(
"next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d
\n
"
,
fcount
,
fetch_count
);
mylog
(
"next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d
\n
"
,
fcount
,
fetch_count
);
...
@@ -413,8 +435,8 @@ QR_next_tuple(QResultClass *self)
...
@@ -413,8 +435,8 @@ QR_next_tuple(QResultClass *self)
}
}
if
(
self
->
base
==
fcount
)
if
(
self
->
base
==
fcount
)
{
/* not a correction */
{
/* not a correction */
/* Determine the optimum cache size. */
/* Determine the optimum cache size. */
if
(
globals
.
fetch_max
%
self
->
rowset_size
==
0
)
if
(
globals
.
fetch_max
%
self
->
rowset_size
==
0
)
fetch_size
=
globals
.
fetch_max
;
fetch_size
=
globals
.
fetch_max
;
...
@@ -427,8 +449,8 @@ QR_next_tuple(QResultClass *self)
...
@@ -427,8 +449,8 @@ QR_next_tuple(QResultClass *self)
self
->
fetch_count
=
1
;
self
->
fetch_count
=
1
;
}
}
else
else
{
/* need to correct */
{
/* need to correct */
corrected
=
TRUE
;
corrected
=
TRUE
;
fetch_size
=
end_tuple
-
fcount
;
fetch_size
=
end_tuple
-
fcount
;
...
@@ -437,10 +459,8 @@ QR_next_tuple(QResultClass *self)
...
@@ -437,10 +459,8 @@ QR_next_tuple(QResultClass *self)
offset
=
self
->
fetch_count
;
offset
=
self
->
fetch_count
;
self
->
fetch_count
++
;
self
->
fetch_count
++
;
}
}
self
->
backend_tuples
=
(
TupleField
*
)
realloc
(
self
->
backend_tuples
,
self
->
num_fields
*
sizeof
(
TupleField
)
*
self
->
cache_size
);
self
->
backend_tuples
=
(
TupleField
*
)
realloc
(
self
->
backend_tuples
,
self
->
num_fields
*
sizeof
(
TupleField
)
*
self
->
cache_size
);
if
(
!
self
->
backend_tuples
)
if
(
!
self
->
backend_tuples
)
{
{
...
@@ -484,17 +504,16 @@ QR_next_tuple(QResultClass *self)
...
@@ -484,17 +504,16 @@ QR_next_tuple(QResultClass *self)
self
->
fcount
=
0
;
self
->
fcount
=
0
;
}
}
sock
=
CC_get_socket
(
self
->
conn
);
sock
=
CC_get_socket
(
self
->
conn
);
self
->
tupleField
=
NULL
;
self
->
tupleField
=
NULL
;
for
(;;)
for
(;;)
{
{
id
=
SOCK_get_char
(
sock
);
id
=
SOCK_get_char
(
sock
);
switch
(
id
)
switch
(
id
)
{
{
case
'T'
:
/* Tuples within tuples cannot be handled */
case
'T'
:
/* Tuples within tuples cannot be handled */
self
->
status
=
PGRES_BAD_RESPONSE
;
self
->
status
=
PGRES_BAD_RESPONSE
;
QR_set_message
(
self
,
"Tuples within tuples cannot be handled"
);
QR_set_message
(
self
,
"Tuples within tuples cannot be handled"
);
...
@@ -523,11 +542,9 @@ QR_next_tuple(QResultClass *self)
...
@@ -523,11 +542,9 @@ QR_next_tuple(QResultClass *self)
QR_set_message
(
self
,
"Error reading the tuple"
);
QR_set_message
(
self
,
"Error reading the tuple"
);
return
FALSE
;
return
FALSE
;
}
}
self
->
fcount
++
;
self
->
fcount
++
;
break
;
/* continue reading */
break
;
/* continue reading */
case
'C'
:
/* End of tuple list */
case
'C'
:
/* End of tuple list */
SOCK_get_string
(
sock
,
cmdbuffer
,
ERROR_MSG_LENGTH
);
SOCK_get_string
(
sock
,
cmdbuffer
,
ERROR_MSG_LENGTH
);
QR_set_command
(
self
,
cmdbuffer
);
QR_set_command
(
self
,
cmdbuffer
);
...
@@ -537,7 +554,6 @@ QR_next_tuple(QResultClass *self)
...
@@ -537,7 +554,6 @@ QR_next_tuple(QResultClass *self)
self
->
inTuples
=
FALSE
;
self
->
inTuples
=
FALSE
;
if
(
self
->
fcount
>
0
)
if
(
self
->
fcount
>
0
)
{
{
qlog
(
" [ fetched %d rows ]
\n
"
,
self
->
fcount
);
qlog
(
" [ fetched %d rows ]
\n
"
,
self
->
fcount
);
mylog
(
"_next_tuple: 'C' fetch_max && fcount = %d
\n
"
,
self
->
fcount
);
mylog
(
"_next_tuple: 'C' fetch_max && fcount = %d
\n
"
,
self
->
fcount
);
...
@@ -546,8 +562,8 @@ QR_next_tuple(QResultClass *self)
...
@@ -546,8 +562,8 @@ QR_next_tuple(QResultClass *self)
return
TRUE
;
return
TRUE
;
}
}
else
else
{
/* We are surely done here (we read 0
{
*
tuples) */
/* We are surely done here (we read 0
tuples) */
qlog
(
" [ fetched 0 rows ]
\n
"
);
qlog
(
" [ fetched 0 rows ]
\n
"
);
mylog
(
"_next_tuple: 'C': DONE (fcount == 0)
\n
"
);
mylog
(
"_next_tuple: 'C': DONE (fcount == 0)
\n
"
);
return
-
1
;
/* end of tuples */
return
-
1
;
/* end of tuples */
...
@@ -585,6 +601,7 @@ QR_next_tuple(QResultClass *self)
...
@@ -585,6 +601,7 @@ QR_next_tuple(QResultClass *self)
return
TRUE
;
return
TRUE
;
}
}
char
char
QR_read_tuple
(
QResultClass
*
self
,
char
binary
)
QR_read_tuple
(
QResultClass
*
self
,
char
binary
)
{
{
...
@@ -601,7 +618,6 @@ QR_read_tuple(QResultClass *self, char binary)
...
@@ -601,7 +618,6 @@ QR_read_tuple(QResultClass *self, char binary)
SocketClass
*
sock
=
CC_get_socket
(
self
->
conn
);
SocketClass
*
sock
=
CC_get_socket
(
self
->
conn
);
ColumnInfoClass
*
flds
;
ColumnInfoClass
*
flds
;
/* set the current row to read the fields into */
/* set the current row to read the fields into */
this_tuplefield
=
self
->
backend_tuples
+
(
self
->
fcount
*
num_fields
);
this_tuplefield
=
self
->
backend_tuples
+
(
self
->
fcount
*
num_fields
);
...
@@ -630,7 +646,6 @@ QR_read_tuple(QResultClass *self, char binary)
...
@@ -630,7 +646,6 @@ QR_read_tuple(QResultClass *self, char binary)
}
}
else
else
{
{
/*
/*
* NO, the field is not null. so get at first the length of
* NO, the field is not null. so get at first the length of
* the field (four bytes)
* the field (four bytes)
...
...
src/interfaces/odbc/results.c
View file @
296e7ba2
/* Module: results.c
/*-------
* Module: results.c
*
*
* Description: This module contains functions related to
* Description: This module contains functions related to
* retrieving result information through the ODBC API.
* retrieving result information through the ODBC API.
*
*
* Classes: n/a
* Classes: n/a
*
*
* API functions: SQLRowCount, SQLNumResultCols, SQLDescribeCol,
SQLColAttributes,
* API functions: SQLRowCount, SQLNumResultCols, SQLDescribeCol,
* SQLGetData, SQLFetch, SQLExtendedFetch,
* SQL
ColAttributes, SQL
GetData, SQLFetch, SQLExtendedFetch,
* SQLMoreResults(NI), SQLSetPos, SQLSetScrollOptions(NI),
* SQLMoreResults(NI), SQLSetPos, SQLSetScrollOptions(NI),
* SQLSetCursorName, SQLGetCursorName
* SQLSetCursorName, SQLGetCursorName
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -42,7 +43,6 @@
...
@@ -42,7 +43,6 @@
extern
GLOBAL_VALUES
globals
;
extern
GLOBAL_VALUES
globals
;
RETCODE
SQL_API
RETCODE
SQL_API
SQLRowCount
(
SQLRowCount
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -81,7 +81,6 @@ SQLRowCount(
...
@@ -81,7 +81,6 @@ SQLRowCount(
}
}
else
else
{
{
res
=
SC_get_Result
(
stmt
);
res
=
SC_get_Result
(
stmt
);
if
(
res
&&
pcrow
)
if
(
res
&&
pcrow
)
{
{
...
@@ -97,7 +96,6 @@ SQLRowCount(
...
@@ -97,7 +96,6 @@ SQLRowCount(
else
else
{
{
*
pcrow
=
-
1
;
*
pcrow
=
-
1
;
mylog
(
"**** SQLRowCount(): NO ROWS: *pcrow = %d
\n
"
,
*
pcrow
);
mylog
(
"**** SQLRowCount(): NO ROWS: *pcrow = %d
\n
"
,
*
pcrow
);
}
}
...
@@ -110,10 +108,10 @@ SQLRowCount(
...
@@ -110,10 +108,10 @@ SQLRowCount(
}
}
/*
This returns the number of columns associated with the database */
/*
/* attached to "hstmt". */
* This returns the number of columns associated with the database
* attached to "hstmt".
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLNumResultCols
(
SQLNumResultCols
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -135,7 +133,6 @@ SQLNumResultCols(
...
@@ -135,7 +133,6 @@ SQLNumResultCols(
parse_ok
=
FALSE
;
parse_ok
=
FALSE
;
if
(
globals
.
parse
&&
stmt
->
statement_type
==
STMT_TYPE_SELECT
)
if
(
globals
.
parse
&&
stmt
->
statement_type
==
STMT_TYPE_SELECT
)
{
{
if
(
stmt
->
parse_status
==
STMT_PARSE_NONE
)
if
(
stmt
->
parse_status
==
STMT_PARSE_NONE
)
{
{
mylog
(
"SQLNumResultCols: calling parse_statement on stmt=%u
\n
"
,
stmt
);
mylog
(
"SQLNumResultCols: calling parse_statement on stmt=%u
\n
"
,
stmt
);
...
@@ -152,7 +149,6 @@ SQLNumResultCols(
...
@@ -152,7 +149,6 @@ SQLNumResultCols(
if
(
!
parse_ok
)
if
(
!
parse_ok
)
{
{
SC_pre_execute
(
stmt
);
SC_pre_execute
(
stmt
);
result
=
SC_get_Result
(
stmt
);
result
=
SC_get_Result
(
stmt
);
...
@@ -173,12 +169,10 @@ SQLNumResultCols(
...
@@ -173,12 +169,10 @@ SQLNumResultCols(
}
}
/* - - - - - - - - - */
/*
* Return information about the database column the user wants
* information about.
*/
/* Return information about the database column the user wants */
/* information about. */
RETCODE
SQL_API
RETCODE
SQL_API
SQLDescribeCol
(
SQLDescribeCol
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -205,7 +199,6 @@ SQLDescribeCol(
...
@@ -205,7 +199,6 @@ SQLDescribeCol(
int
len
=
0
;
int
len
=
0
;
RETCODE
result
;
RETCODE
result
;
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
if
(
!
stmt
)
if
(
!
stmt
)
...
@@ -225,23 +218,19 @@ SQLDescribeCol(
...
@@ -225,23 +218,19 @@ SQLDescribeCol(
icol
--
;
/* use zero based column numbers */
icol
--
;
/* use zero based column numbers */
parse_ok
=
FALSE
;
parse_ok
=
FALSE
;
if
(
globals
.
parse
&&
stmt
->
statement_type
==
STMT_TYPE_SELECT
)
if
(
globals
.
parse
&&
stmt
->
statement_type
==
STMT_TYPE_SELECT
)
{
{
if
(
stmt
->
parse_status
==
STMT_PARSE_NONE
)
if
(
stmt
->
parse_status
==
STMT_PARSE_NONE
)
{
{
mylog
(
"SQLDescribeCol: calling parse_statement on stmt=%u
\n
"
,
stmt
);
mylog
(
"SQLDescribeCol: calling parse_statement on stmt=%u
\n
"
,
stmt
);
parse_statement
(
stmt
);
parse_statement
(
stmt
);
}
}
mylog
(
"PARSE: DescribeCol: icol=%d, stmt=%u, stmt->nfld=%d, stmt->fi=%u
\n
"
,
icol
,
stmt
,
stmt
->
nfld
,
stmt
->
fi
);
mylog
(
"PARSE: DescribeCol: icol=%d, stmt=%u, stmt->nfld=%d, stmt->fi=%u
\n
"
,
icol
,
stmt
,
stmt
->
nfld
,
stmt
->
fi
);
if
(
stmt
->
parse_status
!=
STMT_PARSE_FATAL
&&
stmt
->
fi
&&
stmt
->
fi
[
icol
])
if
(
stmt
->
parse_status
!=
STMT_PARSE_FATAL
&&
stmt
->
fi
&&
stmt
->
fi
[
icol
])
{
{
if
(
icol
>=
stmt
->
nfld
)
if
(
icol
>=
stmt
->
nfld
)
{
{
stmt
->
errornumber
=
STMT_INVALID_COLUMN_NUMBER_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_COLUMN_NUMBER_ERROR
;
...
@@ -261,7 +250,6 @@ SQLDescribeCol(
...
@@ -261,7 +250,6 @@ SQLDescribeCol(
}
}
}
}
/*
/*
* If couldn't parse it OR the field being described was not parsed
* If couldn't parse it OR the field being described was not parsed
* (i.e., because it was a function or expression, etc, then do it the
* (i.e., because it was a function or expression, etc, then do it the
...
@@ -295,20 +283,19 @@ SQLDescribeCol(
...
@@ -295,20 +283,19 @@ SQLDescribeCol(
col_name
=
QR_get_fieldname
(
res
,
icol
);
col_name
=
QR_get_fieldname
(
res
,
icol
);
fieldtype
=
QR_get_field_type
(
res
,
icol
);
fieldtype
=
QR_get_field_type
(
res
,
icol
);
precision
=
pgtype_precision
(
stmt
,
fieldtype
,
icol
,
globals
.
unknown_sizes
);
/* atoi(ci->unknown_sizes
/* atoi(ci->unknown_sizes) */
* ) */
precision
=
pgtype_precision
(
stmt
,
fieldtype
,
icol
,
globals
.
unknown_sizes
);
}
}
mylog
(
"describeCol: col %d fieldname = '%s'
\n
"
,
icol
,
col_name
);
mylog
(
"describeCol: col %d fieldname = '%s'
\n
"
,
icol
,
col_name
);
mylog
(
"describeCol: col %d fieldtype = %d
\n
"
,
icol
,
fieldtype
);
mylog
(
"describeCol: col %d fieldtype = %d
\n
"
,
icol
,
fieldtype
);
mylog
(
"describeCol: col %d precision = %d
\n
"
,
icol
,
precision
);
mylog
(
"describeCol: col %d precision = %d
\n
"
,
icol
,
precision
);
result
=
SQL_SUCCESS
;
result
=
SQL_SUCCESS
;
/*
***********************/
/*
/* COLUMN NAME */
* COLUMN NAME
/***********************
*/
*/
len
=
strlen
(
col_name
);
len
=
strlen
(
col_name
);
if
(
pcbColName
)
if
(
pcbColName
)
...
@@ -326,10 +313,9 @@ SQLDescribeCol(
...
@@ -326,10 +313,9 @@ SQLDescribeCol(
}
}
}
}
/*
/************************/
* SQL TYPE
/* SQL TYPE */
*/
/************************/
if
(
pfSqlType
)
if
(
pfSqlType
)
{
{
*
pfSqlType
=
pgtype_to_sqltype
(
stmt
,
fieldtype
);
*
pfSqlType
=
pgtype_to_sqltype
(
stmt
,
fieldtype
);
...
@@ -337,12 +323,11 @@ SQLDescribeCol(
...
@@ -337,12 +323,11 @@ SQLDescribeCol(
mylog
(
"describeCol: col %d *pfSqlType = %d
\n
"
,
icol
,
*
pfSqlType
);
mylog
(
"describeCol: col %d *pfSqlType = %d
\n
"
,
icol
,
*
pfSqlType
);
}
}
/*
***********************/
/*
/* PRECISION */
* PRECISION
/***********************
*/
*/
if
(
pcbColDef
)
if
(
pcbColDef
)
{
{
if
(
precision
<
0
)
if
(
precision
<
0
)
precision
=
0
;
/* "I dont know" */
precision
=
0
;
/* "I dont know" */
...
@@ -351,9 +336,9 @@ SQLDescribeCol(
...
@@ -351,9 +336,9 @@ SQLDescribeCol(
mylog
(
"describeCol: col %d *pcbColDef = %d
\n
"
,
icol
,
*
pcbColDef
);
mylog
(
"describeCol: col %d *pcbColDef = %d
\n
"
,
icol
,
*
pcbColDef
);
}
}
/*
***********************/
/*
/* SCALE */
* SCALE
/***********************
*/
*/
if
(
pibScale
)
if
(
pibScale
)
{
{
Int2
scale
;
Int2
scale
;
...
@@ -366,9 +351,9 @@ SQLDescribeCol(
...
@@ -366,9 +351,9 @@ SQLDescribeCol(
mylog
(
"describeCol: col %d *pibScale = %d
\n
"
,
icol
,
*
pibScale
);
mylog
(
"describeCol: col %d *pibScale = %d
\n
"
,
icol
,
*
pibScale
);
}
}
/*
***********************/
/*
/* NULLABILITY */
* NULLABILITY
/***********************
*/
*/
if
(
pfNullable
)
if
(
pfNullable
)
{
{
*
pfNullable
=
(
parse_ok
)
?
stmt
->
fi
[
icol
]
->
nullable
:
pgtype_nullable
(
stmt
,
fieldtype
);
*
pfNullable
=
(
parse_ok
)
?
stmt
->
fi
[
icol
]
->
nullable
:
pgtype_nullable
(
stmt
,
fieldtype
);
...
@@ -379,8 +364,8 @@ SQLDescribeCol(
...
@@ -379,8 +364,8 @@ SQLDescribeCol(
return
result
;
return
result
;
}
}
/* Returns result column descriptor information for a result set. */
/* Returns result column descriptor information for a result set. */
RETCODE
SQL_API
RETCODE
SQL_API
SQLColAttributes
(
SQLColAttributes
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -421,16 +406,16 @@ SQLColAttributes(
...
@@ -421,16 +406,16 @@ SQLColAttributes(
icol
--
;
icol
--
;
unknown_sizes
=
globals
.
unknown_sizes
;
/* atoi(ci->unknown_sizes);
/* atoi(ci->unknown_sizes); */
* */
unknown_sizes
=
globals
.
unknown_sizes
;
if
(
unknown_sizes
==
UNKNOWNS_AS_DONTKNOW
)
/* not appropriate for
* SQLColAttributes() */
/* not appropriate for SQLColAttributes() */
if
(
unknown_sizes
==
UNKNOWNS_AS_DONTKNOW
)
unknown_sizes
=
UNKNOWNS_AS_MAX
;
unknown_sizes
=
UNKNOWNS_AS_MAX
;
parse_ok
=
FALSE
;
parse_ok
=
FALSE
;
if
(
globals
.
parse
&&
stmt
->
statement_type
==
STMT_TYPE_SELECT
)
if
(
globals
.
parse
&&
stmt
->
statement_type
==
STMT_TYPE_SELECT
)
{
{
if
(
stmt
->
parse_status
==
STMT_PARSE_NONE
)
if
(
stmt
->
parse_status
==
STMT_PARSE_NONE
)
{
{
mylog
(
"SQLColAttributes: calling parse_statement
\n
"
);
mylog
(
"SQLColAttributes: calling parse_statement
\n
"
);
...
@@ -453,7 +438,6 @@ SQLColAttributes(
...
@@ -453,7 +438,6 @@ SQLColAttributes(
if
(
stmt
->
parse_status
!=
STMT_PARSE_FATAL
&&
stmt
->
fi
&&
stmt
->
fi
[
icol
])
if
(
stmt
->
parse_status
!=
STMT_PARSE_FATAL
&&
stmt
->
fi
&&
stmt
->
fi
[
icol
])
{
{
if
(
icol
>=
cols
)
if
(
icol
>=
cols
)
{
{
stmt
->
errornumber
=
STMT_INVALID_COLUMN_NUMBER_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_COLUMN_NUMBER_ERROR
;
...
@@ -461,7 +445,6 @@ SQLColAttributes(
...
@@ -461,7 +445,6 @@ SQLColAttributes(
SC_log_error
(
func
,
""
,
stmt
);
SC_log_error
(
func
,
""
,
stmt
);
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
field_type
=
stmt
->
fi
[
icol
]
->
type
;
field_type
=
stmt
->
fi
[
icol
]
->
type
;
if
(
field_type
>
0
)
if
(
field_type
>
0
)
parse_ok
=
TRUE
;
parse_ok
=
TRUE
;
...
@@ -527,7 +510,6 @@ SQLColAttributes(
...
@@ -527,7 +510,6 @@ SQLColAttributes(
*
*
* case SQL_COLUMN_COUNT:
* case SQL_COLUMN_COUNT:
*/
*/
case
SQL_COLUMN_DISPLAY_SIZE
:
case
SQL_COLUMN_DISPLAY_SIZE
:
value
=
(
parse_ok
)
?
stmt
->
fi
[
icol
]
->
display_size
:
pgtype_display_size
(
stmt
,
field_type
,
icol
,
unknown_sizes
);
value
=
(
parse_ok
)
?
stmt
->
fi
[
icol
]
->
display_size
:
pgtype_display_size
(
stmt
,
field_type
,
icol
,
unknown_sizes
);
...
@@ -543,11 +525,10 @@ SQLColAttributes(
...
@@ -543,11 +525,10 @@ SQLColAttributes(
mylog
(
"SQLColAttr: COLUMN_LABEL = '%s'
\n
"
,
p
);
mylog
(
"SQLColAttr: COLUMN_LABEL = '%s'
\n
"
,
p
);
break
;
break
;
}
/* otherwise same as column name -- FALL
}
*
THROUGH!!! */
/* otherwise same as column name -- FALL
THROUGH!!! */
case
SQL_COLUMN_NAME
:
case
SQL_COLUMN_NAME
:
p
=
(
parse_ok
)
?
stmt
->
fi
[
icol
]
->
name
:
QR_get_fieldname
(
stmt
->
result
,
icol
);
p
=
(
parse_ok
)
?
stmt
->
fi
[
icol
]
->
name
:
QR_get_fieldname
(
stmt
->
result
,
icol
);
mylog
(
"SQLColAttr: COLUMN_NAME = '%s'
\n
"
,
p
);
mylog
(
"SQLColAttr: COLUMN_NAME = '%s'
\n
"
,
p
);
...
@@ -590,7 +571,6 @@ SQLColAttributes(
...
@@ -590,7 +571,6 @@ SQLColAttributes(
break
;
break
;
case
SQL_COLUMN_TABLE_NAME
:
case
SQL_COLUMN_TABLE_NAME
:
p
=
(
parse_ok
&&
stmt
->
fi
[
icol
]
->
ti
)
?
stmt
->
fi
[
icol
]
->
ti
->
name
:
""
;
p
=
(
parse_ok
&&
stmt
->
fi
[
icol
]
->
ti
)
?
stmt
->
fi
[
icol
]
->
ti
->
name
:
""
;
mylog
(
"SQLColAttr: TABLE_NAME = '%s'
\n
"
,
p
);
mylog
(
"SQLColAttr: TABLE_NAME = '%s'
\n
"
,
p
);
...
@@ -612,14 +592,12 @@ SQLColAttributes(
...
@@ -612,14 +592,12 @@ SQLColAttributes(
break
;
break
;
case
SQL_COLUMN_UPDATABLE
:
case
SQL_COLUMN_UPDATABLE
:
/*
/*
* Neither Access or Borland care about this.
* Neither Access or Borland care about this.
*
*
* if (field_type == PG_TYPE_OID) pfDesc = SQL_ATTR_READONLY;
* if (field_type == PG_TYPE_OID) pfDesc = SQL_ATTR_READONLY;
* else
* else
*/
*/
value
=
SQL_ATTR_WRITE
;
value
=
SQL_ATTR_WRITE
;
mylog
(
"SQLColAttr: UPDATEABLE = %d
\n
"
,
value
);
mylog
(
"SQLColAttr: UPDATEABLE = %d
\n
"
,
value
);
...
@@ -648,19 +626,17 @@ SQLColAttributes(
...
@@ -648,19 +626,17 @@ SQLColAttributes(
*
pcbDesc
=
len
;
*
pcbDesc
=
len
;
}
}
else
else
{
/* numeric data */
{
/* numeric data */
if
(
pfDesc
)
if
(
pfDesc
)
*
pfDesc
=
value
;
*
pfDesc
=
value
;
}
}
return
result
;
return
result
;
}
}
/* Returns result data for a single column in the current row. */
/* Returns result data for a single column in the current row. */
RETCODE
SQL_API
RETCODE
SQL_API
SQLGetData
(
SQLGetData
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -707,7 +683,6 @@ SQLGetData(
...
@@ -707,7 +683,6 @@ SQLGetData(
if
(
icol
==
0
)
if
(
icol
==
0
)
{
{
if
(
stmt
->
options
.
use_bookmarks
==
SQL_UB_OFF
)
if
(
stmt
->
options
.
use_bookmarks
==
SQL_UB_OFF
)
{
{
stmt
->
errornumber
=
STMT_COLNUM_ERROR
;
stmt
->
errornumber
=
STMT_COLNUM_ERROR
;
...
@@ -726,12 +701,9 @@ SQLGetData(
...
@@ -726,12 +701,9 @@ SQLGetData(
}
}
get_bookmark
=
TRUE
;
get_bookmark
=
TRUE
;
}
}
else
else
{
{
/* use zero-based column numbers */
/* use zero-based column numbers */
icol
--
;
icol
--
;
...
@@ -770,7 +742,8 @@ SQLGetData(
...
@@ -770,7 +742,8 @@ SQLGetData(
}
}
}
}
else
else
{
/* it's a SOCKET result (backend data) */
{
/* it's a SOCKET result (backend data) */
if
(
stmt
->
currTuple
==
-
1
||
!
res
||
!
res
->
tupleField
)
if
(
stmt
->
currTuple
==
-
1
||
!
res
||
!
res
->
tupleField
)
{
{
stmt
->
errormsg
=
"Not positioned on a valid row for GetData."
;
stmt
->
errormsg
=
"Not positioned on a valid row for GetData."
;
...
@@ -845,10 +818,10 @@ SQLGetData(
...
@@ -845,10 +818,10 @@ SQLGetData(
}
}
/*
/* Returns data for bound columns in the current row ("hstmt->iCursor"), */
* Returns data for bound columns in the current row ("hstmt->iCursor"),
/* advances the cursor. */
* advances the cursor.
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLFetch
(
SQLFetch
(
HSTMT
hstmt
)
HSTMT
hstmt
)
...
@@ -892,7 +865,6 @@ SQLFetch(
...
@@ -892,7 +865,6 @@ SQLFetch(
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
if
(
stmt
->
status
!=
STMT_FINISHED
)
if
(
stmt
->
status
!=
STMT_FINISHED
)
{
{
stmt
->
errornumber
=
STMT_STATUS_ERROR
;
stmt
->
errornumber
=
STMT_STATUS_ERROR
;
...
@@ -917,8 +889,8 @@ SQLFetch(
...
@@ -917,8 +889,8 @@ SQLFetch(
return
SC_fetch
(
stmt
);
return
SC_fetch
(
stmt
);
}
}
/* This fetchs a block of data (rowset). */
/* This fetchs a block of data (rowset). */
RETCODE
SQL_API
RETCODE
SQL_API
SQLExtendedFetch
(
SQLExtendedFetch
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -1020,7 +992,6 @@ SQLExtendedFetch(
...
@@ -1020,7 +992,6 @@ SQLExtendedFetch(
switch
(
fFetchType
)
switch
(
fFetchType
)
{
{
case
SQL_FETCH_NEXT
:
case
SQL_FETCH_NEXT
:
/*
/*
* From the odbc spec... If positioned before the start of the
* From the odbc spec... If positioned before the start of the
* RESULT SET, then this should be equivalent to
* RESULT SET, then this should be equivalent to
...
@@ -1031,36 +1002,25 @@ SQLExtendedFetch(
...
@@ -1031,36 +1002,25 @@ SQLExtendedFetch(
stmt
->
rowset_start
=
0
;
stmt
->
rowset_start
=
0
;
else
else
{
stmt
->
rowset_start
+=
(
save_rowset_size
>
0
?
save_rowset_size
:
stmt
->
options
.
rowset_size
);
stmt
->
rowset_start
+=
(
save_rowset_size
>
0
?
save_rowset_size
:
stmt
->
options
.
rowset_size
);
}
mylog
(
"SQL_FETCH_NEXT: num_tuples=%d, currtuple=%d
\n
"
,
num_tuples
,
stmt
->
currTuple
);
mylog
(
"SQL_FETCH_NEXT: num_tuples=%d, currtuple=%d
\n
"
,
num_tuples
,
stmt
->
currTuple
);
break
;
break
;
case
SQL_FETCH_PRIOR
:
case
SQL_FETCH_PRIOR
:
mylog
(
"SQL_FETCH_PRIOR: num_tuples=%d, currtuple=%d
\n
"
,
num_tuples
,
stmt
->
currTuple
);
mylog
(
"SQL_FETCH_PRIOR: num_tuples=%d, currtuple=%d
\n
"
,
num_tuples
,
stmt
->
currTuple
);
/*
/*
* From the odbc spec... If positioned after the end of the
* From the odbc spec... If positioned after the end of the
* RESULT SET, then this should be equivalent to
* RESULT SET, then this should be equivalent to
* SQL_FETCH_LAST.
* SQL_FETCH_LAST.
*/
*/
if
(
stmt
->
rowset_start
>=
num_tuples
)
if
(
stmt
->
rowset_start
>=
num_tuples
)
{
{
stmt
->
rowset_start
=
num_tuples
<=
0
?
0
:
(
num_tuples
-
stmt
->
options
.
rowset_size
);
stmt
->
rowset_start
=
num_tuples
<=
0
?
0
:
(
num_tuples
-
stmt
->
options
.
rowset_size
);
}
}
else
else
{
stmt
->
rowset_start
-=
stmt
->
options
.
rowset_size
;
stmt
->
rowset_start
-=
stmt
->
options
.
rowset_size
;
}
break
;
break
;
case
SQL_FETCH_FIRST
:
case
SQL_FETCH_FIRST
:
...
@@ -1091,11 +1051,9 @@ SQLExtendedFetch(
...
@@ -1091,11 +1051,9 @@ SQLExtendedFetch(
/* Position with respect to the end of the result set */
/* Position with respect to the end of the result set */
else
else
stmt
->
rowset_start
=
num_tuples
+
irow
;
stmt
->
rowset_start
=
num_tuples
+
irow
;
break
;
break
;
case
SQL_FETCH_RELATIVE
:
case
SQL_FETCH_RELATIVE
:
/*
/*
* Refresh the current rowset -- not currently implemented,
* Refresh the current rowset -- not currently implemented,
* but lie anyway
* but lie anyway
...
@@ -1104,25 +1062,20 @@ SQLExtendedFetch(
...
@@ -1104,25 +1062,20 @@ SQLExtendedFetch(
break
;
break
;
stmt
->
rowset_start
+=
irow
;
stmt
->
rowset_start
+=
irow
;
break
;
break
;
case
SQL_FETCH_BOOKMARK
:
case
SQL_FETCH_BOOKMARK
:
stmt
->
rowset_start
=
irow
-
1
;
stmt
->
rowset_start
=
irow
-
1
;
break
;
break
;
default:
default:
SC_log_error
(
func
,
"Unsupported SQLExtendedFetch Direction"
,
stmt
);
SC_log_error
(
func
,
"Unsupported SQLExtendedFetch Direction"
,
stmt
);
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
/*
/***********************************/
* CHECK FOR PROPER CURSOR STATE
/* CHECK FOR PROPER CURSOR STATE */
*/
/***********************************/
/*
/*
* Handle Declare Fetch style specially because the end is not really
* Handle Declare Fetch style specially because the end is not really
...
@@ -1172,7 +1125,6 @@ SQLExtendedFetch(
...
@@ -1172,7 +1125,6 @@ SQLExtendedFetch(
truncated
=
error
=
FALSE
;
truncated
=
error
=
FALSE
;
for
(
i
=
0
;
i
<
stmt
->
options
.
rowset_size
;
i
++
)
for
(
i
=
0
;
i
<
stmt
->
options
.
rowset_size
;
i
++
)
{
{
stmt
->
bind_row
=
i
;
/* set the binding location */
stmt
->
bind_row
=
i
;
/* set the binding location */
result
=
SC_fetch
(
stmt
);
result
=
SC_fetch
(
stmt
);
...
@@ -1212,21 +1164,21 @@ SQLExtendedFetch(
...
@@ -1212,21 +1164,21 @@ SQLExtendedFetch(
*
pcrow
=
i
;
*
pcrow
=
i
;
if
(
i
==
0
)
if
(
i
==
0
)
return
SQL_NO_DATA_FOUND
;
/* Only DeclareFetch should wind
/* Only DeclareFetch should wind up here */
* up here */
return
SQL_NO_DATA_FOUND
;
else
if
(
error
)
else
if
(
error
)
return
SQL_ERROR
;
return
SQL_ERROR
;
else
if
(
truncated
)
else
if
(
truncated
)
return
SQL_SUCCESS_WITH_INFO
;
return
SQL_SUCCESS_WITH_INFO
;
else
else
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* This determines whether there are more results sets available for */
/*
/* the "hstmt". */
* This determines whether there are more results sets available for
* the "hstmt".
*/
/* CC: return SQL_NO_DATA_FOUND since we do not support multiple result sets */
/* CC: return SQL_NO_DATA_FOUND since we do not support multiple result sets */
RETCODE
SQL_API
RETCODE
SQL_API
SQLMoreResults
(
SQLMoreResults
(
...
@@ -1235,8 +1187,11 @@ SQLMoreResults(
...
@@ -1235,8 +1187,11 @@ SQLMoreResults(
return
SQL_NO_DATA_FOUND
;
return
SQL_NO_DATA_FOUND
;
}
}
/* This positions the cursor within a rowset, that was positioned using SQLExtendedFetch. */
/* This will be useful (so far) only when using SQLGetData after SQLExtendedFetch. */
/*
* This positions the cursor within a rowset, that was positioned using SQLExtendedFetch.
* This will be useful (so far) only when using SQLGetData after SQLExtendedFetch.
*/
RETCODE
SQL_API
RETCODE
SQL_API
SQLSetPos
(
SQLSetPos
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -1301,11 +1256,10 @@ SQLSetPos(
...
@@ -1301,11 +1256,10 @@ SQLSetPos(
stmt
->
currTuple
=
stmt
->
rowset_start
+
irow
;
stmt
->
currTuple
=
stmt
->
rowset_start
+
irow
;
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* Sets options that control the behavior of cursors. */
/* Sets options that control the behavior of cursors. */
RETCODE
SQL_API
RETCODE
SQL_API
SQLSetScrollOptions
(
SQLSetScrollOptions
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -1321,7 +1275,6 @@ SQLSetScrollOptions(
...
@@ -1321,7 +1275,6 @@ SQLSetScrollOptions(
/* Set the cursor name on a statement handle */
/* Set the cursor name on a statement handle */
RETCODE
SQL_API
RETCODE
SQL_API
SQLSetCursorName
(
SQLSetCursorName
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
@@ -1354,8 +1307,8 @@ SQLSetCursorName(
...
@@ -1354,8 +1307,8 @@ SQLSetCursorName(
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
}
}
/* Return the cursor name for a statement handle */
/* Return the cursor name for a statement handle */
RETCODE
SQL_API
RETCODE
SQL_API
SQLGetCursorName
(
SQLGetCursorName
(
HSTMT
hstmt
,
HSTMT
hstmt
,
...
...
src/interfaces/odbc/setup.c
View file @
296e7ba2
/* Module: setup.c
/*-------
* Module: setup.c
*
*
* Description: This module contains the setup functions for
* Description: This module contains the setup functions for
* adding/modifying a Data Source in the ODBC.INI portion
* adding/modifying a Data Source in the ODBC.INI portion
...
@@ -9,7 +10,7 @@
...
@@ -9,7 +10,7 @@
* API functions: ConfigDSN
* API functions: ConfigDSN
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#include "psqlodbc.h"
#include "psqlodbc.h"
...
@@ -28,7 +29,7 @@
...
@@ -28,7 +29,7 @@
extern
HINSTANCE
NEAR
s_hModule
;
/* Saved module handle. */
extern
HINSTANCE
NEAR
s_hModule
;
/* Saved module handle. */
extern
GLOBAL_VALUES
globals
;
extern
GLOBAL_VALUES
globals
;
/* Constants
---------------------------------------------------------------
*/
/* Constants */
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#ifdef WIN32
#ifdef WIN32
...
@@ -40,7 +41,7 @@ extern GLOBAL_VALUES globals;
...
@@ -40,7 +41,7 @@ extern GLOBAL_VALUES globals;
#define MAXDSNAME (32+1)
/* Max data source name length */
#define MAXDSNAME (32+1)
/* Max data source name length */
/* Globals
-----------------------------------------------------------------
*/
/* Globals */
/* NOTE: All these are used by the dialog procedures */
/* NOTE: All these are used by the dialog procedures */
typedef
struct
tagSETUPDLG
typedef
struct
tagSETUPDLG
{
{
...
@@ -55,24 +56,26 @@ typedef struct tagSETUPDLG
...
@@ -55,24 +56,26 @@ typedef struct tagSETUPDLG
/* Prototypes
--------------------------------------------------------------
*/
/* Prototypes */
void
INTFUNC
CenterDialog
(
HWND
hdlg
);
void
INTFUNC
CenterDialog
(
HWND
hdlg
);
int
CALLBACK
ConfigDlgProc
(
HWND
hdlg
,
WORD
wMsg
,
WPARAM
wParam
,
LPARAM
lParam
);
int
CALLBACK
ConfigDlgProc
(
HWND
hdlg
,
WORD
wMsg
,
WPARAM
wParam
,
LPARAM
lParam
);
void
INTFUNC
ParseAttributes
(
LPCSTR
lpszAttributes
,
LPSETUPDLG
lpsetupdlg
);
void
INTFUNC
ParseAttributes
(
LPCSTR
lpszAttributes
,
LPSETUPDLG
lpsetupdlg
);
BOOL
INTFUNC
SetDSNAttributes
(
HWND
hwnd
,
LPSETUPDLG
lpsetupdlg
);
BOOL
INTFUNC
SetDSNAttributes
(
HWND
hwnd
,
LPSETUPDLG
lpsetupdlg
);
/* ConfigDSN ---------------------------------------------------------------
/*--------
Description: ODBC Setup entry point
* ConfigDSN
This entry point is called by the ODBC Installer
*
(see file header for more details)
* Description: ODBC Setup entry point
Input : hwnd ----------- Parent window handle
* This entry point is called by the ODBC Installer
fRequest ------- Request type (i.e., add, config, or remove)
* (see file header for more details)
lpszDriver ----- Driver name
* Input : hwnd ----------- Parent window handle
lpszAttributes - data source attribute string
* fRequest ------- Request type (i.e., add, config, or remove)
Output : TRUE success, FALSE otherwise
* lpszDriver ----- Driver name
--------------------------------------------------------------------------*/
* lpszAttributes - data source attribute string
* Output : TRUE success, FALSE otherwise
*--------
*/
BOOL
CALLBACK
BOOL
CALLBACK
ConfigDSN
(
HWND
hwnd
,
ConfigDSN
(
HWND
hwnd
,
WORD
fRequest
,
WORD
fRequest
,
...
@@ -111,7 +114,6 @@ ConfigDSN(HWND hwnd,
...
@@ -111,7 +114,6 @@ ConfigDSN(HWND hwnd,
else
else
fSuccess
=
SQLRemoveDSNFromIni
(
lpsetupdlg
->
ci
.
dsn
);
fSuccess
=
SQLRemoveDSNFromIni
(
lpsetupdlg
->
ci
.
dsn
);
}
}
/* Add or Configure data source */
/* Add or Configure data source */
else
else
{
{
...
@@ -134,7 +136,6 @@ ConfigDSN(HWND hwnd,
...
@@ -134,7 +136,6 @@ ConfigDSN(HWND hwnd,
ConfigDlgProc
,
ConfigDlgProc
,
(
LONG
)
(
LPSTR
)
lpsetupdlg
));
(
LONG
)
(
LPSTR
)
lpsetupdlg
));
}
}
else
if
(
lpsetupdlg
->
ci
.
dsn
[
0
])
else
if
(
lpsetupdlg
->
ci
.
dsn
[
0
])
fSuccess
=
SetDSNAttributes
(
hwnd
,
lpsetupdlg
);
fSuccess
=
SetDSNAttributes
(
hwnd
,
lpsetupdlg
);
else
else
...
@@ -148,11 +149,14 @@ ConfigDSN(HWND hwnd,
...
@@ -148,11 +149,14 @@ ConfigDSN(HWND hwnd,
}
}
/* CenterDialog ------------------------------------------------------------
/*-------
Description: Center the dialog over the frame window
* CenterDialog
Input : hdlg -- Dialog window handle
*
Output : None
* Description: Center the dialog over the frame window
--------------------------------------------------------------------------*/
* Input : hdlg -- Dialog window handle
* Output : None
*-------
*/
void
INTFUNC
void
INTFUNC
CenterDialog
(
HWND
hdlg
)
CenterDialog
(
HWND
hdlg
)
{
{
...
@@ -198,23 +202,22 @@ CenterDialog(HWND hdlg)
...
@@ -198,23 +202,22 @@ CenterDialog(HWND hdlg)
return
;
return
;
}
}
/*
ConfigDlgProc ----------------------------------------------------
-------
/*-------
Description: Manage add data source name dialog
* ConfigDlgProc
Input : hdlg --- Dialog window handle
* Description: Manage add data source name dialog
wMsg --- Messag
e
* Input : hdlg --- Dialog window handl
e
wParam - Message parameter
* wMsg --- Message
l
Param - Message parameter
* w
Param - Message parameter
Output : TRUE if message processed, FALSE otherwise
* lParam - Message parameter
--------------------------------------------------------------------------*/
* Output : TRUE if message processed, FALSE otherwise
*-------
*/
int
CALLBACK
int
CALLBACK
ConfigDlgProc
(
HWND
hdlg
,
ConfigDlgProc
(
HWND
hdlg
,
WORD
wMsg
,
WORD
wMsg
,
WPARAM
wParam
,
WPARAM
wParam
,
LPARAM
lParam
)
LPARAM
lParam
)
{
{
switch
(
wMsg
)
switch
(
wMsg
)
{
{
/* Initialize the dialog */
/* Initialize the dialog */
...
@@ -241,11 +244,9 @@ ConfigDlgProc(HWND hdlg,
...
@@ -241,11 +244,9 @@ ConfigDlgProc(HWND hdlg,
/* Fill in any defaults */
/* Fill in any defaults */
getDSNdefaults
(
ci
);
getDSNdefaults
(
ci
);
/* Initialize dialog fields */
/* Initialize dialog fields */
SetDlgStuff
(
hdlg
,
ci
);
SetDlgStuff
(
hdlg
,
ci
);
if
(
lpsetupdlg
->
fDefault
)
if
(
lpsetupdlg
->
fDefault
)
{
{
EnableWindow
(
GetDlgItem
(
hdlg
,
IDC_DSNAME
),
FALSE
);
EnableWindow
(
GetDlgItem
(
hdlg
,
IDC_DSNAME
),
FALSE
);
...
@@ -260,13 +261,10 @@ ConfigDlgProc(HWND hdlg,
...
@@ -260,13 +261,10 @@ ConfigDlgProc(HWND hdlg,
return
TRUE
;
/* Focus was not set */
return
TRUE
;
/* Focus was not set */
}
}
/* Process buttons */
/* Process buttons */
case
WM_COMMAND
:
case
WM_COMMAND
:
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
switch
(
GET_WM_COMMAND_ID
(
wParam
,
lParam
))
{
{
/*
/*
* Ensure the OK button is enabled only when a data
* Ensure the OK button is enabled only when a data
* source name
* source name
...
@@ -281,7 +279,6 @@ ConfigDlgProc(HWND hdlg,
...
@@ -281,7 +279,6 @@ ConfigDlgProc(HWND hdlg,
EnableWindow
(
GetDlgItem
(
hdlg
,
IDOK
),
EnableWindow
(
GetDlgItem
(
hdlg
,
IDOK
),
GetDlgItemText
(
hdlg
,
IDC_DSNAME
,
GetDlgItemText
(
hdlg
,
IDC_DSNAME
,
szItem
,
sizeof
(
szItem
)));
szItem
,
sizeof
(
szItem
)));
return
TRUE
;
return
TRUE
;
}
}
break
;
break
;
...
@@ -297,8 +294,6 @@ ConfigDlgProc(HWND hdlg,
...
@@ -297,8 +294,6 @@ ConfigDlgProc(HWND hdlg,
GetDlgItemText
(
hdlg
,
IDC_DSNAME
,
GetDlgItemText
(
hdlg
,
IDC_DSNAME
,
lpsetupdlg
->
ci
.
dsn
,
lpsetupdlg
->
ci
.
dsn
,
sizeof
(
lpsetupdlg
->
ci
.
dsn
));
sizeof
(
lpsetupdlg
->
ci
.
dsn
));
/* Get Dialog Values */
/* Get Dialog Values */
GetDlgStuff
(
hdlg
,
&
lpsetupdlg
->
ci
);
GetDlgStuff
(
hdlg
,
&
lpsetupdlg
->
ci
);
...
@@ -312,7 +307,6 @@ ConfigDlgProc(HWND hdlg,
...
@@ -312,7 +307,6 @@ ConfigDlgProc(HWND hdlg,
return
TRUE
;
return
TRUE
;
case
IDC_DRIVER
:
case
IDC_DRIVER
:
DialogBoxParam
(
s_hModule
,
MAKEINTRESOURCE
(
DLG_OPTIONS_DRV
),
DialogBoxParam
(
s_hModule
,
MAKEINTRESOURCE
(
DLG_OPTIONS_DRV
),
hdlg
,
driver_optionsProc
,
(
LPARAM
)
NULL
);
hdlg
,
driver_optionsProc
,
(
LPARAM
)
NULL
);
...
@@ -330,7 +324,6 @@ ConfigDlgProc(HWND hdlg,
...
@@ -330,7 +324,6 @@ ConfigDlgProc(HWND hdlg,
return
TRUE
;
return
TRUE
;
}
}
}
}
break
;
break
;
}
}
...
@@ -339,11 +332,14 @@ ConfigDlgProc(HWND hdlg,
...
@@ -339,11 +332,14 @@ ConfigDlgProc(HWND hdlg,
}
}
/* ParseAttributes ---------------------------------------------------------
/*-------
Description: Parse attribute string moving values into the aAttr array
* ParseAttributes
Input : lpszAttributes - Pointer to attribute string
*
Output : None (global aAttr normally updated)
* Description: Parse attribute string moving values into the aAttr array
--------------------------------------------------------------------------*/
* Input : lpszAttributes - Pointer to attribute string
* Output : None (global aAttr normally updated)
*-------
*/
void
INTFUNC
void
INTFUNC
ParseAttributes
(
LPCSTR
lpszAttributes
,
LPSETUPDLG
lpsetupdlg
)
ParseAttributes
(
LPCSTR
lpszAttributes
,
LPSETUPDLG
lpsetupdlg
)
{
{
...
@@ -356,8 +352,8 @@ ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
...
@@ -356,8 +352,8 @@ ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
memset
(
&
lpsetupdlg
->
ci
,
0
,
sizeof
(
ConnInfo
));
memset
(
&
lpsetupdlg
->
ci
,
0
,
sizeof
(
ConnInfo
));
for
(
lpsz
=
lpszAttributes
;
*
lpsz
;
lpsz
++
)
for
(
lpsz
=
lpszAttributes
;
*
lpsz
;
lpsz
++
)
{
/* Extract key name (e.g., DSN), it must
{
*
be terminated by an equals */
/* Extract key name (e.g., DSN), it must
be terminated by an equals */
lpszStart
=
lpsz
;
lpszStart
=
lpsz
;
for
(;;
lpsz
++
)
for
(;;
lpsz
++
)
{
{
...
@@ -370,15 +366,14 @@ ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
...
@@ -370,15 +366,14 @@ ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
cbKey
=
lpsz
-
lpszStart
;
cbKey
=
lpsz
-
lpszStart
;
if
(
cbKey
<
sizeof
(
aszKey
))
if
(
cbKey
<
sizeof
(
aszKey
))
{
{
_fmemcpy
(
aszKey
,
lpszStart
,
cbKey
);
_fmemcpy
(
aszKey
,
lpszStart
,
cbKey
);
aszKey
[
cbKey
]
=
'\0'
;
aszKey
[
cbKey
]
=
'\0'
;
}
}
/* Locate end of key value */
/* Locate end of key value */
lpszStart
=
++
lpsz
;
lpszStart
=
++
lpsz
;
for
(;
*
lpsz
;
lpsz
++
)
;
for
(;
*
lpsz
;
lpsz
++
)
;
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
_fmemcpy
(
value
,
lpszStart
,
MIN
(
lpsz
-
lpszStart
+
1
,
MAXPGPATH
));
_fmemcpy
(
value
,
lpszStart
,
MIN
(
lpsz
-
lpszStart
+
1
,
MAXPGPATH
));
...
@@ -392,12 +387,14 @@ ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
...
@@ -392,12 +387,14 @@ ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
}
}
/* SetDSNAttributes --------------------------------------------------------
/*--------
Description: Write data source attributes to ODBC.INI
* SetDSNAttributes
Input : hwnd - Parent window handle (plus globals)
*
Output : TRUE if successful, FALSE otherwise
* Description: Write data source attributes to ODBC.INI
--------------------------------------------------------------------------*/
* Input : hwnd - Parent window handle (plus globals)
* Output : TRUE if successful, FALSE otherwise
*--------
*/
BOOL
INTFUNC
BOOL
INTFUNC
SetDSNAttributes
(
HWND
hwndParent
,
LPSETUPDLG
lpsetupdlg
)
SetDSNAttributes
(
HWND
hwndParent
,
LPSETUPDLG
lpsetupdlg
)
{
{
...
@@ -425,11 +422,9 @@ SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
...
@@ -425,11 +422,9 @@ SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
return
FALSE
;
return
FALSE
;
}
}
/* Update ODBC.INI */
/* Update ODBC.INI */
writeDSNinfo
(
&
lpsetupdlg
->
ci
);
writeDSNinfo
(
&
lpsetupdlg
->
ci
);
/* If the data source name has changed, remove the old name */
/* If the data source name has changed, remove the old name */
if
(
lstrcmpi
(
lpsetupdlg
->
szDSN
,
lpsetupdlg
->
ci
.
dsn
))
if
(
lstrcmpi
(
lpsetupdlg
->
szDSN
,
lpsetupdlg
->
ci
.
dsn
))
SQLRemoveDSNFromIni
(
lpsetupdlg
->
szDSN
);
SQLRemoveDSNFromIni
(
lpsetupdlg
->
szDSN
);
...
...
src/interfaces/odbc/socket.c
View file @
296e7ba2
/* Module: socket.c
/*-------
* Module: socket.c
*
*
* Description: This module contains functions for low level socket
* Description: This module contains functions for low level socket
* operations (connecting/reading/writing to the backend)
* operations (connecting/reading/writing to the backend)
...
@@ -8,7 +9,7 @@
...
@@ -8,7 +9,7 @@
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -42,6 +43,7 @@ SOCK_clear_error(SocketClass *self)
...
@@ -42,6 +43,7 @@ SOCK_clear_error(SocketClass *self)
self
->
errormsg
=
NULL
;
self
->
errormsg
=
NULL
;
}
}
SocketClass
*
SocketClass
*
SOCK_Constructor
()
SOCK_Constructor
()
{
{
...
@@ -70,16 +72,14 @@ SOCK_Constructor()
...
@@ -70,16 +72,14 @@ SOCK_Constructor()
free
(
rv
);
free
(
rv
);
return
NULL
;
return
NULL
;
}
}
rv
->
errormsg
=
NULL
;
rv
->
errormsg
=
NULL
;
rv
->
errornumber
=
0
;
rv
->
errornumber
=
0
;
rv
->
reverse
=
FALSE
;
rv
->
reverse
=
FALSE
;
}
}
return
rv
;
return
rv
;
}
}
void
void
SOCK_Destructor
(
SocketClass
*
self
)
SOCK_Destructor
(
SocketClass
*
self
)
{
{
...
@@ -97,7 +97,6 @@ SOCK_Destructor(SocketClass *self)
...
@@ -97,7 +97,6 @@ SOCK_Destructor(SocketClass *self)
free
(
self
->
buffer_out
);
free
(
self
->
buffer_out
);
free
(
self
);
free
(
self
);
}
}
...
@@ -149,7 +148,6 @@ SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
...
@@ -149,7 +148,6 @@ SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
if
(
connect
(
self
->
socket
,
(
struct
sockaddr
*
)
&
(
sadr
),
if
(
connect
(
self
->
socket
,
(
struct
sockaddr
*
)
&
(
sadr
),
sizeof
(
sadr
))
<
0
)
sizeof
(
sadr
))
<
0
)
{
{
self
->
errornumber
=
SOCKET_COULD_NOT_CONNECT
;
self
->
errornumber
=
SOCKET_COULD_NOT_CONNECT
;
self
->
errormsg
=
"Could not connect to remote socket."
;
self
->
errormsg
=
"Could not connect to remote socket."
;
closesocket
(
self
->
socket
);
closesocket
(
self
->
socket
);
...
@@ -194,9 +192,10 @@ SOCK_put_n_char(SocketClass *self, char *buffer, int len)
...
@@ -194,9 +192,10 @@ SOCK_put_n_char(SocketClass *self, char *buffer, int len)
}
}
/* bufsize must include room for the null terminator
/*
will read at most bufsize-1 characters + null.
* bufsize must include room for the null terminator
*/
* will read at most bufsize-1 characters + null.
*/
void
void
SOCK_get_string
(
SocketClass
*
self
,
char
*
buffer
,
int
bufsize
)
SOCK_get_string
(
SocketClass
*
self
,
char
*
buffer
,
int
bufsize
)
{
{
...
@@ -297,15 +296,16 @@ SOCK_flush_output(SocketClass *self)
...
@@ -297,15 +296,16 @@ SOCK_flush_output(SocketClass *self)
self
->
buffer_filled_out
=
0
;
self
->
buffer_filled_out
=
0
;
}
}
unsigned
char
unsigned
char
SOCK_get_next_byte
(
SocketClass
*
self
)
SOCK_get_next_byte
(
SocketClass
*
self
)
{
{
if
(
self
->
buffer_read_in
>=
self
->
buffer_filled_in
)
if
(
self
->
buffer_read_in
>=
self
->
buffer_filled_in
)
{
{
/* there are no more bytes left in the buffer so */
/*
/* reload the buffer */
* there are no more bytes left in the buffer so
* reload the buffer
*/
self
->
buffer_read_in
=
0
;
self
->
buffer_read_in
=
0
;
self
->
buffer_filled_in
=
recv
(
self
->
socket
,
(
char
*
)
self
->
buffer_in
,
globals
.
socket_buffersize
,
0
);
self
->
buffer_filled_in
=
recv
(
self
->
socket
,
(
char
*
)
self
->
buffer_in
,
globals
.
socket_buffersize
,
0
);
...
@@ -329,6 +329,7 @@ SOCK_get_next_byte(SocketClass *self)
...
@@ -329,6 +329,7 @@ SOCK_get_next_byte(SocketClass *self)
return
self
->
buffer_in
[
self
->
buffer_read_in
++
];
return
self
->
buffer_in
[
self
->
buffer_read_in
++
];
}
}
void
void
SOCK_put_next_byte
(
SocketClass
*
self
,
unsigned
char
next_byte
)
SOCK_put_next_byte
(
SocketClass
*
self
,
unsigned
char
next_byte
)
{
{
...
...
src/interfaces/odbc/statement.c
View file @
296e7ba2
/* Module: statement.c
/*-------
* Module: statement.c
*
*
* Description: This module contains functions related to creating
* Description: This module contains functions related to creating
* and manipulating a statement.
* and manipulating a statement.
...
@@ -8,7 +9,7 @@
...
@@ -8,7 +9,7 @@
* API functions: SQLAllocStmt, SQLFreeStmt
* API functions: SQLAllocStmt, SQLFreeStmt
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
...
@@ -44,6 +45,7 @@ extern GLOBAL_VALUES globals;
...
@@ -44,6 +45,7 @@ extern GLOBAL_VALUES globals;
#endif
#endif
#define PRN_NULLCHECK
#define PRN_NULLCHECK
/* Map sql commands to statement types */
/* Map sql commands to statement types */
static
struct
static
struct
{
{
...
@@ -126,12 +128,9 @@ SQLAllocStmt(HDBC hdbc,
...
@@ -126,12 +128,9 @@ SQLAllocStmt(HDBC hdbc,
*
phstmt
=
(
HSTMT
)
stmt
;
*
phstmt
=
(
HSTMT
)
stmt
;
/*
/* Copy default statement options based from Connection options */
* Copy default statement options based from Connection options
*/
stmt
->
options
=
conn
->
stmtOptions
;
stmt
->
options
=
conn
->
stmtOptions
;
/* Save the handle for later */
/* Save the handle for later */
stmt
->
phstmt
=
phstmt
;
stmt
->
phstmt
=
phstmt
;
...
@@ -180,29 +179,27 @@ SQLFreeStmt(HSTMT hstmt,
...
@@ -180,29 +179,27 @@ SQLFreeStmt(HSTMT hstmt,
/* Destroy the statement and free any results, cursors, etc. */
/* Destroy the statement and free any results, cursors, etc. */
SC_Destructor
(
stmt
);
SC_Destructor
(
stmt
);
}
}
else
if
(
fOption
==
SQL_UNBIND
)
else
if
(
fOption
==
SQL_UNBIND
)
{
{
SC_unbind_cols
(
stmt
);
SC_unbind_cols
(
stmt
);
}
}
else
if
(
fOption
==
SQL_CLOSE
)
else
if
(
fOption
==
SQL_CLOSE
)
{
{
/* this should discard all the results, but leave the statement */
/*
/* itself in place (it can be executed again) */
* this should discard all the results, but leave the statement
* itself in place (it can be executed again)
*/
if
(
!
SC_recycle_statement
(
stmt
))
if
(
!
SC_recycle_statement
(
stmt
))
{
{
/* errormsg passed in above */
/* errormsg passed in above */
SC_log_error
(
func
,
""
,
stmt
);
SC_log_error
(
func
,
""
,
stmt
);
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
}
}
else
if
(
fOption
==
SQL_RESET_PARAMS
)
else
if
(
fOption
==
SQL_RESET_PARAMS
)
{
{
SC_free_params
(
stmt
,
STMT_FREE_PARAMS_ALL
);
SC_free_params
(
stmt
,
STMT_FREE_PARAMS_ALL
);
}
}
else
else
{
{
...
@@ -216,8 +213,7 @@ SQLFreeStmt(HSTMT hstmt,
...
@@ -216,8 +213,7 @@ SQLFreeStmt(HSTMT hstmt,
}
}
/*
/**********************************************************************
* StatementClass implementation
* StatementClass implementation
*/
*/
void
void
...
@@ -234,6 +230,7 @@ InitializeStatementOptions(StatementOptions *opt)
...
@@ -234,6 +230,7 @@ InitializeStatementOptions(StatementOptions *opt)
opt
->
use_bookmarks
=
SQL_UB_OFF
;
opt
->
use_bookmarks
=
SQL_UB_OFF
;
}
}
StatementClass
*
StatementClass
*
SC_Constructor
(
void
)
SC_Constructor
(
void
)
{
{
...
@@ -288,7 +285,6 @@ SC_Constructor(void)
...
@@ -288,7 +285,6 @@ SC_Constructor(void)
rv
->
nfld
=
0
;
rv
->
nfld
=
0
;
rv
->
parse_status
=
STMT_PARSE_NONE
;
rv
->
parse_status
=
STMT_PARSE_NONE
;
/* Clear Statement Options -- defaults will be set in AllocStmt */
/* Clear Statement Options -- defaults will be set in AllocStmt */
memset
(
&
rv
->
options
,
0
,
sizeof
(
StatementOptions
));
memset
(
&
rv
->
options
,
0
,
sizeof
(
StatementOptions
));
...
@@ -298,10 +294,10 @@ SC_Constructor(void)
...
@@ -298,10 +294,10 @@ SC_Constructor(void)
return
rv
;
return
rv
;
}
}
char
char
SC_Destructor
(
StatementClass
*
self
)
SC_Destructor
(
StatementClass
*
self
)
{
{
mylog
(
"SC_Destructor: self=%u, self->result=%u, self->hdbc=%u
\n
"
,
self
,
self
->
result
,
self
->
hdbc
);
mylog
(
"SC_Destructor: self=%u, self->result=%u, self->hdbc=%u
\n
"
,
self
,
self
->
result
,
self
->
hdbc
);
if
(
STMT_EXECUTING
==
self
->
status
)
if
(
STMT_EXECUTING
==
self
->
status
)
{
{
...
@@ -325,18 +321,13 @@ SC_Destructor(StatementClass *self)
...
@@ -325,18 +321,13 @@ SC_Destructor(StatementClass *self)
/*
/*
* the memory pointed to by the bindings is not deallocated by the
* the memory pointed to by the bindings is not deallocated by the
* driver
* driver but by the application that uses that driver, so we don't have to
*/
/*
* by by the application that uses that driver, so we don't have to
* care
* care
*/
*/
/* about that here. */
/* about that here. */
if
(
self
->
bindings
)
if
(
self
->
bindings
)
free
(
self
->
bindings
);
free
(
self
->
bindings
);
/* Free the parsed table information */
/* Free the parsed table information */
if
(
self
->
ti
)
if
(
self
->
ti
)
{
{
...
@@ -358,7 +349,6 @@ SC_Destructor(StatementClass *self)
...
@@ -358,7 +349,6 @@ SC_Destructor(StatementClass *self)
free
(
self
->
fi
);
free
(
self
->
fi
);
}
}
free
(
self
);
free
(
self
);
mylog
(
"SC_Destructor: EXIT
\n
"
);
mylog
(
"SC_Destructor: EXIT
\n
"
);
...
@@ -366,9 +356,11 @@ SC_Destructor(StatementClass *self)
...
@@ -366,9 +356,11 @@ SC_Destructor(StatementClass *self)
return
TRUE
;
return
TRUE
;
}
}
/* Free parameters and free the memory from the
data-at-execution parameters that was allocated in SQLPutData.
/*
*/
* Free parameters and free the memory from the
* data-at-execution parameters that was allocated in SQLPutData.
*/
void
void
SC_free_params
(
StatementClass
*
self
,
char
option
)
SC_free_params
(
StatementClass
*
self
,
char
option
)
{
{
...
@@ -383,7 +375,6 @@ SC_free_params(StatementClass *self, char option)
...
@@ -383,7 +375,6 @@ SC_free_params(StatementClass *self, char option)
{
{
if
(
self
->
parameters
[
i
].
data_at_exec
==
TRUE
)
if
(
self
->
parameters
[
i
].
data_at_exec
==
TRUE
)
{
{
if
(
self
->
parameters
[
i
].
EXEC_used
)
if
(
self
->
parameters
[
i
].
EXEC_used
)
{
{
free
(
self
->
parameters
[
i
].
EXEC_used
);
free
(
self
->
parameters
[
i
].
EXEC_used
);
...
@@ -430,9 +421,10 @@ statement_type(char *statement)
...
@@ -430,9 +421,10 @@ statement_type(char *statement)
}
}
/* Called from SQLPrepare if STMT_PREMATURE, or
/*
from SQLExecute if STMT_FINISHED, or
* Called from SQLPrepare if STMT_PREMATURE, or
from SQLFreeStmt(SQL_CLOSE)
* from SQLExecute if STMT_FINISHED, or
* from SQLFreeStmt(SQL_CLOSE)
*/
*/
char
char
SC_recycle_statement
(
StatementClass
*
self
)
SC_recycle_statement
(
StatementClass
*
self
)
...
@@ -472,7 +464,6 @@ SC_recycle_statement(StatementClass *self)
...
@@ -472,7 +464,6 @@ SC_recycle_statement(StatementClass *self)
conn
=
SC_get_conn
(
self
);
conn
=
SC_get_conn
(
self
);
if
(
!
CC_is_in_autocommit
(
conn
)
&&
CC_is_in_trans
(
conn
))
if
(
!
CC_is_in_autocommit
(
conn
)
&&
CC_is_in_trans
(
conn
))
{
{
QResultClass
*
res
=
CC_send_query
(
conn
,
"ABORT"
,
NULL
);
QResultClass
*
res
=
CC_send_query
(
conn
,
"ABORT"
,
NULL
);
QR_Destructor
(
res
);
QR_Destructor
(
res
);
...
@@ -523,10 +514,9 @@ SC_recycle_statement(StatementClass *self)
...
@@ -523,10 +514,9 @@ SC_recycle_statement(StatementClass *self)
}
}
self
->
inaccurate_result
=
FALSE
;
self
->
inaccurate_result
=
FALSE
;
/****************************************************************/
/*
/* Reset only parameters that have anything to do with results */
* Reset only parameters that have anything to do with results
/****************************************************************/
*/
self
->
status
=
STMT_READY
;
self
->
status
=
STMT_READY
;
self
->
manual_result
=
FALSE
;
/* very important */
self
->
manual_result
=
FALSE
;
/* very important */
...
@@ -542,14 +532,17 @@ SC_recycle_statement(StatementClass *self)
...
@@ -542,14 +532,17 @@ SC_recycle_statement(StatementClass *self)
self
->
lobj_fd
=
-
1
;
self
->
lobj_fd
=
-
1
;
/* Free any data at exec params before the statement is executed */
/*
/* again. If not, then there will be a memory leak when */
* Free any data at exec params before the statement is executed
/* the next SQLParamData/SQLPutData is called. */
* again. If not, then there will be a memory leak when
* the next SQLParamData/SQLPutData is called.
*/
SC_free_params
(
self
,
STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY
);
SC_free_params
(
self
,
STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY
);
return
TRUE
;
return
TRUE
;
}
}
/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */
/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */
void
void
SC_pre_execute
(
StatementClass
*
self
)
SC_pre_execute
(
StatementClass
*
self
)
...
@@ -586,6 +579,7 @@ SC_pre_execute(StatementClass *self)
...
@@ -586,6 +579,7 @@ SC_pre_execute(StatementClass *self)
}
}
}
}
/* This is only called from SQLFreeStmt(SQL_UNBIND) */
/* This is only called from SQLFreeStmt(SQL_UNBIND) */
char
char
SC_unbind_cols
(
StatementClass
*
self
)
SC_unbind_cols
(
StatementClass
*
self
)
...
@@ -607,6 +601,7 @@ SC_unbind_cols(StatementClass *self)
...
@@ -607,6 +601,7 @@ SC_unbind_cols(StatementClass *self)
return
1
;
return
1
;
}
}
void
void
SC_clear_error
(
StatementClass
*
self
)
SC_clear_error
(
StatementClass
*
self
)
{
{
...
@@ -616,8 +611,10 @@ SC_clear_error(StatementClass *self)
...
@@ -616,8 +611,10 @@ SC_clear_error(StatementClass *self)
}
}
/* This function creates an error msg which is the concatenation */
/*
/* of the result, statement, connection, and socket messages. */
* This function creates an error msg which is the concatenation
* of the result, statement, connection, and socket messages.
*/
char
*
char
*
SC_create_errormsg
(
StatementClass
*
self
)
SC_create_errormsg
(
StatementClass
*
self
)
{
{
...
@@ -654,12 +651,13 @@ SC_create_errormsg(StatementClass *self)
...
@@ -654,12 +651,13 @@ SC_create_errormsg(StatementClass *self)
return
msg
;
return
msg
;
}
}
char
char
SC_get_error
(
StatementClass
*
self
,
int
*
number
,
char
**
message
)
SC_get_error
(
StatementClass
*
self
,
int
*
number
,
char
**
message
)
{
{
char
rv
;
char
rv
;
/* Create a very informative errormsg if it hasn't been done yet. */
/* Create a very informative errormsg if it hasn't been done yet. */
if
(
!
self
->
errormsg_created
)
if
(
!
self
->
errormsg_created
)
{
{
self
->
errormsg
=
SC_create_errormsg
(
self
);
self
->
errormsg
=
SC_create_errormsg
(
self
);
...
@@ -679,16 +677,19 @@ SC_get_error(StatementClass *self, int *number, char **message)
...
@@ -679,16 +677,19 @@ SC_get_error(StatementClass *self, int *number, char **message)
return
rv
;
return
rv
;
}
}
/* Currently, the driver offers very simple bookmark support -- it is
just the current row number. But it could be more sophisticated
/*
someday, such as mapping a key to a 32 bit value
* Currently, the driver offers very simple bookmark support -- it is
*/
* just the current row number. But it could be more sophisticated
* someday, such as mapping a key to a 32 bit value
*/
unsigned
long
unsigned
long
SC_get_bookmark
(
StatementClass
*
self
)
SC_get_bookmark
(
StatementClass
*
self
)
{
{
return
(
self
->
currTuple
+
1
);
return
(
self
->
currTuple
+
1
);
}
}
RETCODE
RETCODE
SC_fetch
(
StatementClass
*
self
)
SC_fetch
(
StatementClass
*
self
)
{
{
...
@@ -702,7 +703,7 @@ SC_fetch(StatementClass *self)
...
@@ -702,7 +703,7 @@ SC_fetch(StatementClass *self)
char
*
value
;
char
*
value
;
ColumnInfoClass
*
ci
;
ColumnInfoClass
*
ci
;
/* TupleField *tupleField; */
/* TupleField *tupleField; */
self
->
last_fetch_count
=
0
;
self
->
last_fetch_count
=
0
;
ci
=
QR_get_fields
(
res
);
/* the column info */
ci
=
QR_get_fields
(
res
);
/* the column info */
...
@@ -711,11 +712,9 @@ SC_fetch(StatementClass *self)
...
@@ -711,11 +712,9 @@ SC_fetch(StatementClass *self)
if
(
self
->
manual_result
||
!
globals
.
use_declarefetch
)
if
(
self
->
manual_result
||
!
globals
.
use_declarefetch
)
{
{
if
(
self
->
currTuple
>=
QR_get_num_tuples
(
res
)
-
1
||
if
(
self
->
currTuple
>=
QR_get_num_tuples
(
res
)
-
1
||
(
self
->
options
.
maxRows
>
0
&&
self
->
currTuple
==
self
->
options
.
maxRows
-
1
))
(
self
->
options
.
maxRows
>
0
&&
self
->
currTuple
==
self
->
options
.
maxRows
-
1
))
{
{
/*
/*
* if at the end of the tuples, return "no data found" and set
* if at the end of the tuples, return "no data found" and set
* the cursor past the end of the result set
* the cursor past the end of the result set
...
@@ -729,7 +728,6 @@ SC_fetch(StatementClass *self)
...
@@ -729,7 +728,6 @@ SC_fetch(StatementClass *self)
}
}
else
else
{
{
/* read from the cache or the physical next tuple */
/* read from the cache or the physical next tuple */
retval
=
QR_next_tuple
(
res
);
retval
=
QR_next_tuple
(
res
);
if
(
retval
<
0
)
if
(
retval
<
0
)
...
@@ -739,7 +737,6 @@ SC_fetch(StatementClass *self)
...
@@ -739,7 +737,6 @@ SC_fetch(StatementClass *self)
}
}
else
if
(
retval
>
0
)
else
if
(
retval
>
0
)
(
self
->
currTuple
)
++
;
/* all is well */
(
self
->
currTuple
)
++
;
/* all is well */
else
else
{
{
mylog
(
"SQLFetch: error
\n
"
);
mylog
(
"SQLFetch: error
\n
"
);
...
@@ -772,7 +769,6 @@ SC_fetch(StatementClass *self)
...
@@ -772,7 +769,6 @@ SC_fetch(StatementClass *self)
for
(
lf
=
0
;
lf
<
num_cols
;
lf
++
)
for
(
lf
=
0
;
lf
<
num_cols
;
lf
++
)
{
{
mylog
(
"fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u
\n
"
,
num_cols
,
lf
,
self
,
self
->
bindings
,
self
->
bindings
[
lf
].
buffer
);
mylog
(
"fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u
\n
"
,
num_cols
,
lf
,
self
,
self
->
bindings
,
self
->
bindings
[
lf
].
buffer
);
/* reset for SQLGetData */
/* reset for SQLGetData */
...
@@ -828,8 +824,8 @@ SC_fetch(StatementClass *self)
...
@@ -828,8 +824,8 @@ SC_fetch(StatementClass *self)
result
=
SQL_SUCCESS_WITH_INFO
;
result
=
SQL_SUCCESS_WITH_INFO
;
break
;
break
;
case
COPY_GENERAL_ERROR
:
/* error msg already
/* error msg already filled in */
* filled in */
case
COPY_GENERAL_ERROR
:
SC_log_error
(
func
,
""
,
self
);
SC_log_error
(
func
,
""
,
self
);
result
=
SQL_ERROR
;
result
=
SQL_ERROR
;
break
;
break
;
...
@@ -908,13 +904,10 @@ SC_execute(StatementClass *self)
...
@@ -908,13 +904,10 @@ SC_execute(StatementClass *self)
CC_set_in_trans
(
conn
);
CC_set_in_trans
(
conn
);
}
}
oldstatus
=
conn
->
status
;
oldstatus
=
conn
->
status
;
conn
->
status
=
CONN_EXECUTING
;
conn
->
status
=
CONN_EXECUTING
;
self
->
status
=
STMT_EXECUTING
;
self
->
status
=
STMT_EXECUTING
;
/* If it's a SELECT statement, use a cursor. */
/* If it's a SELECT statement, use a cursor. */
/*
/*
...
@@ -924,19 +917,16 @@ SC_execute(StatementClass *self)
...
@@ -924,19 +917,16 @@ SC_execute(StatementClass *self)
/* in copy_statement... */
/* in copy_statement... */
if
(
self
->
statement_type
==
STMT_TYPE_SELECT
)
if
(
self
->
statement_type
==
STMT_TYPE_SELECT
)
{
{
char
fetch
[
128
];
char
fetch
[
128
];
mylog
(
" Sending SELECT statement on stmt=%u, cursor_name='%s'
\n
"
,
self
,
self
->
cursor_name
);
mylog
(
" Sending SELECT statement on stmt=%u, cursor_name='%s'
\n
"
,
self
,
self
->
cursor_name
);
/* send the declare/select */
/* send the declare/select */
self
->
result
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
);
self
->
result
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
);
if
(
globals
.
use_declarefetch
&&
self
->
result
!=
NULL
&&
if
(
globals
.
use_declarefetch
&&
self
->
result
!=
NULL
&&
QR_command_successful
(
self
->
result
))
QR_command_successful
(
self
->
result
))
{
{
QR_Destructor
(
self
->
result
);
QR_Destructor
(
self
->
result
);
/*
/*
...
@@ -954,20 +944,15 @@ SC_execute(StatementClass *self)
...
@@ -954,20 +944,15 @@ SC_execute(StatementClass *self)
* will correct for any discrepancies in sizes and adjust the
* will correct for any discrepancies in sizes and adjust the
* cache accordingly.
* cache accordingly.
*/
*/
sprintf
(
fetch
,
"fetch %d in %s"
,
qi
.
row_size
,
self
->
cursor_name
);
sprintf
(
fetch
,
"fetch %d in %s"
,
qi
.
row_size
,
self
->
cursor_name
);
self
->
result
=
CC_send_query
(
conn
,
fetch
,
&
qi
);
self
->
result
=
CC_send_query
(
conn
,
fetch
,
&
qi
);
}
}
mylog
(
" done sending the query:
\n
"
);
mylog
(
" done sending the query:
\n
"
);
}
}
else
else
{
/* not a SELECT statement so don't use a
{
*
cursor */
/* not a SELECT statement so don't use a
cursor */
mylog
(
" it's NOT a select statement: stmt=%u
\n
"
,
self
);
mylog
(
" it's NOT a select statement: stmt=%u
\n
"
,
self
);
self
->
result
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
);
self
->
result
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
);
...
@@ -986,7 +971,6 @@ SC_execute(StatementClass *self)
...
@@ -986,7 +971,6 @@ SC_execute(StatementClass *self)
QR_Destructor
(
res
);
QR_Destructor
(
res
);
CC_set_no_trans
(
conn
);
CC_set_no_trans
(
conn
);
}
}
}
}
conn
->
status
=
oldstatus
;
conn
->
status
=
oldstatus
;
...
@@ -995,7 +979,6 @@ SC_execute(StatementClass *self)
...
@@ -995,7 +979,6 @@ SC_execute(StatementClass *self)
/* Check the status of the result */
/* Check the status of the result */
if
(
self
->
result
)
if
(
self
->
result
)
{
{
was_ok
=
QR_command_successful
(
self
->
result
);
was_ok
=
QR_command_successful
(
self
->
result
);
was_nonfatal
=
QR_command_nonfatal
(
self
->
result
);
was_nonfatal
=
QR_command_nonfatal
(
self
->
result
);
...
@@ -1004,8 +987,8 @@ SC_execute(StatementClass *self)
...
@@ -1004,8 +987,8 @@ SC_execute(StatementClass *self)
else
else
self
->
errornumber
=
was_nonfatal
?
STMT_INFO_ONLY
:
STMT_ERROR_TAKEN_FROM_BACKEND
;
self
->
errornumber
=
was_nonfatal
?
STMT_INFO_ONLY
:
STMT_ERROR_TAKEN_FROM_BACKEND
;
self
->
currTuple
=
-
1
;
/* set cursor before the first tuple in
/* set cursor before the first tuple in the list */
* the list */
self
->
currTuple
=
-
1
;
self
->
current_col
=
-
1
;
self
->
current_col
=
-
1
;
self
->
rowset_start
=
-
1
;
self
->
rowset_start
=
-
1
;
...
@@ -1029,9 +1012,8 @@ SC_execute(StatementClass *self)
...
@@ -1029,9 +1012,8 @@ SC_execute(StatementClass *self)
CC_abort
(
conn
);
CC_abort
(
conn
);
}
}
else
else
{
/* Bad Error -- The error message will be
{
* in the Connection */
/* Bad Error -- The error message will be in the Connection */
if
(
self
->
statement_type
==
STMT_TYPE_CREATE
)
if
(
self
->
statement_type
==
STMT_TYPE_CREATE
)
{
{
self
->
errornumber
=
STMT_CREATE_TABLE_ERROR
;
self
->
errornumber
=
STMT_CREATE_TABLE_ERROR
;
...
@@ -1069,6 +1051,7 @@ SC_execute(StatementClass *self)
...
@@ -1069,6 +1051,7 @@ SC_execute(StatementClass *self)
}
}
}
}
void
void
SC_log_error
(
char
*
func
,
char
*
desc
,
StatementClass
*
self
)
SC_log_error
(
char
*
func
,
char
*
desc
,
StatementClass
*
self
)
{
{
...
...
src/interfaces/odbc/tuple.c
View file @
296e7ba2
/* Module: tuple.c
/*-------
* Module: tuple.c
*
*
* Description: This module contains functions for setting the data for individual
* Description: This module contains functions for setting the data
* fields (TupleField structure) of a manual result set.
* for individual fields (TupleField structure) of a
* manual result set.
*
*
* Important Note: These functions are ONLY used in building manual result sets for
* Important Note: These functions are ONLY used in building manual
* info functions (SQLTables, SQLColumns, etc.)
* result sets for info functions (SQLTables,
* SQLColumns, etc.)
*
*
* Classes: n/a
* Classes: n/a
*
*
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
-------
*/
*/
#include "tuple.h"
#include "tuple.h"
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
void
void
set_tuplefield_null
(
TupleField
*
tuple_field
)
set_tuplefield_null
(
TupleField
*
tuple_field
)
{
{
...
@@ -25,6 +29,7 @@ set_tuplefield_null(TupleField *tuple_field)
...
@@ -25,6 +29,7 @@ set_tuplefield_null(TupleField *tuple_field)
tuple_field
->
value
=
NULL
;
/* strdup(""); */
tuple_field
->
value
=
NULL
;
/* strdup(""); */
}
}
void
void
set_tuplefield_string
(
TupleField
*
tuple_field
,
char
*
string
)
set_tuplefield_string
(
TupleField
*
tuple_field
,
char
*
string
)
{
{
...
@@ -39,7 +44,6 @@ set_tuplefield_int2(TupleField *tuple_field, Int2 value)
...
@@ -39,7 +44,6 @@ set_tuplefield_int2(TupleField *tuple_field, Int2 value)
{
{
char
buffer
[
10
];
char
buffer
[
10
];
sprintf
(
buffer
,
"%d"
,
value
);
sprintf
(
buffer
,
"%d"
,
value
);
tuple_field
->
len
=
strlen
(
buffer
)
+
1
;
tuple_field
->
len
=
strlen
(
buffer
)
+
1
;
...
@@ -47,6 +51,7 @@ set_tuplefield_int2(TupleField *tuple_field, Int2 value)
...
@@ -47,6 +51,7 @@ set_tuplefield_int2(TupleField *tuple_field, Int2 value)
tuple_field
->
value
=
strdup
(
buffer
);
tuple_field
->
value
=
strdup
(
buffer
);
}
}
void
void
set_tuplefield_int4
(
TupleField
*
tuple_field
,
Int4
value
)
set_tuplefield_int4
(
TupleField
*
tuple_field
,
Int4
value
)
{
{
...
...
src/interfaces/odbc/tuplelist.c
View file @
296e7ba2
/* Module: tuplelist.c
/*--------
* Module: tuplelist.c
*
*
* Description: This module contains functions for creating a manual result set
* Description: This module contains functions for creating a manual
* (the TupleList) and retrieving data from it for a specific row/column.
* result set (the TupleList) and retrieving data from
* it for a specific row/column.
*
*
* Classes: TupleListClass (Functions prefix: "TL_")
* Classes: TupleListClass (Functions prefix: "TL_")
*
*
* API functions: none
* API functions: none
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
--------
*/
*/
#include <stdlib.h>
#include <stdlib.h>
#include "tuplelist.h"
#include "tuplelist.h"
#include "tuple.h"
#include "tuple.h"
TupleListClass
*
TupleListClass
*
TL_Constructor
(
UInt4
fieldcnt
)
TL_Constructor
(
UInt4
fieldcnt
)
{
{
...
@@ -25,7 +28,6 @@ TL_Constructor(UInt4 fieldcnt)
...
@@ -25,7 +28,6 @@ TL_Constructor(UInt4 fieldcnt)
rv
=
(
TupleListClass
*
)
malloc
(
sizeof
(
TupleListClass
));
rv
=
(
TupleListClass
*
)
malloc
(
sizeof
(
TupleListClass
));
if
(
rv
)
if
(
rv
)
{
{
rv
->
num_fields
=
fieldcnt
;
rv
->
num_fields
=
fieldcnt
;
rv
->
num_tuples
=
0
;
rv
->
num_tuples
=
0
;
rv
->
list_start
=
NULL
;
rv
->
list_start
=
NULL
;
...
@@ -39,6 +41,7 @@ TL_Constructor(UInt4 fieldcnt)
...
@@ -39,6 +41,7 @@ TL_Constructor(UInt4 fieldcnt)
return
rv
;
return
rv
;
}
}
void
void
TL_Destructor
(
TupleListClass
*
self
)
TL_Destructor
(
TupleListClass
*
self
)
{
{
...
@@ -134,7 +137,6 @@ TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
...
@@ -134,7 +137,6 @@ TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
}
}
else
if
(
start_is_closer
)
else
if
(
start_is_closer
)
{
{
/*
/*
* the shortest way is to start the search from the head of the
* the shortest way is to start the search from the head of the
* list
* list
...
@@ -177,11 +179,9 @@ TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
...
@@ -177,11 +179,9 @@ TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
}
}
char
char
TL_add_tuple
(
TupleListClass
*
self
,
TupleNode
*
new_field
)
TL_add_tuple
(
TupleListClass
*
self
,
TupleNode
*
new_field
)
{
{
/*
/*
* we append the tuple at the end of the doubly linked list of the
* we append the tuple at the end of the doubly linked list of the
* tuples we have already read in
* tuples we have already read in
...
@@ -200,7 +200,6 @@ TL_add_tuple(TupleListClass *self, TupleNode *new_field)
...
@@ -200,7 +200,6 @@ TL_add_tuple(TupleListClass *self, TupleNode *new_field)
}
}
else
else
{
{
/*
/*
* there is already an element in the list, so add the new one at
* there is already an element in the list, so add the new one at
* the end of the list
* the end of the list
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment