Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 70b0831

Browse files
author
Hiroshi Inoue
committed
1) Improve the implementation of *Disallow Premature* for
older versions of servers. 2) Implement SQLProcedures. Hiroshi Inoue
1 parent 4f0e6e3 commit 70b0831

File tree

4 files changed

+95
-36
lines changed

4 files changed

+95
-36
lines changed

src/interfaces/odbc/convert.c

+8-5
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ copy_statement_with_parameters(StatementClass *stmt)
994994
unsigned int declare_pos = 0;
995995
ConnectionClass *conn = SC_get_conn(stmt);
996996
ConnInfo *ci = &(conn->connInfo);
997-
BOOL prepare_dummy_cursor = FALSE;
997+
BOOL prepare_dummy_cursor = FALSE, begin_first = FALSE;
998998
char token_save[32];
999999
int token_len;
10001000
BOOL prev_token_end;
@@ -1055,8 +1055,11 @@ copy_statement_with_parameters(StatementClass *stmt)
10551055
{
10561056
if (prepare_dummy_cursor)
10571057
{
1058-
if (!CC_is_in_trans(conn))
1059-
strcpy(new_statement, "begin;");
1058+
if (!CC_is_in_trans(conn) && PG_VERSION_GE(conn, 7.1))
1059+
{
1060+
strcpy(new_statement, "BEGIN;");
1061+
begin_first = TRUE;
1062+
}
10601063
}
10611064
else if (ci->drivers.use_declarefetch)
10621065
SC_set_fetchcursor(stmt);
@@ -1718,8 +1721,8 @@ copy_statement_with_parameters(StatementClass *stmt)
17181721
char fetchstr[128];
17191722
sprintf(fetchstr, ";fetch backward in %s;close %s;",
17201723
stmt->cursor_name, stmt->cursor_name);
1721-
if (!CC_is_in_trans(conn))
1722-
strcat(fetchstr, "commit;");
1724+
if (begin_first && CC_is_in_autocommit(conn))
1725+
strcat(fetchstr, "COMMIT;");
17231726
CVT_APPEND_STR(fetchstr);
17241727
stmt->inaccurate_result = TRUE;
17251728
}

src/interfaces/odbc/execute.c

