mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 19:06:14 +01:00 
			
		
		
		
	 13cf8f5e9a
			
		
	
	
	13cf8f5e9a
	
	
	
		
			
			Replace * select_lex::offset_limit * select_lex::select_limit * select_lex::explicit_limit with select_lex::Lex_select_limit The Lex_select_limit already existed with the same elements and was used in by the yacc parser. This commit is in preparation for FETCH FIRST implementation, as it simplifies a lot of the code. Additionally, the parser is simplified by making use of the stack to return Lex_select_limit objects. Cleanup of init_query() too. Removes explicit_limit= 0 as it's done a bit later in init_select() with limit_params.empty()
		
			
				
	
	
		
			145 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|    Copyright (c) 2014, 2015 SkySQL Ab & MariaDB Foundation
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; version 2 of the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
 | |
| 
 | |
| /*
 | |
|   This file implements the group_by_handler code. This interface
 | |
|   can be used by storage handlers that can intercept summary or GROUP
 | |
|   BY queries from MariaDB and itself return the result to the user or
 | |
|   upper level.
 | |
| */
 | |
| 
 | |
| #include "mariadb.h"
 | |
| #include "sql_priv.h"
 | |
| #include "sql_select.h"
 | |
| 
 | |
| /*
 | |
|   Same return values as do_select();
 | |
| 
 | |
|   @retval
 | |
|     0  if ok
 | |
|   @retval
 | |
|     1  if error is sent
 | |
|   @retval
 | |
|     -1  if error should be sent
 | |
| */
 | |
| 
 | |
| int Pushdown_query::execute(JOIN *join)
 | |
| {
 | |
|   int err;
 | |
|   ha_rows max_limit;
 | |
|   bool reset_limit= FALSE;
 | |
|   Item **reset_item= 0;
 | |
|   THD *thd= handler->thd;
 | |
|   TABLE *table= handler->table;
 | |
|   DBUG_ENTER("Pushdown_query::execute");
 | |
| 
 | |
|   if ((err= handler->init_scan()))
 | |
|     goto error;
 | |
| 
 | |
|   if (store_data_in_temp_table)
 | |
|   {
 | |
|     max_limit= join->tmp_table_param.end_write_records;
 | |
|     reset_limit= TRUE;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     max_limit= join->unit->lim.get_select_limit();
 | |
|     if (join->unit->fake_select_lex)
 | |
|       reset_item= &join->unit->fake_select_lex->limit_params.select_limit;
 | |
|   }
 | |
| 
 | |
|   while (!(err= handler->next_row()))
 | |
|   {
 | |
|     if (unlikely(thd->check_killed()))
 | |
|     {
 | |
|       handler->end_scan();
 | |
|       DBUG_RETURN(-1);
 | |
|     }
 | |
| 
 | |
|     /* Check if we can accept the row */
 | |
|     if (!having || having->val_bool())
 | |
|     {
 | |
|       if (store_data_in_temp_table)
 | |
|       {
 | |
|         if ((err= table->file->ha_write_tmp_row(table->record[0])))
 | |
|         {
 | |
|           bool is_duplicate;
 | |
|           if (likely(!table->file->is_fatal_error(err, HA_CHECK_DUP)))
 | |
|             continue;                           // Distinct elimination
 | |
| 
 | |
|           if (create_internal_tmp_table_from_heap(thd, table,
 | |
|                                                   join->tmp_table_param.
 | |
|                                                   start_recinfo,
 | |
|                                                   &join->tmp_table_param.
 | |
|                                                   recinfo,
 | |
|                                                   err, 1, &is_duplicate))
 | |
|             DBUG_RETURN(1);
 | |
|           if (is_duplicate)
 | |
|             continue;
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         if (join->do_send_rows)
 | |
|         {
 | |
|           int error;
 | |
|           /* result < 0 if row was not accepted and should not be counted */
 | |
|           if (unlikely((error=
 | |
|                         join->result->send_data_with_check(*join->fields,
 | |
|                                                           join->unit,
 | |
|                                                           join->send_records))))
 | |
|           {
 | |
|             handler->end_scan();
 | |
|             DBUG_RETURN(error < 0 ? 0 : -1);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       /* limit handling */
 | |
|       if (++join->send_records >= max_limit && join->do_send_rows)
 | |
|       {
 | |
|         if (!(join->select_options & OPTION_FOUND_ROWS))
 | |
|           break;                              // LIMIT reached
 | |
|         join->do_send_rows= 0;                // Calculate FOUND_ROWS()
 | |
|         if (reset_limit)
 | |
|           join->unit->lim.set_unlimited();
 | |
|         if (reset_item)
 | |
|           *reset_item= 0;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if (err != 0 && err != HA_ERR_END_OF_FILE)
 | |
|     goto error;
 | |
| 
 | |
|   if ((err= handler->end_scan()))
 | |
|     goto error_2;
 | |
|   if (!store_data_in_temp_table && join->result->send_eof())
 | |
|     DBUG_RETURN(1);                              // Don't send error to client
 | |
| 
 | |
|   DBUG_RETURN(0);
 | |
| 
 | |
| error:
 | |
|   handler->end_scan();
 | |
| error_2:
 | |
|   handler->print_error(err, MYF(0));
 | |
|   DBUG_RETURN(-1);                              // Error not sent to client
 | |
| }
 | |
| 
 | |
| 
 | |
| void group_by_handler::print_error(int error, myf errflag)
 | |
| {
 | |
|   my_error(ER_GET_ERRNO, MYF(0), error, hton_name(ht)->str);
 | |
| }
 |