2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Tests for PhpMyAdmin\Rte\Routines
6 * @package PhpMyAdmin-test
8 declare(strict_types
=1);
10 namespace PhpMyAdmin\Tests\Rte
;
12 use PhpMyAdmin\Config
;
13 use PhpMyAdmin\DatabaseInterface
;
14 use PhpMyAdmin\Response
;
15 use PhpMyAdmin\Rte\Routines
;
17 use PHPUnit\Framework\TestCase
;
20 * This class is for testing PhpMyAdmin\Rte\Routines methods
22 * @package PhpMyAdmin-test
24 class RoutinesTest
extends TestCase
36 protected function setUp(): void
38 $GLOBALS['PMA_Config'] = new Config();
39 $GLOBALS['PMA_Config']->enableBc();
40 $GLOBALS['cfg']['Server']['DisableIS'] = false;
41 $GLOBALS['cfg']['ActionLinksMode'] = 'icons';
42 $GLOBALS['server'] = 0;
43 $GLOBALS['db'] = 'db';
44 $GLOBALS['table'] = 'table';
45 $GLOBALS['PMA_PHP_SELF'] = 'index.php';
47 $this->routines
= new Routines($GLOBALS['dbi']);
51 * Test for getDataFromRequest
53 * @param array $in Input
54 * @param array $out Expected output
58 * @dataProvider providerGetDataFromRequest
60 public function testGetDataFromRequest($in, $out): void
64 foreach ($in as $key => $value) {
66 $_POST[$key] = $value;
67 $_REQUEST[$key] = $value;
70 $this->routines
->setGlobals();
71 $this->assertEquals($out, $this->routines
->getDataFromRequest());
75 * Data provider for testGetDataFromRequest
79 public function providerGetDataFromRequest()
85 'item_original_name' => '',
86 'item_returnlength' => '',
87 'item_returnopts_num' => '',
88 'item_returnopts_text' => '',
89 'item_definition' => '',
93 'item_type_toggle' => '',
94 'item_original_type' => '',
95 'item_param_dir' => '',
96 'item_param_name' => '',
97 'item_param_type' => '',
98 'item_param_length' => '',
99 'item_param_opts_num' => '',
100 'item_param_opts_text' => '',
101 'item_returntype' => '',
102 'item_isdeterministic' => '',
103 'item_securitytype' => '',
104 'item_sqldataaccess' => '',
108 'item_original_name' => '',
109 'item_returnlength' => '',
110 'item_returnopts_num' => '',
111 'item_returnopts_text' => '',
112 'item_definition' => '',
113 'item_comment' => '',
114 'item_definer' => '',
115 'item_type' => 'PROCEDURE',
116 'item_type_toggle' => 'FUNCTION',
117 'item_original_type' => 'PROCEDURE',
118 'item_num_params' => 0,
119 'item_param_dir' => [],
120 'item_param_name' => [],
121 'item_param_type' => [],
122 'item_param_length' => [],
123 'item_param_opts_num' => [],
124 'item_param_opts_text' => [],
125 'item_returntype' => '',
126 'item_isdeterministic' => '',
127 'item_securitytype_definer' => '',
128 'item_securitytype_invoker' => '',
129 'item_sqldataaccess' => '',
134 'item_name' => 'proc2',
135 'item_original_name' => 'proc',
136 'item_returnlength' => '',
137 'item_returnopts_num' => '',
138 'item_returnopts_text' => '',
139 'item_definition' => 'SELECT NULL',
140 'item_comment' => 'some text',
141 'item_definer' => 'root@localhost',
142 'item_type' => 'PROCEDURE',
143 'item_type_toggle' => 'FUNCTION',
144 'item_original_type' => 'PROCEDURE',
145 'item_param_dir' => [
149 'item_param_name' => [
153 'item_param_type' => [
157 'item_param_length' => [
161 'item_param_opts_num' => [
165 'item_param_opts_text' => [
169 'item_returntype' => '',
170 'item_isdeterministic' => 'ON',
171 'item_securitytype' => 'INVOKER',
172 'item_sqldataaccess' => 'NO SQL',
175 'item_name' => 'proc2',
176 'item_original_name' => 'proc',
177 'item_returnlength' => '',
178 'item_returnopts_num' => '',
179 'item_returnopts_text' => '',
180 'item_definition' => 'SELECT NULL',
181 'item_comment' => 'some text',
182 'item_definer' => 'root@localhost',
183 'item_type' => 'PROCEDURE',
184 'item_type_toggle' => 'FUNCTION',
185 'item_original_type' => 'PROCEDURE',
186 'item_num_params' => 2,
187 'item_param_dir' => [
191 'item_param_name' => [
195 'item_param_type' => [
199 'item_param_length' => [
203 'item_param_opts_num' => [
207 'item_param_opts_text' => [
211 'item_returntype' => '',
212 'item_isdeterministic' => ' checked=\'checked\'',
213 'item_securitytype_definer' => '',
214 'item_securitytype_invoker' => ' selected=\'selected\'',
215 'item_sqldataaccess' => 'NO SQL',
220 'item_name' => 'func2',
221 'item_original_name' => 'func',
222 'item_returnlength' => '20',
223 'item_returnopts_num' => '',
224 'item_returnopts_text' => 'CHARSET utf8',
225 'item_definition' => 'SELECT NULL',
226 'item_comment' => 'some text',
227 'item_definer' => 'root@localhost',
228 'item_type' => 'FUNCTION',
229 'item_type_toggle' => 'PROCEDURE',
230 'item_original_type' => 'FUNCTION',
231 'item_param_dir' => [
235 'item_param_name' => [
239 'item_param_type' => [
243 'item_param_length' => [
247 'item_param_opts_num' => [
251 'item_param_opts_text' => [
255 'item_returntype' => 'VARCHAR',
256 'item_isdeterministic' => '',
257 'item_securitytype' => 'DEFINER',
258 'item_sqldataaccess' => '',
261 'item_name' => 'func2',
262 'item_original_name' => 'func',
263 'item_returnlength' => '20',
264 'item_returnopts_num' => '',
265 'item_returnopts_text' => 'CHARSET utf8',
266 'item_definition' => 'SELECT NULL',
267 'item_comment' => 'some text',
268 'item_definer' => 'root@localhost',
269 'item_type' => 'FUNCTION',
270 'item_type_toggle' => 'PROCEDURE',
271 'item_original_type' => 'FUNCTION',
272 'item_num_params' => '2',
273 'item_param_dir' => [],
274 'item_param_name' => [
278 'item_param_type' => [
282 'item_param_length' => [
286 'item_param_opts_num' => [
290 'item_param_opts_text' => [
294 'item_returntype' => 'VARCHAR',
295 'item_isdeterministic' => '',
296 'item_securitytype_definer' => ' selected=\'selected\'',
297 'item_securitytype_invoker' => '',
298 'item_sqldataaccess' => '',
305 * Test for getParameterRow
309 public function testGetParameterRowEmpty()
311 $this->routines
->setGlobals();
312 $this->assertEquals('', $this->routines
->getParameterRow([], 0));
316 * Test for getParameterRow
318 * @param array $data Data for routine
319 * @param mixed $index Index
320 * @param array $matcher Matcher
324 * @depends testGetParameterRowEmpty
325 * @dataProvider providerGetParameterRow
327 public function testGetParameterRow($data, $index, $matcher): void
329 $this->routines
->setGlobals();
330 $this->assertStringContainsString(
332 $this->routines
->getParameterRow($data, $index)
337 * Data provider for testGetParameterRow
341 public function providerGetParameterRow()
345 'item_original_name' => '',
346 'item_returnlength' => '',
347 'item_returnopts_num' => '',
348 'item_returnopts_text' => '',
349 'item_definition' => '',
350 'item_comment' => '',
351 'item_definer' => '',
352 'item_type' => 'PROCEDURE',
353 'item_type_toggle' => 'FUNCTION',
354 'item_original_type' => 'PROCEDURE',
355 'item_num_params' => 1,
356 'item_param_dir' => [0 => 'IN'],
357 'item_param_name' => [0 => 'foo'],
358 'item_param_type' => [0 => 'INT'],
359 'item_param_length' => [0 => ''],
360 'item_param_opts_num' => [0 => 'UNSIGNED'],
361 'item_param_opts_text' => [0 => ''],
362 'item_returntype' => '',
363 'item_isdeterministic' => '',
364 'item_securitytype_definer' => '',
365 'item_securitytype_invoker' => '',
366 'item_sqldataaccess' => '',
373 '<select name="item_param_dir[0]"',
378 '<input name="item_param_name[0]"',
383 '<select name="item_param_type[0]"',
388 '<select name="item_param_opts_num[0]"',
393 '<a href="#" class="routine_param_remove_anchor"',
399 * Test for getParameterRow
401 * @param array $data Data for routine
402 * @param array $matcher Matcher
406 * @depends testGetParameterRow
407 * @dataProvider providerGetParameterRowAjax
409 public function testGetParameterRowAjax($data, $matcher): void
411 Response
::getInstance()->setAjax(true);
412 $this->routines
->setGlobals();
413 $this->assertStringContainsString(
415 $this->routines
->getParameterRow($data)
417 Response
::getInstance()->setAjax(false);
421 * Data provider for testGetParameterRowAjax
425 public function providerGetParameterRowAjax()
429 'item_original_name' => '',
430 'item_returnlength' => '',
431 'item_returnopts_num' => '',
432 'item_returnopts_text' => '',
433 'item_definition' => '',
434 'item_comment' => '',
435 'item_definer' => '',
436 'item_type' => 'PROCEDURE',
437 'item_type_toggle' => 'FUNCTION',
438 'item_original_type' => 'PROCEDURE',
439 'item_num_params' => 1,
440 'item_param_dir' => [0 => 'IN'],
441 'item_param_name' => [0 => 'foo'],
442 'item_param_type' => [0 => 'INT'],
443 'item_param_length' => [0 => ''],
444 'item_param_opts_num' => [0 => 'UNSIGNED'],
445 'item_param_opts_text' => [0 => ''],
446 'item_returntype' => '',
447 'item_isdeterministic' => '',
448 'item_securitytype_definer' => '',
449 'item_securitytype_invoker' => '',
450 'item_sqldataaccess' => '',
456 '<select name="item_param_dir[%s]"',
460 '<input name="item_param_name[%s]"',
464 '<select name="item_param_dir[%s]"',
468 '<select name="item_param_opts_num[%s]"',
472 '<a href="#" class="routine_param_remove_anchor"',
478 * Test for getEditorForm
480 * @param array $data Data for routine
481 * @param array $matcher Matcher
485 * @depends testGetParameterRowAjax
486 * @dataProvider providerGetEditorForm1
488 public function testGetEditorForm1($data, $matcher)
490 $this->routines
->setGlobals();
491 $this->assertStringContainsString(
493 $this->routines
->getEditorForm('add', '', $data)
498 * Data provider for testGetEditorForm1
502 public function providerGetEditorForm1()
506 'item_original_name' => '',
507 'item_returnlength' => '',
508 'item_returnopts_num' => '',
509 'item_returnopts_text' => '',
510 'item_definition' => '',
511 'item_comment' => '',
512 'item_definer' => '',
513 'item_type' => 'PROCEDURE',
514 'item_type_toggle' => 'FUNCTION',
515 'item_original_type' => 'PROCEDURE',
516 'item_num_params' => 0,
517 'item_param_dir' => [],
518 'item_param_name' => [],
519 'item_param_type' => [],
520 'item_param_length' => [],
521 'item_param_opts_num' => [],
522 'item_param_opts_text' => [],
523 'item_returntype' => '',
524 'item_isdeterministic' => '',
525 'item_securitytype_definer' => '',
526 'item_securitytype_invoker' => '',
527 'item_sqldataaccess' => '',
533 "<input name='add_item'",
537 "<input type='text' name='item_name'",
541 "<input name='item_type'",
545 "name='routine_changetype'",
549 "name='routine_addparameter'",
553 "name='routine_removeparameter'",
557 "select name='item_returntype'",
561 "name='item_returnlength'",
565 "select name='item_returnopts_num'",
569 "<textarea name='item_definition'",
573 "name='item_isdeterministic'",
577 "name='item_definer'",
581 "select name='item_securitytype'",
585 "select name='item_sqldataaccess'",
589 "name='item_comment'",
593 "name='editor_process_add'",
599 * Test for getEditorForm
601 * @param array $data Data for routine
602 * @param array $matcher Matcher
606 * @depends testGetParameterRowAjax
607 * @dataProvider providerGetEditorForm2
609 public function testGetEditorForm2($data, $matcher)
611 $this->routines
->setGlobals();
612 $this->assertStringContainsString(
614 $this->routines
->getEditorForm('edit', 'change', $data)
619 * Data provider for testGetEditorForm2
623 public function providerGetEditorForm2()
626 'item_name' => 'foo',
627 'item_original_name' => 'bar',
628 'item_returnlength' => '',
629 'item_returnopts_num' => '',
630 'item_returnopts_text' => '',
631 'item_definition' => 'SELECT 1',
632 'item_comment' => '',
633 'item_definer' => '',
634 'item_type' => 'PROCEDURE',
635 'item_type_toggle' => 'FUNCTION',
636 'item_original_type' => 'PROCEDURE',
637 'item_num_params' => 1,
638 'item_param_dir' => [0 => 'IN'],
639 'item_param_name' => [0 => 'baz'],
640 'item_param_type' => [0 => 'INT'],
641 'item_param_length' => [0 => '20'],
642 'item_param_opts_num' => [0 => 'UNSIGNED'],
643 'item_param_opts_text' => [0 => ''],
644 'item_returntype' => '',
645 'item_isdeterministic' => '',
646 'item_securitytype_definer' => '',
647 'item_securitytype_invoker' => '',
648 'item_sqldataaccess' => 'NO SQL',
662 "<input name='item_type' type='hidden' value='FUNCTION'",
666 "name='routine_changetype'",
670 "name='routine_addparameter'",
674 "name='routine_removeparameter'",
678 "name='item_returntype'",
682 "name='item_returnlength'",
686 "name='item_returnopts_num'",
690 "<textarea name='item_definition'",
694 "name='item_isdeterministic'",
698 "name='item_definer'",
702 "<select name='item_securitytype'",
706 "<select name='item_sqldataaccess'",
710 "name='item_comment'",
714 "name='editor_process_edit'",
720 * Test for getEditorForm
722 * @param array $data Data for routine
723 * @param array $matcher Matcher
727 * @depends testGetParameterRowAjax
728 * @dataProvider providerGetEditorForm3
730 public function testGetEditorForm3($data, $matcher)
732 Response
::getInstance()->setAjax(true);
733 $this->routines
->setGlobals();
734 $this->assertStringContainsString(
736 $this->routines
->getEditorForm('edit', 'remove', $data)
738 Response
::getInstance()->setAjax(false);
742 * Data provider for testGetEditorForm3
746 public function providerGetEditorForm3()
749 'item_name' => 'foo',
750 'item_original_name' => 'bar',
751 'item_returnlength' => '',
752 'item_returnopts_num' => 'UNSIGNED',
753 'item_returnopts_text' => '',
754 'item_definition' => 'SELECT 1',
755 'item_comment' => '',
756 'item_definer' => '',
757 'item_type' => 'FUNCTION',
758 'item_type_toggle' => 'PROCEDURE',
759 'item_original_type' => 'FUNCTION',
760 'item_num_params' => 1,
761 'item_param_dir' => [0 => ''],
762 'item_param_name' => [0 => 'baz'],
763 'item_param_type' => [0 => 'INT'],
764 'item_param_length' => [0 => '20'],
765 'item_param_opts_num' => [0 => 'UNSIGNED'],
766 'item_param_opts_text' => [0 => ''],
767 'item_returntype' => 'INT',
768 'item_isdeterministic' => '',
769 'item_securitytype_definer' => '',
770 'item_securitytype_invoker' => '',
771 'item_sqldataaccess' => 'NO SQL',
785 "<select name='item_type'",
789 "name='routine_addparameter'",
793 "name='routine_removeparameter'",
797 "<select name='item_returntype'",
801 "name='item_returnlength'",
805 "<select name='item_returnopts_num'",
809 "<textarea name='item_definition'",
813 "name='item_isdeterministic'",
817 "name='item_definer'",
821 "<select name='item_securitytype'",
825 "<select name='item_sqldataaccess'",
829 "name='item_comment'",
833 "name='ajax_request'",
837 "name='editor_process_edit'",
843 * Test for getEditorForm
845 * @param array $data Data for routine
846 * @param array $matcher Matcher
850 * @depends testGetParameterRowAjax
851 * @dataProvider providerGetEditorForm4
853 public function testGetEditorForm4($data, $matcher)
855 $this->routines
->setGlobals();
856 $this->assertStringContainsString(
858 $this->routines
->getEditorForm('edit', 'change', $data)
863 * Data provider for testGetEditorForm4
867 public function providerGetEditorForm4()
870 'item_name' => 'foo',
871 'item_original_name' => 'bar',
872 'item_returnlength' => '',
873 'item_returnopts_num' => '',
874 'item_returnopts_text' => '',
875 'item_definition' => 'SELECT 1',
876 'item_comment' => '',
877 'item_definer' => '',
878 'item_type' => 'FUNCTION',
879 'item_type_toggle' => 'PROCEDURE',
880 'item_original_type' => 'PROCEDURE',
881 'item_num_params' => 1,
882 'item_param_dir' => [0 => 'IN'],
883 'item_param_name' => [0 => 'baz'],
884 'item_param_type' => [0 => 'INT'],
885 'item_param_length' => [0 => '20'],
886 'item_param_opts_num' => [0 => 'UNSIGNED'],
887 'item_param_opts_text' => [0 => ''],
888 'item_returntype' => '',
889 'item_isdeterministic' => '',
890 'item_securitytype_definer' => '',
891 'item_securitytype_invoker' => '',
892 'item_sqldataaccess' => 'NO SQL',
898 "<input name='item_type' type='hidden' value='PROCEDURE'",
904 * Test for getExecuteForm
906 * @param array $data Data for routine
907 * @param array $matcher Matcher
911 * @dataProvider providerGetExecuteForm1
913 public function testGetExecuteForm1($data, $matcher)
915 $this->routines
->setGlobals();
916 $GLOBALS['cfg']['ShowFunctionFields'] = true;
918 $this->assertStringContainsString(
920 $this->routines
->getExecuteForm($data)
925 * Data provider for testGetExecuteForm1
929 public function providerGetExecuteForm1()
932 'item_name' => 'foo',
933 'item_returnlength' => '',
934 'item_returnopts_num' => '',
935 'item_returnopts_text' => '',
936 'item_definition' => 'SELECT 1;',
937 'item_comment' => '',
938 'item_definer' => '',
939 'item_type' => 'PROCEDURE',
940 'item_num_params' => 6,
941 'item_param_dir' => [
949 'item_param_name' => [
957 'item_param_type' => [
965 'item_param_length' => [
973 'item_param_length_arr' => [
987 'item_param_opts_num' => [
995 'item_param_opts_text' => [
1003 'item_returntype' => '',
1004 'item_isdeterministic' => '',
1005 'item_securitytype_definer' => '',
1006 'item_securitytype_invoker' => '',
1007 'item_sqldataaccess' => '',
1017 "name='funcs[foo]'",
1021 "<input class='datefield' type='text' name='params[foo]'>",
1025 "name='funcs[fob]'",
1029 "<input class='datetimefield' type='text' name='params[fob]'",
1033 "name='params[fod][]'",
1037 "name='params[foe][]'",
1041 "name='execute_routine'",
1047 * Test for getExecuteForm
1049 * @param array $data Data for routine
1050 * @param array $matcher Matcher
1054 * @dataProvider providerGetExecuteForm2
1056 public function testGetExecuteForm2($data, $matcher)
1058 Response
::getInstance()->setAjax(true);
1059 $this->routines
->setGlobals();
1060 $this->assertStringContainsString(
1062 $this->routines
->getExecuteForm($data)
1064 Response
::getInstance()->setAjax(false);
1068 * Data provider for testGetExecuteForm2
1072 public function providerGetExecuteForm2()
1075 'item_name' => 'foo',
1076 'item_returnlength' => '',
1077 'item_returnopts_num' => '',
1078 'item_returnopts_text' => '',
1079 'item_definition' => 'SELECT 1;',
1080 'item_comment' => '',
1081 'item_definer' => '',
1082 'item_type' => 'PROCEDURE',
1083 'item_num_params' => 6,
1084 'item_param_dir' => [
1092 'item_param_name' => [
1100 'item_param_type' => [
1108 'item_param_length' => [
1116 'item_param_length_arr' => [
1130 'item_param_opts_num' => [
1138 'item_param_opts_text' => [
1146 'item_returntype' => '',
1147 'item_isdeterministic' => '',
1148 'item_securitytype_definer' => '',
1149 'item_securitytype_invoker' => '',
1150 'item_sqldataaccess' => '',
1156 "name='execute_routine'",
1160 "name='ajax_request'",
1166 * Test for getQueryFromRequest
1168 * @param array $request Request
1169 * @param string $query Query
1170 * @param int $num_err Error number
1174 * @dataProvider providerGetQueryFromRequest
1176 public function testGetQueryFromRequest($request, $query, $num_err): void
1178 global $errors, $cfg;
1180 $cfg['ShowFunctionFields'] = false;
1183 $this->routines
->setGlobals();
1185 $old_dbi = $GLOBALS['dbi'] ??
null;
1186 $dbi = $this->getMockBuilder('PhpMyAdmin\DatabaseInterface')
1187 ->disableOriginalConstructor()
1189 $dbi->types
= new Types($dbi);
1190 $dbi->expects($this->any())
1191 ->method('escapeString')
1193 $this->returnValueMap(
1197 DatabaseInterface
::CONNECT_USER
,
1202 DatabaseInterface
::CONNECT_USER
,
1207 DatabaseInterface
::CONNECT_USER
,
1213 $GLOBALS['dbi'] = $dbi;
1215 $routines = new Routines($dbi);
1219 $this->assertEquals($query, $routines->getQueryFromRequest());
1220 $this->assertCount($num_err, $errors);
1223 $GLOBALS['dbi'] = $old_dbi;
1227 * Data provider for testGetQueryFromRequest
1231 public function providerGetQueryFromRequest()
1237 'item_name' => 'p r o c',
1238 'item_returnlength' => '',
1239 'item_returnopts_num' => '',
1240 'item_returnopts_text' => '',
1241 'item_definition' => 'SELECT 0;',
1242 'item_comment' => 'foo',
1243 'item_definer' => 'me@home',
1244 'item_type' => 'PROCEDURE',
1245 'item_num_params' => '0',
1246 'item_param_dir' => '',
1247 'item_param_name' => '',
1248 'item_param_type' => '',
1249 'item_param_length' => '',
1250 'item_param_opts_num' => '',
1251 'item_param_opts_text' => '',
1252 'item_returntype' => '',
1253 'item_isdeterministic' => '',
1254 'item_securitytype' => 'INVOKER',
1255 'item_sqldataaccess' => 'NO SQL',
1257 'CREATE DEFINER=`me`@`home` PROCEDURE `p r o c`() COMMENT \'foo\' '
1258 . 'DETERMINISTIC NO SQL SQL SECURITY INVOKER SELECT 0;',
1263 'item_name' => 'pr``oc',
1264 'item_returnlength' => '',
1265 'item_returnopts_num' => '',
1266 'item_returnopts_text' => '',
1267 'item_definition' => 'SELECT \'foobar\';',
1268 'item_comment' => '',
1269 'item_definer' => 'someuser@somehost',
1270 'item_type' => 'PROCEDURE',
1271 'item_num_params' => '2',
1272 'item_param_dir' => [
1276 'item_param_name' => [
1280 'item_param_type' => [
1284 'item_param_length' => [
1288 'item_param_opts_num' => [
1292 'item_param_opts_text' => [
1296 'item_returntype' => '',
1297 'item_securitytype' => 'DEFINER',
1298 'item_sqldataaccess' => 'foobar',
1300 'CREATE DEFINER=`someuser`@`somehost` PROCEDURE `pr````oc`'
1301 . '(IN `pa``ram` INT(10) ZEROFILL, INOUT `par 2` ENUM(\'a\', \'b\')'
1302 . ' CHARSET latin1) NOT DETERMINISTIC SQL SECURITY DEFINER SELECT '
1308 'item_name' => 'func\\',
1309 'item_returnlength' => '5,5',
1310 'item_returnopts_num' => 'UNSIGNED ZEROFILL',
1311 'item_returnopts_text' => '',
1312 'item_definition' => 'SELECT \'foobar\';',
1313 'item_comment' => 'foo\'s bar',
1314 'item_definer' => '',
1315 'item_type' => 'FUNCTION',
1316 'item_num_params' => '1',
1317 'item_param_dir' => '',
1318 'item_param_name' => ['pa`ram'],
1319 'item_param_type' => ['VARCHAR'],
1320 'item_param_length' => ['45'],
1321 'item_param_opts_num' => [''],
1322 'item_param_opts_text' => ['latin1'],
1323 'item_returntype' => 'DECIMAL',
1324 'item_isdeterministic' => 'ON',
1325 'item_securitytype' => 'DEFINER',
1326 'item_sqldataaccess' => 'READ SQL DATA',
1328 'CREATE FUNCTION `func\\`(`pa``ram` VARCHAR(45) CHARSET latin1) '
1329 . 'RETURNS DECIMAL(5,5) UNSIGNED ZEROFILL COMMENT \'foo\\\'s bar\' '
1330 . 'DETERMINISTIC SQL SECURITY DEFINER SELECT \'foobar\';',
1335 'item_name' => 'func',
1336 'item_returnlength' => '20',
1337 'item_returnopts_num' => '',
1338 'item_returnopts_text' => 'utf8',
1339 'item_definition' => 'SELECT 0;',
1340 'item_comment' => '',
1341 'item_definer' => '',
1342 'item_type' => 'FUNCTION',
1343 'item_num_params' => '1',
1344 'item_returntype' => 'VARCHAR',
1345 'item_securitytype' => 'DEFINER',
1346 'item_sqldataaccess' => 'READ SQL DATA',
1348 'CREATE FUNCTION `func`() RETURNS VARCHAR(20) CHARSET utf8 NOT '
1349 . 'DETERMINISTIC SQL SECURITY DEFINER SELECT 0;',
1355 'CREATE () NOT DETERMINISTIC ', // invalid query
1360 'item_name' => 'proc',
1361 'item_returnlength' => '',
1362 'item_returnopts_num' => '',
1363 'item_returnopts_text' => '',
1364 'item_definition' => 'SELECT 0;',
1365 'item_comment' => 'foo',
1366 'item_definer' => 'mehome', // invalid definer format
1367 'item_type' => 'PROCEDURE',
1368 'item_num_params' => '0',
1369 'item_param_dir' => '',
1370 'item_param_name' => '',
1371 'item_param_type' => '',
1372 'item_param_length' => '',
1373 'item_param_opts_num' => '',
1374 'item_param_opts_text' => '',
1375 'item_returntype' => '',
1376 'item_isdeterministic' => '',
1377 'item_securitytype' => 'INVOKER',
1378 'item_sqldataaccess' => 'NO SQL',
1380 'CREATE PROCEDURE `proc`() COMMENT \'foo\' DETERMINISTIC '
1381 . 'NO SQL SQL SECURITY INVOKER SELECT 0;', // valid query
1386 'item_name' => 'proc',
1387 'item_returnlength' => '',
1388 'item_returnopts_num' => '',
1389 'item_returnopts_text' => '',
1390 'item_definition' => 'SELECT 0;',
1391 'item_comment' => '',
1392 'item_definer' => '',
1393 'item_type' => 'PROCEDURE',
1394 'item_num_params' => '2',
1395 'item_param_dir' => [
1398 ], // invalid direction
1399 'item_param_name' => [
1403 'item_param_type' => [
1407 'item_param_length' => [
1410 ], // missing ENUM values
1411 'item_param_opts_num' => [
1415 'item_param_opts_text' => [
1419 'item_returntype' => '',
1420 'item_securitytype' => 'DEFINER',
1421 'item_sqldataaccess' => 'foobar', // invalid, will just be ignored without throwing errors
1423 'CREATE PROCEDURE `proc`((10) ZEROFILL, '
1424 . 'INOUT `goo` ENUM CHARSET latin1) NOT DETERMINISTIC '
1425 . 'SQL SECURITY DEFINER SELECT 0;', // invalid query
1430 'item_name' => 'func',
1431 'item_returnlength' => '', // missing length for VARCHAR
1432 'item_returnopts_num' => '',
1433 'item_returnopts_text' => 'utf8',
1434 'item_definition' => 'SELECT 0;',
1435 'item_comment' => '',
1436 'item_definer' => '',
1437 'item_type' => 'FUNCTION',
1438 'item_num_params' => '2',
1439 'item_param_dir' => ['IN'],
1440 'item_param_name' => [''], // missing name
1441 'item_param_type' => ['INT'],
1442 'item_param_length' => ['10'],
1443 'item_param_opts_num' => ['ZEROFILL'],
1444 'item_param_opts_text' => ['latin1'],
1445 'item_returntype' => 'VARCHAR',
1446 'item_securitytype' => 'DEFINER',
1447 'item_sqldataaccess' => '',
1449 'CREATE FUNCTION `func`() RETURNS VARCHAR CHARSET utf8 NOT '
1450 . 'DETERMINISTIC SQL SECURITY DEFINER SELECT 0;', // invalid query
1455 'item_name' => 'func',
1456 'item_returnlength' => '',
1457 'item_returnopts_num' => '',
1458 'item_returnopts_text' => '',
1459 'item_definition' => 'SELECT 0;',
1460 'item_comment' => '',
1461 'item_definer' => '',
1462 'item_type' => 'FUNCTION',
1463 'item_num_params' => '0',
1464 'item_returntype' => 'FAIL', // invalid return type
1465 'item_securitytype' => 'DEFINER',
1466 'item_sqldataaccess' => '',
1468 'CREATE FUNCTION `func`() NOT DETERMINISTIC SQL '
1469 . 'SECURITY DEFINER SELECT 0;', // invalid query