+33-5
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,29 @@ PGAPI_Execute(
349349
if (SC_is_pre_executable(stmt))
350350
{
351351
BOOL in_trans = CC_is_in_trans(conn);
352+
BOOL issued_begin = FALSE, begin_included = FALSE;
352353
QResultClass *res;
354+
355+
if (strnicmp(stmt->stmt_with_params, "BEGIN;", 6) == 0)
356+
begin_included = TRUE;
357+
else if (!in_trans)
358+
{
359+
res = CC_send_query(conn, "BEGIN", NULL);
360+
if (res && !QR_aborted(res))
361+
issued_begin = TRUE;
362+
if (res)
363+
QR_Destructor(res);
364+
if (!issued_begin)
365+
{
366+
stmt->errornumber = STMT_EXEC_ERROR;
367+
stmt->errormsg = "Handle prepare error";
368+
return SQL_ERROR;
369+
}
370+
}
371+
/* we are now in a transaction */
353372
CC_set_in_trans(conn);
354373
stmt->result = res = CC_send_query(conn, stmt->stmt_with_params, NULL);
355-
if (res && QR_aborted(res))
374+
if (!res || QR_aborted(res))
356375
{
357376
CC_abort(conn);
358377
stmt->errornumber = STMT_EXEC_ERROR;
@@ -361,8 +380,18 @@ PGAPI_Execute(
361380
}
362381
else
363382
{
364-
if (!in_trans)
365-
CC_set_no_trans(conn);
383+
if (CC_is_in_autocommit(conn))
384+
{
385+
if (issued_begin)
386+
{
387+
res = CC_send_query(conn, "COMMIT", NULL);
388+
CC_set_no_trans(conn);
389+
if (res)
390+
QR_Destructor(res);
391+
}
392+
else if (!in_trans && begin_included)
393+
CC_set_no_trans(conn);
394+
}
366395
stmt->status =STMT_FINISHED;
367396
return SQL_SUCCESS;
368397
}
@@ -650,6 +679,7 @@ PGAPI_ParamData(
650679
return SQL_ERROR;
651680
}
652681
ok = QR_command_successful(res);
682+
CC_set_no_trans(stmt->hdbc);
653683
QR_Destructor(res);
654684
if (!ok)
655685
{
@@ -658,8 +688,6 @@ PGAPI_ParamData(
658688
SC_log_error(func, "", stmt);
659689
return SQL_ERROR;
660690
}
661-
662-
CC_set_no_trans(stmt->hdbc);
663691
}
664692
stmt->lobj_fd = -1;
665693
}

src/interfaces/odbc/info.c

+52-22
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,8 @@ PGAPI_GetFunctions(
832832
UWORD FAR *pfExists)
833833
{
834834
static char *func = "PGAPI_GetFunctions";
835-
ConnInfo *ci = &(((ConnectionClass *)hdbc)->connInfo);
835+
ConnectionClass *conn = (ConnectionClass *)hdbc;
836+
ConnInfo *ci = &(conn->connInfo);
836837

837838
mylog("%s: entering...%u\n", func, fFunction);
838839

@@ -915,7 +916,10 @@ PGAPI_GetFunctions(
915916
pfExists[SQL_API_SQLPARAMOPTIONS] = FALSE;
916917
pfExists[SQL_API_SQLPRIMARYKEYS] = TRUE;
917918
pfExists[SQL_API_SQLPROCEDURECOLUMNS] = FALSE;
918-
pfExists[SQL_API_SQLPROCEDURES] = FALSE;
919+
if (PG_VERSION_LT(conn, 6.5))
920+
pfExists[SQL_API_SQLPROCEDURES] = FALSE;
921+
else
922+
pfExists[SQL_API_SQLPROCEDURES] = TRUE;
919923
pfExists[SQL_API_SQLSETPOS] = TRUE;
920924
pfExists[SQL_API_SQLSETSCROLLOPTIONS] = TRUE; /* odbc 1.0 */
921925
pfExists[SQL_API_SQLTABLEPRIVILEGES] = FALSE;
@@ -1090,7 +1094,10 @@ PGAPI_GetFunctions(
10901094
*pfExists = FALSE;
10911095
break;
10921096
case SQL_API_SQLPROCEDURES:
1093-
*pfExists = FALSE;
1097+
if (PG_VERSION_LT(conn, 6.5))
1098+
*pfExists = FALSE;
1099+
else
1100+
*pfExists = TRUE;
10941101
break;
10951102
case SQL_API_SQLSETPOS:
10961103
*pfExists = TRUE;
@@ -3615,30 +3622,53 @@ PGAPI_Procedures(
36153622
{
36163623
static char *func = "PGAPI_Procedures";
36173624
StatementClass *stmt = (StatementClass *) hstmt;
3618-
Int2 result_cols;
3625+
ConnectionClass *conn = SC_get_conn(stmt);
3626+
char proc_query[INFO_INQUIRY_LEN];
3627+
QResultClass *res;
36193628

36203629
mylog("%s: entering...\n", func);
3630+
3631+
if (PG_VERSION_LT(conn, 6.5))
3632+
{
3633+
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
3634+
stmt->errormsg = "Version is too old";
3635+
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
3636+
return SQL_ERROR;
3637+
}
3638+
if (!SC_recycle_statement(stmt))
3639+
return SQL_ERROR;
3640+
/*
3641+
* The following seems the simplest implementation
3642+
*/
3643+
strcpy(proc_query, "select '' as ""PROCEDURE_CAT"", '' as ""PROCEDURE_SCHEM"","
3644+
" proname as ""PROCEDURE_NAME"", '' as ""NUM_INPUT_PARAMS"","
3645+
" '' as ""NUM_OUTPUT_PARAMS"", '' as ""NUM_RESULT_SETS"","
3646+
" '' as ""REMARKS"","
3647+
" case when prorettype =0 then 1::int2 else 2::int2 end as ""PROCEDURE_TYPE"" from pg_proc");
3648+
my_strcat(proc_query, " where proname like '%.*s'", szProcName, cbProcName);
36213649

3650+
res = CC_send_query(conn, proc_query, NULL);
3651+
if (!res || QR_aborted(res))
3652+
{
3653+
if (res)
3654+
QR_Destructor(res);
3655+
stmt->errornumber = STMT_EXEC_ERROR;
3656+
stmt->errormsg = "PGAPI_Procedures query error";
3657+
return SQL_ERROR;
3658+
}
3659+
stmt->result = res;
36223660
/*
3623-
* a statement is actually executed, so we'll have to do this
3624-
* ourselves.
3625-
*/
3626-
result_cols = 8;
3627-
extend_bindings(stmt, result_cols);
3661+
* also, things need to think that this statement is finished so the
3662+
* results can be retrieved.
3663+
*/
3664+
stmt->status = STMT_FINISHED;
3665+
extend_bindings(stmt, 8);
3666+
/* set up the current tuple pointer for SQLFetch */
3667+
stmt->currTuple = -1;
3668+
stmt->rowset_start = -1;
3669+
stmt->current_col = -1;
36283670

3629-
/* set the field names */
3630-
QR_set_num_fields(stmt->result, result_cols);
3631-
QR_set_field_info(stmt->result, 0, "PROCEDURE_CAT", PG_TYPE_TEXT, MAX_INFO_STRING);
3632-
QR_set_field_info(stmt->result, 1, "PROCEDURE_SCHEM", PG_TYPE_TEXT, MAX_INFO_STRING);
3633-
QR_set_field_info(stmt->result, 2, "PROCEDURE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
3634-
QR_set_field_info(stmt->result, 3, "NUM_INPUT_PARAMS", PG_TYPE_TEXT, MAX_INFO_STRING);
3635-
QR_set_field_info(stmt->result, 4, "NUM_OUTPUT_PARAMS", PG_TYPE_TEXT, MAX_INFO_STRING);
3636-
QR_set_field_info(stmt->result, 5, "NUM_RESULT_SET", PG_TYPE_TEXT, MAX_INFO_STRING);
3637-
QR_set_field_info(stmt->result, 6, "REMARKS", PG_TYPE_TEXT, MAX_INFO_STRING);
3638-
QR_set_field_info(stmt->result, 7, "PROCEDURE_TYPE", PG_TYPE_INT2, 2);
3639-
3640-
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
3641-
return SQL_ERROR;
3671+
return SQL_SUCCESS;
36423672
}
36433673

36443674

src/interfaces/odbc/statement.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,8 @@ SC_recycle_statement(StatementClass *self)
468468
conn = SC_get_conn(self);
469469
if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
470470
{
471-
QResultClass *res = CC_send_query(conn, "ABORT", NULL);
472-
473-
QR_Destructor(res);
474-
CC_set_no_trans(conn);
471+
if (SC_is_pre_executable(self) && !conn->connInfo.disallow_premature)
472+
CC_abort(conn);
475473
}
476474
break;
477475

0 commit comments

Comments
 (0)