1--source include/have_udf.inc
2#
3# To run this tests the "sql/udf_example.c" need to be compiled into
4# udf_example.so and LD_LIBRARY_PATH should be setup to point out where
5# the library are.
6#
7
8
9--disable_warnings
10drop table if exists t1;
11--enable_warnings
12
13#
14# Create the example functions from udf_example
15#
16
17--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
18eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
19--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
20eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_SO";
21
22--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
23--error ER_CANT_FIND_DL_ENTRY
24eval CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
25--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
26eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
27--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
28eval CREATE FUNCTION udf_sequence RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
29--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
30eval CREATE FUNCTION lookup RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
31--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
32eval CREATE FUNCTION reverse_lookup
33        RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
34--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
35eval CREATE AGGREGATE FUNCTION avgcost
36        RETURNS REAL SONAME "$UDF_EXAMPLE_SO";
37
38--error ER_CANT_INITIALIZE_UDF
39select myfunc_double();
40select myfunc_double(1);
41select myfunc_double(78654);
42--error 1305
43select myfunc_nonexist();
44select myfunc_int();
45--error ER_CANT_INITIALIZE_UDF
46select lookup();
47select lookup("127.0.0.1");
48--error ER_CANT_INITIALIZE_UDF
49select lookup(127,0,0,1);
50select lookup("localhost") rlike '^127\.\\d+\.\\d+.\\d+$';
51--error ER_CANT_INITIALIZE_UDF
52select reverse_lookup();
53
54# These two function calls should return "localhost", but it's
55# depending on configuration, so just call them and don't log the result
56--disable_result_log
57select reverse_lookup("127.0.0.1");
58select reverse_lookup(127,0,0,1);
59
60# This function call may return different results depending on platform,
61# so ignore results (see Bug#52060).
62select reverse_lookup("localhost");
63--enable_result_log
64
65--error ER_CANT_INITIALIZE_UDF
66select avgcost();
67--error ER_CANT_INITIALIZE_UDF
68select avgcost(100,23.76);
69create table t1(sum int, price float(24));
70insert into t1 values(100, 50.00), (100, 100.00);
71select avgcost(sum, price) from t1;
72delete from t1;
73insert into t1 values(100, 54.33), (200, 199.99);
74select avgcost(sum, price) from t1;
75drop table t1;
76
77#------------------------------------------------------------------------
78# BUG#17261 Passing a variable from a stored procedure to UDF crashes mysqld
79#------------------------------------------------------------------------
80
81select metaphon('hello');
82
83delimiter //;
84CREATE PROCEDURE `XXX1`(in testval varchar(10))
85begin
86select metaphon(testval);
87end//
88delimiter ;//
89
90call XXX1('hello');
91drop procedure xxx1;
92
93delimiter //;
94CREATE PROCEDURE `XXX2`()
95begin
96declare testval varchar(10);
97set testval = 'hello';
98select metaphon(testval);
99end//
100delimiter ;//
101
102call XXX2();
103drop procedure xxx2;
104
105#
106# Bug#19904: UDF: not initialized *is_null per row
107#
108
109CREATE TABLE bug19904(n INT, v varchar(10));
110INSERT INTO bug19904 VALUES (1,'one'),(2,'two'),(NULL,NULL),(3,'three'),(4,'four');
111SELECT myfunc_double(n) AS f FROM bug19904;
112SELECT metaphon(v) AS f FROM bug19904;
113DROP TABLE bug19904;
114
115#
116# Bug#21269: DEFINER-clause is allowed for UDF-functions
117#
118
119--error ER_PARSE_ERROR
120CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse
121RETURNS STRING SONAME "should_not_parse.so";
122
123--error ER_PARSE_ERROR
124CREATE DEFINER=someone@somewhere FUNCTION should_not_parse
125RETURNS STRING SONAME "should_not_parse.so";
126#
127# Bug#19862: Sort with filesort by function evaluates function twice
128#
129create table t1(f1 int);
130insert into t1 values(1),(2);
131explain select myfunc_int(f1) from t1 order by 1;
132drop table t1;
133
134#
135# Bug #21809: Error 1356 while selecting from view with grouping though
136#              underlying select OK.
137#
138CREATE TABLE t1(a INT, b INT); INSERT INTO t1 values (1,1),(2,2);
139
140DELIMITER ||;
141CREATE FUNCTION fn(a int) RETURNS int DETERMINISTIC
142BEGIN
143    RETURN a;
144END
145||
146DELIMITER ;||
147
148CREATE VIEW v1 AS SELECT a, fn(MIN(b)) as c FROM t1 GROUP BY a;
149
150SELECT myfunc_int(a AS attr_name) FROM t1;
151EXPLAIN EXTENDED SELECT myfunc_int(a AS attr_name) FROM t1;
152EXPLAIN EXTENDED SELECT myfunc_int(a) FROM t1;
153SELECT a,c FROM v1;
154
155--error ER_WRONG_PARAMETERS_TO_STORED_FCT
156SELECT a, fn(MIN(b) xx) as c FROM t1 GROUP BY a;
157--error ER_WRONG_PARAMETERS_TO_STORED_FCT
158SELECT myfunc_int(fn(MIN(b) xx)) as c FROM t1 GROUP BY a;
159--error ER_PARSE_ERROR
160SELECT myfunc_int(test.fn(MIN(b) xx)) as c FROM t1 GROUP BY a;
161
162SELECT myfunc_int(fn(MIN(b)) xx) as c FROM t1 GROUP BY a;
163SELECT myfunc_int(test.fn(MIN(b)) xx) as c FROM t1 GROUP BY a;
164
165EXPLAIN EXTENDED SELECT myfunc_int(MIN(b) xx) as c FROM t1 GROUP BY a;
166EXPLAIN EXTENDED SELECT test.fn(MIN(b)) as c FROM t1 GROUP BY a;
167EXPLAIN EXTENDED SELECT myfunc_int(fn(MIN(b))) as c FROM t1 GROUP BY a;
168EXPLAIN EXTENDED SELECT myfunc_int(test.fn(MIN(b))) as c FROM t1 GROUP BY a;
169SELECT myfunc_int(MIN(b) xx) as c FROM t1 GROUP BY a;
170SELECT test.fn(MIN(b)) as c FROM t1 GROUP BY a;
171SELECT myfunc_int(fn(MIN(b))) as c FROM t1 GROUP BY a;
172SELECT myfunc_int(test.fn(MIN(b))) as c FROM t1 GROUP BY a;
173DROP VIEW v1;
174DROP TABLE t1;
175DROP FUNCTION fn;
176
177--echo End of 5.0 tests.
178
179#
180# Bug#24736: UDF functions parsed as Stored Functions
181#
182
183select myfunc_double(3);
184select myfunc_double(3 AS three);
185select myfunc_double(abs(3));
186select myfunc_double(abs(3) AS named_param);
187select abs(myfunc_double(3));
188select abs(myfunc_double(3 AS three));
189
190-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
191select myfunc_double(abs(3 AS wrong));
192-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
193select abs(myfunc_double(3) AS wrong);
194
195#
196# BUG#18239: Possible to overload internal functions with stored functions
197#
198
199--disable_warnings
200drop function if exists pi;
201--enable_warnings
202
203--error ER_NATIVE_FCT_NAME_COLLISION
204CREATE FUNCTION pi RETURNS STRING SONAME "should_not_parse.so";
205
206# Verify that Stored Functions and UDF are mutually exclusive
207DROP FUNCTION IF EXISTS metaphon;
208
209CREATE FUNCTION metaphon(a int) RETURNS int
210return 0;
211
212# this currently passes, and eclipse the stored function
213--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
214eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
215
216DROP FUNCTION metaphon;
217DROP FUNCTION metaphon;
218
219--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
220eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
221
222--error ER_UDF_EXISTS
223CREATE FUNCTION metaphon(a int) RETURNS int
224return 0;
225
226--error ER_UDF_EXISTS
227CREATE FUNCTION test.metaphon(a int) RETURNS int
228return 0;
229
230# End of Bug#18239
231
232#
233# Drop the example functions from udf_example
234#
235
236DROP FUNCTION metaphon;
237DROP FUNCTION myfunc_double;
238--error ER_SP_DOES_NOT_EXIST
239DROP FUNCTION myfunc_nonexist;
240DROP FUNCTION myfunc_int;
241DROP FUNCTION udf_sequence;
242DROP FUNCTION lookup;
243DROP FUNCTION reverse_lookup;
244DROP FUNCTION avgcost;
245
246#
247# Bug #15439: UDF name case handling forces DELETE FROM mysql.func to remove
248#             the UDF
249#
250select * from mysql.func;
251--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
252eval CREATE FUNCTION is_const RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
253
254select IS_const(3);
255
256drop function IS_const;
257
258select * from mysql.func;
259
260--error 1305
261select is_const(3);
262
263#
264# Bug#18761: constant expression as UDF parameters not passed in as constant
265#
266--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
267eval CREATE FUNCTION is_const RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
268
269select
270  is_const(3) as const,
271  is_const(3.14) as const,
272  is_const('fnord') as const,
273  is_const(2+3) as const,
274  is_const(rand()) as 'nc rand()',
275  is_const(sin(3.14)) as const,
276  is_const(upper('test')) as const;
277
278create table bug18761 (n int);
279insert into bug18761 values (null),(2);
280select
281  is_const(3) as const,
282  is_const(3.14) as const,
283  is_const('fnord') as const,
284  is_const(2+3) as const,
285  is_const(2+n) as 'nc  2+n  ',
286  is_const(sin(n)) as 'nc sin(n)',
287  is_const(sin(3.14)) as const,
288  is_const(upper('test')) as const,
289  is_const(rand()) as 'nc rand()',
290  is_const(n) as 'nc   n   ',
291  is_const(is_const(n)) as 'nc ic?(n)',
292  is_const(is_const('c')) as const
293from
294  bug18761;
295drop table bug18761;
296
297--error 1241
298select is_const((1,2,3));
299
300drop function if exists is_const;
301
302#
303# Bug #25382: Passing NULL to an UDF called from stored procedures
304# crashes server
305#
306--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
307eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
308
309--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
310eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_SO";
311
312--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
313eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
314
315delimiter //;
316create function f1(p1 varchar(255))
317returns varchar(255)
318begin
319  return metaphon(p1);
320end//
321
322create function f2(p1 varchar(255))
323returns double
324begin
325  return myfunc_double(p1);
326end//
327
328create function f3(p1 varchar(255))
329returns double
330begin
331  return myfunc_int(p1);
332end//
333
334delimiter ;//
335
336select f3(NULL);
337select f2(NULL);
338select f1(NULL);
339
340drop function f1;
341drop function f2;
342drop function f3;
343drop function metaphon;
344drop function myfunc_double;
345drop function myfunc_int;
346
347#
348# Bug#28318  CREATE FUNCTION (UDF) requires a schema
349#
350
351--disable_warnings
352DROP DATABASE IF EXISTS mysqltest;
353--enable_warnings
354CREATE DATABASE mysqltest;
355USE mysqltest;
356DROP DATABASE mysqltest;
357--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
358eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
359DROP FUNCTION metaphon;
360USE test;
361
362#
363# Bug #29804  UDF parameters don't contain correct string length
364#
365
366CREATE TABLE const_len_bug (
367  str_const varchar(4000),
368  result1 varchar(4000),
369  result2 varchar(4000)
370);
371
372DELIMITER |;
373CREATE TRIGGER check_const_len_trigger BEFORE INSERT ON const_len_bug FOR EACH ROW BEGIN
374   set NEW.str_const = 'bar';
375   set NEW.result2 = check_const_len(NEW.str_const);
376END |
377
378CREATE PROCEDURE check_const_len_sp (IN str_const VARCHAR(4000))
379BEGIN
380DECLARE result VARCHAR(4000);
381SET result = check_const_len(str_const);
382insert into const_len_bug values(str_const, result, "");
383END |
384DELIMITER ;|
385
386--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
387eval CREATE FUNCTION check_const_len RETURNS string SONAME "$UDF_EXAMPLE_SO";
388
389CALL check_const_len_sp("foo");
390
391SELECT * from const_len_bug;
392
393DROP FUNCTION check_const_len;
394DROP PROCEDURE check_const_len_sp;
395DROP TRIGGER check_const_len_trigger;
396DROP TABLE const_len_bug;
397
398
399#
400# Bug #30355: Incorrect ordering of UDF results
401#
402
403--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
404eval CREATE FUNCTION udf_sequence RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
405CREATE TABLE t1 (a INT);
406CREATE TABLE t2 (a INT PRIMARY KEY);
407INSERT INTO t1 VALUES (4),(3),(2),(1);
408INSERT INTO t2 SELECT * FROM t1;
409
410SELECT udf_sequence() AS seq, a FROM t1 ORDER BY seq ASC;
411SELECT udf_sequence() AS seq, a FROM t1 ORDER BY seq DESC;
412
413SELECT * FROM t1 WHERE a = udf_sequence();
414SELECT * FROM t2 WHERE a = udf_sequence();
415
416DROP FUNCTION udf_sequence;
417DROP TABLE t1,t2;
418
419#
420# Bug#31767 (DROP FUNCTION name resolution)
421#
422
423--disable_warnings
424drop function if exists test.metaphon;
425drop function if exists metaphon;
426--enable_warnings
427
428--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
429eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
430
431select metaphon("Hello");
432
433# The UDF should not be dropped
434drop function if exists test.metaphon;
435
436select metaphon("Hello");
437
438drop function metaphon;
439
440CREATE FUNCTION test.metaphon(a TEXT) RETURNS TEXT return "This is a SF";
441
442create database db_31767;
443use db_31767;
444
445--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
446eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
447
448use test;
449
450# Uses the UDF
451select metaphon("Hello");
452
453# Uses the SF
454select test.metaphon("Hello");
455
456# Should drop the UDF, resolving the name the same way select does.
457drop function metaphon;
458
459# Should call the SF
460select metaphon("Hello");
461
462# Drop the SF
463drop function metaphon;
464
465# Change the current database to none.
466use db_31767;
467drop database db_31767;
468
469drop function if exists no_such_func;
470
471--error ER_SP_DOES_NOT_EXIST
472drop function no_such_func;
473
474drop function if exists test.no_such_func;
475
476--error ER_SP_DOES_NOT_EXIST
477drop function test.no_such_func;
478
479--error ER_NO_DB_ERROR
480drop procedure if exists no_such_proc;
481
482--error ER_NO_DB_ERROR
483drop procedure no_such_proc;
484
485use test;
486
487
488--echo #
489--echo # Bug#46259: 5.0.83 -> 5.1.36, query doesn't work
490--echo #
491CREATE TABLE t1 ( a INT );
492
493INSERT INTO t1 VALUES (1), (2), (3);
494
495SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b` + 1, 1 );
496SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b`, 1 );
497
498DROP TABLE t1;
499
500--echo End of 5.0 tests.
501
502--echo #
503--echo # Bug#33546: Slowdown on re-evaluation of constant expressions.
504--echo #
505CREATE TABLE t1 (f1 INT);
506INSERT INTO t1 VALUES(1),(50);
507--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
508eval CREATE FUNCTION myfunc_double RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
509EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE f1=1 + myfunc_double(1);
510DROP FUNCTION myfunc_double;
511DROP TABLE t1;
512--echo #
513--echo End of 5.1 tests.
514
515--echo #
516--echo # MDEV-10134 Add full support for DEFAULT
517--echo #
518
519--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
520eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
521SELECT METAPHON('Hello');
522CREATE TABLE t1 (a VARCHAR(10), b VARCHAR(10) DEFAULT METAPHON(a));
523SHOW CREATE TABLE t1;
524INSERT INTO t1 (a) VALUES ('Hello');
525SELECT * FROM t1;
526DROP FUNCTION METAPHON;
527# QQ: this should return an error
528#INSERT INTO t1 (a) VALUES ('Hello');
529#SELECT * FROM t1;
530DROP TABLE t1;
531
532--echo #
533--echo # MDEV-15424: Unreasonal SQL Error (1356) on select from view
534--echo #
535--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
536eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
537create table t1(a int , b int);
538insert into t1 values(100, 54), (200, 199);
539create view v1 as select myfunc_int(max(a) over (order by b) , b) from t1;
540select * from v1;
541drop view v1;
542drop function myfunc_int;
543drop table t1;
544
545--echo #
546--echo # MDEV-23327: Can't uninstall UDF if the implementation library
547--echo # file doesn't exist
548--echo #
549
550# emulate brocken so/ddl udf
551insert into  mysql.func values ("unexisting_udf", 0, "soname", "function");
552
553# check that we have the function "installed"
554select * from mysql.func WHERE name='unexisting_udf';
555
556# make attempt to drop the function
557DROP FUNCTION unexisting_udf;
558
559# check that we have the plugin uninstalled
560select * from mysql.plugin WHERE name='unexisting_udf';
561
562--error ER_SP_DOES_NOT_EXIST
563DROP FUNCTION unexisting_udf;
564
565--echo #
566--echo # Bug #31674599: THE UDF_INIT() FUNCTION CAUSE SERVER CRASH
567--echo #
568call mtr.add_suppression('Invalid row in mysql.func table');
569insert mysql.func () values ();
570source include/restart_mysqld.inc;
571delete from mysql.func where name = '';
572
573--echo #
574--echo # End of 10.2 tests
575--echo #
576
577--echo #
578--echo # MDEV-15073: Generic UDAF parser code in server for window functions
579--echo #
580
581--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
582eval CREATE AGGREGATE FUNCTION avgcost
583        RETURNS REAL SONAME "$UDF_EXAMPLE_SO";
584--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
585eval CREATE AGGREGATE FUNCTION avg2
586        RETURNS REAL SONAME "$UDF_EXAMPLE_SO";
587--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
588eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_SO";
589
590create table t1(pk int primary key,
591                a int,
592                sum int,
593                price float(24));
594insert into t1 values
595  (1, 1, 100, 50.00),
596  (2, 1, 100, 100.00),
597  (3, 1, 100, 50.00),
598  (4, 1, 100, 50.00),
599  (5, 1, 100, 50.00),
600  (6, 1, 100, NULL),
601  (7, 1, NULL, NULL),
602  (8, 2, 2,   2),
603  (9, 2, 4,   4);
604
605--sorted_result
606select pk, a, sum, price, avgcost(sum, price) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
607from t1;
608--sorted_result
609select pk, a, sum, price, avgcost(sum, price) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
610from t1;
611
612--sorted_result
613select pk, a, sum, price, avg2(sum, price) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
614from t1;
615--sorted_result
616select pk, a, sum, price, avg2(sum, price) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
617from t1;
618--error ER_PARSE_ERROR
619select pk, a, sum, price, tttttttt(sprice,sum) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
620from t1;
621--error ER_PARSE_ERROR
622select pk, a, sum, price, myfunc_double(sum) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
623from t1;
624--error ER_PARSE_ERROR
625select pk, a, sum, price, round(sprice,sum) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
626from t1;
627--error ER_PARSE_ERROR
628select pk, a, sum, price, myfunc_double(sum) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
629from t1;
630
631set @save_sql_mode = @@sql_mode;
632set sql_mode="oracle";
633--sorted_result
634select pk, a, sum, price, avg2(sum, price) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
635from t1;
636set sql_mode= @save_sql_mode;
637
638drop table t1;
639DROP FUNCTION avgcost;
640DROP FUNCTION avg2;
641DROP FUNCTION myfunc_double;
642
643--echo # End of 10.4 tests
644