/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright ( c ) 2009 , 2025 , MariaDB Corporation .
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 */
#ifndef SELECT_RESULT_INCLUDED
#define SELECT_RESULT_INCLUDED
/* Pure interface for sending tabular data */
class select_result_sink: public Sql_alloc
{
public :
THD *thd;
select_result_sink(THD *thd_arg): thd(thd_arg) {}
int send_data_with_check(List<Item> &items,
SELECT_LEX_UNIT *u,
ha_rows sent);
/*
send_data returns 0 on ok , 1 on error and - 1 if data was ignored , for
example for a duplicate row entry written to a temp table .
*/
virtual int send_data(List<Item> &items)=0 ;
virtual ~select_result_sink() = default ;
// Used in cursors to initialize and reset
void reinit(THD *thd_arg) { thd= thd_arg; }
};
class select_result_interceptor;
/*
Interface for sending tabular data , together with some other stuff :
- Primary purpose seems to be sending typed tabular data :
= the DDL is sent with send_fields ( )
= the rows are sent with send_data ( )
Besides that ,
- there seems to be an assumption that the sent data is a result of
SELECT_LEX_UNIT * unit ,
- nest_level is used by SQL parser
*/
class select_result :public select_result_sink
{
protected :
/*
All descendant classes have their send_data ( ) skip the first
unit - > offset_limit_cnt rows sent . Select_materialize
also uses unit - > get_column_types ( ) .
*/
SELECT_LEX_UNIT *unit;
/* Something used only by the parser: */
public :
ha_rows est_records; /* estimated number of records in the result */
select_result(THD *thd_arg): select_result_sink(thd_arg), est_records(0 ) {}
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
virtual ~select_result() = default ;
/**
Change wrapped select_result .
Replace the wrapped result object with new_result and call
prepare ( ) and prepare2 ( ) on new_result .
This base class implementation doesn ' t wrap other select_results .
@ param new_result The new result object to wrap around
@ retval false Success
@ retval true Error
*/
virtual bool change_result(select_result *new_result)
{
return false ;
}
virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u)
{
unit= u;
return 0 ;
}
virtual int prepare2(JOIN *join) { return 0 ; }
/*
Because of peculiarities of prepared statements protocol
we need to know number of columns in the result set ( if
there is a result set ) apart from sending columns metadata .
*/
virtual uint field_count(List<Item> &fields) const
{ return fields.elements; }
virtual bool send_result_set_metadata(List<Item> &list, uint flags)=0 ;
virtual bool initialize_tables (JOIN *join) { return 0 ; }
virtual bool send_eof()=0 ;
/**
Check if this query returns a result set and therefore is allowed in
cursors and set an error message if it is not the case .
@ retval FALSE success
@ retval TRUE error , an error message is set
*/
virtual bool check_simple_select() const ;
virtual void abort_result_set() {}
virtual void reset_for_next_ps_execution();
void set_thd(THD *thd_arg) { thd= thd_arg; }
void reinit(THD *thd_arg)
{
select_result_sink::reinit(thd_arg);
unit= NULL;
}
#ifdef EMBEDDED_LIBRARY
virtual void begin_dataset() {}
#else
void begin_dataset() {}
#endif
virtual void update_used_tables() {}
/* this method is called just before the first row of the table can be read */
virtual void prepare_to_read_rows() {}
void remove_offset_limit()
{
unit->lim.remove_offset();
}
/*
This returns
- NULL if the class sends output row to the client
- this if the output is set elsewhere ( a file , @ variable , or table ) .
*/
virtual select_result_interceptor *result_interceptor()=0 ;
/*
This method is used to distinguish an normal SELECT from the cursor
structure discovery for cursor % ROWTYPE routine variables .
If this method returns " true " , then a SELECT execution performs only
all preparation stages , but does not fetch any rows .
*/
virtual bool view_structure_only() const { return false ; }
};
/*
Base class for select_result descendants which intercept and
transform result set rows . As the rows are not sent to the client ,
sending of result set metadata should be suppressed as well .
*/
class select_result_interceptor: public select_result
{
public :
select_result_interceptor(THD *thd_arg):
select_result(thd_arg), suppress_my_ok(false )
{
DBUG_ENTER("select_result_interceptor::select_result_interceptor" );
DBUG_PRINT("enter" , ("this %p" , this ));
DBUG_VOID_RETURN;
} /* Remove gcc warning */
uint field_count(List<Item> &fields) const override { return 0 ; }
bool send_result_set_metadata(List<Item> &fields, uint flag) override { return FALSE ; }
select_result_interceptor *result_interceptor() override { return this ; }
/*
Instruct the object to not call my_ok ( ) . Client output will be handled
elsewhere . ( this is used by ANALYZE $ stmt feature ) .
*/
void disable_my_ok_calls() { suppress_my_ok= true ; }
void reinit(THD *thd_arg)
{
select_result::reinit(thd_arg);
suppress_my_ok= false ;
}
protected :
bool suppress_my_ok;
};
#endif // SELECT_RESULT_INCLUDED
Messung V0.5 in Prozent C=91 H=100 G=95
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-08)
¤
*© Formatika GbR, Deutschland