=== modified file 'driver/driver.h' --- driver/driver.h 2009-10-07 20:43:23 +0000 +++ driver/driver.h 2010-01-18 19:53:54 +0000 @@ -317,30 +317,32 @@ typedef struct tagDBC { - ENV *env; - MYSQL mysql; - LIST *statements; - LIST *exp_desc; /* explicit descriptors */ - LIST list; - STMT_OPTIONS stmt_options; - MYERROR error; - FILE *query_log; - char st_error_prefix[255]; + ENV *env; + MYSQL mysql; + LIST *statements; + LIST *exp_desc; /* explicit descriptors */ + LIST list; + STMT_OPTIONS stmt_options; + MYERROR error; + FILE *query_log; + char st_error_prefix[255]; char *database; - SQLUINTEGER login_timeout; - time_t last_query_time; - int txn_isolation; - uint port; - uint cursor_count; - uint commit_flag; + SQLUINTEGER login_timeout; + time_t last_query_time; + int txn_isolation; + uint port; + uint cursor_count; + uint commit_flag; #ifdef THREAD pthread_mutex_t lock; #endif - my_bool unicode; /* Whether SQL*ConnectW was used */ - CHARSET_INFO *ansi_charset_info, /* 'ANSI' charset (SQL_C_CHAR) */ - *cxn_charset_info; /* Connection charset ('ANSI' or utf-8) */ - DataSource *ds; /* data source used to connect (parsed or stored) */ + my_bool unicode; /* Whether SQL*ConnectW was used */ + CHARSET_INFO *ansi_charset_info, /* 'ANSI' charset (SQL_C_CHAR) */ + *cxn_charset_info; /* Connection charset ('ANSI' or utf-8) */ + DataSource *ds; /* data source used to connect (parsed or stored) */ + SQLULEN sql_select_limit; /* value of the sql_select_limit currently set for a session + (SQLULEN)(-1) if wasn't set */ } DBC; === modified file 'driver/execute.c' --- driver/execute.c 2009-12-29 20:24:51 +0000 +++ driver/execute.c 2010-01-18 15:46:15 +0000 @@ -41,26 +41,12 @@ if ( !query ) return error; /* Probably error from insert_param */ - if (stmt->stmt_options.max_rows && - stmt->stmt_options.max_rows != (SQLULEN)~0L) + if(!SQL_SUCCEEDED(set_sql_select_limit(stmt->dbc, stmt->stmt_options.max_rows))) { - /* Add limit to select statement */ - char *pos,*tmp_buffer; - for ( pos= query; isspace(*pos) ; pos++ ) ; - if ( !myodbc_casecmp(pos,"select",6) ) - { - uint length= strlen(pos); - if ( (tmp_buffer= my_malloc(length+30,MYF(0))) ) - { - memcpy(tmp_buffer,pos,length); - sprintf(tmp_buffer+length, " limit %lu", - (unsigned long)stmt->stmt_options.max_rows); - if ( query != stmt->query ) - my_free(query,MYF(0)); - query= tmp_buffer; - } - } + /* if setting sql_select_limit fails, the query will probably fail anyway too */ + return error; } + MYLOG_QUERY(stmt, query); pthread_mutex_lock(&stmt->dbc->lock); if ( check_if_server_is_alive( stmt->dbc ) ) === modified file 'driver/handle.c' --- driver/handle.c 2009-05-02 20:53:50 +0000 +++ driver/handle.c 2010-01-18 19:53:54 +0000 @@ -215,6 +215,7 @@ dbc->unicode= 0; dbc->ansi_charset_info= dbc->cxn_charset_info= NULL; dbc->exp_desc= NULL; + dbc->sql_select_limit= (SQLULEN) -1; pthread_mutex_init(&dbc->lock,NULL); pthread_mutex_lock(&dbc->lock); myodbc_ov_init(penv->odbc_ver); /* Initialize based on ODBC version */ === modified file 'driver/myutil.h' --- driver/myutil.h 2009-12-29 20:24:51 +0000 +++ driver/myutil.h 2009-12-29 22:36:32 +0000 @@ -138,6 +138,8 @@ void reset_getdata_position(STMT *stmt); +SQLRETURN set_sql_select_limit(DBC *dbc, SQLULEN new_value); + uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, const char *from, uint32 from_length, CHARSET_INFO *from_cs, === modified file 'driver/utility.c' --- driver/utility.c 2009-12-29 20:24:51 +0000 +++ driver/utility.c 2010-01-18 19:48:17 +0000 @@ -29,6 +29,7 @@ #include "errmsg.h" #include +const SQLULEN sql_select_unlimited= (SQLULEN)-1; /** Execute a SQL statement. @@ -2705,3 +2706,38 @@ return ptr ? ((SQLCHAR *) ptr) + offset : NULL; } + + +/** + Sets the value of @@sql_select_limit + + @param[in] dbc dbc handler + @param[in] new_value Value to set @@sql_select_limit. + + Returns new_value if operation was successful, -1 otherwise + */ +SQLRETURN set_sql_select_limit(DBC *dbc, SQLULEN new_value) +{ + char query[44]; + SQLRETURN rc; + + /* Both 0 and max(SQLULEN) value mean no limit and sql_select_limit to DEFAULT */ + if (new_value == dbc->sql_select_limit + || new_value == sql_select_unlimited && dbc->sql_select_limit == 0) + return SQL_SUCCESS; + + if (new_value > 0 && new_value < sql_select_unlimited) + sprintf(query, "set @@sql_select_limit=%lu", (unsigned long)new_value); + else + { + strcpy(query, "set @@sql_select_limit=DEFAULT"); + new_value= 0; + } + + if (SQL_SUCCEEDED(rc= odbc_stmt(dbc, query))) + { + dbc->sql_select_limit= new_value; + } + + return rc; +}