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