From 4ad1b5b766c574efd5c60dcd1017d0b2538b9e96 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Sat, 8 Sep 2001 02:28:41 +0000 Subject: [PATCH] Resolve compile errors on unix. Rename psqlodbc.def -> psqlodbc_win32.def. Improve internal *declare cursor* handling a little. Hiroshi Inoue --- src/interfaces/odbc/convert.c | 123 ++++++++++++++---- src/interfaces/odbc/convert.h | 4 +- src/interfaces/odbc/execute.c | 2 +- src/interfaces/odbc/gpps.c | 16 +-- src/interfaces/odbc/gpps.h | 16 +-- .../odbc/{psqlodbc.def => psqlodbc_win32.def} | 0 src/interfaces/odbc/qresult.c | 4 +- src/interfaces/odbc/statement.h | 4 +- src/interfaces/odbc/win32.mak | 8 +- 9 files changed, 121 insertions(+), 56 deletions(-) rename src/interfaces/odbc/{psqlodbc.def => psqlodbc_win32.def} (100%) diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index d0abad249e..52303511e1 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -21,6 +21,7 @@ #include #include +#include "psqlodbc.h" #ifdef MULTIBYTE #include "multibyte.h" #endif @@ -938,6 +939,26 @@ into_table_from(const char *stmt) return isspace((unsigned char) stmt[4]); } +/*---------- + * Check if the statement is + * SELECT ... FOR UPDATE ..... + * This isn't really a strict check but ... + *---------- + */ +static BOOL +table_for_update(const char *stmt, int *endpos) +{ + const char *wstmt = stmt; + while (isspace((unsigned char) *(++wstmt))); + if (! *wstmt) + return FALSE; + if (strnicmp(wstmt, "update", 6)) + return FALSE; + wstmt += 6; + *endpos = wstmt - stmt; + return !wstmt[0] || isspace((unsigned char) wstmt[0]); +} + /* * This function inserts parameters into an SQL statements. * It will also modify a SELECT statement for use with declare/fetch cursors. @@ -968,14 +989,17 @@ copy_statement_with_parameters(StatementClass *stmt) Oid lobj_oid; int lobj_fd, retval; - BOOL check_select_into = FALSE; /* select into check */ + BOOL check_cursor_ok = FALSE; /* check cursor restriction */ BOOL proc_no_param = TRUE; - unsigned int declare_pos; + 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; + char token_save[32]; + int token_len; + BOOL prev_token_end; #ifdef DRIVER_CURSOR_IMPLEMENT - BOOL ins_ctrl = FALSE; + BOOL search_from_pos = FALSE; #endif /* DRIVER_CURSOR_IMPLEMENT */ #ifdef PREPARE_TRIAL prepare_dummy_cursor = stmt->pre_executing; @@ -1012,7 +1036,7 @@ copy_statement_with_parameters(StatementClass *stmt) stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; else if (!stmt->ti || stmt->ntab != 1) stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - else ins_ctrl = TRUE; + else search_from_pos = TRUE; } #endif /* DRIVER_CURSOR_IMPLEMENT */ @@ -1021,7 +1045,10 @@ copy_statement_with_parameters(StatementClass *stmt) sprintf(stmt->cursor_name, "SQL_CUR%p", stmt); oldstmtlen = strlen(old_statement); CVT_INIT(oldstmtlen); + stmt->miscinfo = 0; + token_len = 0; + prev_token_end = TRUE; /* For selects, prepend a declare cursor to the statement */ if (stmt->statement_type == STMT_TYPE_SELECT) { @@ -1035,10 +1062,10 @@ copy_statement_with_parameters(StatementClass *stmt) } else if (ci->drivers.use_declarefetch) SC_set_fetchcursor(stmt); - sprintf(new_statement, "%s declare %s cursor for ", + sprintf(new_statement, "%sdeclare %s cursor for ", new_statement, stmt->cursor_name); npos = strlen(new_statement); - check_select_into = TRUE; + check_cursor_ok = TRUE; declare_pos = npos; } } @@ -1176,28 +1203,68 @@ copy_statement_with_parameters(StatementClass *stmt) in_escape = TRUE; else if (oldchar == '\"') in_dquote = TRUE; - else if (check_select_into && /* select into check */ - opos > 0 && - isspace((unsigned char) old_statement[opos - 1]) && - into_table_from(&old_statement[opos])) + else { - stmt->statement_type = STMT_TYPE_CREATE; - SC_no_pre_executable(stmt); - SC_no_fetchcursor(stmt); - stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; - memmove(new_statement, new_statement + declare_pos, npos - declare_pos); - npos -= declare_pos; - } + if (isspace(oldchar)) + { + if (!prev_token_end) + { + prev_token_end = TRUE; + token_save[token_len] = '\0'; + if (token_len == 4) + { + if (check_cursor_ok && + into_table_from(&old_statement[opos - token_len])) + { + stmt->statement_type = STMT_TYPE_CREATE; + SC_no_pre_executable(stmt); + SC_no_fetchcursor(stmt); + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + memmove(new_statement, new_statement + declare_pos, npos - declare_pos); + npos -= declare_pos; + } #ifdef DRIVER_CURSOR_IMPLEMENT - else if (ins_ctrl && /* select into check */ - opos > 0 && - isspace((unsigned char) old_statement[opos - 1]) && - strnicmp(&old_statement[opos], "from", 4) == 0) - { - ins_ctrl = FALSE; - CVT_APPEND_STR(", CTID, OID "); - } + else if (search_from_pos && /* where's from clause */ + strnicmp(token_save, "from", 4) == 0) + { + search_from_pos = FALSE; + npos -= 5; + CVT_APPEND_STR(", CTID, OID from"); + } #endif /* DRIVER_CURSOR_IMPLEMENT */ + } + if (token_len == 3) + { + int endpos; + if (check_cursor_ok && + strnicmp(token_save, "for", 3) == 0 && + table_for_update(&old_statement[opos], &endpos)) + { + SC_no_fetchcursor(stmt); + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + if (prepare_dummy_cursor) + { + npos -= 4; + opos += endpos; + } + else + { + memmove(new_statement, new_statement + declare_pos, npos - declare_pos); + npos -= declare_pos; + } + } + } + } + } + else if (prev_token_end) + { + prev_token_end = FALSE; + token_save[0] = oldchar; + token_len = 1; + } + else + token_save[token_len++] = oldchar; + } CVT_APPEND_CHAR(oldchar); continue; } @@ -1634,7 +1701,7 @@ copy_statement_with_parameters(StatementClass *stmt) } #ifdef DRIVER_CURSOR_IMPLEMENT - if (ins_ctrl) + if (search_from_pos) stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; #endif /* DRIVER_CURSOR_IMPLEMENT */ #ifdef PREPARE_TRIAL @@ -2142,7 +2209,7 @@ decode(const char *in, char *out) *------- */ int -convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, +convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue) { Oid oid; diff --git a/src/interfaces/odbc/convert.h b/src/interfaces/odbc/convert.h index aaf1518344..0746820942 100644 --- a/src/interfaces/odbc/convert.h +++ b/src/interfaces/odbc/convert.h @@ -29,8 +29,8 @@ typedef struct int ss; } SIMPLE_TIME; -int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, const void *value, int col); -int copy_and_convert_field(StatementClass *stmt, Int4 field_type, const void *value, Int2 fCType, +int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col); +int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue); int copy_statement_with_parameters(StatementClass *stmt); diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c index bd2600bd4f..653539ddba 100644 --- a/src/interfaces/odbc/execute.c +++ b/src/interfaces/odbc/execute.c @@ -458,11 +458,11 @@ PGAPI_Cancel( static char *func = "PGAPI_Cancel"; StatementClass *stmt = (StatementClass *) hstmt; RETCODE result; + ConnInfo *ci; #ifdef WIN32 HMODULE hmodule; FARPROC addr; - ConnInfo *ci; #endif diff --git a/src/interfaces/odbc/gpps.c b/src/interfaces/odbc/gpps.c index 4b13fbe62e..450f0b1e50 100644 --- a/src/interfaces/odbc/gpps.c +++ b/src/interfaces/odbc/gpps.c @@ -51,15 +51,15 @@ * ODBCINST_INI */ DWORD -GetPrivateProfileString(char *theSection, /* section name */ - char *theKey, /* search key name */ - char *theDefault, /* default value if not +GetPrivateProfileString(const char *theSection, /* section name */ + const char *theKey, /* search key name */ + const char *theDefault, /* default value if not * found */ char *theReturnBuffer, /* return value stored * here */ size_t theReturnBufferLength, /* byte length of return * buffer */ - char *theIniFileName) /* pathname of ini file to + const char *theIniFileName) /* pathname of ini file to * search */ { char buf[MAXPGPATH]; @@ -273,10 +273,10 @@ GetPrivateProfileString(char *theSection, /* section name */ DWORD -WritePrivateProfileString(char *theSection, /* section name */ - char *theKey, /* write key name */ - char *theBuffer, /* input buffer */ - char *theIniFileName) /* pathname of ini file to +WritePrivateProfileString(const char *theSection, /* section name */ + const char *theKey, /* write key name */ + const char *theBuffer, /* input buffer */ + const char *theIniFileName) /* pathname of ini file to * write */ { return 0; diff --git a/src/interfaces/odbc/gpps.h b/src/interfaces/odbc/gpps.h index 9dc9d64210..c0b6a20796 100644 --- a/src/interfaces/odbc/gpps.h +++ b/src/interfaces/odbc/gpps.h @@ -17,22 +17,22 @@ extern "C" #endif DWORD - GetPrivateProfileString(char *theSection, /* section name */ - char *theKey, /* search key name */ - char *theDefault, /* default value if not + GetPrivateProfileString(const char *theSection, /* section name */ + const char *theKey, /* search key name */ + const char *theDefault, /* default value if not * found */ char *theReturnBuffer, /* return valuse stored * here */ size_t theBufferLength, /* byte length of return * buffer */ - char *theIniFileName); /* pathname of ini file + const char *theIniFileName); /* pathname of ini file * to search */ DWORD - WritePrivateProfileString(char *theSection, /* section name */ - char *theKey, /* write key name */ - char *theBuffer, /* input buffer */ - char *theIniFileName); /* pathname of ini file + WritePrivateProfileString(const char *theSection, /* section name */ + const char *theKey, /* write key name */ + const char *theBuffer, /* input buffer */ + const char *theIniFileName); /* pathname of ini file * to write */ #ifdef __cplusplus diff --git a/src/interfaces/odbc/psqlodbc.def b/src/interfaces/odbc/psqlodbc_win32.def similarity index 100% rename from src/interfaces/odbc/psqlodbc.def rename to src/interfaces/odbc/psqlodbc_win32.def diff --git a/src/interfaces/odbc/qresult.c b/src/interfaces/odbc/qresult.c index e2d7541e36..151f2ab217 100644 --- a/src/interfaces/odbc/qresult.c +++ b/src/interfaces/odbc/qresult.c @@ -32,8 +32,6 @@ #define FALSE (BOOL)0 #endif -extern GLOBAL_VALUES globals; - /* * Used for building a Manual Result only @@ -119,7 +117,7 @@ QR_Constructor() rv->cursor = NULL; rv->aborted = FALSE; - rv->cache_size = globals.fetch_max; + rv->cache_size = 0; rv->rowset_size = 1; } diff --git a/src/interfaces/odbc/statement.h b/src/interfaces/odbc/statement.h index 95ae1437a1..bea157b118 100644 --- a/src/interfaces/odbc/statement.h +++ b/src/interfaces/odbc/statement.h @@ -232,10 +232,10 @@ struct StatementClass_ /* misc info */ #define SC_set_pre_executable(a) (a->miscinfo |= 1L) #define SC_no_pre_executable(a) (a->miscinfo &= ~1L) -#define SC_is_pre_executable(a) (a->miscinfo & 1L != 0) +#define SC_is_pre_executable(a) ((a->miscinfo & 1L) != 0) #define SC_set_fetchcursor(a) (a->miscinfo |= 2L) #define SC_no_fetchcursor(a) (a->miscinfo &= ~2L) -#define SC_is_fetchcursor(a) (a->miscinfo & 2L != 0) +#define SC_is_fetchcursor(a) ((a->miscinfo & 2L) != 0) /* Statement prototypes */ StatementClass *SC_Constructor(void); diff --git a/src/interfaces/odbc/win32.mak b/src/interfaces/odbc/win32.mak index 8b83e054ef..0158adbfa3 100644 --- a/src/interfaces/odbc/win32.mak +++ b/src/interfaces/odbc/win32.mak @@ -139,8 +139,8 @@ BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" BSC32_SBRS= \ LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" -DEF_FILE= "psqlodbc.def" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_win32.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" +DEF_FILE= "psqlodbc_win32.def" LINK32_OBJS= \ "$(INTDIR)\bind.obj" \ "$(INTDIR)\columninfo.obj" \ @@ -277,8 +277,8 @@ BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" BSC32_SBRS= \ LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept -DEF_FILE= "psqlodbc.def" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc_win32.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept +DEF_FILE= "psqlodbc_win32.def" LINK32_OBJS= \ "$(INTDIR)\bind.obj" \ "$(INTDIR)\columninfo.obj" \ -- 2.40.0