]> granicus.if.org Git - postgresql/commitdiff
1) Improve the implementation of *Disallow Premature* for
authorHiroshi Inoue <inoue@tpf.co.jp>
Fri, 14 Sep 2001 06:30:37 +0000 (06:30 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Fri, 14 Sep 2001 06:30:37 +0000 (06:30 +0000)
   older versions of servers.
2) Implement SQLProcedures.

Hiroshi Inoue

src/interfaces/odbc/convert.c
src/interfaces/odbc/execute.c
src/interfaces/odbc/info.c
src/interfaces/odbc/statement.c

index 84f99b40e3e06f7934b4661107de843709c3dfc9..f39a34f4c159b8a45a9f41f71a6b9cbdb3964670 100644 (file)
@@ -994,7 +994,7 @@ copy_statement_with_parameters(StatementClass *stmt)
        unsigned int    declare_pos = 0;
        ConnectionClass *conn = SC_get_conn(stmt);
        ConnInfo        *ci = &(conn->connInfo);
-       BOOL            prepare_dummy_cursor = FALSE;
+       BOOL            prepare_dummy_cursor = FALSE, begin_first = FALSE;
        char    token_save[32];
        int     token_len;
        BOOL    prev_token_end;
@@ -1055,8 +1055,11 @@ copy_statement_with_parameters(StatementClass *stmt)
                {
                        if (prepare_dummy_cursor)
                        {
-                               if (!CC_is_in_trans(conn))
-                                       strcpy(new_statement, "begin;");
+                               if (!CC_is_in_trans(conn) && PG_VERSION_GE(conn, 7.1))
+                               {
+                                       strcpy(new_statement, "BEGIN;");
+                                       begin_first = TRUE;
+                               }
                        }
                        else if (ci->drivers.use_declarefetch)
                                SC_set_fetchcursor(stmt);
@@ -1718,8 +1721,8 @@ copy_statement_with_parameters(StatementClass *stmt)
                char fetchstr[128];     
                sprintf(fetchstr, ";fetch backward in %s;close %s;",
                                stmt->cursor_name, stmt->cursor_name);
-               if (!CC_is_in_trans(conn))
-                       strcat(fetchstr, "commit;");
+               if (begin_first && CC_is_in_autocommit(conn))
+                       strcat(fetchstr, "COMMIT;");
                CVT_APPEND_STR(fetchstr);
                stmt->inaccurate_result = TRUE;
        }
