MySQL 8.1.0
Source Code Documentation
sp_head.h
Go to the documentation of this file.
1/* Copyright (c) 2002, 2023, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef _SP_HEAD_H_
24#define _SP_HEAD_H_
25
26#include <stddef.h>
27#include <sys/types.h>
28#include <string>
29#include <vector>
30
31#include "lex_string.h"
32#include "m_string.h"
33#include "map_helpers.h"
34#include "my_alloc.h"
35#include "my_dbug.h"
36#include "my_inttypes.h"
37#include "my_psi_config.h"
38#include "my_sqlcommand.h"
39#include "my_sys.h"
43#include "mysqld_error.h"
45#include "sql/create_field.h"
46#include "sql/mem_root_array.h" // Mem_root_array
47#include "sql/sql_lex.h"
48#include "sql/sql_list.h"
50#include "sql/table.h"
51
52class Field;
53class Item;
57class THD;
58class sp_head;
59struct CHARSET_INFO;
60struct MY_BITMAP;
61
62/**
63 @defgroup Stored_Routines Stored Routines
64 @ingroup Runtime_Environment
65 @{
66*/
67
68class sp_branch_instr;
69class sp_instr;
70class sp_label;
72class sp_pcontext;
73
74/**
75 Number of PSI_statement_info instruments
76 for internal stored programs statements.
77*/
78#define SP_PSI_STATEMENT_INFO_COUNT 16
79
80#ifdef HAVE_PSI_INTERFACE
81void init_sp_psi_keys(void);
82#endif
83
84///////////////////////////////////////////////////////////////////////////
85
86/**
87 Stored_program_creation_ctx -- base class for creation context of stored
88 programs (stored routines, triggers, events).
89*/
90
92 public:
93 const CHARSET_INFO *get_db_cl() { return m_db_cl; }
94
95 public:
97
98 protected:
99 explicit Stored_program_creation_ctx(THD *thd);
100
102 const CHARSET_INFO *connection_cl,
103 const CHARSET_INFO *db_cl)
104 : Default_object_creation_ctx(client_cs, connection_cl), m_db_cl(db_cl) {}
105
106 protected:
107 void change_env(THD *thd) const override;
108
109 protected:
110 /**
111 db_cl stores the value of the database collation. Both character set
112 and collation attributes are used.
113
114 Database collation is included into the context because it defines the
115 default collation for stored-program variables.
116 */
118};
119
120///////////////////////////////////////////////////////////////////////////
121
122class sp_name {
123 public:
127 bool m_explicit_name; /**< Prepend the db name? */
128
129 sp_name(const LEX_CSTRING &db, const LEX_STRING &name, bool use_explicit_name)
130 : m_db(db), m_name(name), m_explicit_name(use_explicit_name) {
131 m_qname.str = nullptr;
132 m_qname.length = 0;
133 }
134
135 /** Create temporary sp_name object for Sroutine_hash_entry. */
136 sp_name(const Sroutine_hash_entry *rt, char *qname_buff);
137
138 // Init. the qualified name from the db and name.
139 void init_qname(THD *thd); // thd for memroot allocation
140};
141
142///////////////////////////////////////////////////////////////////////////
143
144/**
145 sp_parser_data provides a scope for attributes used at the SP-parsing
146 stage only.
147*/
149 private:
153 };
154
155 public:
162 m_cont_level(0),
165
166 ///////////////////////////////////////////////////////////////////////
167
168 /**
169 Start parsing a stored program body statement.
170
171 This method switches THD::mem_root and THD::m_item_list in order to parse
172 SP-body. The current values are kept to be restored after the body
173 statement is parsed.
174
175 @param thd Thread context.
176 @param sp Stored Program being parsed.
177 */
178 void start_parsing_sp_body(THD *thd, sp_head *sp);
179
180 /**
181 Finish parsing of a stored program body statement.
182
183 This method switches THD::mem_root and THD::m_item_list back when SP-body
184 parsing is completed.
185
186 @param thd Thread context.
187 */
188 void finish_parsing_sp_body(THD *thd);
189
190 /**
191 @retval true if SP-body statement is being parsed.
192 @retval false otherwise.
193 */
194 bool is_parsing_sp_body() const { return m_saved_memroot != nullptr; }
195
196 ///////////////////////////////////////////////////////////////////////
197
198 void process_new_sp_instr(THD *thd, sp_instr *i);
199
200 ///////////////////////////////////////////////////////////////////////
201
202 const char *get_current_stmt_start_ptr() const {
204 }
205
206 void set_current_stmt_start_ptr(const char *stmt_start_ptr) {
207 m_current_stmt_start_ptr = stmt_start_ptr;
208 }
209
210 ///////////////////////////////////////////////////////////////////////
211
212 const char *get_option_start_ptr() const { return m_option_start_ptr; }
213
214 void set_option_start_ptr(const char *option_start_ptr) {
215 m_option_start_ptr = option_start_ptr;
216 }
217
218 ///////////////////////////////////////////////////////////////////////
219
220 const char *get_parameter_start_ptr() const { return m_param_start_ptr; }
221
222 void set_parameter_start_ptr(const char *ptr) { m_param_start_ptr = ptr; }
223
224 const char *get_parameter_end_ptr() const { return m_param_end_ptr; }
225
226 void set_parameter_end_ptr(const char *ptr) { m_param_end_ptr = ptr; }
227
228 ///////////////////////////////////////////////////////////////////////
229
230 const char *get_body_start_ptr() const { return m_body_start_ptr; }
231
232 void set_body_start_ptr(const char *ptr) { m_body_start_ptr = ptr; }
233
234 ///////////////////////////////////////////////////////////////////////
235
236 void push_lex(LEX *lex) { m_lex_stack.push_front(lex); }
237
238 LEX *pop_lex() { return m_lex_stack.pop(); }
239
240 ///////////////////////////////////////////////////////////////////////
241 // Backpatch-list operations.
242 ///////////////////////////////////////////////////////////////////////
243
244 /**
245 Put the instruction on the backpatch list, associated with the label.
246
247 @param i The SP-instruction.
248 @param label The label.
249
250 @return Error flag.
251 */
253
254 /**
255 Update all instruction with the given label in the backpatch list
256 to the given instruction pointer.
257
258 @param label The label.
259 @param dest The instruction pointer.
260 */
261 void do_backpatch(sp_label *label, uint dest);
262
263 ///////////////////////////////////////////////////////////////////////
264 // Backpatch operations for supporting CONTINUE handlers.
265 ///////////////////////////////////////////////////////////////////////
266
267 /**
268 Start a new backpatch level for the SP-instruction requiring continue
269 destination. If the SP-instruction is NULL, the level is just increased.
270
271 @note Only subclasses of sp_lex_branch_instr need backpatching of
272 continue destinations (and no other classes do):
273 - sp_instr_jump_if_not
274 - sp_instr_set_case_expr
275 - sp_instr_jump_case_when
276
277 That's why the methods below accept sp_lex_branch_instr to make this
278 relationship clear. And these two functions are the only places where
279 set_cont_dest() is used, so set_cont_dest() is also a member of
280 sp_lex_branch_instr.
281
282 @todo These functions should probably be declared in a separate
283 interface class, but currently we try to minimize the sp_instr
284 hierarchy.
285
286 @return false always.
287 */
289 ++m_cont_level;
290 return false;
291 }
292
293 /**
294 Add a SP-instruction to the current level.
295
296 @param i The SP-instruction.
297
298 @return Error flag.
299 */
301
302 /**
303 Backpatch (and pop) the current level to the given instruction pointer.
304
305 @param dest The instruction pointer.
306 */
307 void do_cont_backpatch(uint dest);
308
309 private:
310 /// Start of the current statement's query string.
312
313 /// Start of the SET-expression query string.
315
316 /**
317 Stack of LEX-objects. It's needed to handle processing of
318 sub-statements.
319 */
321
322 /**
323 Position in the CREATE PROCEDURE- or CREATE FUNCTION-statement's query
324 string corresponding to the start of parameter declarations (stored
325 procedure or stored function parameters).
326 */
327 const char *m_param_start_ptr;
328
329 /**
330 Position in the CREATE PROCEDURE- or CREATE FUNCTION-statement's query
331 string corresponding to the end of parameter declarations (stored
332 procedure or stored function parameters).
333 */
334 const char *m_param_end_ptr;
335
336 /**
337 Position in the CREATE-/ALTER-stored-program statement's query string
338 corresponding to the start of the first SQL-statement.
339 */
340 const char *m_body_start_ptr;
341
342 /// Instructions needing backpatching
344
345 /**
346 We need a special list for backpatching of instructions with a continue
347 destination (in the case of a continue handler catching an error in
348 the test), since it would otherwise interfere with the normal backpatch
349 mechanism - e.g. jump_if_not instructions have two different destinations
350 which are to be patched differently.
351 Since these occur in a more restricted way (always the same "level" in
352 the code), we don't need the label.
353 */
355
356 /// The current continue backpatch level
358
359 /**********************************************************************
360 The following attributes are used to store THD values during parsing
361 of stored program body.
362
363 @sa start_parsing_sp_body()
364 @sa finish_parsing_sp_body()
365 **********************************************************************/
366
367 /// THD's memroot.
369
370 /// THD's item list.
372};
373
374///////////////////////////////////////////////////////////////////////////
375
376struct SP_TABLE;
377
378/**
379 sp_head represents one instance of a stored program. It might be of any type
380 (stored procedure, function, trigger, event).
381*/
382class sp_head {
383 public:
384 /** Possible values of m_flags */
385 enum {
386 HAS_RETURN = 1, // For FUNCTIONs only: is set if has RETURN
387 MULTI_RESULTS = 8, // Is set if a procedure with SELECT(s)
388 CONTAINS_DYNAMIC_SQL = 16, // Is set if a procedure with PREPARE/EXECUTE
389 IS_INVOKED = 32, // Is set if this sp_head is being used
391 64, // Is set if a procedure with 'set autocommit'
392 /* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */
394 LOG_SLOW_STATEMENTS = 256, // Used by events
395 LOG_GENERAL_LOG = 512, // Used by events
398
399 /**
400 Marks routines that directly (i.e. not by calling other routines)
401 change tables. Note that this flag is set automatically based on
402 type of statements used in the stored routine and is different
403 from routine characteristic provided by user in a form of CONTAINS
404 SQL, READS SQL DATA, MODIFIES SQL DATA clauses. The latter are
405 accepted by parser but pretty much ignored after that.
406 We don't rely on them:
407 a) for compatibility reasons.
408 b) because in CONTAINS SQL case they don't provide enough
409 information anyway.
410 */
412 /**
413 Set when a stored program contains sub-statement(s) that creates or drops
414 temporary table(s). When set, used to mark invoking statement as unsafe to
415 be binlogged in STATEMENT format, when in MIXED mode.
416 */
417 HAS_TEMP_TABLE_DDL = 8192
418 };
419
420 public:
421 /************************************************************************
422 Public attributes.
423 ************************************************************************/
424
425 /// Stored program type.
427
428 /// Stored program flags.
430
431 /**
432 Instrumentation interface for SP.
433 */
435
436 /**
437 Definition of the RETURN-field (from the RETURNS-clause).
438 It's used (and valid) for stored functions only.
439 */
441
442 /// Attributes used during the parsing stage only.
444
445 /// Stored program characteristics.
447
448 /// Code if language is not SQL
450
451 /**
452 The value of sql_mode system variable at the CREATE-time.
453
454 It should be stored along with the character sets in the
455 Stored_program_creation_ctx.
456 */
458
459 /// Fully qualified name (@<db name@>.@<sp name@>).
461
462 bool m_explicit_name; ///< Prepend the db name? */
463
471
474
475 /// Recursion level of the current SP instance. The levels are numbered from
476 /// 0.
478
479 /**
480 A list of different recursion level instances for the same procedure.
481 For every recursion level we have an sp_head instance. This instances
482 connected in the list. The list ordered by increasing recursion level
483 (m_recursion_level).
484 */
486
487 /// Pointer to the first element of the above list
489
490 /**
491 Pointer to the first free (non-INVOKED) routine in the list of
492 cached instances for this SP. This pointer is set only for the first
493 SP in the list of instances (see above m_first_cached_sp pointer).
494 The pointer equal to 0 if we have no free instances.
495 For non-first instance value of this pointer meaningless (point to itself);
496 */
498
499 /**
500 Pointer to the last element in the list of instances of the SP.
501 For non-first instance value of this pointer meaningless (point to itself);
502 */
504
505 /**
506 Set containing names of stored routines used by this routine.
507 Note that unlike elements of similar set for statement elements of this
508 set are not linked in one list. Because of this we are able save memory
509 by using for this set same objects that are used in 'sroutines' sets
510 for statements of which this stored routine consists.
511
512 See Sroutine_hash_entry for explanation why this hash uses binary
513 key comparison.
514 */
516
517 /*
518 Security context for stored routine which should be run under
519 definer privileges.
520 */
522
523 /////////////////////////////////////////////////////////////////////////
524 // Trigger-specific public attributes.
525 /////////////////////////////////////////////////////////////////////////
526
527 /**
528 List of item (Item_trigger_field objects)'s lists representing fields
529 in old/new version of row in trigger. We use this list for checking
530 whether all such fields are valid or not at trigger creation time and for
531 binding these fields to TABLE object at table open (although for latter
532 pointer to table being opened is probably enough).
533 */
535 /**
536 List of all the Item_trigger_field items created while parsing
537 sp instruction. After parsing, in add_instr method this list
538 is moved to per instruction Item_trigger_field list
539 "sp_lex_instr::m_trig_field_list".
540 */
542
543 /// Trigger characteristics.
545
546 /// The Table_trigger_dispatcher instance, where this trigger belongs to.
548
549 public:
550 static void destroy(sp_head *sp);
551
552 /// Is this routine being executed?
553 bool is_invoked() const { return m_flags & IS_INVOKED; }
554
555 /**
556 @returns true if this is an SQL routine, and
557 false if it is an external routine
558 */
559 bool is_sql() const {
560 assert(m_chistics->language.length > 0);
561 return native_strcasecmp(m_chistics->language.str, "SQL") == 0;
562 }
563
564 /**
565 Get the value of the SP cache version, as remembered
566 when the routine was inserted into the cache.
567 */
569
570 /// Set the value of the SP cache version.
573 }
574
576
578 m_creation_ctx = creation_ctx->clone(&main_mem_root);
579 }
580
581 /// Set the body-definition start position.
582 void set_body_start(THD *thd, const char *begin_ptr);
583
584 /// Set the statement-definition (body-definition) end position.
585 void set_body_end(THD *thd);
586
588 GRANT_INFO *subject_table_grant,
589 bool need_fix_fields);
590
591 void mark_used_trigger_fields(TABLE *subject_table);
592
593 bool has_updated_trigger_fields(const MY_BITMAP *used_fields) const;
594
595 /**
596 Execute trigger stored program.
597
598 - changes security context for triggers
599 - switch to new memroot
600 - call sp_head::execute
601 - restore old memroot
602 - restores security context
603
604 @param thd Thread context
605 @param db_name database name
606 @param table_name table name
607 @param grant_info GRANT_INFO structure to be filled with
608 information about definer's privileges
609 on subject table
610
611 @todo
612 We should create sp_rcontext once per command and reuse it
613 on subsequent executions of a trigger.
614
615 @return Error status.
616 */
617 bool execute_trigger(THD *thd, const LEX_CSTRING &db_name,
618 const LEX_CSTRING &table_name, GRANT_INFO *grant_info);
619
620 /**
621 Execute a function.
622
623 - evaluate parameters
624 - changes security context for SUID routines
625 - switch to new memroot
626 - call sp_head::execute
627 - restore old memroot
628 - evaluate the return value
629 - restores security context
630
631 @param thd Thread context.
632 @param args Passed arguments (these are items from containing
633 statement?)
634 @param argcount Number of passed arguments. We need to check if
635 this is correct.
636 @param return_fld Save result here.
637
638 @todo
639 We should create sp_rcontext once per command and reuse
640 it on subsequent executions of a function/trigger.
641
642 @todo
643 In future we should associate call arena/mem_root with
644 sp_rcontext and allocate all these objects (and sp_rcontext
645 itself) on it directly rather than juggle with arenas.
646
647 @return Error status.
648 */
649 bool execute_function(THD *thd, Item **args, uint argcount,
650 Field *return_fld);
651
652 /**
653 Execute a procedure.
654
655 The function does the following steps:
656 - Set all parameters
657 - changes security context for SUID routines
658 - call sp_head::execute
659 - copy back values of INOUT and OUT parameters
660 - restores security context
661
662 @param thd Thread context.
663 @param args List of values passed as arguments.
664
665 @return Error status.
666 */
667
669
670 /**
671 Add instruction to SP.
672
673 @param thd Thread context.
674 @param instr Instruction.
675
676 @return Error status.
677 */
678 bool add_instr(THD *thd, sp_instr *instr);
679
680 /**
681 Returns true if any substatement in the routine directly
682 (not through another routine) modifies data/changes table.
683
684 @sa Comment for MODIFIES_DATA flag.
685 */
686 bool modifies_data() const { return m_flags & MODIFIES_DATA; }
687
688 /**
689 @returns true if stored program has sub-statement(s) to CREATE/DROP
690 temporary table(s).
691 @retval true if HAS_TEMP_TABLE_DDL is set in m_flags.
692 @retval false Otherwise.
693 */
695
696 uint instructions() { return static_cast<uint>(m_instructions.size()); }
697
699
700 /**
701 Reset LEX-object during parsing, before we parse a sub statement.
702
703 @param thd Thread context.
704
705 @return Error status.
706 */
707 bool reset_lex(THD *thd);
708
709 /**
710 Restore LEX-object during parsing, after we have parsed a sub statement.
711
712 @param thd Thread context.
713
714 @return Error status.
715 */
716 bool restore_lex(THD *thd);
717
718 char *name(uint *lenp = nullptr) const {
719 if (lenp) *lenp = (uint)m_name.length;
720 return m_name.str;
721 }
722
723 /**
724 Create Field-object corresponding to the RETURN field of a stored function.
725 This operation makes sense for stored functions only.
726
727 @param thd thread context.
728 @param field_max_length the max length (in the sense of Item classes).
729 @param field_name the field name (item name).
730 @param table the field's table.
731
732 @return newly created and initialized Field-instance,
733 or NULL in case of error.
734 */
735 Field *create_result_field(THD *thd, size_t field_max_length,
736 const char *field_name, TABLE *table) const;
737
738 void returns_type(THD *thd, String *result) const;
739
740 void set_info(longlong created, longlong modified, st_sp_chistics *chistics,
742
743 void set_definer(const char *definer, size_t definerlen);
744 void set_definer(const LEX_CSTRING &user_name, const LEX_CSTRING &host_name);
745
746 /**
747 Do some minimal optimization of the code:
748 -# Mark used instructions
749 -# While doing this, shortcut jumps to jump instructions
750 -# Compact the code, removing unused instructions.
751
752 This is the main mark and move loop; it relies on the following methods
753 in sp_instr and its subclasses:
754
755 - opt_mark() : Mark instruction as reachable
756 - opt_shortcut_jump(): Shortcut jumps to the final destination;
757 used by opt_mark().
758 - opt_move() : Update moved instruction
759 - set_destination() : Set the new destination (jump instructions only)
760 */
761 void optimize();
762
763 /**
764 Helper used during flow analysis during code optimization.
765 See the implementation of <code>opt_mark()</code>.
766 @param ip the instruction to add to the leads list
767 @param leads the list of remaining paths to explore in the graph that
768 represents the code, during flow analysis.
769 */
770 void add_mark_lead(uint ip, List<sp_instr> *leads);
771
772 /**
773 Get SP-instruction at given index.
774
775 NOTE: it is important to have *unsigned* int here, sometimes we get (-1)
776 passed here, so it gets converted to MAX_INT, and the result of the
777 function call is NULL.
778 */
780 return (i < (uint)m_instructions.size()) ? m_instructions.at(i) : NULL;
781 }
782
783 /**
784 Add tables used by routine to the table list.
785
786 Converts multi-set of tables used by this routine to table list and adds
787 this list to the end of table list specified by 'query_tables_last_ptr'.
788
789 Elements of list will be allocated in PS memroot, so this list will be
790 persistent between PS executions.
791
792 @param[in] thd Thread context
793 @param[in,out] query_tables_last_ptr Pointer to the next_global member of
794 last element of the list where tables
795 will be added (or to its root).
796 @param[in] sql_command SQL-command for which we are adding
797 elements to the table list.
798 @param[in] belong_to_view Uppermost view which uses this
799 routine, NULL if none.
800 */
802 Table_ref ***query_tables_last_ptr,
803 enum_sql_command sql_command,
804 Table_ref *belong_to_view);
805
806 /**
807 Check if this stored routine contains statements disallowed
808 in a stored function or trigger, and set an appropriate error message
809 if this is the case.
810 */
813 my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "Dynamic SQL");
814 else if (m_flags & MULTI_RESULTS)
815 my_error(ER_SP_NO_RETSET, MYF(0), where);
817 my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0));
819 my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
820 else if (m_flags & HAS_SQLCOM_RESET)
821 my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "RESET");
822 else if (m_flags & HAS_SQLCOM_FLUSH)
823 my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
824
825 return (m_flags &
828 }
829
830#ifndef NDEBUG
831 /**
832 Return the routine instructions as a result set.
833 @return Error status.
834 */
835 bool show_routine_code(THD *thd);
836#endif
837
838 /*
839 This method is intended for attributes of a routine which need
840 to propagate upwards to the Query_tables_list of the caller (when
841 a property of a sp_head needs to "taint" the calling statement).
842 */
844 /*
845 If this routine needs row-based binary logging, the entire top statement
846 too (we cannot switch from statement-based to row-based only for this
847 routine, as in statement-based the top-statement may be binlogged and
848 the sub-statements not).
849 */
850 DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x",
851 prelocking_ctx->get_stmt_unsafe_flags()));
852 DBUG_PRINT("info", ("sp_head(0x%p=%s)->unsafe_flags: 0x%x", this, name(),
853 unsafe_flags));
854 prelocking_ctx->set_stmt_unsafe_flags(unsafe_flags);
855
856 /*
857 If temporary table is created or dropped in the stored program then
858 statement is unsafe to be logged in STATEMENT format, when in MIXED mode.
859 */
861 }
862
863 /**
864 @return root parsing context for this stored program.
865 */
867 return const_cast<sp_pcontext *>(m_root_parsing_ctx);
868 }
869
870 /**
871 @return SP-persistent mem-root. Instructions and expressions are stored in
872 its memory between executions.
873 */
875 return const_cast<MEM_ROOT *>(&main_mem_root);
876 }
877
878 /**
879 Check if a user has access right to a SP.
880
881 @param thd Thread context.
882 @param[out] full_access Set to 1 if the user is the owner
883 of the stored program.
884
885 @return Error status.
886 */
887 bool check_show_access(THD *thd, bool *full_access);
888
889 /**
890 Change routine security context, and check if there is an EXECUTE privilege
891 in new context. If there is no EXECUTE privilege, change the context back
892 and return an error.
893
894 @param thd Thread context.
895 @param[out] save_ctx Where to save the old security context.
896
897 @todo Cache if the definer has the rights to use the object on the first
898 usage and reset the cache only if someone does a GRANT statement that 'may'
899 affect this.
900
901 @return Error status.
902 */
903 bool set_security_ctx(THD *thd, Security_context **save_ctx);
904
905 private:
906 /// Use sp_start_parsing() to create instances of sp_head.
908
909 /// Use destroy() to destoy instances of sp_head.
910 ~sp_head();
911
912 /// SP-persistent memory root (for instructions and expressions).
914
915 /// Root parsing context (topmost BEGIN..END block) of this SP.
917
918 /// The SP-instructions.
920
921 /**
922 Multi-set representing optimized list of tables to be locked by this
923 routine. Does not include tables which are used by invoked routines.
924
925 @note
926 For prelocking-free SPs this multiset is constructed too.
927 We do so because the same instance of sp_head may be called both
928 in prelocked mode and in non-prelocked mode.
929 */
931
932 /*
933 The same information as in m_sptabs, but sorted (by an arbitrary key).
934 This is useful to get consistent locking order, which makes MTR tests
935 more deterministic across platforms. It does not have a bearing on the
936 actual behavior of the server.
937 */
938 std::vector<SP_TABLE *> m_sptabs_sorted;
939
940 /**
941 Version of the stored routine cache at the moment when the
942 routine was added to it. Is used only for functions and
943 procedures, not used for triggers or events. When sp_head is
944 created, its version is 0. When it's added to the cache, the
945 version is assigned the global value 'Cversion'.
946 If later on Cversion is incremented, we know that the routine
947 is obsolete and should not be used --
948 sp_cache_flush_obsolete() will purge it.
949 */
951
952 /// Snapshot of several system variables at CREATE-time.
954
955 /// Flags of LEX::enum_binlog_stmt_unsafe.
957
958 public:
959 /**
960 language component related state of this sp.
961 */
963
964 /**
965 Initialize and parse an external routine
966
967 If @ref m_language_stored_program is already set,
968 nothing will be done.
969
970 @param service The_program_execution service that will
971 be used to execute this function
972
973 @returns false on success; true on failure
974 */
976 my_service<SERVICE_TYPE(external_program_execution)> &service);
977
978 private:
979 /// Copy sp name from parser.
980 void init_sp_name(THD *thd, sp_name *spname);
981
982 /**
983 Execute the routine. The main instruction jump loop is there.
984 Assume the parameters already set.
985
986 @param thd Thread context.
987 @param merge_da_on_success Flag specifying if Warning Info should be
988 propagated to the caller on Completion
989 Condition or not.
990
991 @todo
992 - Will write this SP statement into binlog separately
993 (TODO: consider changing the condition to "not inside event union")
994
995 @return Error status.
996 */
997 bool execute(THD *thd, bool merge_da_on_success);
998
999 /**
1000 Execute external routine.
1001
1002 @param thd Thread context.
1003
1004 @return Error status.
1005 */
1006 bool execute_external_routine(THD *thd);
1007
1008 /**
1009 Perform a forward flow analysis in the generated code.
1010 Mark reachable instructions, for the optimizer.
1011 */
1012 void opt_mark();
1013
1014 /**
1015 Merge the list of tables used by some query into the multi-set of
1016 tables used by routine.
1017
1018 @param thd Thread context.
1019 @param table Table list.
1020 @param lex_for_tmp_check LEX of the query for which we are merging
1021 table list.
1022
1023 @note
1024 This method will use LEX provided to check whenever we are creating
1025 temporary table and mark it as such in target multi-set.
1026
1027 @return Error status.
1028 */
1029 bool merge_table_list(THD *thd, Table_ref *table, LEX *lex_for_tmp_check);
1030
1031 friend sp_head *sp_start_parsing(THD *thd, enum_sp_type sp_type,
1032 sp_name *sp_name);
1033
1034 // Prevent use of copy constructor and assignment operator.
1037};
1038
1039///////////////////////////////////////////////////////////////////////////
1040
1041/**
1042 @} (end of group Stored_Routines)
1043*/
1044
1045#endif /* _SP_HEAD_H_ */
Create_field is a description a field/column that may or may not exists in a table.
Definition: create_field.h:50
Default_object_creation_ctx – default implementation of Object_creation_ctx.
Definition: table.h:222
Definition: field.h:575
Represents NEW/OLD version of field of row which is changed/read in trigger.
Definition: item.h:6623
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:853
Definition: sql_list.h:433
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:425
Definition: sql_lex.h:2511
void set_stmt_unsafe_flags(uint32 flags)
Set the bits of binlog_stmt_flags determining the type of unsafeness of the current statement.
Definition: sql_lex.h:2844
uint32 get_stmt_unsafe_flags() const
Return a binary combination of all unsafe warnings for the statement.
Definition: sql_lex.h:2857
void set_stmt_unsafe_with_mixed_mode()
Definition: sql_lex.h:3082
Simple intrusive linked list.
Definition: sql_list.h:45
A set of THD members describing the current authenticated user.
Definition: sql_security_ctx.h:52
Structure that represents element in the set of stored routines used by statement or routine.
Definition: sp.h:223
Stored_program_creation_ctx – base class for creation context of stored programs (stored routines,...
Definition: sp_head.h:91
const CHARSET_INFO * m_db_cl
db_cl stores the value of the database collation.
Definition: sp_head.h:117
virtual Stored_program_creation_ctx * clone(MEM_ROOT *mem_root)=0
void change_env(THD *thd) const override
Definition: sp_head.cc:3611
Stored_program_creation_ctx(THD *thd)
Definition: sp_head.cc:3607
Stored_program_creation_ctx(const CHARSET_INFO *client_cs, const CHARSET_INFO *connection_cl, const CHARSET_INFO *db_cl)
Definition: sp_head.h:101
const CHARSET_INFO * get_db_cl()
Definition: sp_head.h:93
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:166
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:33
Definition: table.h:2800
This class holds all information about triggers of a table.
Definition: table_trigger_dispatcher.h:62
This is an interface to be used from Item_trigger_field to access information about table trigger fie...
Definition: table_trigger_field_support.h:43
std::unordered_map, but with my_malloc and collation-aware comparison.
Definition: map_helpers.h:209
std::unordered_map, but with my_malloc, so that you can track the memory used using PSI memory keys.
Definition: map_helpers.h:147
A (partial) implementation of std::deque allocating its blocks on a MEM_ROOT.
Definition: mem_root_deque.h:109
Wraps my_h_service struct conforming ABI into RAII C++ object with ability to cast to desired service...
Definition: my_service.h:34
An interface for all SP-instructions with destinations that need to be updated by the SP-optimizer.
Definition: sp_instr.h:77
sp_head represents one instance of a stored program.
Definition: sp_head.h:382
void set_creation_ctx(Stored_program_creation_ctx *creation_ctx)
Definition: sp_head.h:577
bool execute_external_routine(THD *thd)
Execute external routine.
Definition: sp_head.cc:2413
bool add_instr(THD *thd, sp_instr *instr)
Add instruction to SP.
Definition: sp_head.cc:3151
LEX_STRING m_name
Definition: sp_head.h:465
bool execute_function(THD *thd, Item **args, uint argcount, Field *return_fld)
Execute a function.
Definition: sp_head.cc:2591
st_sp_chistics * m_chistics
Stored program characteristics.
Definition: sp_head.h:446
sp_head(MEM_ROOT &&mem_root, enum_sp_type type)
Use sp_start_parsing() to create instances of sp_head.
Definition: sp_head.cc:1702
int64 sp_cache_version() const
Get the value of the SP cache version, as remembered when the routine was inserted into the cache.
Definition: sp_head.h:568
void set_definer(const char *definer, size_t definerlen)
Definition: sp_head.cc:3127
void operator=(sp_head &)
LEX_CSTRING m_body
Definition: sp_head.h:467
bool setup_trigger_fields(THD *thd, Table_trigger_field_support *tfs, GRANT_INFO *subject_table_grant, bool need_fix_fields)
Definition: sp_head.cc:1830
bool has_updated_trigger_fields(const MY_BITMAP *used_fields) const
Check whether any table's fields are used in trigger.
Definition: sp_head.cc:1882
void init_sp_name(THD *thd, sp_name *spname)
Copy sp name from parser.
Definition: sp_head.cc:1752
bool execute_procedure(THD *thd, mem_root_deque< Item * > *args)
Execute a procedure.
Definition: sp_head.cc:2806
void set_body_end(THD *thd)
Set the statement-definition (body-definition) end position.
Definition: sp_head.cc:1781
void set_info(longlong created, longlong modified, st_sp_chistics *chistics, sql_mode_t sql_mode)
Definition: sp_head.cc:3105
ulong m_recursion_level
Recursion level of the current SP instance.
Definition: sp_head.h:477
longlong m_created
Definition: sp_head.h:472
sp_head * m_first_instance
Pointer to the first element of the above list.
Definition: sp_head.h:488
uint instructions()
Definition: sp_head.h:696
collation_unordered_map< std::string, SP_TABLE * > m_sptabs
Multi-set representing optimized list of tables to be locked by this routine.
Definition: sp_head.h:930
bool execute(THD *thd, bool merge_da_on_success)
Execute the routine.
Definition: sp_head.cc:1994
Security_context m_security_ctx
Definition: sp_head.h:521
Create_field m_return_field_def
Definition of the RETURN-field (from the RETURNS-clause).
Definition: sp_head.h:440
bool is_sql() const
Definition: sp_head.h:559
uint m_flags
Stored program flags.
Definition: sp_head.h:429
SQL_I_List< SQL_I_List< Item_trigger_field > > m_list_of_trig_fields_item_lists
List of item (Item_trigger_field objects)'s lists representing fields in old/new version of row in tr...
Definition: sp_head.h:534
void add_used_tables_to_table_list(THD *thd, Table_ref ***query_tables_last_ptr, enum_sql_command sql_command, Table_ref *belong_to_view)
Add tables used by routine to the table list.
Definition: sp_head.cc:3402
friend sp_head * sp_start_parsing(THD *thd, enum_sp_type sp_type, sp_name *sp_name)
Start parsing of a stored program.
Definition: sp.cc:2236
int64 m_sp_cache_version
Version of the stored routine cache at the moment when the routine was added to it.
Definition: sp_head.h:950
sp_pcontext * m_root_parsing_ctx
Root parsing context (topmost BEGIN..END block) of this SP.
Definition: sp_head.h:916
LEX_STRING m_params
Definition: sp_head.h:466
bool show_routine_code(THD *thd)
Return the routine instructions as a result set.
Definition: sp_head.cc:3256
class Table_trigger_dispatcher * m_trg_list
The Table_trigger_dispatcher instance, where this trigger belongs to.
Definition: sp_head.h:547
malloc_unordered_map< std::string, Sroutine_hash_entry * > m_sroutines
Set containing names of stored routines used by this routine.
Definition: sp_head.h:515
std::vector< SP_TABLE * > m_sptabs_sorted
Definition: sp_head.h:938
LEX_STRING m_db
Definition: sp_head.h:464
Field * create_result_field(THD *thd, size_t field_max_length, const char *field_name, TABLE *table) const
Create Field-object corresponding to the RETURN field of a stored function.
Definition: sp_head.cc:1936
bool check_show_access(THD *thd, bool *full_access)
Check if a user has access right to a SP.
Definition: sp_head.cc:3475
void set_sp_cache_version(int64 sp_cache_version)
Set the value of the SP cache version.
Definition: sp_head.h:571
bool m_explicit_name
Prepend the db name? *‍/.
Definition: sp_head.h:462
bool is_not_allowed_in_function(const char *where)
Check if this stored routine contains statements disallowed in a stored function or trigger,...
Definition: sp_head.h:811
void mark_used_trigger_fields(TABLE *subject_table)
Definition: sp_head.cc:1852
void returns_type(THD *thd, String *result) const
Definition: sp_head.cc:1967
LEX_CSTRING m_body_utf8
Definition: sp_head.h:468
Mem_root_array< sp_instr * > m_instructions
The SP-instructions.
Definition: sp_head.h:919
uint32 unsafe_flags
Flags of LEX::enum_binlog_stmt_unsafe.
Definition: sp_head.h:956
Stored_program_creation_ctx * m_creation_ctx
Snapshot of several system variables at CREATE-time.
Definition: sp_head.h:953
bool is_invoked() const
Is this routine being executed?
Definition: sp_head.h:553
LEX_STRING m_qname
Fully qualified name (<db name>.<sp name>).
Definition: sp_head.h:460
LEX_STRING m_definer_host
Definition: sp_head.h:470
sql_mode_t m_sql_mode
The value of sql_mode system variable at the CREATE-time.
Definition: sp_head.h:457
MEM_ROOT * get_persistent_mem_root() const
Definition: sp_head.h:874
bool merge_table_list(THD *thd, Table_ref *table, LEX *lex_for_tmp_check)
Merge the list of tables used by some query into the multi-set of tables used by routine.
Definition: sp_head.cc:3312
longlong m_modified
Definition: sp_head.h:473
bool restore_lex(THD *thd)
Restore LEX-object during parsing, after we have parsed a sub statement.
Definition: sp_head.cc:3055
static void destroy(sp_head *sp)
Definition: sp_head.cc:1691
~sp_head()
Use destroy() to destoy instances of sp_head.
Definition: sp_head.cc:1901
sp_instr * last_instruction()
Definition: sp_head.h:698
LEX_STRING m_definer_user
Definition: sp_head.h:469
char * name(uint *lenp=nullptr) const
Definition: sp_head.h:718
void set_body_start(THD *thd, const char *begin_ptr)
Set the body-definition start position.
Definition: sp_head.cc:1775
void add_mark_lead(uint ip, List< sp_instr > *leads)
Helper used during flow analysis during code optimization.
Definition: sp_head.cc:3215
bool has_temp_table_ddl() const
Definition: sp_head.h:694
bool execute_trigger(THD *thd, const LEX_CSTRING &db_name, const LEX_CSTRING &table_name, GRANT_INFO *grant_info)
Execute trigger stored program.
Definition: sp_head.cc:2463
PSI_sp_share * m_sp_share
Instrumentation interface for SP.
Definition: sp_head.h:434
sp_parser_data m_parser_data
Attributes used during the parsing stage only.
Definition: sp_head.h:443
Stored_program_creation_ctx * get_creation_ctx()
Definition: sp_head.h:575
sp_head * m_next_cached_sp
A list of different recursion level instances for the same procedure.
Definition: sp_head.h:485
bool reset_lex(THD *thd)
Reset LEX-object during parsing, before we parse a sub statement.
Definition: sp_head.cc:3031
MEM_ROOT main_mem_root
SP-persistent memory root (for instructions and expressions).
Definition: sp_head.h:913
@ MULTI_RESULTS
Definition: sp_head.h:387
@ HAS_TEMP_TABLE_DDL
Set when a stored program contains sub-statement(s) that creates or drops temporary table(s).
Definition: sp_head.h:417
@ HAS_SQLCOM_RESET
Definition: sp_head.h:396
@ MODIFIES_DATA
Marks routines that directly (i.e.
Definition: sp_head.h:411
@ LOG_GENERAL_LOG
Definition: sp_head.h:395
@ HAS_COMMIT_OR_ROLLBACK
Definition: sp_head.h:393
@ IS_INVOKED
Definition: sp_head.h:389
@ CONTAINS_DYNAMIC_SQL
Definition: sp_head.h:388
@ HAS_SQLCOM_FLUSH
Definition: sp_head.h:397
@ LOG_SLOW_STATEMENTS
Definition: sp_head.h:394
@ HAS_RETURN
Definition: sp_head.h:386
@ HAS_SET_AUTOCOMMIT_STMT
Definition: sp_head.h:390
st_trg_chistics m_trg_chistics
Trigger characteristics.
Definition: sp_head.h:544
sp_head * m_first_free_instance
Pointer to the first free (non-INVOKED) routine in the list of cached instances for this SP.
Definition: sp_head.h:497
external_program_handle m_language_stored_program
language component related state of this sp.
Definition: sp_head.h:962
void optimize()
Do some minimal optimization of the code:
Definition: sp_head.cc:3182
enum_sp_type m_type
Stored program type.
Definition: sp_head.h:426
bool modifies_data() const
Returns true if any substatement in the routine directly (not through another routine) modifies data/...
Definition: sp_head.h:686
void propagate_attributes(Query_tables_list *prelocking_ctx)
Definition: sp_head.h:843
sp_head * m_last_cached_sp
Pointer to the last element in the list of instances of the SP.
Definition: sp_head.h:503
void opt_mark()
Perform a forward flow analysis in the generated code.
Definition: sp_head.cc:3221
LEX_CSTRING code
Code if language is not SQL.
Definition: sp_head.h:449
sp_pcontext * get_root_parsing_context() const
Definition: sp_head.h:866
sp_head(const sp_head &)
sp_instr * get_instr(uint i)
Get SP-instruction at given index.
Definition: sp_head.h:779
bool init_external_routine(my_service< const mysql_service_external_program_execution_t > &service)
Initialize and parse an external routine.
Definition: sp_head.cc:2569
bool set_security_ctx(THD *thd, Security_context **save_ctx)
Change routine security context, and check if there is an EXECUTE privilege in new context.
Definition: sp_head.cc:3489
SQL_I_List< Item_trigger_field > m_cur_instr_trig_field_items
List of all the Item_trigger_field items created while parsing sp instruction.
Definition: sp_head.h:541
Base class for every SP-instruction.
Definition: sp_instr.h:104
This class represents an SQL/PSM label.
Definition: sp_pcontext.h:93
sp_lex_branch_instr is a base class for SP-instructions, which might perform conditional jump dependi...
Definition: sp_instr.h:790
Definition: sp_head.h:122
LEX_STRING m_qname
Definition: sp_head.h:126
bool m_explicit_name
Prepend the db name?
Definition: sp_head.h:127
void init_qname(THD *thd)
Init the qualified name from the db and name.
Definition: sp_head.cc:1677
LEX_STRING m_name
Definition: sp_head.h:125
sp_name(const LEX_CSTRING &db, const LEX_STRING &name, bool use_explicit_name)
Definition: sp_head.h:129
LEX_CSTRING m_db
Definition: sp_head.h:124
sp_parser_data provides a scope for attributes used at the SP-parsing stage only.
Definition: sp_head.h:148
const char * m_current_stmt_start_ptr
Start of the current statement's query string.
Definition: sp_head.h:311
void push_lex(LEX *lex)
Definition: sp_head.h:236
uint m_cont_level
The current continue backpatch level.
Definition: sp_head.h:357
bool add_backpatch_entry(sp_branch_instr *i, sp_label *label)
Put the instruction on the backpatch list, associated with the label.
Definition: sp_head.cc:3554
void start_parsing_sp_body(THD *thd, sp_head *sp)
Start parsing a stored program body statement.
Definition: sp_head.cc:3521
Item * m_saved_item_list
THD's item list.
Definition: sp_head.h:371
const char * get_option_start_ptr() const
Definition: sp_head.h:212
const char * m_param_end_ptr
Position in the CREATE PROCEDURE- or CREATE FUNCTION-statement's query string corresponding to the en...
Definition: sp_head.h:334
void do_cont_backpatch(uint dest)
Backpatch (and pop) the current level to the given instruction pointer.
Definition: sp_head.cc:3579
bool is_parsing_sp_body() const
Definition: sp_head.h:194
MEM_ROOT * m_saved_memroot
THD's memroot.
Definition: sp_head.h:368
sp_parser_data()
Definition: sp_head.h:156
const char * m_param_start_ptr
Position in the CREATE PROCEDURE- or CREATE FUNCTION-statement's query string corresponding to the st...
Definition: sp_head.h:327
void process_new_sp_instr(THD *thd, sp_instr *i)
Definition: sp_head.cc:3590
const char * get_parameter_end_ptr() const
Definition: sp_head.h:224
void set_body_start_ptr(const char *ptr)
Definition: sp_head.h:232
void set_parameter_start_ptr(const char *ptr)
Definition: sp_head.h:222
void set_current_stmt_start_ptr(const char *stmt_start_ptr)
Definition: sp_head.h:206
const char * m_body_start_ptr
Position in the CREATE-/ALTER-stored-program statement's query string corresponding to the start of t...
Definition: sp_head.h:340
void set_parameter_end_ptr(const char *ptr)
Definition: sp_head.h:226
List< Backpatch_info > m_backpatch
Instructions needing backpatching.
Definition: sp_head.h:343
LEX * pop_lex()
Definition: sp_head.h:238
bool add_cont_backpatch_entry(sp_lex_branch_instr *i)
Add a SP-instruction to the current level.
Definition: sp_head.cc:3574
List< LEX > m_lex_stack
Stack of LEX-objects.
Definition: sp_head.h:320
const char * m_option_start_ptr
Start of the SET-expression query string.
Definition: sp_head.h:314
List< sp_lex_branch_instr > m_cont_backpatch
We need a special list for backpatching of instructions with a continue destination (in the case of a...
Definition: sp_head.h:354
void set_option_start_ptr(const char *option_start_ptr)
Definition: sp_head.h:214
const char * get_body_start_ptr() const
Definition: sp_head.h:230
bool new_cont_backpatch()
Start a new backpatch level for the SP-instruction requiring continue destination.
Definition: sp_head.h:288
void finish_parsing_sp_body(THD *thd)
Finish parsing of a stored program body statement.
Definition: sp_head.cc:3532
const char * get_parameter_start_ptr() const
Definition: sp_head.h:220
const char * get_current_stmt_start_ptr() const
Definition: sp_head.h:202
void do_backpatch(sp_label *label, uint dest)
Update all instruction with the given label in the backpatch list to the given instruction pointer.
Definition: sp_head.cc:3565
The class represents parse-time context, which keeps track of declared variables/parameters,...
Definition: sp_pcontext.h:251
static MEM_ROOT mem_root
Definition: client_plugin.cc:113
ulonglong sql_mode_t
Definition: dd_event.h:36
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:221
enum_sp_type
enum_sp_type defines type codes of stored programs.
Definition: sql_lex.h:222
void my_error(int nr, myf MyFlags,...)
Fill in and print a previously registered error message.
Definition: my_error.cc:215
void init_sp_psi_keys(void)
Definition: sp_head.cc:1545
struct PSI_sp_share PSI_sp_share
Definition: psi_statement_bits.h:118
struct external_program_handle_imp * external_program_handle
The handle is created by the caller of external_program_execution service.
Definition: language_service.h:36
static int native_strcasecmp(const char *s1, const char *s2)
Definition: m_string.h:206
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:180
Some integer typedefs for easier portability.
int64_t int64
Definition: my_inttypes.h:67
long long int longlong
Definition: my_inttypes.h:54
#define MYF(v)
Definition: my_inttypes.h:96
uint32_t uint32
Definition: my_inttypes.h:66
Defines various enable/disable and HAVE_ macros related to the performance schema instrumentation sys...
enum_sql_command
Definition: my_sqlcommand.h:45
Common header for many mysys elements.
static char * where
Definition: mysqldump.cc:143
static const char * sql_mode
Definition: mysqlslap.cc:198
static PFS_engine_table_share_proxy table
Definition: pfs.cc:60
const char * table_name
Definition: rules_table_service.cc:55
const char * db_name
Definition: rules_table_service.cc:54
Performance schema instrumentation interface.
required string type
Definition: replication_group_member_actions.proto:33
#define SERVICE_TYPE(name)
Generates the standard Service type name.
Definition: service.h:75
case opt name
Definition: sslopt-case.h:32
Definition: m_ctype.h:422
The current state of the privilege checking process for the current user, SQL statement and SQL objec...
Definition: table.h:359
The LEX object currently serves three different purposes:
Definition: sql_lex.h:3714
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:82
Definition: mysql_lex_string.h:39
const char * str
Definition: mysql_lex_string.h:40
size_t length
Definition: mysql_lex_string.h:41
Definition: mysql_lex_string.h:34
char * str
Definition: mysql_lex_string.h:35
size_t length
Definition: mysql_lex_string.h:36
Definition: my_bitmap.h:42
SP_TABLE represents all instances of one table in an optimized multi-set of tables used by a stored p...
Definition: sp_head.cc:1571
Definition: table.h:1394
Definition: result.h:29
Definition: sp_head.h:150
sp_label * label
Definition: sp_head.h:151
sp_branch_instr * instr
Definition: sp_head.h:152
Definition: sql_lex.h:2469
LEX_CSTRING language
CREATE|ALTER ... LANGUAGE <language>
Definition: sql_lex.h:2474
Definition: sql_lex.h:2479
#define NULL
Definition: types.h:54