WL#5095: SQL command class extensions

Affects: Server-9.x   —   Status: Un-Assigned

Describe some possible extensions to the Sql_cmd classes that make them more 
useful.
This worklog descibes some additional functions and member variables that can 
be added to the Sql_cmd class hierarchy, after the initial class has been 
created and after a derived class has been created for every SQL command.
 
1. Extensions to Sql_cmd base class

Sql_cmd is a common base class for all SQL commands. Each SQL command is 
represented by a class derived from Sql_cmd.

1.1 Functions

This chapter describes some high-level aspects of the methods defined for 
Sql_cmd. More details are found in LLD.

1.1.1 prepare()

prepare() is used to prepare a parsed command for execution. A prepared 
command can be executed multiple times.

The default implementation of prepare() is empty, meaning that all preparation 
must take place in execute().

1.1.2 is_select()

Return true if the prepared SQL command returns at least one rowset.
True if the concrete class is Sql_cmd_select or any class derived from 
Sql_cmd_select.

1.1.3 column_count

Returns the number of columns returned from a prepared select-type SQL command.

1.1.4 Column iterator functions

Iterator over result columns. To be defined.

1.1.5 parameter_count

Returns the number of parameters that this query needs for execution.

1.1.6 Parameter iterator functions

Iterator over parameters. To be defined.

1.1.7 table_count()

Returns number of tables and views that this command refers, directly or 
indirectly.

1.1.8 Table iterator functions

Iterator over referred tables. Replaces lex->query_tables. To be defined.

1.1.9 routine_count()

Returns number of routines potentially called by command.

1.1.10 Routine iterator functions

Iterator over called routines. Replaces lex->query_tables. To be defined.

1.1.11 is_readonly()

Returns true if this statement is readonly.

1.1.12 nesting_level()

Returns nesting level of command within command hierarchy.
A directly-executed query or routine has nesting level 0, ie it is an outer-
most command.
A command refereneced by another command has nesting level of other command 
plus 1.
Resource validation, locking and release is only performed for command at the 
outermost level.

1.1.13 is_outermost()

Returns true if this command is at the outermost level.

1.1.14 validate_privileges()

Validate global privileges and resource-specific privileges for this command.

1.1.15 lock_resources()

Lock tables, views and routines required by this SQL command.

1.1.16 release()

Release all locks on resources held by this command.

1.1.17 Other accessor functions

These methods are derived from the array sql_command_flags and various accessor 
functions referring that array. The methods are non-virtual methods implemented 
on the Sql_cmd base class.

changes_data() - Returns true if command changes data (including temp tables?)
has_row_count() - Returns true if command returns row count
is_logging_to_table() - Returns true if command may write log to a table
depends_on_metadata() - Return true is command preparation depends on metadata
needs_commit_before() - Returns true if command requires to be run in new trans.
needs_commit_after() - Returns true if command requires immediate commit.

1.2 Member fields

m_prepared - Whether SQL command has been prepared or not.
m_executed - How many times this SQL command has been executed after prep.
m_column_count - Number of columns in result row set.
m_parameter_count - Number of parameters required for command.
m_table_count - Number of tables and views referred by command.
m_routine_count - Number of routines potentially called by query.
m_readonly - Whether SQL command is only reading data.
m_command_level - Nesting level of SQL command.

2. Factory object

SQL command object creation is encapsulated in a "Factory" object. The 
reasons for encapsulating object creation and not using the constructors 
directly are:

 - Details like memory management can be hidden
 - May contain multiple actions in one routine - may be difficult with
   only constructors.
 - Simpler action rules in parser
 - Easier to debug parser because one can set break on routine entry
   (my experience)

This will be handled by stack-allocating an Sql_cmd_factory object and 
wrapping it into the Parser_state object, before each invocation of the YACC 
parser.