--- sql/oracle/parser3oracle.C 2008/07/07 13:25:26 1.71 +++ sql/oracle/parser3oracle.C 2013/05/27 20:10:14 1.78 @@ -1,21 +1,21 @@ /** @file Parser Oracle driver. - Copyright(c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] */ -static const char *RCSId="$Id: parser3oracle.C,v 1.71 2008/07/07 13:25:26 misha Exp $"; - #include "config_includes.h" #include "pa_sql_driver.h" #include +volatile const char * IDENT_PARSER3ORACLE_C="$Id: parser3oracle.C,v 1.78 2013/05/27 20:10:14 moko Exp $" IDENT_PA_SQL_DRIVER_H; + #define MAX_COLS 500 #define MAX_IN_LOBS 5 #define MAX_LOB_NAME_LENGTH 100 @@ -155,7 +155,7 @@ struct Connection { struct Options { bool bLowerCaseColumnNames; - bool bAllowLimitQueryModification; + bool bDisableQueryModification; const char* client_charset; } options; }; @@ -224,9 +224,9 @@ static const char *options2env(char *s, continue; } - if(strcmp(key, "AllowLimitQueryModification")==0){ + if(strcmp(key, "DisableQueryModification")==0){ if(options) - options->bAllowLimitQueryModification=atoi(value)!=0; + options->bDisableQueryModification=atoi(value)!=0; continue; } @@ -268,15 +268,15 @@ public: const char *initialize(char *dlopen_file_spec) { char *options=lsplit(dlopen_file_spec, '?'); - const char *error=dlopen_file_spec? - dlink(dlopen_file_spec):"client library column is empty"; + const char *error=options2env(options, 0); + if(!error) { - error=options2env(options, 0); + error=dlopen_file_spec ? dlink(dlopen_file_spec) : "client library column is empty"; if(!error) OCIInitialize((ub4)OCI_THREADED/*| OCI_OBJECT*/, (dvoid *)0, - (dvoid * (*)(void *, unsigned int))0, - (dvoid * (*)(void*, void*, unsigned int))0, + (dvoid * (*)(void *, size_t))0, + (dvoid * (*)(void*, void*, size_t))0, (void (*)(void*, void*))0 ); } @@ -307,7 +307,7 @@ public: Connection& connection=*(Connection *)services.malloc(sizeof(Connection)); connection.services=&services; connection.options.bLowerCaseColumnNames=true; - connection.options.bAllowLimitQueryModification=true; + connection.options.bDisableQueryModification=false; *connection_ref=&connection; char *user=url; @@ -445,20 +445,33 @@ public: return true; } - const char* quote(void *aconnection, - const char *from, unsigned int length) + // charset here is services.request_charset(), not connection.client_charset + // thus we can't use the sql server quoting support + const char* quote(void *aconnection, const char *str, unsigned int length) { - Connection& connection=*static_cast(aconnection); - char *result=(char*)connection.services->malloc_atomic(length*2+1); - char *to=result; - while(length--) { - switch(*from) { - case '\'': // "'" -> "''" - *to++='\''; - break; - } - *to++=*from++; + const char* from; + const char* from_end=str+length; + + size_t quoted=0; + + for(from=str; from(aconnection); + char *result=(char*)connection.services->malloc_atomic(length + quoted + 1); + char *to = result; + + for(from=str; from '' + *to++=*from; + } + *to=0; return result; } @@ -882,17 +895,17 @@ private: // private funcs (dvoid**) &col_name, (ub4 *) &col_name_len, (ub4)OCI_ATTR_NAME, (OCIError *)connection.errhp)); + size_t length=(size_t)col_name_len; if(transcode_needed){ // transcode column name from ?ClientCharset to $request:charset services.transcode(col_name, col_name_len, - col_name, col_name_len, + col_name, length, client_charset, request_charset); } Col& col=cols[column_count-1]; { - size_t length=(size_t)col_name_len; char *ptr=(char *)services.malloc_atomic(length+1); if( connection.options.bLowerCaseColumnNames ) tolower_str(ptr, col_name, length); @@ -1059,13 +1072,13 @@ cleanup: // no check call after this poi ){ modified_statement result={astatement, false, false, false}; - if(connection.options.bAllowLimitQueryModification && limit!=SQL_NO_LIMIT && strncasecmp(astatement, "select", 6)==0){ + if(!connection.options.bDisableQueryModification && limit!=SQL_NO_LIMIT && strncasecmp(astatement, "select", 6)==0){ result.limit=true; size_t statement_size=strlen(astatement); char* statement_limited; - if(offset && limit){/* offset and with limit!=0 */ + if(offset && limit/* throwing offset away if limit==0 */){ result.skip_rownum_column=true; result.offset=true; @@ -1086,13 +1099,13 @@ cleanup: // no check call after this poi strcat(statement_limited, astatement); statement_limited+=46+statement_size; - statement_limited+=snprintf(statement_limited, 18+MAX_NUMBER, ") z__) WHERE r__<=%u", limit+offset); - statement_limited+=snprintf(statement_limited, 9+MAX_NUMBER, " AND r__>%u", offset); + statement_limited+=snprintf(statement_limited, 18+MAX_NUMBER, ") z__) WHERE r__<=%lu", limit+offset); + statement_limited+=snprintf(statement_limited, 9+MAX_NUMBER, " AND r__>%lu", offset); } else { - // SELECT * FROM (user_query) WHERE ROWNUM<=limit+offset - // this statement must be easy for the server but we can't use it with offset + // SELECT * FROM (user_query) WHERE ROWNUM<=limit + // this statement can be easy for the sql server but we can't use it with offset statement_limited=(char *)connection.services->malloc_atomic( statement_size @@ -1107,7 +1120,7 @@ cleanup: // no check call after this poi strcat(statement_limited, astatement); statement_limited+=15+statement_size; - statement_limited+=snprintf(statement_limited, 16+MAX_NUMBER, ") WHERE ROWNUM<=%u", limit?limit+offset:0); + statement_limited+=snprintf(statement_limited, 16+MAX_NUMBER, ") WHERE ROWNUM<=%lu", limit); } *statement_limited=0; @@ -1234,11 +1247,19 @@ private: // conn client library funcs private: // conn client library funcs linking const char *dlink(const char *dlopen_file_spec) { - if(lt_dlinit()) - return lt_dlerror(); - lt_dlhandle handle=lt_dlopen(dlopen_file_spec); - if(!handle) - return lt_dlerror(); //"can not open the dynamic link module"; + if(lt_dlinit()){ + if(const char* result=lt_dlerror()) + return result; + return "can not prepare to dynamic loading"; + } + + lt_dlhandle handle=lt_dlopen(dlopen_file_spec); + + if(!handle){ + if(const char* result=lt_dlerror()) + return result; + return "can not open the dynamic link module"; + } #define DSLINK(name, action) \ name=(t_##name)lt_dlsym(handle, #name); \