1
2--echo #
3--echo # Start of 10.3 tests
4--echo #
5
6--echo #
7--echo # MDEV-12461 TYPE OF and ROW TYPE OF anchored data types
8--echo #
9
10--echo #
11--echo # A complete working example
12--echo #
13
14CREATE TABLE t1 (a INT, b VARCHAR(32));
15CREATE TABLE t2 LIKE t1;
16INSERT INTO t1 VALUES (10,'b10');
17INSERT INTO t1 VALUES (20,'b20');
18INSERT INTO t1 VALUES (30,'b30');
19DELIMITER $$;
20CREATE PROCEDURE p1()
21BEGIN
22  DECLARE c CURSOR FOR SELECT a,b FROM t1;
23  BEGIN
24    DECLARE done INT DEFAULT 0;
25    DECLARE rec ROW TYPE OF c;
26    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
27    OPEN c;
28    read_loop: LOOP
29      FETCH c INTO rec;
30      IF done THEN
31        LEAVE read_loop;
32      END IF;
33      SELECT rec.a ,rec.b FROM dual;
34      INSERT INTO t2 VALUES (rec.a, rec.b);
35    END LOOP;
36    CLOSE c;
37  END;
38END;
39$$
40DELIMITER ;$$
41CALL p1();
42SELECT * FROM t2;
43DROP PROCEDURE p1;
44DROP TABLE t2;
45DROP TABLE t1;
46
47
48--echo #
49--echo # cursor ROW TYPE referring to a table in a non-existing database
50--echo #
51
52DELIMITER $$;
53CREATE PROCEDURE p1()
54BEGIN
55  DECLARE cur CURSOR FOR SELECT * FROM tes2.t1;
56  BEGIN
57    DECLARE rec ROW TYPE OF cur;
58  END;
59END;
60$$
61DELIMITER ;$$
62--error ER_NO_SUCH_TABLE
63CALL p1();
64CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10));
65--error ER_NO_SUCH_TABLE
66CALL p1();
67DROP TABLE t1;
68DROP PROCEDURE p1;
69
70
71--echo #
72--echo # cursor ROW TYPE referring to a table in the current database
73--echo #
74
75DELIMITER $$;
76CREATE PROCEDURE p1()
77BEGIN
78  DECLARE cur CURSOR FOR SELECT * FROM t1;
79  BEGIN
80    DECLARE rec ROW TYPE OF cur;
81    CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d;
82    SHOW CREATE TABLE t2;
83    DROP TABLE t2;
84  END;
85END;
86$$
87DELIMITER ;$$
88--error ER_NO_SUCH_TABLE
89CALL p1();
90CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10));
91CALL p1();
92DROP TABLE t1;
93--error ER_NO_SUCH_TABLE
94CALL p1();
95DROP PROCEDURE p1;
96
97
98--echo #
99--echo # cursor ROW TYPE referring to a table in an explicitly specified database
100--echo #
101
102DELIMITER $$;
103CREATE PROCEDURE p1()
104BEGIN
105  DECLARE cur CURSOR FOR SELECT * FROM test.t1;
106  BEGIN
107    DECLARE rec ROW TYPE OF cur;
108    CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d;
109    SHOW CREATE TABLE t2;
110    DROP TABLE t2;
111  END;
112END;
113$$
114DELIMITER ;$$
115--error ER_NO_SUCH_TABLE
116CALL p1();
117CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10));
118CALL p1();
119DROP TABLE t1;
120DROP PROCEDURE p1;
121
122
123--echo #
124--echo # Cursor ROW TYPE referring to a view in the current database
125--echo #
126
127DELIMITER $$;
128CREATE PROCEDURE p1()
129BEGIN
130  DECLARE cur CURSOR FOR SELECT * FROM v1;
131  BEGIN
132    DECLARE rec ROW TYPE OF cur;
133    CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d;
134    SHOW CREATE TABLE t2;
135    DROP TABLE t2;
136  END;
137END;
138$$
139DELIMITER ;$$
140--error ER_NO_SUCH_TABLE
141CALL p1();
142CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10));
143CREATE VIEW v1 AS SELECT * FROM t1;
144CALL p1();
145DROP VIEW v1;
146DROP TABLE t1;
147DROP PROCEDURE p1;
148
149
150--echo #
151--echo # cursor ROW TYPE referring to a view in an explicitly specified database
152--echo #
153
154DELIMITER $$;
155CREATE PROCEDURE p1()
156BEGIN
157  DECLARE cur CURSOR FOR SELECT * FROM test.v1;
158  BEGIN
159    DECLARE rec ROW TYPE OF cur;
160    CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d;
161    SHOW CREATE TABLE t2;
162    DROP TABLE t2;
163  END;
164END;
165$$
166DELIMITER ;$$
167--error ER_NO_SUCH_TABLE
168CALL p1();
169CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10));
170CREATE VIEW v1 AS SELECT * FROM t1;
171CALL p1();
172DROP VIEW v1;
173DROP TABLE t1;
174DROP PROCEDURE p1;
175
176
177--echo #
178--echo # Checking that all cursor ROW TYPE fields are NULL by default
179--echo #
180
181CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2));
182DELIMITER $$;
183CREATE PROCEDURE p1()
184BEGIN
185  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
186  BEGIN
187    DECLARE rec1 ROW TYPE OF cur1;
188    SELECT rec1.a, rec1.b, rec1.c, rec1.d;
189  END;
190END;
191$$
192DELIMITER ;$$
193CALL p1();
194DROP TABLE t1;
195DROP PROCEDURE p1;
196
197
198--echo #
199--echo # A cursor ROW TYPE variable with a ROW expression as a default
200--echo #
201CREATE TABLE t1 (a INT, b VARCHAR(10));
202DELIMITER $$;
203CREATE PROCEDURE p1()
204BEGIN
205  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
206  BEGIN
207    DECLARE rec1 ROW TYPE OF cur1 DEFAULT ROW(10,'bbb');
208    SELECT rec1.a, rec1.b;
209  END;
210END;
211$$
212DELIMITER ;$$
213CALL p1();
214DROP TABLE t1;
215DROP PROCEDURE p1;
216
217
218--echo #
219--echo # A cursor ROW TYPE variable with an incompatible ROW expression as a default
220--echo #
221CREATE TABLE t1 (a INT, b VARCHAR(10));
222DELIMITER $$;
223CREATE PROCEDURE p1()
224BEGIN
225  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
226  BEGIN
227    DECLARE rec1 ROW TYPE OF cur1  DEFAULT  ROW(10,'bbb','ccc');
228    SELECT rec1.a, rec1.b;
229  END;
230END;
231$$
232DELIMITER ;$$
233--error ER_OPERAND_COLUMNS
234CALL p1();
235DROP TABLE t1;
236DROP PROCEDURE p1;
237
238
239--echo #
240--echo # A cursor ROW TYPE variable with a ROW variable as a default
241--echo #
242CREATE TABLE t1 (a INT, b VARCHAR(10));
243DELIMITER $$;
244CREATE PROCEDURE p1()
245BEGIN
246  DECLARE cur CURSOR FOR SELECT * FROM t1;
247  BEGIN
248    DECLARE rec1 ROW(a INT, b VARCHAR(10)) DEFAULT  ROW(10,'bbb');
249    DECLARE rec2 ROW TYPE OF cur  DEFAULT  rec1;
250    SELECT rec2.a, rec2.b;
251  END;
252END;
253$$
254DELIMITER ;$$
255CALL p1();
256DROP TABLE t1;
257DROP PROCEDURE p1;
258
259
260--echo #
261--echo # A ROW variable using a cursor ROW TYPE variable as a default
262--echo #
263CREATE TABLE t1 (a INT, b VARCHAR(10));
264DELIMITER $$;
265CREATE PROCEDURE p1()
266BEGIN
267  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
268  BEGIN
269    DECLARE rec1 ROW TYPE OF cur1  DEFAULT  ROW(10,'bbb');
270    DECLARE rec2 ROW(a INT, b VARCHAR(10)) DEFAULT  rec1;
271    SELECT rec2.a, rec2.b;
272  END;
273END;
274$$
275DELIMITER ;$$
276CALL p1();
277DROP TABLE t1;
278DROP PROCEDURE p1;
279
280
281--echo #
282--echo # Assigning cursor ROW TYPE variables with a different column count
283--echo #
284CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE);
285CREATE TABLE t2 (a INT, b VARCHAR(10));
286DELIMITER $$;
287CREATE PROCEDURE p1()
288BEGIN
289  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
290  DECLARE cur2 CURSOR FOR SELECT * FROM t2;
291  BEGIN
292    DECLARE rec1 ROW TYPE OF cur1;
293    DECLARE rec2 ROW TYPE OF cur2;
294    SET rec2=rec1;
295  END;
296END;
297$$
298DELIMITER ;$$
299--error ER_OPERAND_COLUMNS
300CALL p1();
301DROP PROCEDURE p1;
302DELIMITER $$;
303CREATE PROCEDURE p1()
304BEGIN
305  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
306  DECLARE cur2 CURSOR FOR SELECT * FROM t2;
307  BEGIN
308    DECLARE rec1 ROW TYPE OF cur1;
309    DECLARE rec2 ROW TYPE OF cur2;
310    SET rec1=rec2;
311  END;
312END;
313$$
314DELIMITER ;$$
315--error ER_OPERAND_COLUMNS
316CALL p1();
317DROP TABLE t2;
318DROP TABLE t1;
319DROP PROCEDURE p1;
320
321
322--echo #
323--echo # Assigning compatible cursor ROW TYPE variables (equal number of fields)
324--echo #
325CREATE TABLE t1 (a INT, b VARCHAR(10));
326CREATE TABLE t2 (x INT, y VARCHAR(10));
327DELIMITER $$;
328CREATE PROCEDURE p1()
329BEGIN
330  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
331  DECLARE cur2 CURSOR FOR SELECT * FROM t2;
332  BEGIN
333    DECLARE rec1 ROW TYPE OF cur1;
334    DECLARE rec2 ROW TYPE OF cur2;
335    SET rec1.a= 10;
336    SET rec1.b= 'bbb';
337    SET rec2=rec1;
338    SELECT rec2.x, rec2.y;
339  END;
340END;
341$$
342DELIMITER ;$$
343CALL p1();
344DROP TABLE t2;
345DROP TABLE t1;
346DROP PROCEDURE p1;
347
348
349--echo #
350--echo # Assigning between incompatible cursor ROW TYPE and explicit ROW variables
351--echo #
352
353CREATE TABLE t1 (a INT, b VARCHAR(10));
354DELIMITER $$;
355CREATE PROCEDURE p1()
356BEGIN
357  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
358  BEGIN
359    DECLARE rec1 ROW TYPE OF cur1;
360    DECLARE rec2 ROW(x INT,y INT,z INT);
361    SET rec2.x= 10;
362    SET rec2.y= 20;
363    SET rec2.z= 30;
364    SET rec1= rec2;
365  END;
366END;
367$$
368DELIMITER ;$$
369--error ER_OPERAND_COLUMNS
370CALL p1();
371DROP TABLE t1;
372DROP PROCEDURE p1;
373
374
375--echo #
376--echo # Assigning between compatible cursor ROW TYPE and explicit ROW variables
377--echo #
378
379CREATE TABLE t1 (a INT, b VARCHAR(10));
380DELIMITER $$;
381CREATE PROCEDURE p1()
382BEGIN
383  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
384  BEGIN
385    DECLARE rec1 ROW TYPE OF cur1;
386    DECLARE rec2 ROW(x INT,y INT);
387    SET rec2.x= 10;
388    SET rec2.y= 20;
389    SET rec1= rec2;
390    SELECT rec1.a, rec1.b;
391    SET rec1.a= 11;
392    SET rec1.b= 21;
393    SET rec2= rec1;
394    SELECT rec2.x, rec2.y;
395  END;
396END;
397$$
398DELIMITER ;$$
399CALL p1();
400DROP TABLE t1;
401DROP PROCEDURE p1;
402
403
404--echo #
405--echo # Assigning cursor ROW TYPE from a ROW expression
406--echo #
407
408CREATE TABLE t1 (a INT, b VARCHAR(10));
409DELIMITER $$;
410CREATE PROCEDURE p1()
411BEGIN
412  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
413  BEGIN
414    DECLARE rec1 ROW TYPE OF cur1;
415    SET rec1= ROW(10,20);
416    SELECT rec1.a, rec1.b;
417  END;
418END;
419$$
420DELIMITER ;$$
421CALL p1();
422DROP TABLE t1;
423DROP PROCEDURE p1;
424
425
426--echo #
427--echo # Fetching a cursor into a cursor ROW TYPE variable with a wrong field count
428--echo #
429
430CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2));
431CREATE TABLE t2 (a INT, b VARCHAR(10));
432INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31);
433DELIMITER $$;
434CREATE PROCEDURE p1()
435BEGIN
436  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
437  DECLARE cur2 CURSOR FOR SELECT * FROM t2;
438  BEGIN
439    DECLARE rec2 ROW TYPE OF cur2;
440    OPEN cur1;
441    FETCH cur1 INTO rec2;
442    CLOSE cur1;
443  END;
444END;
445$$
446DELIMITER ;$$
447--error ER_SP_WRONG_NO_OF_FETCH_ARGS
448CALL p1();
449DROP TABLE t2;
450DROP TABLE t1;
451DROP PROCEDURE p1;
452
453
454--echo #
455--echo # Fetching a cursor into a cursor ROW TYPE variable
456--echo #
457
458CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2));
459CREATE TABLE t2 LIKE t1;
460INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31);
461INSERT INTO t1 VALUES (20,'bb2',222.222e2, 12.32);
462INSERT INTO t1 VALUES (30,'bb3',333.333e2, 12.33);
463DELIMITER $$;
464CREATE PROCEDURE p1()
465BEGIN
466  DECLARE cur CURSOR FOR SELECT * FROM t1;
467  BEGIN
468    DECLARE done INT DEFAULT 0;
469    DECLARE rec ROW TYPE OF cur;
470    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
471    OPEN cur;
472    read_loop: LOOP
473      FETCH cur INTO rec;
474      IF done THEN
475        LEAVE read_loop;
476      END IF;
477      SELECT rec.a, rec.b, rec.c, rec.d;
478      INSERT INTO t2 VALUES (rec.a, rec.b, rec.c, rec.d);
479    END LOOP;
480    CLOSE cur;
481  END;
482END;
483$$
484DELIMITER ;$$
485CALL p1();
486SELECT * FROM t2;
487DROP TABLE t2;
488DROP TABLE t1;
489DROP PROCEDURE p1;
490
491
492--echo #
493--echo # Fetching a cursor into a cursor ROW TYPE variable, ROW TYPE OF cur declared inside the LOOP
494--echo #
495
496CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2));
497CREATE TABLE t2 LIKE t1;
498INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31);
499INSERT INTO t1 VALUES (20,'bb2',222.222e2, 12.32);
500INSERT INTO t1 VALUES (30,'bb3',333.333e2, 12.33);
501DELIMITER $$;
502CREATE PROCEDURE p1()
503BEGIN
504  DECLARE done INT DEFAULT 0;
505  DECLARE cur CURSOR FOR SELECT * FROM t1;
506  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
507  OPEN cur;
508  read_loop: LOOP
509    BEGIN
510      DECLARE rec ROW TYPE OF cur;
511      FETCH cur INTO rec;
512      IF done THEN
513        LEAVE read_loop;
514      END IF;
515      SELECT rec.a, rec.b, rec.c, rec.d;
516      INSERT INTO t2 VALUES (rec.a, rec.b, rec.c, rec.d);
517    END;
518  END LOOP;
519  CLOSE cur;
520END;
521$$
522DELIMITER ;$$
523CALL p1();
524SELECT * FROM t2;
525DROP TABLE t2;
526DROP TABLE t1;
527DROP PROCEDURE p1;
528
529
530--echo #
531--echo # Fetching a cursor into a cursor ROW TYPE variable with different column names
532--echo #
533
534CREATE TABLE t1 (a INT, b VARCHAR(10));
535CREATE TABLE t2 (x INT, y VARCHAR(10));
536INSERT INTO t1 VALUES (10,'bbb');
537DELIMITER $$;
538CREATE PROCEDURE p1()
539BEGIN
540  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
541  DECLARE cur2 CURSOR FOR SELECT * FROM t2;
542  BEGIN
543    DECLARE rec2 ROW TYPE OF cur2;
544    OPEN cur1;
545    FETCH cur1 INTO rec2;
546    SELECT rec2.x, rec2.y;
547    CLOSE cur1;
548  END;
549END;
550$$
551DELIMITER ;$$
552CALL p1();
553DROP TABLE t2;
554DROP TABLE t1;
555DROP PROCEDURE p1;
556
557
558--echo #
559--echo # Fetching a cursor into a cursor ROW TYPE variable, with truncation
560--echo #
561
562SET sql_mode='';
563CREATE TABLE t1 (a INT, b VARCHAR(10));
564CREATE TABLE t2 (a INT, b INT);
565INSERT INTO t1 VALUES (10,'11x');
566DELIMITER $$;
567CREATE PROCEDURE p1()
568BEGIN
569  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
570  DECLARE cur2 CURSOR FOR SELECT * FROM t2;
571  BEGIN
572    DECLARE rec2 ROW TYPE OF cur2;
573    OPEN cur1;
574    FETCH cur1 INTO rec2;
575    SELECT rec2.a, rec2.b;
576    CLOSE cur1;
577  END;
578END;
579$$
580DELIMITER ;$$
581CALL p1();
582DROP TABLE t2;
583DROP TABLE t1;
584DROP PROCEDURE p1;
585SET sql_mode=DEFAULT;
586
587
588--echo #
589--echo # cursor ROW TYPE variables are not allowed in LIMIT
590--echo #
591CREATE TABLE t1 (a INT, b INT);
592INSERT INTO t1 VALUES (1,2);
593DELIMITER $$;
594--error ER_WRONG_SPVAR_TYPE_IN_LIMIT
595CREATE PROCEDURE p1()
596BEGIN
597  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
598  BEGIN
599    DECLARE rec1 ROW TYPE OF cur1 DEFAULT (1,2);
600    SELECT * FROM t1 LIMIT rec1.a;
601  END;
602END;
603$$
604DELIMITER ;$$
605DROP TABLE t1;
606
607
608--echo #
609--echo # cursor ROW TYPE variable fields as OUT parameters
610--echo #
611
612CREATE TABLE t1 (a INT, b VARCHAR(10));
613DELIMITER $$;
614CREATE PROCEDURE p1(OUT a INT,OUT b VARCHAR(10))
615BEGIN
616  SET a=10;
617  SET b='bb';
618END;
619$$
620CREATE PROCEDURE p2()
621BEGIN
622  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
623  BEGIN
624    DECLARE rec1 ROW TYPE OF cur1;
625    CALL p1(rec1.a, rec1.b);
626    SELECT rec1.a, rec1.b;
627  END;
628END;
629$$
630DELIMITER ;$$
631CALL p2();
632DROP PROCEDURE p2;
633DROP PROCEDURE p1;
634DROP TABLE t1;
635
636
637--echo #
638--echo # Passing the entire cursor ROW TYPE variable
639--echo #
640
641CREATE TABLE t1 (a INT, b VARCHAR(10));
642DELIMITER $$;
643CREATE PROCEDURE p1(a ROW(a INT, b VARCHAR(10)))
644BEGIN
645  SELECT a.a, a.b;
646END;
647$$
648CREATE PROCEDURE p2()
649BEGIN
650  DECLARE cur CURSOR FOR SELECT * FROM t1;
651  BEGIN
652    DECLARE rec1 ROW TYPE OF cur DEFAULT  ROW(10,'bb');
653    CALL p1(rec1);
654  END;
655END;
656$$
657DELIMITER ;$$
658CALL p2();
659DROP PROCEDURE p2;
660DROP PROCEDURE p1;
661DROP TABLE t1;
662
663
664--echo #
665--echo # Passing the entire cursor ROW TYPE variable as an OUT parameter
666--echo #
667
668CREATE TABLE t1 (a INT, b VARCHAR(10));
669DELIMITER $$;
670CREATE PROCEDURE p1(OUT a ROW(a INT, b VARCHAR(10)))
671BEGIN
672  SET a= ROW(10,'bb');
673END;
674$$
675CREATE PROCEDURE p2()
676BEGIN
677  DECLARE cur CURSOR FOR SELECT * FROM t1;
678  BEGIN
679    DECLARE rec1 ROW TYPE OF cur;
680    CALL p1(rec1);
681    SELECT rec1.a, rec1.b;
682  END;
683END;
684$$
685DELIMITER ;$$
686CALL p2();
687DROP PROCEDURE p2;
688DROP PROCEDURE p1;
689DROP TABLE t1;
690
691
692--echo #
693--echo # Assigning a cursor ROW TYPE field to an OUT parameter
694--echo #
695
696DELIMITER $$;
697CREATE PROCEDURE p1 (INOUT res INTEGER)
698BEGIN
699  DECLARE a INT DEFAULT 10;
700  DECLARE cur1 CURSOR FOR SELECT a FROM DUAL;
701  BEGIN
702    DECLARE rec1 ROW TYPE OF cur1;
703    OPEN cur1;
704    FETCH cur1 INTO rec1;
705    CLOSE cur1;
706    SET res=rec1.a;
707  END;
708END;
709$$
710DELIMITER ;$$
711CALL p1(@res);
712SELECT @res;
713SET @res=NULL;
714DROP PROCEDURE p1;
715
716
717--echo #
718--echo # Testing Item_splocal_row_field_by_name::print
719--echo #
720
721CREATE TABLE t1 (a INT, b VARCHAR(10));
722DELIMITER $$;
723CREATE PROCEDURE p1()
724BEGIN
725  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
726  BEGIN
727    DECLARE rec ROW TYPE OF cur1 DEFAULT ROW(10,'bb');
728    EXPLAIN EXTENDED SELECT rec.a, rec.b;
729  END;
730END;
731$$
732DELIMITER ;$$
733CALL p1();
734DROP PROCEDURE p1;
735DROP TABLE t1;
736
737
738--echo #
739--echo # Run time error in the cursor statement
740--echo #
741
742DELIMITER $$;
743CREATE PROCEDURE p1()
744BEGIN
745  DECLARE cur1 CURSOR FOR SELECT
746    10 AS a,
747    CONCAT(_latin1'a' COLLATE latin1_bin,
748           _latin1'a' COLLATE latin1_swedish_ci) AS b;
749  BEGIN
750    DECLARE rec1 ROW TYPE OF cur1;
751    OPEN cur1;
752    FETCH cur1 INTO rec1;
753    CLOSE cur1;
754  SELECT a,b;
755  END;
756END;
757$$
758DELIMITER ;$$
759--error ER_CANT_AGGREGATE_2COLLATIONS
760CALL p1();
761DROP PROCEDURE p1;
762
763
764
765--echo #
766--echo # Non-existing field
767--echo #
768
769CREATE TABLE t1 (a INT, b VARCHAR(10));
770DELIMITER $$;
771CREATE PROCEDURE p1()
772BEGIN
773  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
774  BEGIN
775    DECLARE rec ROW TYPE OF cur1;
776    SELECT rec.c;
777  END;
778END;
779$$
780DELIMITER ;$$
781--error ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
782CALL p1();
783ALTER TABLE t1 ADD c INT;
784#
785# The below ALTER is needed as a workaround to call sp_cache_invalidate()
786# Please remove it after fixing MDEV-12166
787#
788ALTER PROCEDURE p1 COMMENT 'test';
789CALL p1();
790DROP PROCEDURE p1;
791DROP TABLE t1;
792
793
794--echo #
795--echo # Testing that field names are case insensitive
796--echo #
797
798CREATE TABLE t1 (a INT, b VARCHAR(10));
799DELIMITER $$;
800CREATE PROCEDURE p1()
801BEGIN
802  DECLARE cur CURSOR FOR SELECT * FROM t1;
803  BEGIN
804    DECLARE rec ROW TYPE OF cur DEFAULT ROW(10,'bb');
805    SELECT rec.A, rec.B;
806  END;
807END;
808$$
809DELIMITER ;$$
810CALL p1();
811DROP PROCEDURE p1;
812DROP TABLE t1;
813
814
815--echo #
816--echo # Testing that cursor ROW TYPE uses temporary tables vs shadowed real tables
817--echo #
818
819CREATE TABLE t1 (a INT, b VARCHAR(10));
820CREATE TEMPORARY TABLE t1 (x INT, y VARCHAR(10));
821DELIMITER $$;
822CREATE PROCEDURE p1()
823BEGIN
824  DECLARE cur CURSOR FOR SELECT * FROM t1;
825  BEGIN
826    DECLARE rec ROW TYPE OF cur DEFAULT ROW(10,'bb');
827    SELECT rec.A, rec.B;
828  END;
829END;
830$$
831DELIMITER ;$$
832--error ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
833CALL p1();
834DROP TEMPORARY TABLE t1;
835#
836# The below ALTER is needed as a workaround to call sp_cache_invalidate()
837# Please remove it after fixing MDEV-12166
838#
839ALTER PROCEDURE p1 COMMENT 'test';
840CALL p1();
841DROP PROCEDURE p1;
842DROP TABLE t1;
843
844
845--echo #
846--echo # Testing that the structure of cursor ROW TYPE variables is determined at the DECLARE CURSOR instantiation time
847--echo #
848
849CREATE TABLE t1 (a INT, b VARCHAR(32));
850INSERT INTO t1 VALUES (10,'b10');
851DELIMITER $$;
852CREATE PROCEDURE p1()
853BEGIN
854  DECLARE cur CURSOR FOR SELECT * FROM t1;
855  DROP TABLE t1;
856  CREATE TABLE t1 (a INT, b VARCHAR(32), c INT);
857  BEGIN
858    DECLARE rec ROW TYPE OF cur; -- This has a column "c"
859    SET rec.c=10;
860  END;
861END;
862$$
863DELIMITER ;$$
864CALL p1();
865DROP TABLE t1;
866DROP PROCEDURE p1;
867
868
869CREATE TABLE t1 (a INT, b VARCHAR(32));
870INSERT INTO t1 VALUES (10,'b10');
871DELIMITER $$;
872CREATE PROCEDURE p1()
873BEGIN
874  DECLARE cur CURSOR FOR SELECT * FROM t1;
875  BEGIN
876    DECLARE rec ROW TYPE OF cur; -- This does not have a column "c"
877    DROP TABLE t1;
878    CREATE TABLE t1 (a INT, b VARCHAR(32), c INT);
879    SET rec.c=10;
880  END;
881END;
882$$
883DELIMITER ;$$
884--error ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD
885CALL p1();
886DROP TABLE t1;
887DROP PROCEDURE p1;
888
889
890--echo #
891--echo # Duplicate field nams in a cursor referenced by cursor ROW TYPE
892--echo #
893
894CREATE TABLE t1 (a INT);
895CREATE TABLE t2 (a INT);
896DELIMITER $$;
897CREATE PROCEDURE p1()
898BEGIN
899  DECLARE cur CURSOR FOR SELECT * FROM t1, t2;
900  BEGIN
901    DECLARE rec ROW TYPE OF cur;
902    SELECT rec.a;
903    SET rec.a=10;
904  END;
905END;
906$$
907DELIMITER ;$$
908--error ER_DUP_FIELDNAME
909CALL p1();
910DROP PROCEDURE p1;
911DROP TABLE t2;
912DROP TABLE t1;
913
914
915--echo #
916--echo # Tricky field names a cursor referenced by cursor ROW TYPE
917--echo #
918
919SET NAMES utf8;
920CREATE TABLE t1 (a VARCHAR(10));
921INSERT INTO t1 VALUES ('a');
922DELIMITER $$;
923CREATE PROCEDURE p1()
924BEGIN
925  DECLARE cur CURSOR FOR SELECT a, CONCAT(a,'a'), CONCAT(a,'ö') FROM t1;
926  BEGIN
927    DECLARE rec ROW TYPE OF cur;
928    OPEN cur;
929    FETCH cur INTO rec;
930    CLOSE cur;
931    SELECT rec.a, rec.`CONCAT(a,'a')`, rec.`CONCAT(a,'ö')`;
932  END;
933END;
934$$
935DELIMITER ;$$
936CALL p1();
937DROP PROCEDURE p1;
938DROP TABLE t1;
939SET NAMES latin1;
940
941
942--echo #
943--echo # Using definitions recursively (cursor ROW TYPE variables in another cursor SELECT)
944--echo #
945CREATE TABLE t1 (a INT, b VARCHAR(10));
946INSERT INTO t1 VALUES (10,'b1'),(20,'b2'),(30,'b3');
947DELIMITER $$;
948CREATE PROCEDURE p1()
949BEGIN
950  DECLARE cur1 CURSOR FOR SELECT a,b FROM t1;
951  BEGIN
952    DECLARE rec1 ROW TYPE OF cur1 DEFAULT ROW(0,'b0');
953    DECLARE cur2 CURSOR FOR SELECT rec1.a AS a, rec1.b AS b FROM t1;
954    BEGIN
955      DECLARE done INT DEFAULT 0;
956      DECLARE rec2 ROW TYPE OF cur2;
957      DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
958      OPEN cur2;
959      read_loop: LOOP
960        FETCH cur2 INTO rec2;
961        IF done THEN
962          LEAVE read_loop;
963        END IF;
964        SELECT rec2.a, rec2.b;
965      END LOOP;
966      CLOSE cur2;
967    END;
968  END;
969END;
970$$
971DELIMITER ;$$
972CALL p1();
973DROP PROCEDURE p1;
974DROP TABLE t1;
975
976
977--echo #
978--echo # Testing queries with auto-generated Items.
979--echo # An instance of Item_func_conv_charset is created during the below SELECT query.
980--echo # We check here that during an implicit cursor OPEN
981--echo # done in sp_instr_cursor_copy_struct::exec_core()
982--echo # all temporary Items are created on a proper memory root and are safely destroyed.
983--echo #
984
985CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1, b VARCHAR(10) CHARACTER SET utf8);
986INSERT INTO t1 VALUES (0xFF, 'a');
987DELIMITER $$;
988CREATE PROCEDURE p1()
989BEGIN
990  DECLARE cur1 CURSOR FOR SELECT CONCAT(a,b) AS c FROM t1;
991  BEGIN
992    DECLARE rec1 ROW TYPE OF cur1;
993    OPEN cur1;
994    FETCH cur1 INTO rec1;
995    CLOSE cur1;
996    SELECT HEX(rec1.c);
997  END;
998END;
999$$
1000DELIMITER ;$$
1001CALL p1();
1002DROP PROCEDURE p1;
1003DROP TABLE t1;
1004
1005--echo #
1006--echo # SELECT INTO + cursor ROW TYPE variable with a wrong column count
1007--echo #
1008
1009CREATE TABLE t1 (a INT, b VARCHAR(32));
1010INSERT INTO t1 VALUES (10,'b10');
1011DELIMITER $$;
1012CREATE PROCEDURE p1()
1013BEGIN
1014  DECLARE cur1 CURSOR FOR SELECT 10, 'b0', 'c0';
1015  BEGIN
1016    DECLARE rec1 ROW TYPE OF cur1;
1017    SELECT * FROM t1 INTO rec1;
1018    SELECT rec1.a, rec1.b;
1019  END;
1020END;
1021$$
1022DELIMITER ;$$
1023--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
1024CALL p1();
1025DROP TABLE t1;
1026DROP PROCEDURE p1;
1027
1028
1029--echo #
1030--echo # SELECT INTO + multiple cursor ROW TYPE variables
1031--echo #
1032CREATE TABLE t1 (a INT, b VARCHAR(32));
1033INSERT INTO t1 VALUES (10,'b10');
1034DELIMITER $$;
1035CREATE PROCEDURE p1()
1036BEGIN
1037  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
1038  BEGIN
1039    DECLARE rec1 ROW TYPE OF cur1;
1040    SELECT * FROM t1 INTO rec1, rec1;
1041    SELECT rec1.a, rec1.b;
1042  END;
1043END;
1044$$
1045DELIMITER ;$$
1046--error ER_OPERAND_COLUMNS
1047CALL p1();
1048DROP TABLE t1;
1049DROP PROCEDURE p1;
1050
1051
1052--echo # SELECT INTO + cursor ROW TYPE working example
1053CREATE TABLE t1 (a INT, b VARCHAR(32));
1054INSERT INTO t1 VALUES (10,'b10');
1055DELIMITER $$;
1056CREATE PROCEDURE p1()
1057BEGIN
1058  DECLARE cur1 CURSOR FOR SELECT * FROM t1;
1059  BEGIN
1060    DECLARE rec1 ROW TYPE OF cur1;
1061    SELECT * FROM t1 INTO rec1;
1062    SELECT rec1.a, rec1.b;
1063  END;
1064END;
1065$$
1066DELIMITER ;$$
1067CALL p1();
1068DROP TABLE t1;
1069DROP PROCEDURE p1;
1070
1071--echo #
1072--echo #  End of MDEV-12461 TYPE OF and ROW TYPE OF anchored data types
1073--echo #
1074
1075
1076--echo #
1077--echo # MDEV-12916 Wrong column data type for an INT field of a cursor-anchored ROW variable
1078--echo #
1079
1080DELIMITER $$;
1081CREATE PROCEDURE p1()
1082BEGIN
1083  DECLARE a INT DEFAULT 10;
1084  DECLARE cur1 CURSOR FOR SELECT a;
1085  BEGIN
1086    DECLARE rec1 ROW TYPE OF cur1;
1087    CREATE TABLE t1 AS SELECT rec1.a;
1088    SHOW CREATE TABLE t1;
1089    DROP TABLE t1;
1090  END;
1091END;
1092$$
1093DELIMITER ;$$
1094CALL p1();
1095DROP PROCEDURE p1;
1096
1097
1098--echo #
1099--echo # MDEV-14139 Anchored data types for variables
1100--echo #
1101
1102DELIMITER $$;
1103BEGIN NOT ATOMIC
1104  DECLARE c1 CURSOR FOR SELECT 10 AS a, 'bbb' AS b, TIME'10:20:30' AS c;
1105  BEGIN
1106    DECLARE row1 ROW TYPE OF c1;
1107    DECLARE a_row1 TYPE OF row1;
1108    DECLARE aa_row1 TYPE OF a_row1;
1109    CREATE TABLE t2 AS SELECT a_row1.a AS a, a_row1.b AS b, a_row1.c AS c;
1110    SHOW CREATE TABLE t2;
1111    DROP TABLE t2;
1112    CREATE TABLE t2 AS SELECT aa_row1.a AS a, aa_row1.b AS b, aa_row1.c AS c;
1113    SHOW CREATE TABLE t2;
1114    DROP TABLE t2;
1115  END;
1116END;
1117$$
1118DELIMITER ;$$
1119