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
01e32265
Commit
01e32265
authored
Mar 14, 2002
by
Hiroshi Inoue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1) Internal improvements to handle updatable cursors(1st cut).
2) Fix a bug in SQLColAttribute().
parent
f362dcec
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
414 additions
and
372 deletions
+414
-372
src/interfaces/odbc/connection.c
src/interfaces/odbc/connection.c
+14
-8
src/interfaces/odbc/connection.h
src/interfaces/odbc/connection.h
+4
-1
src/interfaces/odbc/convert.c
src/interfaces/odbc/convert.c
+22
-2
src/interfaces/odbc/environ.c
src/interfaces/odbc/environ.c
+3
-0
src/interfaces/odbc/execute.c
src/interfaces/odbc/execute.c
+18
-3
src/interfaces/odbc/info.c
src/interfaces/odbc/info.c
+14
-14
src/interfaces/odbc/info30.c
src/interfaces/odbc/info30.c
+18
-13
src/interfaces/odbc/multibyte.c
src/interfaces/odbc/multibyte.c
+1
-1
src/interfaces/odbc/odbcapi30.c
src/interfaces/odbc/odbcapi30.c
+4
-164
src/interfaces/odbc/options.c
src/interfaces/odbc/options.c
+31
-54
src/interfaces/odbc/parse.c
src/interfaces/odbc/parse.c
+28
-10
src/interfaces/odbc/psqlodbc.h
src/interfaces/odbc/psqlodbc.h
+2
-1
src/interfaces/odbc/psqlodbc_api30.def
src/interfaces/odbc/psqlodbc_api30.def
+1
-1
src/interfaces/odbc/psqlodbc_api30w.def
src/interfaces/odbc/psqlodbc_api30w.def
+1
-1
src/interfaces/odbc/qresult.c
src/interfaces/odbc/qresult.c
+30
-2
src/interfaces/odbc/qresult.h
src/interfaces/odbc/qresult.h
+4
-0
src/interfaces/odbc/results.c
src/interfaces/odbc/results.c
+181
-78
src/interfaces/odbc/statement.c
src/interfaces/odbc/statement.c
+19
-19
src/interfaces/odbc/statement.h
src/interfaces/odbc/statement.h
+6
-0
src/interfaces/odbc/tuple.h
src/interfaces/odbc/tuple.h
+13
-0
No files found.
src/interfaces/odbc/connection.c
View file @
01e32265
...
@@ -374,7 +374,7 @@ CC_begin(ConnectionClass *self)
...
@@ -374,7 +374,7 @@ CC_begin(ConnectionClass *self)
char
ret
=
TRUE
;
char
ret
=
TRUE
;
if
(
!
CC_is_in_trans
(
self
))
if
(
!
CC_is_in_trans
(
self
))
{
{
QResultClass
*
res
=
CC_send_query
(
self
,
"BEGIN"
,
NULL
,
TRUE
);
QResultClass
*
res
=
CC_send_query
(
self
,
"BEGIN"
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
mylog
(
"CC_begin: sending BEGIN!
\n
"
);
mylog
(
"CC_begin: sending BEGIN!
\n
"
);
if
(
res
!=
NULL
)
if
(
res
!=
NULL
)
...
@@ -401,7 +401,7 @@ CC_commit(ConnectionClass *self)
...
@@ -401,7 +401,7 @@ CC_commit(ConnectionClass *self)
char
ret
=
FALSE
;
char
ret
=
FALSE
;
if
(
CC_is_in_trans
(
self
))
if
(
CC_is_in_trans
(
self
))
{
{
QResultClass
*
res
=
CC_send_query
(
self
,
"COMMIT"
,
NULL
,
TRUE
);
QResultClass
*
res
=
CC_send_query
(
self
,
"COMMIT"
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
mylog
(
"CC_commit: sending COMMIT!
\n
"
);
mylog
(
"CC_commit: sending COMMIT!
\n
"
);
CC_set_no_trans
(
self
);
CC_set_no_trans
(
self
);
...
@@ -427,7 +427,7 @@ CC_abort(ConnectionClass *self)
...
@@ -427,7 +427,7 @@ CC_abort(ConnectionClass *self)
{
{
if
(
CC_is_in_trans
(
self
))
if
(
CC_is_in_trans
(
self
))
{
{
QResultClass
*
res
=
CC_send_query
(
self
,
"ROLLBACK"
,
NULL
,
TRUE
);
QResultClass
*
res
=
CC_send_query
(
self
,
"ROLLBACK"
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
mylog
(
"CC_abort: sending ABORT!
\n
"
);
mylog
(
"CC_abort: sending ABORT!
\n
"
);
CC_set_no_trans
(
self
);
CC_set_no_trans
(
self
);
...
@@ -919,7 +919,7 @@ another_version_retry:
...
@@ -919,7 +919,7 @@ another_version_retry:
*/
*/
mylog
(
"sending an empty query...
\n
"
);
mylog
(
"sending an empty query...
\n
"
);
res
=
CC_send_query
(
self
,
" "
,
NULL
,
TRUE
);
res
=
CC_send_query
(
self
,
" "
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
if
(
res
==
NULL
||
QR_get_status
(
res
)
!=
PGRES_EMPTY_QUERY
)
if
(
res
==
NULL
||
QR_get_status
(
res
)
!=
PGRES_EMPTY_QUERY
)
{
{
mylog
(
"got no result from the empty query. (probably database does not exist)
\n
"
);
mylog
(
"got no result from the empty query. (probably database does not exist)
\n
"
);
...
@@ -956,7 +956,7 @@ another_version_retry:
...
@@ -956,7 +956,7 @@ another_version_retry:
* Multibyte handling is available ?
* Multibyte handling is available ?
*/
*/
#ifdef MULTIBYTE
#ifdef MULTIBYTE
if
(
PG_VERSION_GE
(
self
,
7
.
0
))
if
(
PG_VERSION_GE
(
self
,
6
.
4
))
{
{
CC_lookup_characterset
(
self
);
CC_lookup_characterset
(
self
);
if
(
self
->
errornumber
!=
0
)
if
(
self
->
errornumber
!=
0
)
...
@@ -977,7 +977,7 @@ another_version_retry:
...
@@ -977,7 +977,7 @@ another_version_retry:
if
(
self
->
client_encoding
)
if
(
self
->
client_encoding
)
free
(
self
->
client_encoding
);
free
(
self
->
client_encoding
);
self
->
client_encoding
=
NULL
;
self
->
client_encoding
=
NULL
;
if
(
res
=
CC_send_query
(
self
,
"set client_encoding to 'UTF8'"
,
NULL
,
TRUE
),
res
)
if
(
res
=
CC_send_query
(
self
,
"set client_encoding to 'UTF8'"
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
res
)
{
{
self
->
client_encoding
=
strdup
(
"UNICODE"
);
self
->
client_encoding
=
strdup
(
"UNICODE"
);
QR_Destructor
(
res
);
QR_Destructor
(
res
);
...
@@ -991,7 +991,7 @@ another_version_retry:
...
@@ -991,7 +991,7 @@ another_version_retry:
else
if
(
self
->
unicode
)
else
if
(
self
->
unicode
)
{
{
self
->
errornumber
=
CONN_NOT_IMPLEMENTED_ERROR
;
self
->
errornumber
=
CONN_NOT_IMPLEMENTED_ERROR
;
self
->
errormsg
=
"Unicode isn't supported before
7.0
"
;
self
->
errormsg
=
"Unicode isn't supported before
6.4
"
;
return
0
;
return
0
;
}
}
#endif
/* UNICODE_SUPPORT */
#endif
/* UNICODE_SUPPORT */
...
@@ -1128,12 +1128,14 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
...
@@ -1128,12 +1128,14 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
* 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
* 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
*/
*/
QResultClass
*
QResultClass
*
CC_send_query
(
ConnectionClass
*
self
,
char
*
query
,
QueryInfo
*
qi
,
BOOL
clear_result_on_abort
)
CC_send_query
(
ConnectionClass
*
self
,
char
*
query
,
QueryInfo
*
qi
,
UDWORD
flag
)
{
{
QResultClass
*
result_in
=
NULL
,
QResultClass
*
result_in
=
NULL
,
*
cmdres
=
NULL
,
*
cmdres
=
NULL
,
*
retres
=
NULL
,
*
retres
=
NULL
,
*
res
=
NULL
;
*
res
=
NULL
;
BOOL
clear_result_on_abort
=
((
flag
&
CLEAR_RESULT_ON_ABORT
)
!=
0
),
create_keyset
=
((
flag
&
CREATE_KEYSET
)
!=
0
);
char
swallow
,
char
swallow
,
*
wq
;
*
wq
;
int
id
;
int
id
;
...
@@ -1376,6 +1378,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
...
@@ -1376,6 +1378,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
if
(
query_completed
)
if
(
query_completed
)
{
{
res
->
next
=
QR_Constructor
();
res
->
next
=
QR_Constructor
();
if
(
create_keyset
)
QR_set_haskeyset
(
res
->
next
);
mylog
(
"send_query: 'T' no result_in: res = %u
\n
"
,
res
->
next
);
mylog
(
"send_query: 'T' no result_in: res = %u
\n
"
,
res
->
next
);
if
(
!
res
->
next
)
if
(
!
res
->
next
)
{
{
...
@@ -1392,6 +1396,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
...
@@ -1392,6 +1396,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_resu
}
}
if
(
!
used_passed_result_object
)
if
(
!
used_passed_result_object
)
{
{
if
(
create_keyset
)
QR_set_haskeyset
(
res
);
if
(
!
QR_fetch_tuples
(
res
,
self
,
qi
?
qi
->
cursor
:
NULL
))
if
(
!
QR_fetch_tuples
(
res
,
self
,
qi
?
qi
->
cursor
:
NULL
))
{
{
self
->
errornumber
=
CONNECTION_COULD_NOT_RECEIVE
;
self
->
errornumber
=
CONNECTION_COULD_NOT_RECEIVE
;
...
...
src/interfaces/odbc/connection.h
View file @
01e32265
...
@@ -305,7 +305,7 @@ char CC_connect(ConnectionClass *self, char do_password);
...
@@ -305,7 +305,7 @@ char CC_connect(ConnectionClass *self, char do_password);
char
CC_add_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
);
char
CC_add_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
);
char
CC_remove_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
);
char
CC_remove_statement
(
ConnectionClass
*
self
,
StatementClass
*
stmt
);
char
CC_get_error
(
ConnectionClass
*
self
,
int
*
number
,
char
**
message
);
char
CC_get_error
(
ConnectionClass
*
self
,
int
*
number
,
char
**
message
);
QResultClass
*
CC_send_query
(
ConnectionClass
*
self
,
char
*
query
,
QueryInfo
*
qi
,
BOOL
);
QResultClass
*
CC_send_query
(
ConnectionClass
*
self
,
char
*
query
,
QueryInfo
*
qi
,
UDWORD
flag
);
void
CC_clear_error
(
ConnectionClass
*
self
);
void
CC_clear_error
(
ConnectionClass
*
self
);
char
*
CC_create_errormsg
(
ConnectionClass
*
self
);
char
*
CC_create_errormsg
(
ConnectionClass
*
self
);
int
CC_send_function
(
ConnectionClass
*
conn
,
int
fnid
,
void
*
result_buf
,
int
*
actual_result_len
,
int
result_is_int
,
LO_ARG
*
argv
,
int
nargs
);
int
CC_send_function
(
ConnectionClass
*
conn
,
int
fnid
,
void
*
result_buf
,
int
*
actual_result_len
,
int
result_is_int
,
LO_ARG
*
argv
,
int
nargs
);
...
@@ -316,4 +316,7 @@ void CC_initialize_pg_version(ConnectionClass *conn);
...
@@ -316,4 +316,7 @@ void CC_initialize_pg_version(ConnectionClass *conn);
void
CC_log_error
(
const
char
*
func
,
const
char
*
desc
,
const
ConnectionClass
*
self
);
void
CC_log_error
(
const
char
*
func
,
const
char
*
desc
,
const
ConnectionClass
*
self
);
int
CC_get_max_query_len
(
const
ConnectionClass
*
self
);
int
CC_get_max_query_len
(
const
ConnectionClass
*
self
);
/* CC_send_query_options */
#define CLEAR_RESULT_ON_ABORT 1L
#define CREATE_KEYSET (1L << 1)
/* create keyset for updatable curosrs */
#endif
#endif
src/interfaces/odbc/convert.c
View file @
01e32265
...
@@ -1291,6 +1291,7 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -1291,6 +1291,7 @@ copy_statement_with_parameters(StatementClass *stmt)
#ifdef DRIVER_CURSOR_IMPLEMENT
#ifdef DRIVER_CURSOR_IMPLEMENT
BOOL
search_from_pos
=
FALSE
;
BOOL
search_from_pos
=
FALSE
;
#endif
/* DRIVER_CURSOR_IMPLEMENT */
#endif
/* DRIVER_CURSOR_IMPLEMENT */
Int4
from_pos
=
-
1
,
where_pos
=
-
1
;
if
(
ci
->
disallow_premature
)
if
(
ci
->
disallow_premature
)
prepare_dummy_cursor
=
stmt
->
pre_executing
;
prepare_dummy_cursor
=
stmt
->
pre_executing
;
...
@@ -1326,7 +1327,11 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -1326,7 +1327,11 @@ copy_statement_with_parameters(StatementClass *stmt)
else
if
(
!
stmt
->
ti
||
stmt
->
ntab
!=
1
)
else
if
(
!
stmt
->
ti
||
stmt
->
ntab
!=
1
)
stmt
->
options
.
scroll_concurrency
=
SQL_CONCUR_READ_ONLY
;
stmt
->
options
.
scroll_concurrency
=
SQL_CONCUR_READ_ONLY
;
else
else
search_from_pos
=
TRUE
;
{
/** search_from_pos = TRUE; **/
from_pos
=
stmt
->
from_pos
;
where_pos
=
stmt
->
where_pos
;
}
}
}
#endif
/* DRIVER_CURSOR_IMPLEMENT */
#endif
/* DRIVER_CURSOR_IMPLEMENT */
...
@@ -1366,9 +1371,18 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -1366,9 +1371,18 @@ copy_statement_with_parameters(StatementClass *stmt)
#ifdef MULTIBYTE
#ifdef MULTIBYTE
make_encoded_str
(
&
encstr
,
conn
,
old_statement
);
make_encoded_str
(
&
encstr
,
conn
,
old_statement
);
#endif
#endif
for
(
opos
=
0
;
opos
<
oldstmtlen
;
opos
++
)
for
(
opos
=
0
;
opos
<
oldstmtlen
;
opos
++
)
{
{
if
(
from_pos
==
(
Int4
)
opos
)
{
CVT_APPEND_STR
(
", CTID, OID "
);
}
else
if
(
where_pos
==
(
Int4
)
opos
)
{
stmt
->
load_statement
=
malloc
(
npos
+
1
);
memcpy
(
stmt
->
load_statement
,
new_statement
,
npos
);
stmt
->
load_statement
[
npos
]
=
'\0'
;
}
#ifdef MULTIBYTE
#ifdef MULTIBYTE
oldchar
=
encoded_byte_check
(
&
encstr
,
opos
);
oldchar
=
encoded_byte_check
(
&
encstr
,
opos
);
if
(
ENCODE_STATUS
(
encstr
)
!=
0
)
if
(
ENCODE_STATUS
(
encstr
)
!=
0
)
...
@@ -2033,6 +2047,12 @@ copy_statement_with_parameters(StatementClass *stmt)
...
@@ -2033,6 +2047,12 @@ copy_statement_with_parameters(StatementClass *stmt)
#ifdef DRIVER_CURSOR_IMPLEMENT
#ifdef DRIVER_CURSOR_IMPLEMENT
if
(
search_from_pos
)
if
(
search_from_pos
)
stmt
->
options
.
scroll_concurrency
=
SQL_CONCUR_READ_ONLY
;
stmt
->
options
.
scroll_concurrency
=
SQL_CONCUR_READ_ONLY
;
if
(
!
stmt
->
load_statement
&&
from_pos
>=
0
)
{
stmt
->
load_statement
=
malloc
(
npos
+
1
);
memcpy
(
stmt
->
load_statement
,
new_statement
,
npos
);
stmt
->
load_statement
[
npos
]
=
'\0'
;
}
#endif
/* DRIVER_CURSOR_IMPLEMENT */
#endif
/* DRIVER_CURSOR_IMPLEMENT */
if
(
prepare_dummy_cursor
&&
SC_is_pre_executable
(
stmt
))
if
(
prepare_dummy_cursor
&&
SC_is_pre_executable
(
stmt
))
{
{
...
...
src/interfaces/odbc/environ.c
View file @
01e32265
...
@@ -245,6 +245,9 @@ PGAPI_StmtError( HSTMT hstmt,
...
@@ -245,6 +245,9 @@ PGAPI_StmtError( HSTMT hstmt,
case
STMT_INVALID_CURSOR_STATE_ERROR
:
case
STMT_INVALID_CURSOR_STATE_ERROR
:
strcpy
(
szSqlState
,
"24000"
);
strcpy
(
szSqlState
,
"24000"
);
break
;
break
;
case
STMT_ERROR_IN_ROW
:
strcpy
(
szSqlState
,
"01S01"
);
break
;
case
STMT_OPTION_VALUE_CHANGED
:
case
STMT_OPTION_VALUE_CHANGED
:
strcpy
(
szSqlState
,
"01S02"
);
strcpy
(
szSqlState
,
"01S02"
);
break
;
break
;
...
...
src/interfaces/odbc/execute.c
View file @
01e32265
...
@@ -94,6 +94,12 @@ PGAPI_Prepare(HSTMT hstmt,
...
@@ -94,6 +94,12 @@ PGAPI_Prepare(HSTMT hstmt,
if
(
self
->
statement
)
if
(
self
->
statement
)
free
(
self
->
statement
);
free
(
self
->
statement
);
if
(
self
->
stmt_with_params
)
free
(
self
->
stmt_with_params
);
self
->
stmt_with_params
=
NULL
;
if
(
self
->
load_statement
)
free
(
self
->
load_statement
);
self
->
load_statement
=
NULL
;
self
->
statement
=
make_string
(
szSqlStr
,
cbSqlStr
,
NULL
);
self
->
statement
=
make_string
(
szSqlStr
,
cbSqlStr
,
NULL
);
if
(
!
self
->
statement
)
if
(
!
self
->
statement
)
...
@@ -141,6 +147,12 @@ PGAPI_ExecDirect(
...
@@ -141,6 +147,12 @@ PGAPI_ExecDirect(
if
(
stmt
->
statement
)
if
(
stmt
->
statement
)
free
(
stmt
->
statement
);
free
(
stmt
->
statement
);
if
(
stmt
->
stmt_with_params
)
free
(
stmt
->
stmt_with_params
);
stmt
->
stmt_with_params
=
NULL
;
if
(
stmt
->
load_statement
)
free
(
stmt
->
load_statement
);
stmt
->
load_statement
=
NULL
;
/*
/*
* keep a copy of the un-parametrized statement, in case they try to
* keep a copy of the un-parametrized statement, in case they try to
...
@@ -421,7 +433,7 @@ next_param_row:
...
@@ -421,7 +433,7 @@ next_param_row:
BOOL
in_trans
=
CC_is_in_trans
(
conn
);
BOOL
in_trans
=
CC_is_in_trans
(
conn
);
BOOL
issued_begin
=
FALSE
,
BOOL
issued_begin
=
FALSE
,
begin_included
=
FALSE
;
begin_included
=
FALSE
;
QResultClass
*
res
;
QResultClass
*
res
,
*
curres
;
if
(
strnicmp
(
stmt
->
stmt_with_params
,
"BEGIN;"
,
6
)
==
0
)
if
(
strnicmp
(
stmt
->
stmt_with_params
,
"BEGIN;"
,
6
)
==
0
)
begin_included
=
TRUE
;
begin_included
=
TRUE
;
...
@@ -436,7 +448,7 @@ next_param_row:
...
@@ -436,7 +448,7 @@ next_param_row:
}
}
/* we are now in a transaction */
/* we are now in a transaction */
CC_set_in_trans
(
conn
);
CC_set_in_trans
(
conn
);
res
=
CC_send_query
(
conn
,
stmt
->
stmt_with_params
,
NULL
,
TRUE
);
res
=
CC_send_query
(
conn
,
stmt
->
stmt_with_params
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
if
(
!
res
)
if
(
!
res
)
{
{
CC_abort
(
conn
);
CC_abort
(
conn
);
...
@@ -445,6 +457,9 @@ next_param_row:
...
@@ -445,6 +457,9 @@ next_param_row:
return
SQL_ERROR
;
return
SQL_ERROR
;
}
}
SC_set_Result
(
stmt
,
res
);
SC_set_Result
(
stmt
,
res
);
for
(
curres
=
res
;
!
curres
->
num_fields
;
curres
=
curres
->
next
)
;
SC_set_Curres
(
stmt
,
curres
);
if
(
CC_is_in_autocommit
(
conn
))
if
(
CC_is_in_autocommit
(
conn
))
{
{
if
(
issued_begin
)
if
(
issued_begin
)
...
@@ -518,7 +533,7 @@ PGAPI_Transact(
...
@@ -518,7 +533,7 @@ PGAPI_Transact(
{
{
mylog
(
"PGAPI_Transact: sending on conn %d '%s'
\n
"
,
conn
,
stmt_string
);
mylog
(
"PGAPI_Transact: sending on conn %d '%s'
\n
"
,
conn
,
stmt_string
);
res
=
CC_send_query
(
conn
,
stmt_string
,
NULL
,
TRUE
);
res
=
CC_send_query
(
conn
,
stmt_string
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
CC_set_no_trans
(
conn
);
CC_set_no_trans
(
conn
);
if
(
!
res
)
if
(
!
res
)
...
...
src/interfaces/odbc/info.c
View file @
01e32265
...
@@ -2858,7 +2858,7 @@ getClientTableName(ConnectionClass *conn, char *serverTableName, BOOL *nameAlloc
...
@@ -2858,7 +2858,7 @@ getClientTableName(ConnectionClass *conn, char *serverTableName, BOOL *nameAlloc
return
ret
;
return
ret
;
if
(
!
conn
->
server_encoding
)
if
(
!
conn
->
server_encoding
)
{
{
if
(
res
=
CC_send_query
(
conn
,
"select getdatabaseencoding()"
,
NULL
,
TRUE
),
res
)
if
(
res
=
CC_send_query
(
conn
,
"select getdatabaseencoding()"
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
res
)
{
{
if
(
QR_get_num_tuples
(
res
)
>
0
)
if
(
QR_get_num_tuples
(
res
)
>
0
)
conn
->
server_encoding
=
strdup
(
QR_get_value_backend_row
(
res
,
0
,
0
));
conn
->
server_encoding
=
strdup
(
QR_get_value_backend_row
(
res
,
0
,
0
));
...
@@ -2868,11 +2868,11 @@ getClientTableName(ConnectionClass *conn, char *serverTableName, BOOL *nameAlloc
...
@@ -2868,11 +2868,11 @@ getClientTableName(ConnectionClass *conn, char *serverTableName, BOOL *nameAlloc
if
(
!
conn
->
server_encoding
)
if
(
!
conn
->
server_encoding
)
return
ret
;
return
ret
;
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
server_encoding
);
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
server_encoding
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
)
==
NULL
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
)
==
NULL
);
if
(
!
bError
&&
continueExec
)
if
(
!
bError
&&
continueExec
)
{
{
sprintf
(
query
,
"select OID from pg_class where relname = '%s'"
,
serverTableName
);
sprintf
(
query
,
"select OID from pg_class where relname = '%s'"
,
serverTableName
);
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
),
res
)
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
res
)
{
{
if
(
QR_get_num_tuples
(
res
)
>
0
)
if
(
QR_get_num_tuples
(
res
)
>
0
)
strcpy
(
saveoid
,
QR_get_value_backend_row
(
res
,
0
,
0
));
strcpy
(
saveoid
,
QR_get_value_backend_row
(
res
,
0
,
0
));
...
@@ -2891,11 +2891,11 @@ getClientTableName(ConnectionClass *conn, char *serverTableName, BOOL *nameAlloc
...
@@ -2891,11 +2891,11 @@ getClientTableName(ConnectionClass *conn, char *serverTableName, BOOL *nameAlloc
}
}
/* restore the client encoding */
/* restore the client encoding */
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
client_encoding
);
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
client_encoding
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
)
==
NULL
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
)
==
NULL
);
if
(
bError
||
!
continueExec
)
if
(
bError
||
!
continueExec
)
return
ret
;
return
ret
;
sprintf
(
query
,
"select relname from pg_class where OID = %s"
,
saveoid
);
sprintf
(
query
,
"select relname from pg_class where OID = %s"
,
saveoid
);
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
),
res
)
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
res
)
{
{
if
(
QR_get_num_tuples
(
res
)
>
0
)
if
(
QR_get_num_tuples
(
res
)
>
0
)
{
{
...
@@ -2922,7 +2922,7 @@ getClientColumnName(ConnectionClass *conn, const char *serverTableName, char *se
...
@@ -2922,7 +2922,7 @@ getClientColumnName(ConnectionClass *conn, const char *serverTableName, char *se
return
ret
;
return
ret
;
if
(
!
conn
->
server_encoding
)
if
(
!
conn
->
server_encoding
)
{
{
if
(
res
=
CC_send_query
(
conn
,
"select getdatabaseencoding()"
,
NULL
,
TRUE
),
res
)
if
(
res
=
CC_send_query
(
conn
,
"select getdatabaseencoding()"
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
res
)
{
{
if
(
QR_get_num_tuples
(
res
)
>
0
)
if
(
QR_get_num_tuples
(
res
)
>
0
)
conn
->
server_encoding
=
strdup
(
QR_get_value_backend_row
(
res
,
0
,
0
));
conn
->
server_encoding
=
strdup
(
QR_get_value_backend_row
(
res
,
0
,
0
));
...
@@ -2932,13 +2932,13 @@ getClientColumnName(ConnectionClass *conn, const char *serverTableName, char *se
...
@@ -2932,13 +2932,13 @@ getClientColumnName(ConnectionClass *conn, const char *serverTableName, char *se
if
(
!
conn
->
server_encoding
)
if
(
!
conn
->
server_encoding
)
return
ret
;
return
ret
;
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
server_encoding
);
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
server_encoding
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
)
==
NULL
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
)
==
NULL
);
if
(
!
bError
&&
continueExec
)
if
(
!
bError
&&
continueExec
)
{
{
sprintf
(
query
,
"select attrelid, attnum from pg_class, pg_attribute "
sprintf
(
query
,
"select attrelid, attnum from pg_class, pg_attribute "
"where relname = '%s' and attrelid = pg_class.oid "
"where relname = '%s' and attrelid = pg_class.oid "
"and attname = '%s'"
,
serverTableName
,
serverColumnName
);
"and attname = '%s'"
,
serverTableName
,
serverColumnName
);
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
),
res
)
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
res
)
{
{
if
(
QR_get_num_tuples
(
res
)
>
0
)
if
(
QR_get_num_tuples
(
res
)
>
0
)
{
{
...
@@ -2960,11 +2960,11 @@ getClientColumnName(ConnectionClass *conn, const char *serverTableName, char *se
...
@@ -2960,11 +2960,11 @@ getClientColumnName(ConnectionClass *conn, const char *serverTableName, char *se
}
}
/* restore the cleint encoding */
/* restore the cleint encoding */
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
client_encoding
);
sprintf
(
query
,
"SET CLIENT_ENCODING TO '%s'"
,
conn
->
client_encoding
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
)
==
NULL
);
bError
=
(
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
)
==
NULL
);
if
(
bError
||
!
continueExec
)
if
(
bError
||
!
continueExec
)
return
ret
;
return
ret
;
sprintf
(
query
,
"select attname from pg_attribute where attrelid = %s and attnum = %s"
,
saveattrelid
,
saveattnum
);
sprintf
(
query
,
"select attname from pg_attribute where attrelid = %s and attnum = %s"
,
saveattrelid
,
saveattnum
);
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
TRUE
),
res
)
if
(
res
=
CC_send_query
(
conn
,
query
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
res
)
{
{
if
(
QR_get_num_tuples
(
res
)
>
0
)
if
(
QR_get_num_tuples
(
res
)
>
0
)
{
{
...
@@ -3790,7 +3790,7 @@ PGAPI_Procedures(
...
@@ -3790,7 +3790,7 @@ PGAPI_Procedures(
" case when prorettype = 0 then 1::int2 else 2::int2 end as "
"PROCEDURE_TYPE"
" from pg_proc"
);
" case when prorettype = 0 then 1::int2 else 2::int2 end as "
"PROCEDURE_TYPE"
" from pg_proc"
);
my_strcat
(
proc_query
,
" where proname like '%.*s'"
,
szProcName
,
cbProcName
);
my_strcat
(
proc_query
,
" where proname like '%.*s'"
,
szProcName
,
cbProcName
);
if
(
res
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
TRUE
),
!
res
)
if
(
res
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
!
res
)
{
{
stmt
->
errornumber
=
STMT_EXEC_ERROR
;
stmt
->
errornumber
=
STMT_EXEC_ERROR
;
stmt
->
errormsg
=
"PGAPI_Procedures query error"
;
stmt
->
errormsg
=
"PGAPI_Procedures query error"
;
...
@@ -3927,7 +3927,7 @@ PGAPI_TablePrivileges(
...
@@ -3927,7 +3927,7 @@ PGAPI_TablePrivileges(
my_strcat
(
proc_query
,
" relname like '%.*s' and"
,
esc_table_name
,
escTbnamelen
);
my_strcat
(
proc_query
,
" relname like '%.*s' and"
,
esc_table_name
,
escTbnamelen
);
}
}
strcat
(
proc_query
,
" pg_user.usesysid = relowner"
);
strcat
(
proc_query
,
" pg_user.usesysid = relowner"
);
if
(
res
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
TRUE
),
!
res
)
if
(
res
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
!
res
)
{
{
stmt
->
errornumber
=
STMT_EXEC_ERROR
;
stmt
->
errornumber
=
STMT_EXEC_ERROR
;
stmt
->
errormsg
=
"PGAPI_TablePrivileges query error"
;
stmt
->
errormsg
=
"PGAPI_TablePrivileges query error"
;
...
@@ -3935,7 +3935,7 @@ PGAPI_TablePrivileges(
...
@@ -3935,7 +3935,7 @@ PGAPI_TablePrivileges(
}
}
strncpy_null
(
proc_query
,
"select usename, usesysid, usesuper from pg_user"
,
sizeof
(
proc_query
));
strncpy_null
(
proc_query
,
"select usename, usesysid, usesuper from pg_user"
,
sizeof
(
proc_query
));
tablecount
=
QR_get_num_tuples
(
res
);
tablecount
=
QR_get_num_tuples
(
res
);
if
(
allures
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
TRUE
),
!
allures
)
if
(
allures
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
CLEAR_RESULT_ON_ABORT
),
!
allures
)
{
{
QR_Destructor
(
res
);
QR_Destructor
(
res
);
stmt
->
errornumber
=
STMT_EXEC_ERROR
;
stmt
->
errornumber
=
STMT_EXEC_ERROR
;
...
@@ -3983,7 +3983,7 @@ PGAPI_TablePrivileges(
...
@@ -3983,7 +3983,7 @@ PGAPI_TablePrivileges(
char
*
grolist
,
*
uid
,
*
delm
;
char
*
grolist
,
*
uid
,
*
delm
;
snprintf
(
proc_query
,
sizeof
(
proc_query
)
-
1
,
"select grolist from pg_group where groname = '%s'"
,
user
);
snprintf
(
proc_query
,
sizeof
(
proc_query
)
-
1
,
"select grolist from pg_group where groname = '%s'"
,
user
);
if
(
gres
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
TRUE
))
if
(
gres
=
CC_send_query
(
conn
,
proc_query
,
NULL
,
CLEAR_RESULT_ON_ABORT
))
{
{
grolist
=
QR_get_value_backend_row
(
gres
,
0
,
0
);
grolist
=
QR_get_value_backend_row
(
gres
,
0
,
0
);
if
(
grolist
&&
grolist
[
0
]
==
'{'
)
if
(
grolist
&&
grolist
[
0
]
==
'{'
)
...
...
src/interfaces/odbc/info30.c
View file @
01e32265
...
@@ -47,14 +47,15 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
...
@@ -47,14 +47,15 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
break
;
break
;
case
SQL_KEYSET_CURSOR_ATTRIBUTES1
:
case
SQL_KEYSET_CURSOR_ATTRIBUTES1
:
len
=
4
;
len
=
4
;
value
=
SQL_CA1_NEXT
|
SQL_CA1_ABSOLUTE
value
=
0
;
if
(
ci
->
updatable_cursors
||
ci
->
drivers
.
lie
)
value
|=
(
SQL_CA1_NEXT
|
SQL_CA1_ABSOLUTE
|
SQL_CA1_RELATIVE
|
SQL_CA1_BOOKMARK
|
SQL_CA1_RELATIVE
|
SQL_CA1_BOOKMARK
|
SQL_CA1_LOCK_NO_CHANGE
|
SQL_CA1_POS_POSITION
|
SQL_CA1_LOCK_NO_CHANGE
|
SQL_CA1_POS_POSITION
|
SQL_CA1_POS_UPDATE
|
SQL_CA1_POS_DELETE
|
SQL_CA1_POS_UPDATE
|
SQL_CA1_POS_DELETE
|
SQL_CA1_POS_REFRESH
;
|
SQL_CA1_POS_REFRESH
)
;
if
(
ci
->
drivers
.
lie
)
if
(
ci
->
drivers
.
lie
)
value
|=
value
|=
(
SQL_CA1_BULK_ADD
(
SQL_CA1_BULK_ADD
|
SQL_CA1_BULK_UPDATE_BY_BOOKMARK
|
SQL_CA1_BULK_UPDATE_BY_BOOKMARK
|
SQL_CA1_BULK_DELETE_BY_BOOKMARK
|
SQL_CA1_BULK_DELETE_BY_BOOKMARK
|
SQL_CA1_BULK_FETCH_BY_BOOKMARK
|
SQL_CA1_BULK_FETCH_BY_BOOKMARK
...
@@ -68,13 +69,14 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
...
@@ -68,13 +69,14 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
break
;
break
;
case
SQL_KEYSET_CURSOR_ATTRIBUTES2
:
case
SQL_KEYSET_CURSOR_ATTRIBUTES2
:
len
=
4
;
len
=
4
;
value
=
SQL_CA2_OPT_ROWVER_CONCURRENCY
value
=
0
;
if
(
ci
->
updatable_cursors
||
ci
->
drivers
.
lie
)
value
|=
(
SQL_CA2_OPT_ROWVER_CONCURRENCY
|
SQL_CA2_SENSITIVITY_ADDITIONS
|
SQL_CA2_SENSITIVITY_ADDITIONS
|
SQL_CA2_SENSITIVITY_DELETIONS
|
SQL_CA2_SENSITIVITY_DELETIONS
|
SQL_CA2_SENSITIVITY_UPDATES
;
|
SQL_CA2_SENSITIVITY_UPDATES
)
;
if
(
ci
->
drivers
.
lie
)
if
(
ci
->
drivers
.
lie
)
value
|=
value
|=
(
SQL_CA2_READ_ONLY_CONCURRENCY
(
SQL_CA2_READ_ONLY_CONCURRENCY
|
SQL_CA2_LOCK_CONCURRENCY
|
SQL_CA2_LOCK_CONCURRENCY
|
SQL_CA2_OPT_VALUES_CONCURRENCY
|
SQL_CA2_OPT_VALUES_CONCURRENCY
|
SQL_CA2_MAX_ROWS_SELECT
|
SQL_CA2_MAX_ROWS_SELECT
...
@@ -95,16 +97,19 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
...
@@ -95,16 +97,19 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
len
=
4
;
len
=
4
;
value
=
SQL_CA1_NEXT
|
SQL_CA1_ABSOLUTE
value
=
SQL_CA1_NEXT
|
SQL_CA1_ABSOLUTE
|
SQL_CA1_RELATIVE
|
SQL_CA1_BOOKMARK
|
SQL_CA1_RELATIVE
|
SQL_CA1_BOOKMARK
|
SQL_CA1_LOCK_NO_CHANGE
|
SQL_CA1_POS_POSITION
|
SQL_CA1_LOCK_NO_CHANGE
|
SQL_CA1_POS_POSITION
;
|
SQL_CA1_POS_UPDATE
|
SQL_CA1_POS_DELETE
if
(
ci
->
updatable_cursors
)
|
SQL_CA1_POS_REFRESH
;
value
|=
(
SQL_CA1_POS_UPDATE
|
SQL_CA1_POS_DELETE
|
SQL_CA1_POS_REFRESH
);
break
;
break
;
case
SQL_STATIC_CURSOR_ATTRIBUTES2
:
case
SQL_STATIC_CURSOR_ATTRIBUTES2
:
len
=
4
;
len
=
4
;
value
=
SQL_CA2_OPT_ROWVER_CONCURRENCY
value
=
0
;
if
(
ci
->
updatable_cursors
)
value
|=
(
SQL_CA2_OPT_ROWVER_CONCURRENCY
|
SQL_CA2_SENSITIVITY_ADDITIONS
|
SQL_CA2_SENSITIVITY_ADDITIONS
|
SQL_CA2_SENSITIVITY_DELETIONS
|
SQL_CA2_SENSITIVITY_DELETIONS
|
SQL_CA2_SENSITIVITY_UPDATES
;
|
SQL_CA2_SENSITIVITY_UPDATES
)
;
break
;
break
;
case
SQL_ODBC_INTERFACE_CONFORMANCE
:
case
SQL_ODBC_INTERFACE_CONFORMANCE
:
...
...
src/interfaces/odbc/multibyte.c
View file @
01e32265
...
@@ -300,7 +300,7 @@ CC_lookup_cs_new(ConnectionClass *self)
...
@@ -300,7 +300,7 @@ CC_lookup_cs_new(ConnectionClass *self)
char
*
encstr
=
NULL
;
char
*
encstr
=
NULL
;
QResultClass
*
res
;
QResultClass
*
res
;
res
=
CC_send_query
(
self
,
"select pg_client_encoding()"
,
NULL
,
TRUE
);
res
=
CC_send_query
(
self
,
"select pg_client_encoding()"
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
if
(
res
)
if
(
res
)
{
{
char
*
enc
=
QR_get_value_backend_row
(
res
,
0
,
0
);
char
*
enc
=
QR_get_value_backend_row
(
res
,
0
,
0
);
...
...
src/interfaces/odbc/odbcapi30.c
View file @
01e32265
...
@@ -419,177 +419,17 @@ SQLSetConnectAttr(HDBC ConnectionHandle,
...
@@ -419,177 +419,17 @@ SQLSetConnectAttr(HDBC ConnectionHandle,
return
PGAPI_SetConnectOption
(
ConnectionHandle
,
(
UWORD
)
Attribute
,
(
UDWORD
)
Value
);
return
PGAPI_SetConnectOption
(
ConnectionHandle
,
(
UWORD
)
Attribute
,
(
UDWORD
)
Value
);
}
}
static
RETCODE
SQL_API
ARDSetField
(
StatementClass
*
stmt
,
SQLSMALLINT
RecNumber
,
SQLSMALLINT
FieldIdentifier
,
PTR
Value
,
SQLINTEGER
BufferLength
)
{
RETCODE
ret
=
SQL_SUCCESS
;
PTR
tptr
;
switch
(
FieldIdentifier
)
{
case
SQL_DESC_ARRAY_SIZE
:
stmt
->
options
.
rowset_size
=
(
SQLUINTEGER
)
Value
;
break
;
case
SQL_DESC_ARRAY_STATUS_PTR
:
stmt
->
options
.
row_operation_ptr
=
Value
;
break
;
case
SQL_DESC_BIND_OFFSET_PTR
:
stmt
->
options
.
row_offset_ptr
=
Value
;
break
;
case
SQL_DESC_BIND_TYPE
:
stmt
->
options
.
bind_size
=
(
SQLUINTEGER
)
Value
;
break
;
case
SQL_DESC_DATA_PTR
:
if
(
!
RecNumber
)
stmt
->
bookmark
.
buffer
=
Value
;
else
stmt
->
bindings
[
RecNumber
-
1
].
buffer
=
Value
;
break
;
case
SQL_DESC_INDICATOR_PTR
:
if
(
!
RecNumber
)
tptr
=
stmt
->
bookmark
.
used
;
else
tptr
=
stmt
->
bindings
[
RecNumber
-
1
].
used
;
if
(
Value
!=
tptr
)
{
ret
=
SQL_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_OPTION_IDENTIFIER
;
stmt
->
errormsg
=
"INDICATOR != OCTET_LENGTH_PTR"
;
}
break
;
case
SQL_DESC_OCTET_LENGTH_PTR
:
if
(
!
RecNumber
)
stmt
->
bookmark
.
used
=
Value
;
else
stmt
->
bindings
[
RecNumber
-
1
].
used
=
Value
;
break
;
default:
ret
=
SQL_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_OPTION_IDENTIFIER
;
stmt
->
errormsg
=
"not implemedted yet"
;
}
return
ret
;
}
static
RETCODE
SQL_API
APDSetField
(
StatementClass
*
stmt
,
SQLSMALLINT
RecNumber
,
SQLSMALLINT
FieldIdentifier
,
PTR
Value
,
SQLINTEGER
BufferLength
)
{
RETCODE
ret
=
SQL_SUCCESS
;
switch
(
FieldIdentifier
)
{
case
SQL_DESC_ARRAY_SIZE
:
stmt
->
options
.
paramset_size
=
(
SQLUINTEGER
)
Value
;
break
;
case
SQL_DESC_ARRAY_STATUS_PTR
:
stmt
->
options
.
param_operation_ptr
=
Value
;
break
;
case
SQL_DESC_BIND_OFFSET_PTR
:
stmt
->
options
.
param_offset_ptr
=
Value
;
break
;
case
SQL_DESC_BIND_TYPE
:
stmt
->
options
.
param_bind_type
=
(
SQLUINTEGER
)
Value
;
break
;
case
SQL_DESC_DATA_PTR
:
if
(
stmt
->
parameters_allocated
<
RecNumber
)
PGAPI_BindParameter
(
stmt
,
RecNumber
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
stmt
->
parameters
[
RecNumber
-
1
].
buffer
=
Value
;
break
;
case
SQL_DESC_INDICATOR_PTR
:
if
(
stmt
->
parameters_allocated
<
RecNumber
||
Value
!=
stmt
->
parameters
[
RecNumber
-
1
].
used
)
{
ret
=
SQL_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_OPTION_IDENTIFIER
;
stmt
->
errormsg
=
"INDICATOR != OCTET_LENGTH_PTR"
;
}
break
;
case
SQL_DESC_OCTET_LENGTH_PTR
:
if
(
stmt
->
parameters_allocated
<
RecNumber
)
PGAPI_BindParameter
(
stmt
,
RecNumber
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
stmt
->
parameters
[
RecNumber
-
1
].
used
=
Value
;
break
;
default:
ret
=
SQL_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_OPTION_IDENTIFIER
;
}
return
ret
;
}
static
RETCODE
SQL_API
IRDSetField
(
StatementClass
*
stmt
,
SQLSMALLINT
RecNumber
,
SQLSMALLINT
FieldIdentifier
,
PTR
Value
,
SQLINTEGER
BufferLength
)
{
RETCODE
ret
=
SQL_SUCCESS
;
switch
(
FieldIdentifier
)
{
case
SQL_DESC_ARRAY_STATUS_PTR
:
stmt
->
options
.
rowStatusArray
=
(
SQLUSMALLINT
*
)
Value
;
break
;
case
SQL_DESC_ROWS_PROCESSED_PTR
:
stmt
->
options
.
rowsFetched
=
(
SQLUINTEGER
*
)
Value
;
break
;
default:
ret
=
SQL_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_OPTION_IDENTIFIER
;
}
return
ret
;
}
static
RETCODE
SQL_API
IPDSetField
(
StatementClass
*
stmt
,
SQLSMALLINT
RecNumber
,
SQLSMALLINT
FieldIdentifier
,
PTR
Value
,
SQLINTEGER
BufferLength
)
{
RETCODE
ret
=
SQL_SUCCESS
;
switch
(
FieldIdentifier
)
{
case
SQL_DESC_ARRAY_STATUS_PTR
:
stmt
->
options
.
param_status_ptr
=
(
SQLUSMALLINT
*
)
Value
;
break
;
case
SQL_DESC_ROWS_PROCESSED_PTR
:
stmt
->
options
.
param_processed_ptr
=
(
SQLUINTEGER
*
)
Value
;
break
;
default:
ret
=
SQL_ERROR
;
stmt
->
errornumber
=
STMT_INVALID_OPTION_IDENTIFIER
;
}
return
ret
;
}
/* new function */
/* new function */
RETCODE
SQL_API
RETCODE
SQL_API
SQLSetDescField
(
SQLHDESC
DescriptorHandle
,
SQLSetDescField
(
SQLHDESC
DescriptorHandle
,
SQLSMALLINT
RecNumber
,
SQLSMALLINT
FieldIdentifier
,
SQLSMALLINT
RecNumber
,
SQLSMALLINT
FieldIdentifier
,
PTR
Value
,
SQLINTEGER
BufferLength
)
PTR
Value
,
SQLINTEGER
BufferLength
)
{
{
RETCODE
ret
=
SQL_SUCCESS
;
RETCODE
ret
;
HSTMT
hstmt
;
SQLUINTEGER
descType
;
StatementClass
*
stmt
;
static
const
char
*
func
=
"SQLSetDescField"
;
mylog
(
"[[SQLSetDescField]] h=%u rec=%d field=%d val=%x
\n
"
,
DescriptorHandle
,
RecNumber
,
FieldIdentifier
,
Value
);
mylog
(
"[[SQLSetDescField]] h=%u rec=%d field=%d val=%x
\n
"
,
DescriptorHandle
,
RecNumber
,
FieldIdentifier
,
Value
);
hstmt
=
statementHandleFromDescHandle
(
DescriptorHandle
,
&
descType
);
ret
=
PGAPI_SetDescField
(
DescriptorHandle
,
RecNumber
,
FieldIdentifier
,
mylog
(
"stmt=%x type=%d
\n
"
,
hstmt
,
descType
);
Value
,
BufferLength
);
stmt
=
(
StatementClass
*
)
hstmt
;
switch
(
descType
)
{
case
SQL_ATTR_APP_ROW_DESC
:
ret
=
ARDSetField
(
stmt
,
RecNumber
,
FieldIdentifier
,
Value
,
BufferLength
);
break
;
case
SQL_ATTR_APP_PARAM_DESC
:
ret
=
APDSetField
(
stmt
,
RecNumber
,
FieldIdentifier
,
Value
,
BufferLength
);
break
;
case
SQL_ATTR_IMP_ROW_DESC
:
ret
=
IRDSetField
(
stmt
,
RecNumber
,
FieldIdentifier
,
Value
,
BufferLength
);
break
;
case
SQL_ATTR_IMP_PARAM_DESC
:
ret
=
IPDSetField
(
stmt
,
RecNumber
,
FieldIdentifier
,
Value
,
BufferLength
);
break
;
default:
ret
=
SQL_ERROR
;
stmt
->
errornumber
=
STMT_INTERNAL_ERROR
;
stmt
->
errormsg
=
"Error not implemented"
;
}
if
(
ret
==
SQL_ERROR
)
SC_log_error
(
func
,
""
,
stmt
);
return
ret
;
return
ret
;
}
}
...
@@ -602,7 +442,7 @@ SQLSetDescRec(SQLHDESC DescriptorHandle,
...
@@ -602,7 +442,7 @@ SQLSetDescRec(SQLHDESC DescriptorHandle,
PTR
Data
,
SQLINTEGER
*
StringLength
,
PTR
Data
,
SQLINTEGER
*
StringLength
,
SQLINTEGER
*
Indicator
)
SQLINTEGER
*
Indicator
)
{
{
const
char
*
func
=
"SQLSetDesc
Field
"
;
const
char
*
func
=
"SQLSetDesc
Rec
"
;
mylog
(
"[[SQLSetDescRec]]
\n
"
);
mylog
(
"[[SQLSetDescRec]]
\n
"
);
mylog
(
"Error not implemented
\n
"
);
mylog
(
"Error not implemented
\n
"
);
...
...
src/interfaces/odbc/options.c
View file @
01e32265
...
@@ -39,6 +39,7 @@ set_statement_option(ConnectionClass *conn,
...
@@ -39,6 +39,7 @@ set_statement_option(ConnectionClass *conn,
static
char
*
func
=
"set_statement_option"
;
static
char
*
func
=
"set_statement_option"
;
char
changed
=
FALSE
;
char
changed
=
FALSE
;
ConnInfo
*
ci
=
NULL
;
ConnInfo
*
ci
=
NULL
;
UDWORD
setval
;
if
(
conn
)
if
(
conn
)
ci
=
&
(
conn
->
connInfo
);
ci
=
&
(
conn
->
connInfo
);
...
@@ -63,22 +64,21 @@ set_statement_option(ConnectionClass *conn,
...
@@ -63,22 +64,21 @@ set_statement_option(ConnectionClass *conn,
* positioned update isn't supported so cursor concurrency is
* positioned update isn't supported so cursor concurrency is
* read-only
* read-only
*/
*/
mylog
(
"SetStmtOption(): SQL_CONCURRENCY = %d
\n
"
,
vParam
);
mylog
(
"SetStmtOption(): SQL_CONCURRENCY = %d "
,
vParam
);
if
(
ci
->
drivers
.
lie
||
vParam
==
SQL_CONCUR_READ_ONLY
||
vParam
==
SQL_CONCUR_ROWVER
)
setval
=
SQL_CONCUR_READ_ONLY
;
{
if
(
SQL_CONCUR_READ_ONLY
==
vParam
)
if
(
conn
)
;
conn
->
stmtOptions
.
scroll_concurrency
=
vParam
;
if
(
ci
->
drivers
.
lie
)
if
(
stmt
)
setval
=
vParam
;
stmt
->
options
.
scroll_concurrency
=
vParam
;
else
if
(
ci
->
updatable_cursors
)
}
setval
=
SQL_CONCUR_ROWVER
;
else
if
(
conn
)
{
conn
->
stmtOptions
.
scroll_concurrency
=
setval
;
if
(
conn
)
else
if
(
stmt
)
conn
->
stmtOptions
.
scroll_concurrency
=
SQL_CONCUR_ROWVER
;
stmt
->
options
.
scroll_concurrency
=
setval
;
if
(
stmt
)
if
(
setval
!=
vParam
)
stmt
->
options
.
scroll_concurrency
=
SQL_CONCUR_ROWVER
;
changed
=
TRUE
;
changed
=
TRUE
;
}
mylog
(
"-> %d
\n
"
,
setval
);
break
;
break
;
case
SQL_CURSOR_TYPE
:
case
SQL_CURSOR_TYPE
:
...
@@ -87,47 +87,24 @@ set_statement_option(ConnectionClass *conn,
...
@@ -87,47 +87,24 @@ set_statement_option(ConnectionClass *conn,
* 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.
*/
*/
mylog
(
"SetStmtOption(): SQL_CURSOR_TYPE = %d
\n
"
,
vParam
);
mylog
(
"SetStmtOption(): SQL_CURSOR_TYPE = %d
"
,
vParam
);
setval
=
SQL_CURSOR_FORWARD_ONLY
;
if
(
ci
->
drivers
.
lie
)
if
(
ci
->
drivers
.
lie
)
{
setval
=
vParam
;
if
(
conn
)
else
if
(
ci
->
drivers
.
use_declarefetch
)
conn
->
stmtOptions
.
cursor_type
=
vParam
;
;
if
(
stmt
)
else
if
(
SQL_CURSOR_STATIC
==
vParam
)
stmt
->
options
.
cursor_type
=
vParam
;
setval
=
vParam
;
}
/** else if (SQL_CURSOR_KEYSET_DRIVEN == vParam && ci->updatable)
else
setval = vParam; **/
{
if
(
ci
->
drivers
.
use_declarefetch
)
{
if
(
conn
)
conn
->
stmtOptions
.
cursor_type
=
SQL_CURSOR_FORWARD_ONLY
;
if
(
stmt
)
stmt
->
options
.
cursor_type
=
SQL_CURSOR_FORWARD_ONLY
;
if
(
vParam
!=
SQL_CURSOR_FORWARD_ONLY
)
if
(
conn
)
changed
=
TRUE
;
conn
->
stmtOptions
.
cursor_type
=
setval
;
}
else
if
(
stmt
)
else
stmt
->
options
.
cursor_type
=
setval
;
{
if
(
setval
!=
vParam
)
if
(
vParam
==
SQL_CURSOR_FORWARD_ONLY
||
vParam
==
SQL_CURSOR_STATIC
)
changed
=
TRUE
;
{
mylog
(
"-> %d
\n
"
,
setval
);
if
(
conn
)
conn
->
stmtOptions
.
cursor_type
=
vParam
;
/* valid type */
if
(
stmt
)
stmt
->
options
.
cursor_type
=
vParam
;
/* valid type */
}
else
{
if
(
conn
)
conn
->
stmtOptions
.
cursor_type
=
SQL_CURSOR_STATIC
;
if
(
stmt
)
stmt
->
options
.
cursor_type
=
SQL_CURSOR_STATIC
;
changed
=
TRUE
;
}
}
}
break
;
break
;
case
SQL_KEYSET_SIZE
:
/* ignored, but saved and returned */
case
SQL_KEYSET_SIZE
:
/* ignored, but saved and returned */
...
...
src/interfaces/odbc/parse.c
View file @
01e32265
...
@@ -297,7 +297,6 @@ parse_statement(StatementClass *stmt)
...
@@ -297,7 +297,6 @@ parse_statement(StatementClass *stmt)
in_distinct
=
FALSE
,
in_distinct
=
FALSE
,
in_on
=
FALSE
,
in_on
=
FALSE
,
in_from
=
FALSE
,
in_from
=
FALSE
,
from_found
=
FALSE
,
in_where
=
FALSE
,
in_where
=
FALSE
,
in_table
=
FALSE
;
in_table
=
FALSE
;
char
in_field
=
FALSE
,
char
in_field
=
FALSE
,
...
@@ -309,7 +308,6 @@ parse_statement(StatementClass *stmt)
...
@@ -309,7 +308,6 @@ parse_statement(StatementClass *stmt)
i
,
i
,
k
=
0
,
k
=
0
,
n
,
n
,
first_where
=
0
,
blevel
=
0
;
blevel
=
0
;
FIELD_INFO
**
fi
;
FIELD_INFO
**
fi
;
TABLE_INFO
**
ti
;
TABLE_INFO
**
ti
;
...
@@ -318,6 +316,7 @@ parse_statement(StatementClass *stmt)
...
@@ -318,6 +316,7 @@ parse_statement(StatementClass *stmt)
HSTMT
hcol_stmt
;
HSTMT
hcol_stmt
;
StatementClass
*
col_stmt
;
StatementClass
*
col_stmt
;
RETCODE
result
;
RETCODE
result
;
BOOL
updatable
=
TRUE
;
mylog
(
"%s: entering...
\n
"
,
func
);
mylog
(
"%s: entering...
\n
"
,
func
);
...
@@ -327,6 +326,8 @@ parse_statement(StatementClass *stmt)
...
@@ -327,6 +326,8 @@ parse_statement(StatementClass *stmt)
stmt
->
nfld
=
0
;
stmt
->
nfld
=
0
;
stmt
->
ntab
=
0
;
stmt
->
ntab
=
0
;
stmt
->
from_pos
=
-
1
;
stmt
->
where_pos
=
-
1
;
#ifdef MULTIBYTE
#ifdef MULTIBYTE
while
(
pptr
=
ptr
,
(
ptr
=
getNextToken
(
conn
->
ccsc
,
pptr
,
token
,
sizeof
(
token
),
&
delim
,
&
quote
,
&
dquote
,
&
numeric
))
!=
NULL
)
while
(
pptr
=
ptr
,
(
ptr
=
getNextToken
(
conn
->
ccsc
,
pptr
,
token
,
sizeof
(
token
),
&
delim
,
&
quote
,
&
dquote
,
&
numeric
))
!=
NULL
)
...
@@ -343,6 +344,7 @@ parse_statement(StatementClass *stmt)
...
@@ -343,6 +344,7 @@ parse_statement(StatementClass *stmt)
if
(
!
stricmp
(
token
,
"distinct"
))
if
(
!
stricmp
(
token
,
"distinct"
))
{
{
in_distinct
=
TRUE
;
in_distinct
=
TRUE
;
updatable
=
FALSE
;
mylog
(
"DISTINCT
\n
"
);
mylog
(
"DISTINCT
\n
"
);
continue
;
continue
;
...
@@ -359,11 +361,11 @@ parse_statement(StatementClass *stmt)
...
@@ -359,11 +361,11 @@ parse_statement(StatementClass *stmt)
{
{
in_select
=
FALSE
;
in_select
=
FALSE
;
in_from
=
TRUE
;
in_from
=
TRUE
;
if
(
!
from_found
&&
if
(
stmt
->
from_pos
<
0
&&
(
!
strnicmp
(
pptr
,
"from"
,
4
)))
(
!
strnicmp
(
pptr
,
"from"
,
4
)))
{
{
mylog
(
"First "
);
mylog
(
"First "
);
from_found
=
TRUE
;
stmt
->
from_pos
=
pptr
-
stmt
->
statement
;
}
}
mylog
(
"FROM
\n
"
);
mylog
(
"FROM
\n
"
);
...
@@ -384,9 +386,13 @@ parse_statement(StatementClass *stmt)
...
@@ -384,9 +386,13 @@ parse_statement(StatementClass *stmt)
in_from
=
FALSE
;
in_from
=
FALSE
;
in_where
=
TRUE
;
in_where
=
TRUE
;
if
(
!
first_where
&&
if
(
!
stricmp
(
token
,
"where"
))
(
!
stricmp
(
token
,
"where"
)))
{
first_where
=
ptr
-
stmt
->
statement
;
if
(
stmt
->
where_pos
<
0
)
stmt
->
where_pos
=
pptr
-
stmt
->
statement
;
}
else
if
(
stricmp
(
token
,
"order"
))
updatable
=
FALSE
;
mylog
(
"WHERE...
\n
"
);
mylog
(
"WHERE...
\n
"
);
break
;
break
;
...
@@ -733,6 +739,10 @@ parse_statement(StatementClass *stmt)
...
@@ -733,6 +739,10 @@ parse_statement(StatementClass *stmt)
*/
*/
/* Call SQLColumns for each table and store the result */
/* Call SQLColumns for each table and store the result */
if
(
stmt
->
ntab
>
1
)
updatable
=
FALSE
;
else
if
(
stmt
->
from_pos
<
0
)
updatable
=
FALSE
;
for
(
i
=
0
;
i
<
stmt
->
ntab
;
i
++
)
for
(
i
=
0
;
i
<
stmt
->
ntab
;
i
++
)
{
{
/* See if already got it */
/* See if already got it */
...
@@ -828,9 +838,11 @@ parse_statement(StatementClass *stmt)
...
@@ -828,9 +838,11 @@ parse_statement(StatementClass *stmt)
*/
*/
for
(
i
=
0
;
i
<
stmt
->
nfld
;)
for
(
i
=
0
;
i
<
stmt
->
nfld
;)
{
{
fi
[
i
]
->
updatable
=
updatable
;
/* 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
)
{
{
fi
[
i
]
->
updatable
=
FALSE
;
i
++
;
i
++
;
continue
;
continue
;
}
}
...
@@ -928,6 +940,7 @@ parse_statement(StatementClass *stmt)
...
@@ -928,6 +940,7 @@ parse_statement(StatementClass *stmt)
mylog
(
"about to copy at %d
\n
"
,
n
+
i
);
mylog
(
"about to copy at %d
\n
"
,
n
+
i
);
getColInfo
(
the_ti
->
col_info
,
fi
[
n
+
i
],
n
);
getColInfo
(
the_ti
->
col_info
,
fi
[
n
+
i
],
n
);
fi
[
n
+
i
]
->
updatable
=
updatable
;
mylog
(
"done copying
\n
"
);
mylog
(
"done copying
\n
"
);
}
}
...
@@ -945,24 +958,29 @@ parse_statement(StatementClass *stmt)
...
@@ -945,24 +958,29 @@ 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
;
fi
[
i
]
->
updatable
=
FALSE
;
}
i
++
;
i
++
;
}
}
/* Don't know the table -- search all tables in "from" list */
/* Don't know the table -- search all tables in "from" list */
else
else
{
{
parse
=
FALSE
;
for
(
k
=
0
;
k
<
stmt
->
ntab
;
k
++
)
for
(
k
=
0
;
k
<
stmt
->
ntab
;
k
++
)
{
{
if
(
searchColInfo
(
ti
[
k
]
->
col_info
,
fi
[
i
]))
if
(
searchColInfo
(
ti
[
k
]
->
col_info
,
fi
[
i
]))
{
{
fi
[
i
]
->
ti
=
ti
[
k
];
/* now know the table */
fi
[
i
]
->
ti
=
ti
[
k
];
/* now know the table */
parse
=
TRUE
;
break
;
break
;
}
}
}
}
if
(
k
>=
stmt
->
ntab
)
{
parse
=
FALSE
;
fi
[
i
]
->
updatable
=
FALSE
;
}
i
++
;
i
++
;
}
}
}
}
...
...
src/interfaces/odbc/psqlodbc.h
View file @
01e32265
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
*
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*
* $Id: psqlodbc.h,v 1.
59 2002/03/11 10:25:57
inoue Exp $
* $Id: psqlodbc.h,v 1.
60 2002/03/14 05:42:03
inoue Exp $
*
*
*/
*/
...
@@ -166,6 +166,7 @@ typedef struct TupleListClass_ TupleListClass;
...
@@ -166,6 +166,7 @@ typedef struct TupleListClass_ TupleListClass;
typedef
struct
EnvironmentClass_
EnvironmentClass
;
typedef
struct
EnvironmentClass_
EnvironmentClass
;
typedef
struct
TupleNode_
TupleNode
;
typedef
struct
TupleNode_
TupleNode
;
typedef
struct
TupleField_
TupleField
;
typedef
struct
TupleField_
TupleField
;
typedef
struct
KeySet_
KeySet
;
typedef
struct
col_info
COL_INFO
;
typedef
struct
col_info
COL_INFO
;
typedef
struct
lo_arg
LO_ARG
;
typedef
struct
lo_arg
LO_ARG
;
...
...
src/interfaces/odbc/psqlodbc_api30.def
View file @
01e32265
...
@@ -5,7 +5,7 @@ SQLAllocEnv @2
...
@@ -5,7 +5,7 @@ SQLAllocEnv @2
SQLAllocStmt @3
SQLAllocStmt @3
SQLBindCol @4
SQLBindCol @4
SQLCancel @5
SQLCancel @5
SQLColAttributes @6
; SQLColAttributes @6 */
SQLConnect @7
SQLConnect @7
SQLDescribeCol @8
SQLDescribeCol @8
SQLDisconnect @9
SQLDisconnect @9
...
...
src/interfaces/odbc/psqlodbc_api30w.def
View file @
01e32265
...
@@ -5,7 +5,7 @@ SQLAllocEnv @2
...
@@ -5,7 +5,7 @@ SQLAllocEnv @2
SQLAllocStmt @3
SQLAllocStmt @3
SQLBindCol @4
SQLBindCol @4
SQLCancel @5
SQLCancel @5
SQLColAttributes @6
;
SQLColAttributes @6
SQLConnect @7
SQLConnect @7
SQLDescribeCol @8
SQLDescribeCol @8
SQLDisconnect @9
SQLDisconnect @9
...
...
src/interfaces/odbc/qresult.c
View file @
01e32265
...
@@ -121,6 +121,8 @@ QR_Constructor()
...
@@ -121,6 +121,8 @@ QR_Constructor()
rv
->
cache_size
=
0
;
rv
->
cache_size
=
0
;
rv
->
rowset_size
=
1
;
rv
->
rowset_size
=
1
;
rv
->
haskeyset
=
0
;
rv
->
keyset
=
NULL
;
}
}
mylog
(
"exit QR_Constructor
\n
"
);
mylog
(
"exit QR_Constructor
\n
"
);
...
@@ -221,6 +223,11 @@ QR_free_memory(QResultClass *self)
...
@@ -221,6 +223,11 @@ QR_free_memory(QResultClass *self)
free
(
self
->
backend_tuples
);
free
(
self
->
backend_tuples
);
self
->
backend_tuples
=
NULL
;
self
->
backend_tuples
=
NULL
;
}
}
if
(
self
->
keyset
)
{
free
(
self
->
keyset
);
self
->
keyset
=
NULL
;
}
self
->
fcount
=
0
;
self
->
fcount
=
0
;
...
@@ -296,6 +303,8 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
...
@@ -296,6 +303,8 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
mylog
(
"MALLOC: tuple_size = %d, size = %d
\n
"
,
tuple_size
,
self
->
num_fields
*
sizeof
(
TupleField
)
*
tuple_size
);
mylog
(
"MALLOC: tuple_size = %d, size = %d
\n
"
,
tuple_size
,
self
->
num_fields
*
sizeof
(
TupleField
)
*
tuple_size
);
self
->
count_allocated
=
0
;
self
->
count_allocated
=
0
;
self
->
backend_tuples
=
(
TupleField
*
)
malloc
(
self
->
num_fields
*
sizeof
(
TupleField
)
*
tuple_size
);
self
->
backend_tuples
=
(
TupleField
*
)
malloc
(
self
->
num_fields
*
sizeof
(
TupleField
)
*
tuple_size
);
if
(
self
->
haskeyset
)
self
->
keyset
=
(
KeySet
*
)
calloc
(
sizeof
(
KeySet
),
tuple_size
);
if
(
!
self
->
backend_tuples
)
if
(
!
self
->
backend_tuples
)
{
{
self
->
status
=
PGRES_FATAL_ERROR
;
self
->
status
=
PGRES_FATAL_ERROR
;
...
@@ -347,7 +356,7 @@ QR_close(QResultClass *self)
...
@@ -347,7 +356,7 @@ QR_close(QResultClass *self)
sprintf
(
buf
,
"close %s"
,
self
->
cursor
);
sprintf
(
buf
,
"close %s"
,
self
->
cursor
);
mylog
(
"QResult: closing cursor: '%s'
\n
"
,
buf
);
mylog
(
"QResult: closing cursor: '%s'
\n
"
,
buf
);
res
=
CC_send_query
(
self
->
conn
,
buf
,
NULL
,
TRUE
);
res
=
CC_send_query
(
self
->
conn
,
buf
,
NULL
,
CLEAR_RESULT_ON_ABORT
);
self
->
inTuples
=
FALSE
;
self
->
inTuples
=
FALSE
;
self
->
currTuple
=
-
1
;
self
->
currTuple
=
-
1
;
...
@@ -482,6 +491,8 @@ QR_next_tuple(QResultClass *self)
...
@@ -482,6 +491,8 @@ QR_next_tuple(QResultClass *self)
QR_set_message
(
self
,
"Out of memory while reading tuples."
);
QR_set_message
(
self
,
"Out of memory while reading tuples."
);
return
FALSE
;
return
FALSE
;
}
}
if
(
self
->
haskeyset
)
self
->
keyset
=
(
KeySet
*
)
realloc
(
self
->
keyset
,
sizeof
(
KeySet
)
*
self
->
cache_size
);
self
->
count_allocated
=
self
->
cache_size
;
self
->
count_allocated
=
self
->
cache_size
;
}
}
sprintf
(
fetch
,
"fetch %d in %s"
,
fetch_size
,
self
->
cursor
);
sprintf
(
fetch
,
"fetch %d in %s"
,
fetch_size
,
self
->
cursor
);
...
@@ -492,7 +503,7 @@ QR_next_tuple(QResultClass *self)
...
@@ -492,7 +503,7 @@ QR_next_tuple(QResultClass *self)
qi
.
row_size
=
self
->
cache_size
;
qi
.
row_size
=
self
->
cache_size
;
qi
.
result_in
=
self
;
qi
.
result_in
=
self
;
qi
.
cursor
=
NULL
;
qi
.
cursor
=
NULL
;
res
=
CC_send_query
(
self
->
conn
,
fetch
,
&
qi
,
TRUE
);
res
=
CC_send_query
(
self
->
conn
,
fetch
,
&
qi
,
CLEAR_RESULT_ON_ABORT
);
if
(
res
==
NULL
)
if
(
res
==
NULL
)
{
{
self
->
status
=
PGRES_FATAL_ERROR
;
self
->
status
=
PGRES_FATAL_ERROR
;
...
@@ -552,6 +563,8 @@ QR_next_tuple(QResultClass *self)
...
@@ -552,6 +563,8 @@ QR_next_tuple(QResultClass *self)
QR_set_message
(
self
,
"Out of memory while reading tuples."
);
QR_set_message
(
self
,
"Out of memory while reading tuples."
);
return
FALSE
;
return
FALSE
;
}
}
if
(
self
->
haskeyset
)
self
->
keyset
=
(
KeySet
*
)
realloc
(
self
->
keyset
,
sizeof
(
KeySet
)
*
tuple_size
);
self
->
count_allocated
=
tuple_size
;
self
->
count_allocated
=
tuple_size
;
}
}
...
@@ -626,6 +639,7 @@ QR_read_tuple(QResultClass *self, char binary)
...
@@ -626,6 +639,7 @@ QR_read_tuple(QResultClass *self, char binary)
{
{
Int2
field_lf
;
Int2
field_lf
;
TupleField
*
this_tuplefield
;
TupleField
*
this_tuplefield
;
KeySet
*
this_keyset
=
NULL
;
char
bmp
,
char
bmp
,
bitmap
[
MAX_FIELDS
];
/* Max. len of the bitmap */
bitmap
[
MAX_FIELDS
];
/* Max. len of the bitmap */
Int2
bitmaplen
;
/* len of the bitmap in bytes */
Int2
bitmaplen
;
/* len of the bitmap in bytes */
...
@@ -639,6 +653,11 @@ QR_read_tuple(QResultClass *self, char binary)
...
@@ -639,6 +653,11 @@ QR_read_tuple(QResultClass *self, char binary)
/* 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
);
if
(
self
->
haskeyset
)
{
this_keyset
=
self
->
keyset
+
self
->
fcount
;
this_keyset
->
status
=
0
;
}
bitmaplen
=
(
Int2
)
num_fields
/
BYTELEN
;
bitmaplen
=
(
Int2
)
num_fields
/
BYTELEN
;
if
((
num_fields
%
BYTELEN
)
>
0
)
if
((
num_fields
%
BYTELEN
)
>
0
)
...
@@ -709,6 +728,15 @@ QR_read_tuple(QResultClass *self, char binary)
...
@@ -709,6 +728,15 @@ QR_read_tuple(QResultClass *self, char binary)
else
else
bmp
<<=
1
;
bmp
<<=
1
;
}
}
if
(
this_keyset
)
{
if
(
this_tuplefield
[
num_fields
-
2
].
value
)
sscanf
(
this_tuplefield
[
num_fields
-
2
].
value
,
"(%u,%hu)"
,
&
this_keyset
->
blocknum
,
&
this_keyset
->
offset
);
if
(
this_tuplefield
[
num_fields
-
1
].
value
)
sscanf
(
this_tuplefield
[
num_fields
-
1
].
value
,
"%u"
,
&
this_keyset
->
oid
);
}
self
->
currTuple
++
;
self
->
currTuple
++
;
return
TRUE
;
return
TRUE
;
}
}
src/interfaces/odbc/qresult.h
View file @
01e32265
...
@@ -72,6 +72,9 @@ struct QResultClass_
...
@@ -72,6 +72,9 @@ struct QResultClass_
char
inTuples
;
/* is a fetch of rows from the backend in
char
inTuples
;
/* is a fetch of rows from the backend in
* progress? */
* progress? */
char
aborted
;
/* was aborted? */
char
aborted
;
/* was aborted? */
char
haskeyset
;
/* this result contains keyset ? */
KeySet
*
keyset
;
};
};
#define QR_get_fields(self) (self->fields)
#define QR_get_fields(self) (self->fields)
...
@@ -102,6 +105,7 @@ struct QResultClass_
...
@@ -102,6 +105,7 @@ struct QResultClass_
#define QR_set_status(self, condition) ( self->status = condition )
#define QR_set_status(self, condition) ( self->status = condition )
#define QR_set_message(self, message_) ( self->message = message_)
#define QR_set_message(self, message_) ( self->message = message_)
#define QR_set_aborted(self, aborted_) ( self->aborted = aborted_)
#define QR_set_aborted(self, aborted_) ( self->aborted = aborted_)
#define QR_set_haskeyset(self) (self->haskeyset = TRUE)
#define QR_get_message(self) (self->message)
#define QR_get_message(self) (self->message)
#define QR_get_command(self) (self->command)
#define QR_get_command(self) (self->command)
...
...
src/interfaces/odbc/results.c
View file @
01e32265
This diff is collapsed.
Click to expand it.
src/interfaces/odbc/statement.c
View file @
01e32265
...
@@ -242,6 +242,7 @@ SC_Constructor(void)
...
@@ -242,6 +242,7 @@ SC_Constructor(void)
rv
->
statement
=
NULL
;
rv
->
statement
=
NULL
;
rv
->
stmt_with_params
=
NULL
;
rv
->
stmt_with_params
=
NULL
;
rv
->
load_statement
=
NULL
;
rv
->
stmt_size_limit
=
-
1
;
rv
->
stmt_size_limit
=
-
1
;
rv
->
statement_type
=
STMT_TYPE_UNKNOWN
;
rv
->
statement_type
=
STMT_TYPE_UNKNOWN
;
...
@@ -318,6 +319,8 @@ SC_Destructor(StatementClass *self)
...
@@ -318,6 +319,8 @@ SC_Destructor(StatementClass *self)
free
(
self
->
stmt_with_params
);
free
(
self
->
stmt_with_params
);
self
->
stmt_with_params
=
NULL
;
self
->
stmt_with_params
=
NULL
;
}
}
if
(
self
->
load_statement
)
free
(
self
->
load_statement
);
SC_free_params
(
self
,
STMT_FREE_PARAMS_ALL
);
SC_free_params
(
self
,
STMT_FREE_PARAMS_ALL
);
...
@@ -548,6 +551,12 @@ SC_recycle_statement(StatementClass *self)
...
@@ -548,6 +551,12 @@ SC_recycle_statement(StatementClass *self)
* SQLParamData/SQLPutData is called.
* 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
);
if
(
self
->
stmt_with_params
)
free
(
self
->
stmt_with_params
);
self
->
stmt_with_params
=
NULL
;
if
(
self
->
load_statement
)
free
(
self
->
load_statement
);
self
->
load_statement
=
NULL
;
return
TRUE
;
return
TRUE
;
}
}
...
@@ -635,12 +644,16 @@ SC_create_errormsg(StatementClass *self)
...
@@ -635,12 +644,16 @@ SC_create_errormsg(StatementClass *self)
QResultClass
*
res
=
SC_get_Curres
(
self
);
QResultClass
*
res
=
SC_get_Curres
(
self
);
ConnectionClass
*
conn
=
self
->
hdbc
;
ConnectionClass
*
conn
=
self
->
hdbc
;
int
pos
;
int
pos
;
BOOL
detailmsg
=
FALSE
;
static
char
msg
[
4096
];
static
char
msg
[
4096
];
msg
[
0
]
=
'\0'
;
msg
[
0
]
=
'\0'
;
if
(
res
&&
res
->
message
)
if
(
res
&&
res
->
message
)
{
strcpy
(
msg
,
res
->
message
);
strcpy
(
msg
,
res
->
message
);
detailmsg
=
TRUE
;
}
else
if
(
self
->
errormsg
)
else
if
(
self
->
errormsg
)
strcpy
(
msg
,
self
->
errormsg
);
strcpy
(
msg
,
self
->
errormsg
);
...
@@ -660,10 +673,10 @@ SC_create_errormsg(StatementClass *self)
...
@@ -660,10 +673,10 @@ SC_create_errormsg(StatementClass *self)
{
{
SocketClass
*
sock
=
conn
->
sock
;
SocketClass
*
sock
=
conn
->
sock
;
if
(
conn
->
errormsg
&&
conn
->
errormsg
[
0
]
!=
'\0'
)
if
(
!
detailmsg
&&
conn
->
errormsg
&&
conn
->
errormsg
[
0
]
!=
'\0'
)
{
{
pos
=
strlen
(
msg
);
pos
=
strlen
(
msg
);
/*sprintf(&msg[pos], ";\n%s", conn->errormsg);*/
sprintf
(
&
msg
[
pos
],
";
\n
%s"
,
conn
->
errormsg
);
}
}
if
(
sock
&&
sock
->
errormsg
&&
sock
->
errormsg
[
0
]
!=
'\0'
)
if
(
sock
&&
sock
->
errormsg
&&
sock
->
errormsg
[
0
]
!=
'\0'
)
...
@@ -722,9 +735,6 @@ SC_fetch(StatementClass *self)
...
@@ -722,9 +735,6 @@ SC_fetch(StatementClass *self)
int
retval
,
int
retval
,
result
;
result
;
#ifdef DRIVER_CURSOR_IMPLEMENT
int
updret
;
#endif
/* DRIVER_CURSOR_IMPLEMENT */
Int2
num_cols
,
Int2
num_cols
,
lf
;
lf
;
Oid
type
;
Oid
type
;
...
@@ -799,20 +809,13 @@ SC_fetch(StatementClass *self)
...
@@ -799,20 +809,13 @@ SC_fetch(StatementClass *self)
}
}
#ifdef DRIVER_CURSOR_IMPLEMENT
#ifdef DRIVER_CURSOR_IMPLEMENT
updret
=
0
;
if
(
self
->
options
.
scroll_concurrency
!=
SQL_CONCUR_READ_ONLY
)
if
(
self
->
options
.
scroll_concurrency
!=
SQL_CONCUR_READ_ONLY
)
{
{
if
(
!
QR_get_value_backend_row
(
res
,
self
->
currTuple
,
num_cols
-
1
))
updret
=
SQL_ROW_DELETED
;
num_cols
-=
2
;
num_cols
-=
2
;
}
}
#endif
/* DRIVER_CURSOR_IMPLEMENT */
#endif
/* DRIVER_CURSOR_IMPLEMENT */
if
(
self
->
options
.
retrieve_data
==
SQL_RD_OFF
)
/* data isn't required */
if
(
self
->
options
.
retrieve_data
==
SQL_RD_OFF
)
/* data isn't required */
#ifdef DRIVER_CURSOR_IMPLEMENT
return
updret
?
updret
+
10
:
SQL_SUCCESS
;
#else
return
SQL_SUCCESS
;
return
SQL_SUCCESS
;
#endif
/* DRIVER_CURSOR_IMPLEMENT */
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
);
...
@@ -893,10 +896,6 @@ SC_fetch(StatementClass *self)
...
@@ -893,10 +896,6 @@ SC_fetch(StatementClass *self)
}
}
}
}
#ifdef DRIVER_CURSOR_IMPLEMENT
if
(
updret
)
result
=
updret
+
10
;
#endif
/* DRIVER_CURSOR_IMPLEMENT */
return
result
;
return
result
;
}
}
...
@@ -955,11 +954,12 @@ SC_execute(StatementClass *self)
...
@@ -955,11 +954,12 @@ SC_execute(StatementClass *self)
if
(
self
->
statement_type
==
STMT_TYPE_SELECT
)
if
(
self
->
statement_type
==
STMT_TYPE_SELECT
)
{
{
char
fetch
[
128
];
char
fetch
[
128
];
UDWORD
qflag
=
(
SQL_CONCUR_ROWVER
==
self
->
options
.
scroll_concurrency
?
CREATE_KEYSET
:
0
);
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 */
res
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
,
FALSE
);
res
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
,
qflag
);
if
(
SC_is_fetchcursor
(
self
)
&&
res
!=
NULL
&&
if
(
SC_is_fetchcursor
(
self
)
&&
res
!=
NULL
&&
QR_command_successful
(
res
))
QR_command_successful
(
res
))
{
{
...
@@ -982,7 +982,7 @@ SC_execute(StatementClass *self)
...
@@ -982,7 +982,7 @@ SC_execute(StatementClass *self)
*/
*/
sprintf
(
fetch
,
"fetch %d in %s"
,
qi
.
row_size
,
self
->
cursor_name
);
sprintf
(
fetch
,
"fetch %d in %s"
,
qi
.
row_size
,
self
->
cursor_name
);
res
=
CC_send_query
(
conn
,
fetch
,
&
qi
,
FALSE
);
res
=
CC_send_query
(
conn
,
fetch
,
&
qi
,
qflag
);
}
}
mylog
(
" done sending the query:
\n
"
);
mylog
(
" done sending the query:
\n
"
);
}
}
...
@@ -990,7 +990,7 @@ SC_execute(StatementClass *self)
...
@@ -990,7 +990,7 @@ SC_execute(StatementClass *self)
{
{
/* 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
);
res
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
,
FALSE
);
res
=
CC_send_query
(
conn
,
self
->
stmt_with_params
,
NULL
,
0
);
/*
/*
* We shouldn't send COMMIT. Postgres backend does the autocommit
* We shouldn't send COMMIT. Postgres backend does the autocommit
...
...
src/interfaces/odbc/statement.h
View file @
01e32265
...
@@ -76,6 +76,7 @@ typedef enum
...
@@ -76,6 +76,7 @@ typedef enum
#define STMT_BAD_ERROR 27
#define STMT_BAD_ERROR 27
#define STMT_INVALID_OPTION_IDENTIFIER 28
#define STMT_INVALID_OPTION_IDENTIFIER 28
#define STMT_RETURN_NULL_WITHOUT_INDICATOR 29
#define STMT_RETURN_NULL_WITHOUT_INDICATOR 29
#define STMT_ERROR_IN_ROW 30
/* statement types */
/* statement types */
enum
enum
...
@@ -135,6 +136,7 @@ typedef struct
...
@@ -135,6 +136,7 @@ typedef struct
char
quote
;
char
quote
;
char
dquote
;
char
dquote
;
char
numeric
;
char
numeric
;
char
updatable
;
char
dot
[
MAX_TABLE_LEN
+
1
];
char
dot
[
MAX_TABLE_LEN
+
1
];
char
name
[
MAX_COLUMN_LEN
+
1
];
char
name
[
MAX_COLUMN_LEN
+
1
];
char
alias
[
MAX_COLUMN_LEN
+
1
];
char
alias
[
MAX_COLUMN_LEN
+
1
];
...
@@ -219,11 +221,15 @@ struct StatementClass_
...
@@ -219,11 +221,15 @@ struct StatementClass_
char
miscinfo
;
char
miscinfo
;
SWORD
errorpos
;
SWORD
errorpos
;
SWORD
error_recsize
;
SWORD
error_recsize
;
char
*
load_statement
;
/* to (re)load updatable individual rows */
Int4
from_pos
;
Int4
where_pos
;
};
};
#define SC_get_conn(a) (a->hdbc)
#define SC_get_conn(a) (a->hdbc)
#define SC_set_Result(a, b) (a->result = a->curres = b)
#define SC_set_Result(a, b) (a->result = a->curres = b)
#define SC_get_Result(a) (a->result)
#define SC_get_Result(a) (a->result)
#define SC_set_Curres(a, b) (a->curres = b)
#define SC_get_Curres(a) (a->curres)
#define SC_get_Curres(a) (a->curres)
/* options for SC_free_params() */
/* options for SC_free_params() */
...
...
src/interfaces/odbc/tuple.h
View file @
01e32265
...
@@ -30,6 +30,19 @@ struct TupleNode_
...
@@ -30,6 +30,19 @@ struct TupleNode_
TupleField
tuple
[
1
];
TupleField
tuple
[
1
];
};
};
/* keyset(TID + OID) info */
struct
KeySet_
{
UWORD
status
;
UWORD
offset
;
UDWORD
blocknum
;
UDWORD
oid
;
};
#define KEYSET_INFO_PUBLIC 0x0f
#define DRV_SELF_ADDED (1L << 4)
#define DRV_SELF_DELETED (1L << 5)
#define DRV_SELF_UPDATED (1L << 6)
/* These macros are wrappers for the corresponding set_tuplefield functions
/* These macros are wrappers for the corresponding set_tuplefield functions
but these handle automatic NULL determination and call set_tuplefield_null()
but these handle automatic NULL determination and call set_tuplefield_null()
if appropriate for the datatype (used by SQLGetTypeInfo).
if appropriate for the datatype (used by SQLGetTypeInfo).
...
...
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