===== File: sql/item_func.h ===== 874 : 196993 : :Item_func(thd, a), m_func_handler(NULL) { } 875 : 1443681 : Item_handled_func(THD *thd, Item *a, Item *b) 876 : 1443681 : :Item_func(thd, a, b), m_func_handler(NULL) { } 877 : 15 : + Item_handled_func(THD *thd, Item *a, Item *b, Item *c) 878 : 15 : + :Item_func(thd, a, b, c), m_func_handler(NULL) { } 879 : 2706969 : void set_func_handler(const Handler *handler) 880 : : { 881 : 2706969 : m_func_handler= handler; 920 : : { 921 : 24 : return m_func_handler->val_native(thd, this, to); 922 : : } 923 : 0 : + virtual bool get_date_common(THD *thd, MYSQL_TIME *ltime, 924 : : + date_mode_t fuzzydate, timestamp_type) 925 : : + { 926 : 0 : + DBUG_ASSERT(0); 927 : 0 : + return 0; 928 : : + } 929 : : }; 930 : : 931 : : ===== File: sql/item_timefunc.cc ===== 465 : 717 : } 466 : : 467 : : 468 : : +/* 469 : : + Oracle has many formatting models, we list all but only part of them 470 : : + are implemented, because some models depend on oracle functions 471 : : + which mariadb is not supported. 472 : : + 473 : : + Models for datetime, used by TO_CHAR/TO_DATE. Normal format characters are 474 : : + stored as short integer < 128, while format characters are stored as a 475 : : + integer > 128 476 : : +*/ 477 : : + 478 : : +enum enum_tochar_formats 479 : : +{ 480 : : + FMT_BASE= 128, 481 : : + FMT_AD, /* Handled: Anno Domini ("in the year of the Lord") */ 482 : : + FMT_AD_DOT, /* Handled: Anno Domini ("in the year of the Lord") */ 483 : : + FMT_AM, /* Handled: Meridian indicator (Before midday) */ 484 : : + FMT_AM_DOT, /* Handled Meridian indicator (Before midday) */ 485 : : + FMT_BC, /* Handled: Before Christ */ 486 : : + FMT_BC_DOT, /* Handled: Before Christ */ 487 : : + FMT_CC, 488 : : + FMT_SCC, 489 : : + FMT_D, 490 : : + FMT_DAY, /* Handled: Name of day */ 491 : : + FMT_DD, /* Handled: Day (1-31) */ 492 : : + FMT_DDD, /* Handled: Day of year (1-336) */ 493 : : + FMT_DL, 494 : : + FMT_DS, 495 : : + FMT_DY, /* Handled: Abbreviated name of day */ 496 : : + FMT_E, 497 : : + FMT_EE, 498 : : + FMT_FF, /* Handled: Fractional seconds */ 499 : : + FMT_FM, /* Handled: Value with no leading or trailing blanks */ 500 : : + FMT_FX, 501 : : + FMT_HH, /* Handled: Hour (1-12) */ 502 : : + FMT_HH12, /* Handled: Hour (1-12) */ 503 : : + FMT_HH24, /* Handled: Hour (0-23) */ 504 : : + FMT_IW, /* Handled: Week of year (1-53). Used with FMT_I*. ISO 8601 */ 505 : : + /* FMT_I, FMT_IY...FMT_IYYY must be in sequence */ 506 : : + FMT_I, /* Handled: Year, 1 digit. Used with IW. ISO 8601 */ 507 : : + FMT_IY, /* Handled: Year, 2 digits. Used with IW. ISO 8601 */ 508 : : + FMT_IYY, /* Handled: Year, 3 digits. Used with IW. ISO 8601 */ 509 : : + FMT_IYYY, /* Handled: Year, 4 digits. Used with IW. ISO 8601 */ 510 : : + FMT_J, 511 : : + FMT_MI, /* Handled: Minutes (0-59) */ 512 : : + FMT_MM, /* Handled: Month (1-12) */ 513 : : + FMT_MON, /* Handled: Abbreviated name of month */ 514 : : + FMT_MONTH, /* Handled: Name of Month */ 515 : : + FMT_PM, /* Handled: Handled: Meridian indicator (After midday) */ 516 : : + FMT_PM_DOT, /* Handled: Handled: Meridian indicator (After midday) */ 517 : : + FMT_RM, 518 : : + FMT_RR, /* Handled: 20th century dates in the 21st century. 2 digits */ 519 : : + FMT_RRRR, /* Handled: 20th century dates in the 21st century. 4 digits */ 520 : : + FMT_SS, /* Handled: Seconds */ 521 : : + FMT_SSSSSS, 522 : : + FMT_TS, 523 : : + FMT_TZD, 524 : : + FMT_TZH, 525 : : + FMT_TZM, 526 : : + FMT_TZR, 527 : : + FMT_W, 528 : : + FMT_WW, 529 : : + FMT_X, 530 : : + FMT_Y, /* Handled: 1 digit year */ 531 : : + FMT_YY, /* Handled: 2 digits year */ 532 : : + FMT_YYY, /* Handled: 3 digits year */ 533 : : + FMT_YYYY, /* Handled: 4 digits year */ 534 : : + FMT_YYYY_COMMA, 535 : : + FMT_YEAR, 536 : : + FMT_SYYYY, /* Handled as YYYY */ 537 : : + FMT_SYEAR 538 : : +}; 539 : : + 540 : : +static const char *ad_bc_names[]= 541 : : +{ 542 : : + "AD", "A.D.", "BC", "B.C.", NullS 543 : : +}; 544 : : + 545 : : +static TYPELIB ad_bc_typelib= 546 : : +{ 547 : : + array_elements(ad_bc_names)-1,"", ad_bc_names, NULL, NULL 548 : : +}; 549 : : + 550 : : +#define INVALID_CHARACTER(x) (((x) >= 'A' && (x) <= 'Z') || ((x) >= '0' && (x) <= '9') || (x) >= 127 || ((x) < 32)) 551 : : + 552 : : +/* 553 : : + A value between 0-49 will return a 20xx year. 554 : : + A value between 50-99 will return a 19xx year. 555 : : +*/ 556 : : + 557 : 15 : +uint oracle_year_2000_handling(uint year) 558 : : +{ 559 : 15 : + DBUG_ASSERT(year < 100); 560 : 15 : + if ((year=year+1900) < 1950) 561 : 10 : + year+=100; 562 : 15 : + return year; 563 : : +} 564 : : + 565 : : +/** 566 : : + Extract datetime value to MYSQL_TIME struct from string value 567 : : + according to Oracle format string. 568 : : + 569 : : + @param format date/time format specification 570 : : + @param val String to decode 571 : : + @param length Length of string 572 : : + @param l_time Store result here. 573 : : + This value should be prefilled with the 574 : : + current date in case format does not 575 : : + have all date parts. 576 : : + @parrm locale Used to get day and month names 577 : : + @param data_time_type Type of string. Used for error messages 578 : : + @param fuzzy_date If partial dates are allowed 579 : : + @param give_error Generate a warning/error 580 : : + @par 581 : : + @retval 582 : : + 0 ok 583 : : + @retval 584 : : + 1 error 585 : : +*/ 586 : : + 587 : : +static bool 588 : 310 : +extract_oracle_date_time(THD *thd, uint16 *format, 589 : : + const char *val, uint length, MYSQL_TIME *l_time, 590 : : + const MY_LOCALE *locale, 591 : : + const char *date_time_type, 592 : : + date_conv_mode_t fuzzydate, 593 : : + bool give_error) 594 : : +{ 595 : 310 : + int weekday= 0, yearday= 0, daypart= 0; 596 : : + int frac_part; 597 : 310 : + bool usa_time= 0; 598 : 310 : + bool before_christ= 0; 599 : 310 : + const char *val_begin= val; 600 : 310 : + const char *val_end= val + length; 601 : : + char *tmp; 602 : 310 : + CHARSET_INFO *cs= &my_charset_bin; 603 : 310 : + DBUG_ENTER("extract_oracle_date_time"); 604 : : + 605 : 2440 : + for ( ; *format ; format++) 606 : : + { 607 : : + uint val_len; 608 : : + int error; 609 : : + 610 : 2450 : + while (my_isspace(cs, *val)) 611 : 260 : + val++; 612 : 2190 : + if (*format < 128) 613 : : + { 614 : : + /* A control character or text string found in the format */ 615 : : + 616 : 1000 : + char format_char= (char) (*format & 255); 617 : : + char upper_val; 618 : : + bool control_character; 619 : 1000 : + if (my_isspace(cs, format_char)) 620 : 990 : + continue; 621 : : + 622 : 750 : + if (format_char == '"') 623 : : + { 624 : 110 : + while (*++format != '"') 625 : : + { 626 : 85 : + if (!*format) 627 : 60 : + goto error; 628 : 85 : + if (my_toupper(system_charset_info, (char) (*format & 255)) != 629 : 85 : + my_toupper(system_charset_info, *val)) 630 : 10 : + goto error; 631 : 75 : + val++; 632 : : + } 633 : 25 : + continue; 634 : : + } 635 : 715 : + upper_val= my_toupper(system_charset_info, *val); 636 : 715 : + control_character= !INVALID_CHARACTER(format_char); 637 : : + 638 : 715 : + if (control_character) 639 : : + { 640 : 715 : + if (my_isdigit(cs, *val)) 641 : : + { 642 : : + /* 643 : : + Oracle tochar allows values without punctuation characters for 644 : : + numercial values 645 : : + */ 646 : 5 : + continue; 647 : : + } 648 : 710 : + if (format_char == *val) 649 : : + { 650 : 685 : + val++; 651 : 685 : + if (format[0] != format[1]) 652 : : + { 653 : : + /* 654 : : + Oracle allow skipping of multiple format_characters 655 : : + Needed for things like TO_DATE('2001 -- 10','YYYY - MM') 656 : : + */ 657 : 690 : + while (*val == format_char) 658 : 5 : + val++; 659 : : + } 660 : 685 : + continue; 661 : : + } 662 : 25 : + if (!INVALID_CHARACTER(upper_val)) 663 : : + { 664 : 20 : + val++; 665 : 20 : + continue; 666 : : + } 667 : : + } 668 : 0 : + else if (format_char == *val) 669 : : + { 670 : 0 : + val++; 671 : : + } 672 : 5 : + continue; 673 : 5 : + } 674 : : + 675 : 1190 : + error= 0; 676 : 1190 : + val_len= (uint) (val_end - val); 677 : : + 678 : 1190 : + switch (*format) { 679 : : + /* Year */ 680 : 220 : + case FMT_YYYY: 681 : : + case FMT_SYYYY: 682 : 220 : + tmp= (char*) val + MY_MIN(4, val_len); 683 : 220 : + l_time->year= (int) my_strtoll10(val, &tmp, &error); 684 : 220 : + val= tmp; 685 : 220 : + break; 686 : 0 : + case FMT_YYY: 687 : 0 : + tmp= (char*) val + MY_MIN(3, val_len); 688 : 0 : + l_time->year= ((int) my_strtoll10(val, &tmp, &error) + 689 : 0 : + l_time->year/1000*1000); 690 : 0 : + val= tmp; 691 : 0 : + break; 692 : 25 : + case FMT_YY: 693 : 25 : + tmp= (char*) val + MY_MIN(2, val_len); 694 : 25 : + l_time->year= ((int) my_strtoll10(val, &tmp, &error) + 695 : 25 : + l_time->year/100*100); 696 : 25 : + val= tmp; 697 : 25 : + break; 698 : 0 : + case FMT_Y: 699 : 0 : + tmp= (char*) val + MY_MIN(1, val_len); 700 : 0 : + l_time->year= ((int) my_strtoll10(val, &tmp, &error) + 701 : 0 : + l_time->year/10*10); 702 : 0 : + val= tmp; 703 : 0 : + break; 704 : 15 : + case FMT_RR: 705 : : + { 706 : : + uint year; 707 : 15 : + tmp= (char*) val + MY_MIN(2, val_len); 708 : 15 : + year= (uint)my_strtoll10(val, &tmp, &error); 709 : 15 : + l_time->year= oracle_year_2000_handling(year); 710 : 15 : + val= tmp; 711 : 15 : + break; 712 : : + } 713 : 0 : + case FMT_RRRR: 714 : : + { 715 : : + uint year; 716 : 0 : + tmp= (char*) val + MY_MIN(4, val_len); 717 : 0 : + year= (uint)my_strtoll10(val, &tmp, &error); 718 : 0 : + l_time->year= year > 100 ? year : oracle_year_2000_handling(year); 719 : 0 : + val= tmp; 720 : 0 : + break; 721 : : + } 722 : : + 723 : 10 : + case FMT_AD: 724 : : + case FMT_AD_DOT: 725 : : + case FMT_BC: 726 : : + case FMT_BC_DOT: 727 : : + { 728 : : + int period; 729 : 10 : + if ((period= check_word(&ad_bc_typelib, val, val_end, &val)) <= 0) 730 : 0 : + goto error; 731 : 10 : + before_christ= period > 2; 732 : 10 : + break; 733 : : + } 734 : : + 735 : : + /* Month */ 736 : 195 : + case FMT_MM: 737 : 195 : + tmp= (char*) val + MY_MIN(2, val_len); 738 : 195 : + l_time->month= (int) my_strtoll10(val, &tmp, &error); 739 : 195 : + val= tmp; 740 : 195 : + break; 741 : 50 : + case FMT_MONTH: 742 : 50 : + if ((l_time->month= check_word(locale->month_names, 743 : 50 : + val, val_end, &val)) <= 0) 744 : 5 : + goto error; 745 : 45 : + break; 746 : 25 : + case FMT_MON: 747 : 25 : + if ((l_time->month= check_word(locale->ab_month_names, 748 : 25 : + val, val_end, &val)) <= 0) 749 : 0 : + goto error; 750 : 25 : + break; 751 : : + 752 : : + /* Day */ 753 : 215 : + case FMT_DD: 754 : 215 : + tmp= (char*) val + MY_MIN(2, val_len); 755 : 215 : + l_time->day= (int) my_strtoll10(val, &tmp, &error); 756 : 215 : + val= tmp; 757 : 215 : + break; 758 : : + 759 : : + /* Hour */ 760 : 55 : + case FMT_HH: 761 : : + case FMT_HH12: 762 : 55 : + usa_time= 1; 763 : : + /* fall through */ 764 : 140 : + case FMT_HH24: 765 : 140 : + tmp= (char*) val + MY_MIN(2, val_len); 766 : 140 : + l_time->hour= (int) my_strtoll10(val, &tmp, &error); 767 : 140 : + val= tmp; 768 : 140 : + break; 769 : : + 770 : : + /* Minute */ 771 : 120 : + case FMT_MI: 772 : 120 : + tmp= (char*) val + MY_MIN(2, val_len); 773 : 120 : + l_time->minute= (int) my_strtoll10(val, &tmp, &error); 774 : 120 : + val= tmp; 775 : 120 : + break; 776 : : + 777 : : + /* Second */ 778 : 105 : + case FMT_SS: 779 : 105 : + tmp= (char*) val + MY_MIN(2, val_len); 780 : 105 : + l_time->second= (int) my_strtoll10(val, &tmp, &error); 781 : 105 : + val= tmp; 782 : 105 : + break; 783 : : + 784 : : + /* Second part */ 785 : 30 : + case FMT_FF: 786 : : + { 787 : 30 : + uint length= 6; 788 : 30 : + if (format[1] >= '1' && format[1] <= '6') 789 : 20 : + length= *++format - (uint) '0'; 790 : 30 : + tmp= (char*) val + MY_MIN(length, val_len); 791 : 30 : + l_time->second_part= (int) my_strtoll10(val, &tmp, &error); 792 : 30 : + frac_part= 6 - (int) (tmp - val); 793 : 30 : + if (frac_part > 0) 794 : 20 : + l_time->second_part*= (ulong) log_10_int[frac_part]; 795 : 30 : + val= tmp; 796 : 30 : + break; 797 : : + } 798 : : + /* AM / PM */ 799 : 20 : + case FMT_AM: 800 : : + case FMT_AM_DOT: 801 : : + case FMT_PM: 802 : : + case FMT_PM_DOT: 803 : 20 : + if (val_len < 2 || ! usa_time) 804 : 0 : + goto error; 805 : 20 : + if (!my_charset_latin1.strnncoll(val, 2, "PM", 2)) 806 : : + { 807 : 5 : + daypart= 12; 808 : 5 : + val+= 2; 809 : : + } 810 : 15 : + else if (!my_charset_latin1.strnncoll(val, 2, "AM", 2)) 811 : 0 : + val+= 2; 812 : 15 : + else if (!my_charset_latin1.strnncoll(val, 4, "P.M.", 4)) 813 : : + { 814 : 0 : + daypart= 12; 815 : 0 : + val+= 4; 816 : : + } 817 : 15 : + else if (!my_charset_latin1.strnncoll(val, 4, "A.M.", 4)) 818 : 15 : + val+= 4; 819 : : + else 820 : 0 : + goto error; 821 : 20 : + break; 822 : : + 823 : : + /* Exotic things. Weekdays are only use validation of date */ 824 : 15 : + case FMT_DAY: 825 : 15 : + if ((weekday= check_word(locale->day_names, val, val_end, &val)) <= 0) 826 : 0 : + goto error; 827 : 15 : + break; 828 : 0 : + case FMT_DY: 829 : 0 : + if ((weekday= check_word(locale->ab_day_names, val, val_end, &val)) <= 0) 830 : 0 : + goto error; 831 : 0 : + break; 832 : : + 833 : 5 : + case FMT_DDD: // Day of year 834 : 5 : + tmp= (char*) val + MY_MIN(val_len, 3); 835 : 5 : + yearday= (int) my_strtoll10(val, &tmp, &error); 836 : 5 : + val= tmp; 837 : 5 : + break; 838 : : + 839 : 0 : + default: 840 : 0 : + goto error; 841 : : + } 842 : 1185 : + if (unlikely(error)) // Error from my_strtoll10 843 : 45 : + goto error; 844 : : + } 845 : : + 846 : : + /* Generate the datetime */ 847 : 250 : + if (usa_time) 848 : : + { 849 : 55 : + if (l_time->hour > 12 || l_time->hour < 1) 850 : 0 : + goto error; 851 : 55 : + l_time->hour= l_time->hour%12+daypart; 852 : : + } 853 : : + 854 : 250 : + if (yearday > 0) 855 : : + { 856 : : + uint days; 857 : 5 : + days= calc_daynr(l_time->year,1,1) + yearday - 1; 858 : 5 : + if (get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day)) 859 : 0 : + goto error; 860 : : + } 861 : : + 862 : 250 : + if (before_christ) // Cannot handle negative dates 863 : 5 : + goto error; 864 : : + 865 : 260 : + if (weekday && calc_weekday(calc_daynr(l_time->year,l_time->month, 866 : 15 : + l_time->day),0) != weekday -1) 867 : 5 : + goto error; 868 : : + 869 : 240 : + if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || 870 : 225 : + l_time->minute > 59 || l_time->second > 59) 871 : 15 : + goto error; 872 : : + 873 : : + int was_cut; 874 : 225 : + if (check_date(l_time, fuzzydate, &was_cut)) 875 : 10 : + goto error; 876 : : + 877 : 215 : + if (val != val_end) 878 : : + { 879 : : + do 880 : : + { 881 : 5 : + if (!my_isspace(&my_charset_latin1,*val)) 882 : : + { 883 : 5 : + ErrConvString err(val_begin, length, &my_charset_bin); 884 : 5 : + make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, 885 : : + &err, l_time->time_type, 886 : : + nullptr, nullptr, nullptr); 887 : 5 : + break; 888 : 5 : + } 889 : 0 : + } while (++val != val_end); 890 : : + } 891 : 215 : + DBUG_RETURN(0); 892 : : + 893 : 95 : +error: 894 : 95 : + if (give_error) 895 : : + { 896 : : + char buff[128]; 897 : 75 : + strmake(buff, val_begin, MY_MIN(length, sizeof(buff)-1)); 898 : 75 : + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 899 : : + ER_WRONG_VALUE_FOR_TYPE, 900 : 75 : + ER_THD(thd, ER_WRONG_VALUE_FOR_TYPE), 901 : : + date_time_type, buff, "to_date"); 902 : : + } 903 : 95 : + DBUG_RETURN(1); 904 : 310 : +} 905 : : + 906 : : + 907 : : /** 908 : : Create a formatted date/time value in a string. 909 : : */ 2450 : : 2451 : : @retval false - on success 2452 : : @retval true - on error (e.g. EOM) 2453 : : + */ 2454 : : + bool format(const uint16 *fmt_array, 2455 : : + const MYSQL_TIME *l_time, 2456 : : + const MY_LOCALE *locale, 2457 : : + String *str); 2458 : : }; 2459 : : 2460 : : + 2461 : : /** 2462 : : Flip 'quotation_flag' if we found a quote (") character. 2463 : : 2478 : 42939 : return *quotation_flag; 2479 : : } 2480 : : 2481 : : /** 2482 : : Special characters are directly output in the result 2483 : : 2521 : : } 2522 : : 2523 : : 2524 : 1753 : +static inline bool formats_used(uint64 *used, int src) 2525 : : +{ 2526 : 1753 : + uint64 bit= 1ULL << (src-128); 2527 : 1753 : + if (*used & bit) 2528 : 3 : + return 1; // Duplicate item 2529 : 1750 : + (*used)|= bit; 2530 : 1750 : + return 0; 2531 : : +} 2532 : : + 2533 : : + 2534 : : /** 2535 : : Parse the format string, convert it to an compact array and calculate the 2536 : : length of output string 2537 : : 2538 : : + @param format Format string 2539 : : + @param fmt_array Packed format 2540 : : + @param fmt_len Max length of formated date string is stored here 2541 : : + @param locale Locale 2542 : : + @param for_to_date If the format is for the to_date() oracle function 2543 : : + @param warning_message Error message is stored here. 2544 : : + @param flags Bits of PARSE_TYPE_FLAGS of formats used 2545 : : 2546 : : + @return 0 ok. fmt_len and flags are updated 2547 : : + @return 1 error warnings_massage set and flags=0 2548 : : */ 2549 : : 2550 : : + 2551 : 1386 : +static bool parse_format_string(const String *format, uint16 *fmt_array, 2552 : : + uint *fmt_len, const MY_LOCALE *locale, 2553 : : + bool for_to_date, 2554 : : + String *warning_message, 2555 : : + PARSE_TYPE_FLAGS *flags) 2556 : : { 2557 : : const char *ptr, *end; 2558 : 1386 : uint16 *tmp_fmt= fmt_array; 2559 : 1386 : uint tmp_len= 0; 2560 : 1386 : int offset= 0; 2561 : 1386 : bool quotation_flag= false; 2562 : 1386 : + uint64 used= 0; // Formats used 2563 : 1386 : + uint type_flags= PARSE_TYPE_NONE; 2564 : : 2565 : 1386 : + *flags= PARSE_TYPE_NONE; 2566 : 1386 : ptr= format->ptr(); 2567 : 1386 : end= ptr + format->length(); 2568 : : 2569 : 1386 : if (format->length() > MAX_DATETIME_FORMAT_MODEL_LEN) 2570 : : { 2571 : 5 : + warning_message->append(STRING_WITH_LEN("datetime format string is too " 2572 : : + "long")); 2573 : 5 : return 1; 2574 : : } 2575 : : 2600 : 132 : case 'A': // AD/A.D./AM/A.M. 2601 : 132 : if (ptr+1 >= end) 2602 : 0 : goto error; 2603 : : + 2604 : 132 : next_char= my_toupper(system_charset_info, *(ptr+1)); 2605 : 132 : if (next_char == 'D') 2606 : : { 2607 : 23 : + if (for_to_date && formats_used(&used, FMT_AD)) 2608 : 0 : + goto error; 2609 : 23 : *tmp_fmt= FMT_AD; 2610 : 23 : ptr+= 1; 2611 : 23 : tmp_len+= 2; 2612 : : } 2613 : 109 : else if (next_char == 'M') 2614 : : { 2615 : 15 : + if (for_to_date && formats_used(&used, FMT_AM)) 2616 : 0 : + goto error; 2617 : 15 : *tmp_fmt= FMT_AM; 2618 : 15 : ptr+= 1; 2619 : 15 : tmp_len+= 2; 2622 : : { 2623 : 92 : if (my_toupper(system_charset_info, *(ptr+2)) == 'D') 2624 : : { 2625 : 56 : + if (for_to_date && formats_used(&used, FMT_AD)) 2626 : 0 : + goto error; 2627 : 56 : *tmp_fmt= FMT_AD_DOT; 2628 : 56 : ptr+= 3; 2629 : 56 : tmp_len+= 4; 2630 : : } 2631 : 36 : else if (my_toupper(system_charset_info, *(ptr+2)) == 'M') 2632 : : { 2633 : 36 : + if (for_to_date && formats_used(&used, FMT_AM)) 2634 : 0 : + goto error; 2635 : 36 : *tmp_fmt= FMT_AM_DOT; 2636 : 36 : ptr+= 3; 2637 : 36 : tmp_len+= 4; 2641 : : } 2642 : : else 2643 : 2 : goto error; 2644 : 130 : + type_flags|= PARSE_TYPE_NON_DETERMINISTIC; 2645 : 130 : break; 2646 : 39 : case 'B': // BC and B.C 2647 : 39 : if (ptr+1 >= end) 2648 : 0 : goto error; 2649 : 39 : + if (for_to_date && formats_used(&used, FMT_BC)) 2650 : 0 : + goto error; 2651 : : + 2652 : 39 : next_char= my_toupper(system_charset_info, *(ptr+1)); 2653 : 39 : if (next_char == 'C') 2654 : : { 2667 : : else 2668 : 0 : goto error; 2669 : 39 : break; 2670 : 32 : + case 'I': 2671 : 32 : + if (for_to_date) 2672 : 0 : + goto error; 2673 : 32 : + if (ptr+1 >= end) 2674 : 4 : + goto found_I; 2675 : 28 : + next_char= my_toupper(system_charset_info, *(ptr+1)); 2676 : 28 : + if (next_char == 'W') 2677 : : + { 2678 : 8 : + *tmp_fmt= FMT_IW; 2679 : 8 : + tmp_len+=2; 2680 : 8 : + ptr++; 2681 : : + } 2682 : 20 : + else if (next_char == 'Y') 2683 : : + { 2684 : : + uint i; 2685 : 36 : + for (i= 0 ; i < 3 && ++ptr < end; i++) 2686 : 36 : + if (my_toupper(system_charset_info, *(ptr+1)) != 'Y') 2687 : 16 : + break; 2688 : : + 2689 : 16 : + *tmp_fmt= FMT_IY+i; 2690 : 16 : + tmp_len+= 2 + i; 2691 : : + } 2692 : : + else 2693 : : + { 2694 : 4 : + found_I: 2695 : 8 : + *tmp_fmt= FMT_I; 2696 : 8 : + tmp_len+= 1; 2697 : : + } 2698 : 32 : + break; 2699 : 16 : case 'P': // PM or P.M. 2700 : 16 : + if (ptr + 1 == end) 2701 : 0 : + goto error; 2702 : : + 2703 : 16 : + if (for_to_date && formats_used(&used, FMT_AM)) 2704 : 0 : + goto error; 2705 : : + 2706 : 16 : next_char= my_toupper(system_charset_info, *(ptr+1)); 2707 : 16 : if (next_char == 'M') 2708 : : { 2721 : : else 2722 : 0 : goto error; 2723 : 16 : break; 2724 : 1642 : + case 'Y': // Y, YY, YYY or YYYYY 2725 : 1642 : + if (for_to_date && formats_used(&used, FMT_Y)) 2726 : 0 : + goto error; 2727 : : + 2728 : 1642 : if (ptr + 1 == end || my_toupper(system_charset_info, *(ptr+1)) != 'Y') 2729 : : { 2730 : 48 : *tmp_fmt= FMT_Y; 2731 : 48 : tmp_len+= 1; 2732 : 48 : + type_flags|= PARSE_TYPE_PART_YEAR; 2733 : 48 : break; 2734 : : } 2735 : 1594 : if (ptr + 2 == end || 2736 : 1573 : my_toupper(system_charset_info, *(ptr+2)) != 'Y') /* YY */ 2737 : : { 2738 : 111 : *tmp_fmt= FMT_YY; 2739 : 111 : + type_flags|= PARSE_TYPE_PART_YEAR; 2740 : 111 : ulen= 2; 2741 : : } 2742 : : else 2745 : : { 2746 : 1427 : *tmp_fmt= FMT_YYYY; 2747 : 1427 : ulen= 4; 2748 : 1427 : + type_flags|= PARSE_TYPE_YEAR; 2749 : : } 2750 : : else 2751 : : { 2752 : 56 : *tmp_fmt= FMT_YYY; 2753 : 56 : + type_flags|= PARSE_TYPE_PART_YEAR; 2754 : 56 : ulen= 3; 2755 : : } 2756 : : } 2757 : 1594 : ptr+= ulen-1; 2758 : 1594 : tmp_len+= ulen; 2759 : 1594 : break; 2760 : 53 : case 'R': // RR or RRRR 2761 : 53 : + if (for_to_date && formats_used(&used, FMT_Y)) 2762 : 0 : + goto error; 2763 : : + 2764 : 53 : if (ptr + 1 == end || my_toupper(system_charset_info, *(ptr+1)) != 'R') 2765 : 0 : goto error; 2766 : : 2778 : : } 2779 : 53 : ptr+= ulen-1; 2780 : 53 : tmp_len+= ulen; 2781 : 53 : + type_flags|= PARSE_TYPE_YEAR; 2782 : 53 : break; 2783 : 3403 : case 'M': 2784 : : { 2789 : 3403 : tmp1= my_toupper(system_charset_info, *(ptr+1)); 2790 : 3403 : if (tmp1 == 'M') 2791 : : { 2792 : 1343 : + if (for_to_date && formats_used(&used, FMT_MM)) 2793 : 0 : + goto error; 2794 : 1343 : *tmp_fmt= FMT_MM; 2795 : 1343 : tmp_len+= 2; 2796 : 1343 : + type_flags|= PARSE_TYPE_MONTH; 2797 : 1343 : ptr+= 1; 2798 : : } 2799 : 2060 : else if (tmp1 == 'I') 2800 : : { 2801 : 1121 : + if (for_to_date && formats_used(&used, FMT_MI)) 2802 : 0 : + goto error; 2803 : 1121 : *tmp_fmt= FMT_MI; 2804 : 1121 : tmp_len+= 2; 2805 : 1121 : + type_flags|= PARSE_TYPE_MM; 2806 : 1121 : ptr+= 1; 2807 : : } 2808 : 939 : else if (tmp1 == 'O') 2809 : : { 2810 : 935 : if (ptr + 2 >= end) 2811 : 0 : goto error; 2812 : 935 : + if (for_to_date && formats_used(&used, FMT_MM)) 2813 : 0 : + goto error; 2814 : : + 2815 : 935 : char tmp2= my_toupper(system_charset_info, *(ptr+2)); 2816 : 935 : if (tmp2 != 'N') 2817 : 0 : goto error; 2831 : 860 : my_charset_utf8mb3_bin.mbmaxlen); 2832 : 860 : ptr+= 4; 2833 : : } 2834 : 935 : + type_flags|= PARSE_TYPE_MONTH | PARSE_TYPE_NON_DETERMINISTIC; 2835 : : } 2836 : : else 2837 : 4 : goto error; 2838 : : } 2839 : 3399 : break; 2840 : 2238 : + case 'D': // D, DD, DY, or DAY 2841 : : { 2842 : : + char tmp1; 2843 : 2238 : if (ptr + 1 >= end) 2844 : 2 : goto error; 2845 : : 2846 : 2236 : + tmp1= my_toupper(system_charset_info, *(ptr+1)); 2847 : 2236 : if (tmp1 == 'D') 2848 : : { 2849 : 1399 : + if (ptr + 2 != end && 2850 : 1191 : + my_toupper(system_charset_info, *(ptr+2)) == 'D') 2851 : : + { 2852 : 33 : + if (for_to_date && 2853 : 14 : + (formats_used(&used, FMT_DDD) || 2854 : 14 : + formats_used(&used, FMT_DD) || 2855 : 7 : + formats_used(&used, FMT_MM))) 2856 : 0 : + goto error; 2857 : 19 : + *tmp_fmt= FMT_DDD; // Day of year 2858 : 19 : + tmp_len+= 3; 2859 : 19 : + ptr+= 2; 2860 : 19 : + break; 2861 : : + } 2862 : 1380 : + if (for_to_date && formats_used(&used, FMT_DD)) 2863 : 3 : + goto error; 2864 : 1377 : + *tmp_fmt= FMT_DD; // Day of month 1-31 2865 : 1377 : tmp_len+= 2; 2866 : 1377 : + type_flags|= PARSE_TYPE_DAY | PARSE_TYPE_NON_DETERMINISTIC; 2867 : : } 2868 : 837 : else if (tmp1 == 'Y') 2869 : : { 2870 : 20 : + *tmp_fmt= FMT_DY; // Day name 2871 : 20 : tmp_len+= 3; 2872 : 20 : + type_flags|= PARSE_TYPE_WEEKDAY | PARSE_TYPE_NON_DETERMINISTIC; 2873 : : } 2874 : 817 : + else if (tmp1 == 'A') 2875 : : { 2876 : 815 : if (ptr + 2 == end || my_toupper(system_charset_info, *(ptr+2)) != 'Y') 2877 : 0 : goto error; 2878 : 815 : + *tmp_fmt= FMT_DAY; // Day name 2879 : 815 : tmp_len+= locale->max_day_name_length * my_charset_utf8mb3_bin.mbmaxlen; 2880 : 815 : + type_flags|= PARSE_TYPE_WEEKDAY | PARSE_TYPE_NON_DETERMINISTIC; 2881 : 815 : ptr+= 1; 2882 : : } 2883 : : else 2884 : 2 : + goto error; // 'D', weekday 1-7, territory 2885 : 2212 : ptr+= 1; 2886 : : } 2887 : 2212 : break; 2890 : : char tmp1, tmp2, tmp3; 2891 : 1176 : if (ptr + 1 >= end) 2892 : 0 : goto error; 2893 : 1176 : + if (for_to_date && formats_used(&used, FMT_HH)) 2894 : 0 : + goto error; 2895 : : 2896 : 1176 : + tmp1= my_toupper(system_charset_info, *(ptr+1)); 2897 : 1176 : if (tmp1 != 'H') 2898 : 3 : goto error; 2899 : : 2924 : : } 2925 : : } 2926 : 1173 : tmp_len+= 2; 2927 : 1173 : + type_flags|= PARSE_TYPE_HH; 2928 : 1173 : break; 2929 : : } 2930 : 1165 : case 'S': // SS 2931 : 1165 : + if (ptr + 1 == end) 2932 : 0 : goto error; 2933 : 1165 : + if (my_toupper(system_charset_info, *(ptr+1)) == 'S') 2934 : : + { 2935 : 1109 : + if (for_to_date && formats_used(&used, FMT_SS)) 2936 : 0 : + goto error; 2937 : 1109 : + *tmp_fmt= FMT_SS; 2938 : 1109 : + tmp_len+= 2; 2939 : 1109 : + type_flags|= PARSE_TYPE_SS; 2940 : 1109 : + ptr+= 1; 2941 : : + } 2942 : 56 : + else if (ptr + 5 <= end || 2943 : 0 : + !my_charset_latin1.strnncoll(ptr+1, 4, "YYYY", 4)) 2944 : : + { 2945 : 56 : + *tmp_fmt= FMT_SYYYY; 2946 : 56 : + tmp_len+= 4; 2947 : 56 : + type_flags|= PARSE_TYPE_YEAR; 2948 : 56 : + ptr+= 4; 2949 : : + } 2950 : 1165 : break; 2951 : 24 : case '|': 2952 : : /* 2967 : 8 : ptr--; // Fix ptr for above for loop 2968 : 8 : tmp_fmt--; 2969 : 8 : break; 2970 : 799 : case 'F': 2971 : 799 : if (ptr + 1 == end) 2972 : 18 : goto error; 2973 : 781 : if (my_toupper(system_charset_info, ptr[1]) == 'M') 2974 : : { 2975 : 702 : + if (for_to_date) 2976 : 0 : + goto error; 2977 : 702 : *tmp_fmt= FMT_FM; 2978 : 702 : ptr+= 1; 2979 : : } 2980 : 79 : + else if (my_toupper(system_charset_info, ptr[1]) == 'F') 2981 : : + { 2982 : 61 : + if (for_to_date && formats_used(&used, FMT_FF)) 2983 : 0 : + goto error; 2984 : 61 : + *tmp_fmt= FMT_FF; 2985 : 61 : + type_flags|= PARSE_TYPE_SUBSECONDS; 2986 : 61 : + ptr+= 1; 2987 : 61 : + if (ptr + 1 <= end && ptr[1] >= '1' && ptr[1] <= '6') 2988 : 36 : + *++tmp_fmt= *++ptr; // Copy format length 2989 : 61 : + tmp_len+= 6; 2990 : : + } 2991 : : + else 2992 : 18 : + goto error; 2993 : 763 : + break; 2994 : : 2995 : 8790 : default: 2996 : 8790 : offset= parse_special(cfmt, ptr, end, tmp_fmt); 3005 : : } 3006 : 1303 : *fmt_len= tmp_len; 3007 : 1303 : *tmp_fmt= 0; 3008 : 1303 : + *flags= (PARSE_TYPE_FLAGS) type_flags; 3009 : 1303 : return 0; 3010 : : 3011 : 78 : error: 3012 : 78 : + warning_message->append(STRING_WITH_LEN("date format not recognized at ")); 3013 : 78 : + warning_message->append(ptr, MY_MIN(8, end- ptr)); 3014 : 78 : return 1; 3015 : : } 3016 : : 3017 : : +/** 3018 : : + Get the result datetime type for parsed string 3019 : : + 3020 : : + Same logic used as in get_date_time_result_type() 3021 : : +*/ 3022 : : + 3023 : : +static const Item_handled_func::Handler * 3024 : 420 : +get_parsed_result_type(PARSE_TYPE_FLAGS type) 3025 : : +{ 3026 : 420 : + if (type & PARSE_TYPE_SUBSECONDS) 3027 : 42 : + return &func_handler_str_to_date_datetime_usec; 3028 : 378 : + return &func_handler_str_to_date_datetime_sec; 3029 : : +} 3030 : : + 3031 : : 3032 : 1660 : bool Date_time_format_oracle::format(const uint16 *fmt_array, 3033 : : const MYSQL_TIME *l_time, 3038 : 1660 : const uint16 *ptr= fmt_array; 3039 : : uint hours_i; 3040 : : uint weekday; 3041 : 1660 : + uint year= 0, week= 0; 3042 : : 3043 : 1660 : str->length(0); 3044 : : 3057 : : } 3058 : : 3059 : 23069 : switch (*ptr) { 3060 : 48 : case FMT_AM: 3061 : : case FMT_PM: 3062 : 48 : if (l_time->hour > 11) 3105 : 0 : goto err_exit; 3106 : 96 : break; 3107 : : 3108 : 1576 : + case FMT_SYYYY: 3109 : : case FMT_YYYY: 3110 : : case FMT_RRRR: 3111 : 1576 : if (append_val(l_time->year, 4, str)) 3204 : 0 : goto err_exit; 3205 : 1416 : break; 3206 : : 3207 : 9 : + case FMT_FF: 3208 : : + { 3209 : 9 : + uint length= 6; 3210 : 9 : + if (ptr[1] >= '1' && ptr[1] <= '6') 3211 : 6 : + length= *++ptr - (uint) '0'; 3212 : 9 : + if (append_val((int)(l_time->second_part / log_10_int[6-length]), length, str)) 3213 : 0 : + goto err_exit; 3214 : 9 : + break; 3215 : : + } 3216 : 702 : case FMT_FM: 3217 : 702 : m_fm= !m_fm; 3218 : 702 : break; 3219 : : 3220 : 27 : + case FMT_DDD: 3221 : : + { 3222 : 27 : + uint day= (calc_daynr(l_time->year, l_time->month, l_time->day) - 3223 : 27 : + calc_daynr(l_time->year, 1, 1) + 1); 3224 : 27 : + if (append_val(day, 3, str)) 3225 : 0 : + goto err_exit; 3226 : 27 : + break; 3227 : : + } 3228 : 30 : + case FMT_IW: 3229 : : + case FMT_I: 3230 : : + case FMT_IY: 3231 : : + case FMT_IYY: 3232 : : + case FMT_IYYY: 3233 : 30 : + if (!week) 3234 : 21 : + week= calc_week(l_time, WEEK_MONDAY_FIRST | WEEK_YEAR, &year); 3235 : 30 : + if (*ptr == FMT_IW) 3236 : : + { 3237 : 9 : + if (str->append_longlong(week)) 3238 : 0 : + goto err_exit; 3239 : : + } 3240 : : + else 3241 : : + { 3242 : : + /* Handling FMT_I, FMT_IY, FMT_IYY and FMT_IYYY */ 3243 : 21 : + int length= (*ptr - FMT_I) + 1; 3244 : 21 : + if (append_val(year % log_10_int[length], length, str)) 3245 : 0 : + goto err_exit; 3246 : : + } 3247 : 30 : + break; 3248 : 10889 : default: 3249 : 10889 : + if (*ptr > 127) 3250 : 0 : + goto err_exit; 3251 : 10889 : str->append((char) *ptr); 3252 : : } 3253 : : 3299 : 571 : if (args[1]->basic_const_item() && (str= args[1]->val_str(&buffer))) 3300 : : { 3301 : : uint ulen; 3302 : : + PARSE_TYPE_FLAGS flags; 3303 : 499 : fixed_length= 1; 3304 : 499 : + if (parse_format_string(str, fmt_array, &ulen, locale, 0, &warning_message, 3305 : : + &flags)) 3306 : : { 3307 : 28 : my_printf_error(ER_STD_INVALID_ARGUMENT, 3308 : 28 : ER(ER_STD_INVALID_ARGUMENT), 3345 : 1706 : if (!fixed_length) 3346 : : { 3347 : : uint ulen; 3348 : : + PARSE_TYPE_FLAGS flags; 3349 : 916 : if (!(format= args[1]->val_str(&format_buffer)) || !format->length() || 3350 : 458 : + parse_format_string(format, fmt_array, &ulen, locale, 0, 3351 : : + &warning_message, &flags)) 3352 : 46 : goto null_date; 3353 : 412 : max_result_length= ((size_t) ulen) * collation.collation->mbmaxlen; 3354 : : } 4092 : : 0099-12-31 4093 : : */ 4094 : : 4095 : 702 : +bool Item_func_makedate::get_date(THD *thd, MYSQL_TIME *ltime, 4096 : : + date_mode_t fuzzydate) 4097 : : { 4098 : 702 : DBUG_ASSERT(fixed()); 4099 : 702 : long year, days, daynr= (long) args[1]->val_int(); 4171 : : Result: Time value 4172 : : */ 4173 : : 4174 : 582 : +bool Item_func_timediff::get_date(THD *thd, MYSQL_TIME *ltime, 4175 : : + date_mode_t fuzzydate) 4176 : : { 4177 : 582 : DBUG_ASSERT(fixed()); 4178 : 582 : int l_sign= 1; 4601 : 732 : } 4602 : : 4603 : : 4604 : : +/** 4605 : : + Compile the format string to fmt_array 4606 : : + 4607 : : + @return The type flags found. PARSE_TYPE_NONE in case of error 4608 : : +*/ 4609 : : + 4610 : 429 : +PARSE_TYPE_FLAGS Item_func_to_date::get_format() 4611 : : +{ 4612 : 429 : + StringBuffer<64> format_str; 4613 : 429 : + String *format= args[1]->val_str(&format_str, &format_converter, 4614 : : + internal_charset); 4615 : : + PARSE_TYPE_FLAGS result_type; 4616 : : + 4617 : 429 : + if (!args[1]->null_value) 4618 : : + { 4619 : : + uint ulen; 4620 : 429 : + warning_message.length(0); 4621 : 429 : + if (parse_format_string(format, fmt_array, &ulen, locale, 1, 4622 : : + &warning_message, &result_type)) 4623 : : + { 4624 : 9 : + my_printf_error(ER_STD_INVALID_ARGUMENT, 4625 : 9 : + ER(ER_STD_INVALID_ARGUMENT), 4626 : : + MYF(0), 4627 : : + warning_message.c_ptr(), 4628 : : + func_name()); 4629 : 9 : + return PARSE_TYPE_NONE; 4630 : : + } 4631 : : + } 4632 : 420 : + DBUG_ASSERT(result_type != 0); 4633 : 420 : + return result_type; 4634 : 429 : +} 4635 : : + 4636 : : + 4637 : : +/** 4638 : : + Read arguments from a string of value pair in the format of 'variable=value' 4639 : : + 4640 : : + @param pos Parsing point. Will be updated to end of value pare 4641 : : + @param variable Will contain the variable name 4642 : : + @param value Will contain the value 4643 : : + 4644 : : + @return 0 value pair found 4645 : : + @return 1 Error 4646 : : + 4647 : : + The caller has ensured that there is no prespace in the string and 4648 : : + the string is not empty. 4649 : : + Value pairs are separated by space or tab. There may be space before 4650 : : + and after '='. 4651 : : + The value may be surrounded by quotes ' or ". 4652 : : +*/ 4653 : : + 4654 : 57 : +bool get_next_argument(const char **pos_arg, const char *end, 4655 : : + LEX_CSTRING *variable, LEX_CSTRING *value) 4656 : : +{ 4657 : 57 : + const char *pos= *pos_arg; 4658 : 57 : + DBUG_ASSERT(pos < end); 4659 : 57 : + DBUG_ASSERT(!my_isspace(&my_charset_latin1, *pos)); 4660 : : + 4661 : 57 : + variable->str= pos; 4662 : : + 4663 : : + for (;;) 4664 : : + { 4665 : 570 : + if (*pos == '=') 4666 : : + { 4667 : 30 : + variable->length= (size_t) (pos - variable->str); 4668 : 30 : + break; 4669 : : + } 4670 : 540 : + if (++pos == end) 4671 : 0 : + return true; 4672 : 540 : + if (my_isspace(&my_charset_latin1, *pos)) 4673 : : + { 4674 : 27 : + variable->length= (pos - variable->str); 4675 : : + do 4676 : : + { 4677 : 27 : + if (++pos == end) 4678 : 0 : + return true; 4679 : 27 : + } while (my_isspace(&my_charset_latin1, *pos)); 4680 : 27 : + if (likely(*pos == '=')) 4681 : 27 : + break; 4682 : 0 : + return true; 4683 : : + } 4684 : : + } 4685 : 57 : + if (variable->length == 0) 4686 : 6 : + return true; // Empty variables are not allowed 4687 : : + 4688 : 51 : + pos++; // Skip '=' 4689 : 51 : + if (pos == end) 4690 : 9 : + return true; // Empty values are not allowed 4691 : : + 4692 : 63 : + while (my_isspace(&my_charset_latin1, *pos)) 4693 : : + { 4694 : 21 : + if (++pos == end) 4695 : 0 : + return true; // Empty values are not allowed 4696 : : + } 4697 : : + /* To make it easier for MariaDB users, we support both " and ' for quting */ 4698 : 42 : + if (*pos == '\'' || *pos == '"') 4699 : : + { 4700 : 3 : + char quote= *pos; 4701 : 3 : + value->str= pos+1; 4702 : : + do 4703 : : + { 4704 : 18 : + pos++; 4705 : 18 : + if (pos == end) 4706 : 0 : + return 1; 4707 : 18 : + } while (*pos != quote); 4708 : 3 : + value->length= (size_t) (pos - value->str); 4709 : 3 : + pos++; // Skip end quote 4710 : 3 : + } 4711 : : + else 4712 : : + { 4713 : 39 : + value->str= pos; 4714 : : + do 4715 : : + { 4716 : 246 : + pos++; 4717 : 246 : + } while (pos != end && !my_isspace(&my_charset_latin1, *pos)); 4718 : 39 : + value->length= (size_t) (pos - value->str); 4719 : : + } 4720 : 42 : + *pos_arg= pos; 4721 : 42 : + return 0; 4722 : : +} 4723 : : + 4724 : : + 4725 : : + 4726 : : +/* Parse Oracle NLS_PARAM and set locale if used */ 4727 : : + 4728 : 198 : +void Item_func_to_date::parse_nls_param(LEX_CSTRING *nls_param) 4729 : : +{ 4730 : : + LEX_CSTRING param, value; 4731 : : + const char *pos, *end, *start; 4732 : : + 4733 : 198 : + if (!nls_param || nls_param->length == 0) 4734 : 189 : + return; 4735 : 45 : + pos= nls_param->str; 4736 : 45 : + end= pos+ nls_param->length; 4737 : : + 4738 : 66 : + for (start= pos ;start != end ; start= pos) 4739 : : + { 4740 : 87 : + while (my_isspace(&my_charset_latin1, *start)) 4741 : : + { 4742 : 30 : + if (++start == end) 4743 : 0 : + return; 4744 : : + } 4745 : 57 : + pos= start; 4746 : 57 : + if (get_next_argument(&pos, end, ¶m, &value)) 4747 : : + { 4748 : 15 : + my_printf_error(ER_STD_INVALID_ARGUMENT, 4749 : 15 : + ER(ER_STD_INVALID_ARGUMENT), 4750 : : + MYF(ME_WARNING), 4751 : : + start, 4752 : : + func_name()); 4753 : 15 : + return; 4754 : : + } 4755 : : + 4756 : 42 : + if (!my_charset_latin1.strnncoll(param.str, param.length, 4757 : : + STRING_WITH_LEN("NLS_CALENDAR"))) 4758 : : + { 4759 : : + /* Skip default calendar */ 4760 : 12 : + if (!my_charset_latin1.strnncoll(value.str, value.length, 4761 : : + STRING_WITH_LEN("GREGORIAN"))) 4762 : 9 : + continue; 4763 : 3 : + goto warning; 4764 : : + } 4765 : : + 4766 : 30 : + if (!my_charset_latin1.strnncoll(param.str, param.length, 4767 : : + STRING_WITH_LEN("NLS_DATE_LANGUAGE"))) 4768 : : + { 4769 : : + /* Check first Oracle name, then MariaDB name */ 4770 : 30 : + if (!(locale= my_locale_by_oracle_name((LEX_CSTRING) value)) && 4771 : 30 : + !(locale= my_locale_by_name((LEX_CSTRING) value))) 4772 : : + { 4773 : 3 : + my_error(ER_UNKNOWN_LOCALE, MYF(0), value.str); 4774 : : + /* return error in fix_fields()/Item_func_to_date::fix_length_and_dec */ 4775 : 3 : + nls_param_error= 1; 4776 : : + } 4777 : 21 : + return; 4778 : : + } 4779 : : + 4780 : : + /* Give warning about unknown NSL parameter */ 4781 : 9 : + warning: 4782 : 12 : + warning_message.length(0); 4783 : 12 : + warning_message.append(param.str, param.length); 4784 : 12 : + warning_message.append_char('='); 4785 : 12 : + warning_message.append(value.str, value.length); 4786 : 12 : + my_printf_error(ER_STD_INVALID_ARGUMENT, 4787 : 12 : + ER(ER_STD_INVALID_ARGUMENT), 4788 : : + MYF(ME_WARNING), 4789 : : + warning_message.c_ptr(), 4790 : : + func_name()); 4791 : : + /* Reset warning as it is used by other functions */ 4792 : 12 : + warning_message.length(0); 4793 : : + } 4794 : : +} 4795 : : + 4796 : : + 4797 : 0 : +void Item_func_to_date::print(String *str, enum_query_type query_type) 4798 : : +{ 4799 : 0 : + str->append(func_name_cstring()); 4800 : 0 : + str->append('('); 4801 : 0 : + args[0]->print(str, query_type); 4802 : 0 : + if (arg_count == 3) 4803 : : + { 4804 : 0 : + str->append(STRING_WITH_LEN("DEFAULT ")); 4805 : 0 : + args[2]->print(str, query_type); 4806 : 0 : + str->append(STRING_WITH_LEN(" ON CONVERSION ERROR")); 4807 : : + } 4808 : 0 : + str->append(','); 4809 : 0 : + args[1]->print(str, query_type); 4810 : 0 : + if (nls_param.length) 4811 : : + { 4812 : 0 : + str->append(','); 4813 : 0 : + str->append(nls_param); 4814 : : + } 4815 : 0 : + str->append(')'); 4816 : 0 : +} 4817 : : + 4818 : : + 4819 : 429 : +bool Item_func_to_date::fix_length_and_dec(THD *thd) 4820 : : +{ 4821 : 429 : + format_flags= PARSE_TYPE_NONE; 4822 : 429 : + if (nls_param_error) 4823 : 0 : + return true; 4824 : : + 4825 : 429 : + if (!locale) // If not set by parse_nls_param 4826 : 171 : + locale= thd->variables.lc_time_names; 4827 : : + 4828 : 429 : + if (!args[0]->type_handler()->is_traditional_scalar_type() || 4829 : 858 : + !args[1]->type_handler()->is_traditional_scalar_type() || 4830 : 429 : + (arg_count == 3 && 4831 : 35 : + !args[2]->type_handler()->is_traditional_scalar_type())) 4832 : : + { 4833 : 0 : + my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), 4834 : 0 : + args[0]->type_handler()->name().ptr(), 4835 : 0 : + args[2]->type_handler()->name().ptr(), func_name()); 4836 : 0 : + return TRUE; 4837 : : + } 4838 : 429 : + if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1)) 4839 : 0 : + return TRUE; 4840 : 429 : + if (collation.collation->mbminlen > 1) 4841 : 0 : + internal_charset= &my_charset_utf8mb4_general_ci; 4842 : : + 4843 : 429 : + set_maybe_null(); 4844 : 429 : + set_func_handler(&func_handler_str_to_date_datetime_usec); 4845 : : + 4846 : 429 : + if ((const_item= args[1]->const_item())) 4847 : : + { 4848 : 429 : + if (!(format_flags= get_format())) 4849 : 9 : + return true; 4850 : 420 : + set_func_handler(get_parsed_result_type(format_flags)); 4851 : : + } 4852 : 420 : + if (!test_all_bits(format_flags, PARSE_TYPE_DATE)) 4853 : : + { 4854 : : + /* Some time part is missing, get current time to fill them in */ 4855 : 119 : + thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->query_start()); 4856 : 119 : + now_time.hour= now_time.minute= now_time.second= 0; 4857 : 119 : + now_time.second_part= 0; 4858 : 119 : + now_time.neg= 0; 4859 : : + } 4860 : : + else 4861 : 301 : + bzero(&now_time, sizeof(now_time)); 4862 : 420 : + now_time.time_type= MYSQL_TIMESTAMP_NONE; 4863 : : + 4864 : 420 : + return m_func_handler->fix_length_and_dec(this); 4865 : : +} 4866 : : + 4867 : : + 4868 : 300 : +bool Item_func_to_date::get_date_common(THD *thd, MYSQL_TIME *ltime, 4869 : : + date_mode_t fuzzydate, 4870 : : + timestamp_type tstype) 4871 : : +{ 4872 : 300 : + StringBuffer<64> val_string; 4873 : : + String *val; 4874 : : + 4875 : 300 : + val= args[0]->val_str(&val_string, &subject_converter, internal_charset); 4876 : 300 : + if (args[1]->null_value) 4877 : 0 : + goto error; 4878 : 300 : + if (args[0]->null_value) 4879 : : + { 4880 : 10 : + if (arg_count == 2) 4881 : 5 : + goto error; 4882 : 5 : + val= args[2]->val_str(&val_string, &subject_converter, internal_charset); 4883 : 5 : + if (args[2]->null_value) 4884 : 0 : + goto error; 4885 : : + } 4886 : : + 4887 : 295 : + if (!const_item && !get_format()) 4888 : 0 : + goto error; 4889 : : + 4890 : : + /* Set default year, month and day */ 4891 : 295 : + memcpy(ltime, &now_time, sizeof(*ltime)); 4892 : 295 : + ltime->time_type= tstype; 4893 : : + 4894 : 295 : + if (!extract_oracle_date_time(thd, fmt_array, 4895 : : + val->ptr(), val->length(), 4896 : : + ltime, locale, "datetime", 4897 : 295 : + (date_conv_mode_t(fuzzydate) | 4898 : 295 : + sql_mode_for_dates(thd)), 4899 : 295 : + arg_count == 2)) 4900 : 205 : + return (null_value= 0); 4901 : : + 4902 : 90 : + if (arg_count == 3) 4903 : : + { 4904 : : + /* Try to use default value */ 4905 : 20 : + val= args[2]->val_str(&val_string, &subject_converter, internal_charset); 4906 : 20 : + if (args[2]->null_value) 4907 : 5 : + goto error; 4908 : 15 : + if (!extract_oracle_date_time(thd, fmt_array, 4909 : : + val->ptr(), val->length(), 4910 : : + ltime, locale, "datetime", 4911 : 15 : + (date_conv_mode_t(fuzzydate) | 4912 : 30 : + sql_mode_for_dates(thd)), 1)) 4913 : 10 : + return (null_value= 0); 4914 : : + } 4915 : 70 : + error: 4916 : 85 : + return (null_value=1); 4917 : 300 : +} 4918 : : + 4919 : : + 4920 : 202 : bool Item_func_last_day::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) 4921 : : { 4922 : 202 : Datetime::Options opt(date_conv_mode_t(fuzzydate & ~TIME_TIME_ONLY), ===== File: sql/item_timefunc.h ===== 1125 : 1276 : return name; 1126 : : } 1127 : : bool fix_length_and_dec(THD *thd) override; 1128 : : 1129 : 0 : bool check_vcol_func_processor(void *arg) override 1130 : : { 1755 : 507 : internal_charset(NULL) 1756 : 507 : {} 1757 : : bool get_date_common(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate, 1758 : : + timestamp_type) override; 1759 : 2810 : LEX_CSTRING func_name_cstring() const override 1760 : : { 1761 : : static LEX_CSTRING name= {STRING_WITH_LEN("str_to_date") }; 1767 : : }; 1768 : : 1769 : : 1770 : : +/* Oracle TO_DATE() function */ 1771 : : + 1772 : : + 1773 : : +/* Flags used by parse_format_string() */ 1774 : : + 1775 : : +enum PARSE_TYPE_FLAGS 1776 : : +{ 1777 : : + PARSE_TYPE_NONE= 0, 1778 : : + PARSE_TYPE_YEAR= 1, 1779 : : + PARSE_TYPE_MONTH= 2, 1780 : : + PARSE_TYPE_DAY= 4, 1781 : : + PARSE_TYPE_HH= 8, 1782 : : + PARSE_TYPE_MM= 16, 1783 : : + PARSE_TYPE_SS= 32, 1784 : : + PARSE_TYPE_SUBSECONDS= 64, 1785 : : + PARSE_TYPE_WEEKDAY= 128, 1786 : : + PARSE_TYPE_PART_YEAR= 256, 1787 : : + PARSE_TYPE_NON_DETERMINISTIC= 512 1788 : : +}; 1789 : : + 1790 : : +#define PARSE_TYPE_DATE (PARSE_TYPE_YEAR | PARSE_TYPE_MONTH | PARSE_TYPE_DAY) 1791 : : +#define PARSE_TYPE_FULLDATE (PARSE_TYPE_YEAR | PARSE_TYPE_HH | \ 1792 : : + PARSE_TYPE_MM | PARSE_TYPE_SS) 1793 : : + 1794 : : +class Item_func_to_date :public Item_handled_func 1795 : : +{ 1796 : : + bool const_item; 1797 : : + String subject_converter; 1798 : : + String format_converter; 1799 : : + CHARSET_INFO *internal_charset; 1800 : : + MYSQL_TIME now_time; // Used for incomplete dates 1801 : : + PARSE_TYPE_FLAGS format_flags; 1802 : : + THD *thd; 1803 : : + const MY_LOCALE *locale; 1804 : : + String warning_message; 1805 : : + PARSE_TYPE_FLAGS formats_used; 1806 : : + LEX_CSTRING nls_param; 1807 : : + bool nls_param_error; 1808 : : + 1809 : : + /* 1810 : : + When datetime format models is parsed, use uint16 integers to 1811 : : + represent the format models and store in fmt_array. 1812 : : + */ 1813 : : + uint16 fmt_array[MAX_DATETIME_FORMAT_MODEL_LEN+1]; 1814 : : + 1815 : : +public: 1816 : 183 : + Item_func_to_date(THD *thd, Item *a, Item *b, LEX_CSTRING *nls): 1817 : 183 : + Item_handled_func(thd, a, b), const_item(false), 1818 : 183 : + internal_charset(NULL), locale(0), nls_param(*nls), nls_param_error(0) 1819 : : + { 1820 : : + /* NOTE: max length of warning message is 64 */ 1821 : 183 : + warning_message.alloc(64); 1822 : 183 : + warning_message.length(0); 1823 : 183 : + parse_nls_param(&nls_param); 1824 : 183 : + } 1825 : 15 : + Item_func_to_date(THD *thd, Item *a, Item *b, Item *c, LEX_CSTRING *nls): 1826 : 15 : + Item_handled_func(thd, a, b, c), const_item(false), 1827 : 15 : + internal_charset(NULL), locale(0), nls_param(*nls), nls_param_error(0) 1828 : : + { 1829 : : + /* NOTE: max length of warning message is 64 */ 1830 : 15 : + warning_message.alloc(64); 1831 : 15 : + warning_message.length(0); 1832 : 15 : + parse_nls_param(&nls_param); 1833 : 15 : + } 1834 : : + bool get_date_common(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate, 1835 : : + timestamp_type) override; 1836 : 1370 : + LEX_CSTRING func_name_cstring() const override 1837 : : + { 1838 : : + static LEX_CSTRING name= {STRING_WITH_LEN("to_date") }; 1839 : 1370 : + return name; 1840 : : + } 1841 : : + bool fix_length_and_dec(THD *thd) override; 1842 : 0 : + Item *do_get_copy(THD *thd) const override 1843 : 0 : + { return get_item_copy(thd, this); } 1844 : : + 1845 : 12 : + bool check_vcol_func_processor(void *arg) override 1846 : : + { 1847 : : + /* 1848 : : + We have to mark this as non deterministic as when this 1849 : : + function is called, fix_length_and_dec() has not been run 1850 : : + and we do not know if this usage is deterministic or not. 1851 : : + If the item would be const and format_flags says all 1852 : : + fields is used, we would know if the function would be 1853 : : + deterministic or not. 1854 : : + */ 1855 : 12 : + return mark_unsupported_function(func_name(), "()", arg, 1856 : 12 : + VCOL_NON_DETERMINISTIC); 1857 : : + } 1858 : : + PARSE_TYPE_FLAGS get_format(); 1859 : : + void parse_nls_param(LEX_CSTRING *); 1860 : : + void print(String *str, enum_query_type query_type) override; 1861 : : +}; 1862 : : + 1863 : : + 1864 : : class Item_func_last_day :public Item_datefunc 1865 : : { 1866 : 192 : bool check_arguments() const override 2160 : 514 : bool get_date(THD *thd, Item_handled_func *item, 2161 : : MYSQL_TIME *to, date_mode_t fuzzy) const override 2162 : : { 2163 : 514 : + return item->get_date_common(thd, to, fuzzy, MYSQL_TIMESTAMP_DATETIME); 2164 : : } 2165 : : }; 2166 : : 2177 : 69 : bool get_date(THD *thd, Item_handled_func *item, 2178 : : MYSQL_TIME *to, date_mode_t fuzzy) const override 2179 : : { 2180 : 69 : + return item->get_date_common(thd, to, fuzzy, MYSQL_TIMESTAMP_DATETIME); 2181 : : } 2182 : : }; 2183 : : 2188 : 433 : bool get_date(THD *thd, Item_handled_func *item, 2189 : : MYSQL_TIME *to, date_mode_t fuzzy) const override 2190 : : { 2191 : 433 : + return item->get_date_common(thd, to, fuzzy, MYSQL_TIMESTAMP_DATE); 2192 : : } 2193 : : }; 2194 : : 2199 : 16 : bool get_date(THD *thd, Item_handled_func *item, 2200 : : MYSQL_TIME *to, date_mode_t fuzzy) const override 2201 : : { 2202 : 16 : + if (item->get_date_common(thd, to, fuzzy, MYSQL_TIMESTAMP_TIME)) 2203 : 3 : return true; 2204 : 13 : if (to->day) 2205 : : { ===== File: sql/lex.h ===== 150 : : { "CONTEXT", SYM(CONTEXT_SYM)}, 151 : : { "CONTINUE", SYM(CONTINUE_MARIADB_SYM)}, 152 : : { "CONTRIBUTORS", SYM(CONTRIBUTORS_SYM)}, 153 : : + { "CONVERSION", SYM(CONVERSION_SYM)}, 154 : : { "CONVERT", SYM(CONVERT_SYM)}, 155 : : + { "CPU", SYM(CPU_SYM)}, 156 : : { "CREATE", SYM(CREATE)}, 157 : : { "CROSS", SYM(CROSS)}, 158 : : { "CUBE", SYM(CUBE_SYM)}, 673 : : { "TINYINT", SYM(TINYINT)}, 674 : : { "TINYTEXT", SYM(TINYTEXT)}, 675 : : { "TO", SYM(TO_SYM)}, 676 : : + { "TO_DATE", SYM(TO_DATE)}, 677 : : { "TRAILING", SYM(TRAILING)}, 678 : : { "TRANSACTION", SYM(TRANSACTION_SYM)}, 679 : : { "TRANSACTIONAL", SYM(TRANSACTIONAL_SYM)}, ===== File: sql/sql_locale.cc ===== 3499 : : }; 3500 : : 3501 : : 3502 : : +/* Mapping for Oracle NLS_LANGUAGE_DATE to MY_LOCALE */ 3503 : : + 3504 : : +struct ORACLE_DATE_LOCALE 3505 : : +{ 3506 : : + const Lex_ident_locale name; 3507 : : + MY_LOCALE *locale; 3508 : : +}; 3509 : : + 3510 : : +struct ORACLE_DATE_LOCALE Oracle_date_locale[]= 3511 : : +{ 3512 : : + { "ALBANIAN"_Lex_ident_locale, &my_locale_sq_AL }, 3513 : : + { "AMERICAN"_Lex_ident_locale, &my_locale_en_US }, 3514 : : + { "ARABIC"_Lex_ident_locale, &my_locale_ar_YE }, 3515 : : + //{ "ARMENIAN"_Lex_ident_locale, &my_locale_hy }, 3516 : : + //{ "ASSAMESE"_Lex_ident_locale, &my_locale_as }, 3517 : : + //{ "AZERBAIJANI"_Lex_ident_locale, &my_locale_az }, 3518 : : + //{ "BANGLA"_Lex_ident_locale, &my_locale_bn }, 3519 : : + { "BASQUE"_Lex_ident_locale, &my_locale_eu_ES }, 3520 : : + { "BELARUSIAN"_Lex_ident_locale, &my_locale_be_BY }, 3521 : : + { "BRAZILIAN PORTUGUESE"_Lex_ident_locale, &my_locale_pt_BR }, 3522 : : + { "BULGARIAN"_Lex_ident_locale, &my_locale_bg_BG }, 3523 : : + { "CANADIAN FRENCH"_Lex_ident_locale, &my_locale_fr_FR }, 3524 : : + { "CATALAN"_Lex_ident_locale, &my_locale_ca_ES }, 3525 : : + { "CROATIAN"_Lex_ident_locale, &my_locale_hr_HR }, 3526 : : + //{ "CYRILLIC KAZAKH"_Lex_ident_locale, &my_locale_ckk }, 3527 : : + { "CYRILLIC SERBIAN"_Lex_ident_locale, &my_locale_sr_RS }, 3528 : : + //{"CYRILLIC UZBEK"_Lex_ident_locale, &my_locale_cuz }, 3529 : : + { "CZECH"_Lex_ident_locale, &my_locale_cs_CZ }, 3530 : : + { "DANISH"_Lex_ident_locale, &my_locale_da_DK }, 3531 : : + //{ "DARI"_Lex_ident_locale, &my_locale_prs }, 3532 : : + //{ "DIVEHI"_Lex_ident_locale, &my_locale_dv }, 3533 : : + { "DUTCH"_Lex_ident_locale, &my_locale_nl_BE }, 3534 : : + { "EGYPTIAN"_Lex_ident_locale, &my_locale_ar_EG }, 3535 : : + { "ENGLISH"_Lex_ident_locale, &my_locale_en_GB }, 3536 : : + { "ESTONIAN"_Lex_ident_locale, &my_locale_et_EE }, 3537 : : + { "FINNISH"_Lex_ident_locale, &my_locale_fi_FI }, 3538 : : + { "FRENCH"_Lex_ident_locale, &my_locale_fr_BE }, 3539 : : + //{ "GERMAN DIN"_Lex_ident_locale, &my_locale_din }, 3540 : : + { "GERMAN"_Lex_ident_locale, &my_locale_de_DE }, 3541 : : + { "GREEK"_Lex_ident_locale, &my_locale_el_GR }, 3542 : : + //{ "GUJARATI"_Lex_ident_locale, &my_locale_gu }, 3543 : : + { "HEBREW"_Lex_ident_locale, &my_locale_he_IL }, 3544 : : + { "HINDI"_Lex_ident_locale, &my_locale_hi_IN }, 3545 : : + { "HUNGARIAN"_Lex_ident_locale, &my_locale_hu_HU }, 3546 : : + { "ICELANDIC"_Lex_ident_locale, &my_locale_is_IS }, 3547 : : + { "INDONESIAN"_Lex_ident_locale, &my_locale_id_ID }, 3548 : : + //{ "IRISH"_Lex_ident_locale, &my_locale_ga }, 3549 : : + { "ITALIAN"_Lex_ident_locale, &my_locale_it_IT }, 3550 : : + { "JAPANESE"_Lex_ident_locale, &my_locale_ja_JP }, 3551 : : + { "KANNADA"_Lex_ident_locale, &my_locale_en_CA }, 3552 : : + //{ "KHMER"_Lex_ident_locale, &my_locale_km_KM }, 3553 : : + { "KOREAN"_Lex_ident_locale, &my_locale_ko_KR }, 3554 : : + //{ "LAO"_Lex_ident_locale, &my_locale_lo_LO }, 3555 : : + { "LATIN AMERICAN SPANISH"_Lex_ident_locale, &my_locale_es_ES }, 3556 : : + //{ "LATIN BOSNIAN"_Lex_ident_locale, &my_locale_lbs_LBS }, 3557 : : + //{ "LATIN SERBIAN"_Lex_ident_locale, &my_locale_lsr_LSR }, 3558 : : + //{ "LATIN UZBEK"_Lex_ident_locale, &my_locale_luz_LUZ }, 3559 : : + { "LATVIAN"_Lex_ident_locale, &my_locale_lv_LV }, 3560 : : + { "LITHUANIAN"_Lex_ident_locale, &my_locale_lt_LT }, 3561 : : + { "MACEDONIAN"_Lex_ident_locale, &my_locale_mk_MK }, 3562 : : + { "MALAY"_Lex_ident_locale, &my_locale_ms_MY }, 3563 : : + //{ "MALAYALAM"_Lex_ident_locale, &my_locale_ml_ML }, 3564 : : + //{ "MALTESE"_Lex_ident_locale, &my_locale_mt_MT }, 3565 : : + //{ "MARATHI"_Lex_ident_locale, &my_locale_mr_MR }, 3566 : : + { "MEXICAN SPANISH"_Lex_ident_locale, &my_locale_es_MX }, 3567 : : + //{ "NEPALI"_Lex_ident_locale, &my_locale_ne_NE }, 3568 : : + { "NORWEGIAN"_Lex_ident_locale, &my_locale_nb_NO }, 3569 : : + //{ "ORIYA"_Lex_ident_locale, &my_locale_or_OR }, 3570 : : + //{ "PERSIAN"_Lex_ident_locale, &my_locale_fa_FA }, 3571 : : + { "POLISH"_Lex_ident_locale, &my_locale_pl_PL }, 3572 : : + { "PORTUGUESE"_Lex_ident_locale, &my_locale_pt_PT }, 3573 : : + //{ "PUNJABI"_Lex_ident_locale, &my_locale_pa_PA }, 3574 : : + { "ROMANIAN"_Lex_ident_locale, &my_locale_ro_RO }, 3575 : : + { "RUSSIAN"_Lex_ident_locale, &my_locale_ru_RU }, 3576 : : + { "SIMPLIFIED CHINESE"_Lex_ident_locale, &my_locale_zh_CN }, 3577 : : + //{ "SINHALA"_Lex_ident_locale, &my_locale_si_SI }, 3578 : : + { "SLOVAK"_Lex_ident_locale, &my_locale_sk_SK }, 3579 : : + { "SLOVENIAN"_Lex_ident_locale, &my_locale_sl_SI }, 3580 : : + { "SPANISH"_Lex_ident_locale, &my_locale_es_ES }, 3581 : : + { "SWAHILI"_Lex_ident_locale, &my_locale_sw_KE }, 3582 : : + { "SWEDISH"_Lex_ident_locale, &my_locale_sv_SE }, 3583 : : + { "TAMIL"_Lex_ident_locale, &my_locale_ta_IN }, 3584 : : + //{ "TELUGU"_Lex_ident_locale, &my_locale_te_TE }, 3585 : : + { "THAI"_Lex_ident_locale, &my_locale_th_TH }, 3586 : : + { "TRADITIONAL CHINESE"_Lex_ident_locale, &my_locale_zh_CN }, 3587 : : + { "TURKISH"_Lex_ident_locale, &my_locale_tr_TR }, 3588 : : + //{ "TURKMEN"_Lex_ident_locale, &my_locale_tk_TK }, 3589 : : + { "UKRAINIAN"_Lex_ident_locale, &my_locale_uk_UA }, 3590 : : + { "URDU"_Lex_ident_locale, &my_locale_ur_PK }, 3591 : : + { "VIETNAMESE"_Lex_ident_locale, &my_locale_vi_VN }, 3592 : : + { ""_Lex_ident_locale, 0} 3593 : : +}; 3594 : : + 3595 : : + 3596 : 1806 : MY_LOCALE *my_locale_by_number(uint number) 3597 : : { 3598 : : MY_LOCALE *locale; 3632 : : } 3633 : : 3634 : : 3635 : 21 : +MY_LOCALE *my_locale_by_oracle_name(const LEX_CSTRING &name) 3636 : : +{ 3637 : : + ORACLE_DATE_LOCALE *locale; 3638 : 681 : + for (locale= Oracle_date_locale; locale->locale ; locale++) 3639 : : + { 3640 : 672 : + if (locale->name.streq(name)) 3641 : 12 : + return locale->locale; 3642 : : + } 3643 : 9 : + return 0; 3644 : : +} 3645 : : + 3646 : : + 3647 : 11887 : void cleanup_errmsgs() 3648 : : { 3649 : 332836 : for (MY_LOCALE_ERRMSGS *msgs= global_errmsgs; msgs->language; msgs++) ===== File: sql/sql_locale.h ===== 95 : : 96 : : MY_LOCALE *my_locale_by_name(const LEX_CSTRING &name); 97 : : MY_LOCALE *my_locale_by_number(uint number); 98 : : +MY_LOCALE *my_locale_by_oracle_name(const LEX_CSTRING &name); 99 : : void cleanup_errmsgs(void); 100 : : 101 : : #endif /* SQL_LOCALE_INCLUDED */ ===== File: sql/sql_yacc.yy ===== 133 : 234493 : return new (thd->mem_root) Item_string_ascii(thd, esc, MY_TEST(esc[0])); 134 : : } 135 : : 136 : : /** 137 : : @brief Bison callback to report a syntax/OOM error 138 : : 826 : : %token CONTAINS_SYM /* SQL-2003-N */ 827 : : %token CONTEXT_SYM 828 : : %token CONTRIBUTORS_SYM 829 : : +%token CONVERSION_SYM 830 : : %token CPU_SYM 831 : : %token CUBE_SYM /* SQL-2003-R */ 832 : : %token CURRENT_SYM /* SQL-2003-R */ 1142 : : %token TRANSACTION_SYM 1143 : : %token TRANSACTIONAL_SYM 1144 : : %token THREADS_SYM 1145 : : +%token TO_DATE /* PLSQL function */ 1146 : : %token TRIGGERS_SYM 1147 : : %token TRIM_ORACLE 1148 : : %token TRUNCATE_SYM 1339 : : key_cache_name 1340 : : sp_opt_label BIN_NUM TEXT_STRING_filesystem 1341 : : opt_constraint constraint opt_ident 1342 : : + sp_block_label sp_control_label opt_place opt_db opt_nls_param 1343 : : udt_name 1344 : : 1345 : : %ifdef ORACLE 10414 : : $7)))) 10415 : 0 : MYSQL_YYABORT; 10416 : : } 10417 : : + | TO_DATE '(' expr ',' expr opt_nls_param')' 10418 : : + { 10419 : 183 : + $$= new (thd->mem_root) Item_func_to_date(thd, $3, $5, &$6); 10420 : 183 : + if (unlikely($$ == 0)) 10421 : 0 : + MYSQL_YYABORT; 10422 : : + } 10423 : : + | TO_DATE '(' expr DEFAULT expr ON CONVERSION_SYM ERROR_SYM 10424 : : + ',' expr opt_nls_param')' 10425 : : + { 10426 : 15 : + $$= new (thd->mem_root) Item_func_to_date(thd, $3, $10, $5, &$11); 10427 : 15 : + if (unlikely($$ == NULL)) 10428 : 0 : + MYSQL_YYABORT; 10429 : : + } 10430 : : ; 10431 : : 10432 : : primary_expr: 10507 : 0 : MYSQL_YYABORT; 10508 : : } 10509 : : ; 10510 : : + 10511 : : +opt_nls_param: 10512 : : + /* empty */ 10513 : : + { 10514 : 153 : + $$= (LEX_CSTRING) empty_clex_str; 10515 : : + } 10516 : : + | ',' TEXT_STRING_sys 10517 : : + { 10518 : 45 : + $$= $2; 10519 : : + } 10520 : : + 10521 : : + 10522 : : /* 10523 : : Function call syntax using official SQL 2003 keywords. 10524 : : Because the function name is an official token, Line coverage: 1139/1238 Branch coverage: 0/0