index b57a98b34c49c4a3f55c4f04c02148b59a636bef..d13a37e8effdacbabd9928232d8cafee1233cd53 100644 (file)
@@ -349,10 +349,29 @@ PGAPI_Execute(
                if (SC_is_pre_executable(stmt))
                {
                        BOOL    in_trans = CC_is_in_trans(conn);
+                       BOOL    issued_begin = FALSE, begin_included = FALSE;
                        QResultClass    *res;
+
+                       if (strnicmp(stmt->stmt_with_params, "BEGIN;", 6) == 0)
+                               begin_included = TRUE;
+                       else if (!in_trans)
+                       {
+                               res = CC_send_query(conn, "BEGIN", NULL);
+                               if (res && !QR_aborted(res))
+                                       issued_begin = TRUE;
+                               if (res)
+                                       QR_Destructor(res);
+                               if (!issued_begin)
+                               {
+                                       stmt->errornumber = STMT_EXEC_ERROR;
+                                       stmt->errormsg = "Handle prepare error";
+                                       return SQL_ERROR;
+                               }
+                       }
+                       /* we are now in a transaction */
                        CC_set_in_trans(conn);
                        stmt->result = res = CC_send_query(conn, stmt->stmt_with_params, NULL);
-                       if (res && QR_aborted(res))
+                       if (!res || QR_aborted(res))
                        {
                                CC_abort(conn);
                                stmt->errornumber = STMT_EXEC_ERROR;
@@ -361,8 +380,18 @@ PGAPI_Execute(
                        }
                        else
                        {
-                               if (!in_trans)
-                                       CC_set_no_trans(conn);
+                               if (CC_is_in_autocommit(conn))
+                               {
+                                       if (issued_begin)
+                                       {
+                                               res = CC_send_query(conn, "COMMIT", NULL);
+                                               CC_set_no_trans(conn);
+                                               if (res)
+                                                       QR_Destructor(res);
+                                       }
+                                       else if (!in_trans && begin_included)
+                                               CC_set_no_trans(conn);
+                               }       
                                stmt->status =STMT_FINISHED;
                                return SQL_SUCCESS;
                        }
@@ -650,6 +679,7 @@ PGAPI_ParamData(
                                return SQL_ERROR;
                        }
                        ok = QR_command_successful(res);
+                       CC_set_no_trans(stmt->hdbc);
                        QR_Destructor(res);
                        if (!ok)
                        {
@@ -658,8 +688,6 @@ PGAPI_ParamData(
                                SC_log_error(func, "", stmt);
                                return SQL_ERROR;
                        }
-
-                       CC_set_no_trans(stmt->hdbc);
                }
                stmt->lobj_fd = -1;
        }
index 54d97304bc317ea50171971ae0388e395e65f144..431a9b1d14017c3f96153bed2e8810c27d2a5e99 100644 (file)
@@ -832,7 +832,8 @@ PGAPI_GetFunctions(
                                UWORD FAR *pfExists)
 {
        static char *func = "PGAPI_GetFunctions";
-       ConnInfo *ci = &(((ConnectionClass *)hdbc)->connInfo);
+       ConnectionClass *conn = (ConnectionClass *)hdbc;
+       ConnInfo *ci = &(conn->connInfo);
 
        mylog("%s: entering...%u\n", func, fFunction);
 
@@ -915,7 +916,10 @@ PGAPI_GetFunctions(
                        pfExists[SQL_API_SQLPARAMOPTIONS] = FALSE;
                        pfExists[SQL_API_SQLPRIMARYKEYS] = TRUE;
                        pfExists[SQL_API_SQLPROCEDURECOLUMNS] = FALSE;
-                       pfExists[SQL_API_SQLPROCEDURES] = FALSE;
+                       if (PG_VERSION_LT(conn, 6.5))
+                               pfExists[SQL_API_SQLPROCEDURES] = FALSE;
+                       else
+                               pfExists[SQL_API_SQLPROCEDURES] = TRUE;
                        pfExists[SQL_API_SQLSETPOS] = TRUE;
                        pfExists[SQL_API_SQLSETSCROLLOPTIONS] = TRUE;           /* odbc 1.0 */
                        pfExists[SQL_API_SQLTABLEPRIVILEGES] = FALSE;
@@ -1090,7 +1094,10 @@ PGAPI_GetFunctions(
                                        *pfExists = FALSE;
                                        break;
                                case SQL_API_SQLPROCEDURES:
-                                       *pfExists = FALSE;
+                                       if (PG_VERSION_LT(conn, 6.5))
+                                               *pfExists = FALSE;
+                                       else
+                                               *pfExists = TRUE;
                                        break;
                                case SQL_API_SQLSETPOS:
                                        *pfExists = TRUE;
@@ -3615,30 +3622,53 @@ PGAPI_Procedures(
 {
        static char *func = "PGAPI_Procedures";
        StatementClass  *stmt = (StatementClass *) hstmt;
-       Int2            result_cols;
+       ConnectionClass *conn = SC_get_conn(stmt);
+       char            proc_query[INFO_INQUIRY_LEN];
+       QResultClass    *res;
 
        mylog("%s: entering...\n", func);
+       
+       if (PG_VERSION_LT(conn, 6.5))
+       {
+               stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
+               stmt->errormsg = "Version is too old";
+               SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
+               return SQL_ERROR;
+       }
+       if (!SC_recycle_statement(stmt))
+               return SQL_ERROR;
+       /*
+        *      The following seems the simplest implementation
+        */
+       strcpy(proc_query, "select '' as ""PROCEDURE_CAT"", '' as ""PROCEDURE_SCHEM"","
+               " proname as ""PROCEDURE_NAME"", '' as ""NUM_INPUT_PARAMS"","
+               " '' as ""NUM_OUTPUT_PARAMS"", '' as ""NUM_RESULT_SETS"","
+               " '' as ""REMARKS"","
+               " 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);
 
+       res = CC_send_query(conn, proc_query, NULL);
+       if (!res || QR_aborted(res))
+       {
+               if (res)
+                       QR_Destructor(res);
+               stmt->errornumber = STMT_EXEC_ERROR;
+               stmt->errormsg = "PGAPI_Procedures query error";
+               return SQL_ERROR;
+       }
+       stmt->result = res;
        /*
-       * a statement is actually executed, so we'll have to do this
-       * ourselves.
-       */
-       result_cols = 8;
-       extend_bindings(stmt, result_cols);
+        * also, things need to think that this statement is finished so the
+        * results can be retrieved.
+        */
+       stmt->status = STMT_FINISHED;
+       extend_bindings(stmt, 8);
+       /* set up the current tuple pointer for SQLFetch */
+       stmt->currTuple = -1;
+       stmt->rowset_start = -1;
+       stmt->current_col = -1;
 
-       /* set the field names */
-       QR_set_num_fields(stmt->result, result_cols);
-       QR_set_field_info(stmt->result, 0, "PROCEDURE_CAT", PG_TYPE_TEXT, MAX_INFO_STRING);
-       QR_set_field_info(stmt->result, 1, "PROCEDURE_SCHEM", PG_TYPE_TEXT, MAX_INFO_STRING);
-       QR_set_field_info(stmt->result, 2, "PROCEDURE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
-       QR_set_field_info(stmt->result, 3, "NUM_INPUT_PARAMS", PG_TYPE_TEXT, MAX_INFO_STRING);
-       QR_set_field_info(stmt->result, 4, "NUM_OUTPUT_PARAMS", PG_TYPE_TEXT, MAX_INFO_STRING);
-       QR_set_field_info(stmt->result, 5, "NUM_RESULT_SET", PG_TYPE_TEXT, MAX_INFO_STRING);
-       QR_set_field_info(stmt->result, 6, "REMARKS", PG_TYPE_TEXT, MAX_INFO_STRING);
-       QR_set_field_info(stmt->result, 7, "PROCEDURE_TYPE", PG_TYPE_INT2, 2);
-                                                             
-       SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
-       return SQL_ERROR;
+       return SQL_SUCCESS;
 }
 
 
index 584d5a710d7643d97576490ed52fd007d51dd186..9efd4fb52c8fff9a3a00faf6dcbad1db3a1baf4e 100644 (file)
@@ -468,10 +468,8 @@ SC_recycle_statement(StatementClass *self)
                        conn = SC_get_conn(self);
                        if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
                        {
-                               QResultClass *res = CC_send_query(conn, "ABORT", NULL);
-
-                               QR_Destructor(res);
-                               CC_set_no_trans(conn);
+                               if (SC_is_pre_executable(self) && !conn->connInfo.disallow_premature) 
+                                       CC_abort(conn);
                        }
                        break;