Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-4742

A function for native natural sorting / natural compare

Details

    Description

      Hi guys, could be nice a natural sorting inside mariadb
      today some guys use SQL procedures/functions to execute this cpu intensive task
      php released a nice function to do this job, maybe we could port part of it and implement in udf function, and release as a default udf function?

      functions:
      1) natural sort, used in ORDER BY / GROUP BY
      2) natural sort compare, could be used as an operator, like the "SOUNDS LIKE" operator, in other words, the function that return a canonical form of the string could be used to compare, something that could be rewrite "field NATURAL LIKE value" to "natual(field)=natural(value)"

      i didn't found (2) in internet, but it's used in php, and the (1) should use it in some place to order/group correctly
      --------------
      example of (2):
      http://www.php.net/manual/en/function.strnatcmp.php
      https://github.com/php/php-src/blob/master/ext/standard/strnatcmp.c
      --------------

      example of (1)
      Here a example in STORED PROCEDURE/FUNCTIONS for ORDER BY, but not exaust tested:
      source: http://stackoverflow.com/questions/153633/natural-sort-in-mysql

      DROP FUNCTION IF EXISTS `udf_FirstNumberPos`;
      DELIMITER ;;
      CREATE FUNCTION `udf_FirstNumberPos` (`instring` varchar(4000)) 
      RETURNS int
      LANGUAGE SQL
      DETERMINISTIC
      NO SQL
      SQL SECURITY INVOKER
      BEGIN
          DECLARE position int;
          DECLARE tmp_position int;
          SET position = 5000;
          SET tmp_position = LOCATE('0', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF; 
          SET tmp_position = LOCATE('1', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('2', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('3', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('4', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('5', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('6', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('7', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('8', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
          SET tmp_position = LOCATE('9', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
       
          IF (position = 5000) THEN RETURN 0; END IF;
          RETURN position;
      END
      ;;
       
      DROP FUNCTION IF EXISTS `udf_NaturalSortFormat`;
      DELIMITER ;;
      CREATE FUNCTION `udf_NaturalSortFormat` (`instring` varchar(4000), `numberLength` int, `sameOrderChars` char(50)) 
      RETURNS varchar(4000)
      LANGUAGE SQL
      DETERMINISTIC
      NO SQL
      SQL SECURITY INVOKER
      BEGIN
          DECLARE sortString varchar(4000);
          DECLARE numStartIndex int;
          DECLARE numEndIndex int;
          DECLARE padLength int;
          DECLARE totalPadLength int;
          DECLARE i int;
          DECLARE sameOrderCharsLen int;
       
          SET totalPadLength = 0;
          SET instring = TRIM(instring);
          SET sortString = instring;
          SET numStartIndex = udf_FirstNumberPos(instring);
          SET numEndIndex = 0;
          SET i = 1;
          SET sameOrderCharsLen = LENGTH(sameOrderChars);
       
          WHILE (i <= sameOrderCharsLen) DO
              SET sortString = REPLACE(sortString, SUBSTRING(sameOrderChars, i, 1), ' ');
              SET i = i + 1;
          END WHILE;
       
          WHILE (numStartIndex <> 0) DO
              SET numStartIndex = numStartIndex + numEndIndex;
              SET numEndIndex = numStartIndex;
       
              WHILE (udf_FirstNumberPos(SUBSTRING(instring, numEndIndex, 1)) = 1) DO
                  SET numEndIndex = numEndIndex + 1;
              END WHILE;
       
              SET numEndIndex = numEndIndex - 1;
       
              SET padLength = numberLength - (numEndIndex + 1 - numStartIndex);
       
              IF padLength < 0 THEN
                  SET padLength = 0;
              END IF;
       
              SET sortString = INSERT(sortString, numStartIndex + totalPadLength, 0, REPEAT('0', padLength));
       
              SET totalPadLength = totalPadLength + padLength;
              SET numStartIndex = udf_FirstNumberPos(RIGHT(instring, LENGTH(instring) - numEndIndex));
          END WHILE;
       
          RETURN sortString;
      END
      ;;

      Attachments

        Issue Links

          Activity

            rspadim roberto spadim created issue -
            rspadim roberto spadim made changes -
            Field Original Value New Value
            rspadim roberto spadim made changes -
            Description Hi guys, could be nice a natural sorting inside mariadb
            today some guys use SQL procedures/functions to execute this cpu intensive task
            php released a nice function to do this job, maybe we could port part of it and implement in udf function, and release as a default udf function?
            Hi guys, could be nice a natural sorting inside mariadb
            today some guys use SQL procedures/functions to execute this cpu intensive task
            php released a nice function to do this job, maybe we could port part of it and implement in udf function, and release as a default udf function?


            Here a example in STORED PROCEDURE/FUNCTIONS, but not exaust tested:
            source: http://stackoverflow.com/questions/153633/natural-sort-in-mysql
            {code}
            DROP FUNCTION IF EXISTS `udf_FirstNumberPos`;
            DELIMITER ;;
            CREATE FUNCTION `udf_FirstNumberPos` (`instring` varchar(4000))
            RETURNS int
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE position int;
                DECLARE tmp_position int;
                SET position = 5000;
                SET tmp_position = LOCATE('0', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('1', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('2', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('3', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('4', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('5', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('6', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('7', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('8', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('9', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;

                IF (position = 5000) THEN RETURN 0; END IF;
                RETURN position;
            END
            ;;

            DROP FUNCTION IF EXISTS `udf_NaturalSortFormat`;
            DELIMITER ;;
            CREATE FUNCTION `udf_NaturalSortFormat` (`instring` varchar(4000), `numberLength` int, `sameOrderChars` char(50))
            RETURNS varchar(4000)
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE sortString varchar(4000);
                DECLARE numStartIndex int;
                DECLARE numEndIndex int;
                DECLARE padLength int;
                DECLARE totalPadLength int;
                DECLARE i int;
                DECLARE sameOrderCharsLen int;

                SET totalPadLength = 0;
                SET instring = TRIM(instring);
                SET sortString = instring;
                SET numStartIndex = udf_FirstNumberPos(instring);
                SET numEndIndex = 0;
                SET i = 1;
                SET sameOrderCharsLen = LENGTH(sameOrderChars);

                WHILE (i <= sameOrderCharsLen) DO
                    SET sortString = REPLACE(sortString, SUBSTRING(sameOrderChars, i, 1), ' ');
                    SET i = i + 1;
                END WHILE;

                WHILE (numStartIndex <> 0) DO
                    SET numStartIndex = numStartIndex + numEndIndex;
                    SET numEndIndex = numStartIndex;

                    WHILE (udf_FirstNumberPos(SUBSTRING(instring, numEndIndex, 1)) = 1) DO
                        SET numEndIndex = numEndIndex + 1;
                    END WHILE;

                    SET numEndIndex = numEndIndex - 1;

                    SET padLength = numberLength - (numEndIndex + 1 - numStartIndex);

                    IF padLength < 0 THEN
                        SET padLength = 0;
                    END IF;

                    SET sortString = INSERT(sortString, numStartIndex + totalPadLength, 0, REPEAT('0', padLength));

                    SET totalPadLength = totalPadLength + padLength;
                    SET numStartIndex = udf_FirstNumberPos(RIGHT(instring, LENGTH(instring) - numEndIndex));
                END WHILE;

                RETURN sortString;
            END
            ;;
            {code}
            rspadim roberto spadim made changes -
            rspadim roberto spadim made changes -
            Summary UDF - Native natural sorting UDF - Native natural sorting / natural compare
            rspadim roberto spadim made changes -
            Description Hi guys, could be nice a natural sorting inside mariadb
            today some guys use SQL procedures/functions to execute this cpu intensive task
            php released a nice function to do this job, maybe we could port part of it and implement in udf function, and release as a default udf function?


            Here a example in STORED PROCEDURE/FUNCTIONS, but not exaust tested:
            source: http://stackoverflow.com/questions/153633/natural-sort-in-mysql
            {code}
            DROP FUNCTION IF EXISTS `udf_FirstNumberPos`;
            DELIMITER ;;
            CREATE FUNCTION `udf_FirstNumberPos` (`instring` varchar(4000))
            RETURNS int
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE position int;
                DECLARE tmp_position int;
                SET position = 5000;
                SET tmp_position = LOCATE('0', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('1', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('2', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('3', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('4', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('5', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('6', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('7', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('8', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('9', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;

                IF (position = 5000) THEN RETURN 0; END IF;
                RETURN position;
            END
            ;;

            DROP FUNCTION IF EXISTS `udf_NaturalSortFormat`;
            DELIMITER ;;
            CREATE FUNCTION `udf_NaturalSortFormat` (`instring` varchar(4000), `numberLength` int, `sameOrderChars` char(50))
            RETURNS varchar(4000)
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE sortString varchar(4000);
                DECLARE numStartIndex int;
                DECLARE numEndIndex int;
                DECLARE padLength int;
                DECLARE totalPadLength int;
                DECLARE i int;
                DECLARE sameOrderCharsLen int;

                SET totalPadLength = 0;
                SET instring = TRIM(instring);
                SET sortString = instring;
                SET numStartIndex = udf_FirstNumberPos(instring);
                SET numEndIndex = 0;
                SET i = 1;
                SET sameOrderCharsLen = LENGTH(sameOrderChars);

                WHILE (i <= sameOrderCharsLen) DO
                    SET sortString = REPLACE(sortString, SUBSTRING(sameOrderChars, i, 1), ' ');
                    SET i = i + 1;
                END WHILE;

                WHILE (numStartIndex <> 0) DO
                    SET numStartIndex = numStartIndex + numEndIndex;
                    SET numEndIndex = numStartIndex;

                    WHILE (udf_FirstNumberPos(SUBSTRING(instring, numEndIndex, 1)) = 1) DO
                        SET numEndIndex = numEndIndex + 1;
                    END WHILE;

                    SET numEndIndex = numEndIndex - 1;

                    SET padLength = numberLength - (numEndIndex + 1 - numStartIndex);

                    IF padLength < 0 THEN
                        SET padLength = 0;
                    END IF;

                    SET sortString = INSERT(sortString, numStartIndex + totalPadLength, 0, REPEAT('0', padLength));

                    SET totalPadLength = totalPadLength + padLength;
                    SET numStartIndex = udf_FirstNumberPos(RIGHT(instring, LENGTH(instring) - numEndIndex));
                END WHILE;

                RETURN sortString;
            END
            ;;
            {code}
            Hi guys, could be nice a natural sorting inside mariadb
            today some guys use SQL procedures/functions to execute this cpu intensive task
            php released a nice function to do this job, maybe we could port part of it and implement in udf function, and release as a default udf function?

            functions:
            1) natural sort, used in ORDER BY / GROUP BY
            2) natural sort compare, could be used as an operator, like the "SOUNDS LIKE" operator, in other words, the function that return a canonical form of the string could be used to compare, something that could be rewrite "field NATURAL LIKE value" to "natual(field)=natural(value)"

            i didn't found (2) in internet, but it's used in php, and the (1) should use it in some place to order/group correctly
            example of (2): http://www.php.net/manual/en/function.strnatcmp.php
            --------------


            1)
            Here a example in STORED PROCEDURE/FUNCTIONS for ORDER BY, but not exaust tested:
            source: http://stackoverflow.com/questions/153633/natural-sort-in-mysql
            {code}
            DROP FUNCTION IF EXISTS `udf_FirstNumberPos`;
            DELIMITER ;;
            CREATE FUNCTION `udf_FirstNumberPos` (`instring` varchar(4000))
            RETURNS int
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE position int;
                DECLARE tmp_position int;
                SET position = 5000;
                SET tmp_position = LOCATE('0', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('1', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('2', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('3', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('4', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('5', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('6', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('7', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('8', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('9', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;

                IF (position = 5000) THEN RETURN 0; END IF;
                RETURN position;
            END
            ;;

            DROP FUNCTION IF EXISTS `udf_NaturalSortFormat`;
            DELIMITER ;;
            CREATE FUNCTION `udf_NaturalSortFormat` (`instring` varchar(4000), `numberLength` int, `sameOrderChars` char(50))
            RETURNS varchar(4000)
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE sortString varchar(4000);
                DECLARE numStartIndex int;
                DECLARE numEndIndex int;
                DECLARE padLength int;
                DECLARE totalPadLength int;
                DECLARE i int;
                DECLARE sameOrderCharsLen int;

                SET totalPadLength = 0;
                SET instring = TRIM(instring);
                SET sortString = instring;
                SET numStartIndex = udf_FirstNumberPos(instring);
                SET numEndIndex = 0;
                SET i = 1;
                SET sameOrderCharsLen = LENGTH(sameOrderChars);

                WHILE (i <= sameOrderCharsLen) DO
                    SET sortString = REPLACE(sortString, SUBSTRING(sameOrderChars, i, 1), ' ');
                    SET i = i + 1;
                END WHILE;

                WHILE (numStartIndex <> 0) DO
                    SET numStartIndex = numStartIndex + numEndIndex;
                    SET numEndIndex = numStartIndex;

                    WHILE (udf_FirstNumberPos(SUBSTRING(instring, numEndIndex, 1)) = 1) DO
                        SET numEndIndex = numEndIndex + 1;
                    END WHILE;

                    SET numEndIndex = numEndIndex - 1;

                    SET padLength = numberLength - (numEndIndex + 1 - numStartIndex);

                    IF padLength < 0 THEN
                        SET padLength = 0;
                    END IF;

                    SET sortString = INSERT(sortString, numStartIndex + totalPadLength, 0, REPEAT('0', padLength));

                    SET totalPadLength = totalPadLength + padLength;
                    SET numStartIndex = udf_FirstNumberPos(RIGHT(instring, LENGTH(instring) - numEndIndex));
                END WHILE;

                RETURN sortString;
            END
            ;;
            {code}
            rspadim roberto spadim made changes -
            Description Hi guys, could be nice a natural sorting inside mariadb
            today some guys use SQL procedures/functions to execute this cpu intensive task
            php released a nice function to do this job, maybe we could port part of it and implement in udf function, and release as a default udf function?

            functions:
            1) natural sort, used in ORDER BY / GROUP BY
            2) natural sort compare, could be used as an operator, like the "SOUNDS LIKE" operator, in other words, the function that return a canonical form of the string could be used to compare, something that could be rewrite "field NATURAL LIKE value" to "natual(field)=natural(value)"

            i didn't found (2) in internet, but it's used in php, and the (1) should use it in some place to order/group correctly
            example of (2): http://www.php.net/manual/en/function.strnatcmp.php
            --------------


            1)
            Here a example in STORED PROCEDURE/FUNCTIONS for ORDER BY, but not exaust tested:
            source: http://stackoverflow.com/questions/153633/natural-sort-in-mysql
            {code}
            DROP FUNCTION IF EXISTS `udf_FirstNumberPos`;
            DELIMITER ;;
            CREATE FUNCTION `udf_FirstNumberPos` (`instring` varchar(4000))
            RETURNS int
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE position int;
                DECLARE tmp_position int;
                SET position = 5000;
                SET tmp_position = LOCATE('0', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('1', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('2', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('3', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('4', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('5', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('6', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('7', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('8', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('9', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;

                IF (position = 5000) THEN RETURN 0; END IF;
                RETURN position;
            END
            ;;

            DROP FUNCTION IF EXISTS `udf_NaturalSortFormat`;
            DELIMITER ;;
            CREATE FUNCTION `udf_NaturalSortFormat` (`instring` varchar(4000), `numberLength` int, `sameOrderChars` char(50))
            RETURNS varchar(4000)
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE sortString varchar(4000);
                DECLARE numStartIndex int;
                DECLARE numEndIndex int;
                DECLARE padLength int;
                DECLARE totalPadLength int;
                DECLARE i int;
                DECLARE sameOrderCharsLen int;

                SET totalPadLength = 0;
                SET instring = TRIM(instring);
                SET sortString = instring;
                SET numStartIndex = udf_FirstNumberPos(instring);
                SET numEndIndex = 0;
                SET i = 1;
                SET sameOrderCharsLen = LENGTH(sameOrderChars);

                WHILE (i <= sameOrderCharsLen) DO
                    SET sortString = REPLACE(sortString, SUBSTRING(sameOrderChars, i, 1), ' ');
                    SET i = i + 1;
                END WHILE;

                WHILE (numStartIndex <> 0) DO
                    SET numStartIndex = numStartIndex + numEndIndex;
                    SET numEndIndex = numStartIndex;

                    WHILE (udf_FirstNumberPos(SUBSTRING(instring, numEndIndex, 1)) = 1) DO
                        SET numEndIndex = numEndIndex + 1;
                    END WHILE;

                    SET numEndIndex = numEndIndex - 1;

                    SET padLength = numberLength - (numEndIndex + 1 - numStartIndex);

                    IF padLength < 0 THEN
                        SET padLength = 0;
                    END IF;

                    SET sortString = INSERT(sortString, numStartIndex + totalPadLength, 0, REPEAT('0', padLength));

                    SET totalPadLength = totalPadLength + padLength;
                    SET numStartIndex = udf_FirstNumberPos(RIGHT(instring, LENGTH(instring) - numEndIndex));
                END WHILE;

                RETURN sortString;
            END
            ;;
            {code}
            Hi guys, could be nice a natural sorting inside mariadb
            today some guys use SQL procedures/functions to execute this cpu intensive task
            php released a nice function to do this job, maybe we could port part of it and implement in udf function, and release as a default udf function?

            functions:
            1) natural sort, used in ORDER BY / GROUP BY
            2) natural sort compare, could be used as an operator, like the "SOUNDS LIKE" operator, in other words, the function that return a canonical form of the string could be used to compare, something that could be rewrite "field NATURAL LIKE value" to "natual(field)=natural(value)"

            i didn't found (2) in internet, but it's used in php, and the (1) should use it in some place to order/group correctly
            --------------
            example of (2):
            http://www.php.net/manual/en/function.strnatcmp.php
            https://github.com/php/php-src/blob/master/ext/standard/strnatcmp.c
            --------------


            example of (1)
            Here a example in STORED PROCEDURE/FUNCTIONS for ORDER BY, but not exaust tested:
            source: http://stackoverflow.com/questions/153633/natural-sort-in-mysql
            {code}
            DROP FUNCTION IF EXISTS `udf_FirstNumberPos`;
            DELIMITER ;;
            CREATE FUNCTION `udf_FirstNumberPos` (`instring` varchar(4000))
            RETURNS int
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE position int;
                DECLARE tmp_position int;
                SET position = 5000;
                SET tmp_position = LOCATE('0', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('1', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('2', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('3', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('4', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('5', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('6', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('7', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('8', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
                SET tmp_position = LOCATE('9', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;

                IF (position = 5000) THEN RETURN 0; END IF;
                RETURN position;
            END
            ;;

            DROP FUNCTION IF EXISTS `udf_NaturalSortFormat`;
            DELIMITER ;;
            CREATE FUNCTION `udf_NaturalSortFormat` (`instring` varchar(4000), `numberLength` int, `sameOrderChars` char(50))
            RETURNS varchar(4000)
            LANGUAGE SQL
            DETERMINISTIC
            NO SQL
            SQL SECURITY INVOKER
            BEGIN
                DECLARE sortString varchar(4000);
                DECLARE numStartIndex int;
                DECLARE numEndIndex int;
                DECLARE padLength int;
                DECLARE totalPadLength int;
                DECLARE i int;
                DECLARE sameOrderCharsLen int;

                SET totalPadLength = 0;
                SET instring = TRIM(instring);
                SET sortString = instring;
                SET numStartIndex = udf_FirstNumberPos(instring);
                SET numEndIndex = 0;
                SET i = 1;
                SET sameOrderCharsLen = LENGTH(sameOrderChars);

                WHILE (i <= sameOrderCharsLen) DO
                    SET sortString = REPLACE(sortString, SUBSTRING(sameOrderChars, i, 1), ' ');
                    SET i = i + 1;
                END WHILE;

                WHILE (numStartIndex <> 0) DO
                    SET numStartIndex = numStartIndex + numEndIndex;
                    SET numEndIndex = numStartIndex;

                    WHILE (udf_FirstNumberPos(SUBSTRING(instring, numEndIndex, 1)) = 1) DO
                        SET numEndIndex = numEndIndex + 1;
                    END WHILE;

                    SET numEndIndex = numEndIndex - 1;

                    SET padLength = numberLength - (numEndIndex + 1 - numStartIndex);

                    IF padLength < 0 THEN
                        SET padLength = 0;
                    END IF;

                    SET sortString = INSERT(sortString, numStartIndex + totalPadLength, 0, REPEAT('0', padLength));

                    SET totalPadLength = totalPadLength + padLength;
                    SET numStartIndex = udf_FirstNumberPos(RIGHT(instring, LENGTH(instring) - numEndIndex));
                END WHILE;

                RETURN sortString;
            END
            ;;
            {code}
            serg Sergei Golubchik made changes -
            serg Sergei Golubchik made changes -
            Labels upstream
            rspadim roberto spadim made changes -
            Attachment mariadb_nat_comp.c [ 22501 ]
            serg Sergei Golubchik made changes -
            Workflow defaullt [ 27800 ] MariaDB v2 [ 46652 ]
            ratzpo Rasmus Johansson (Inactive) made changes -
            Workflow MariaDB v2 [ 46652 ] MariaDB v3 [ 61595 ]
            serg Sergei Golubchik made changes -
            Priority Trivial [ 5 ] Major [ 3 ]
            serg Sergei Golubchik made changes -
            Summary UDF - Native natural sorting / natural compare A function for native natural sorting / natural compare
            ralf.gebhardt Ralf Gebhardt made changes -
            Labels upstream
            serg Sergei Golubchik made changes -
            Fix Version/s 10.7 [ 24805 ]
            serg Sergei Golubchik made changes -
            Assignee Oleksandr Byelkin [ sanja ]
            ralf.gebhardt Ralf Gebhardt made changes -
            Priority Major [ 3 ] Critical [ 2 ]
            ralf.gebhardt Ralf Gebhardt made changes -
            Due Date 2021-09-14
            sanja Oleksandr Byelkin made changes -
            Assignee Oleksandr Byelkin [ sanja ] Vladislav Vaintroub [ wlad ]
            bar Alexander Barkov made changes -
            Attachment num.01.diff [ 58407 ]
            bar Alexander Barkov made changes -
            Attachment num.01.diff [ 58407 ]
            bar Alexander Barkov made changes -
            Attachment num.01.diff [ 58408 ]
            wlad Vladislav Vaintroub made changes -
            serg Sergei Golubchik made changes -
            Status Open [ 1 ] In Progress [ 3 ]
            wlad Vladislav Vaintroub made changes -
            Assignee Vladislav Vaintroub [ wlad ] Sergei Golubchik [ serg ]
            Status In Progress [ 3 ] In Review [ 10002 ]
            serg Sergei Golubchik made changes -
            Assignee Sergei Golubchik [ serg ] Vladislav Vaintroub [ wlad ]
            Status In Review [ 10002 ] Stalled [ 10000 ]
            wlad Vladislav Vaintroub made changes -
            Status Stalled [ 10000 ] In Progress [ 3 ]
            wlad Vladislav Vaintroub made changes -
            Assignee Vladislav Vaintroub [ wlad ] Sergei Golubchik [ serg ]
            Status In Progress [ 3 ] In Review [ 10002 ]
            serg Sergei Golubchik made changes -
            Assignee Sergei Golubchik [ serg ] Vladislav Vaintroub [ wlad ]
            Status In Review [ 10002 ] Stalled [ 10000 ]
            wlad Vladislav Vaintroub made changes -
            Assignee Vladislav Vaintroub [ wlad ] Elena Stepanova [ elenst ]
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            Assignee Elena Stepanova [ elenst ] Anel Husakovic [ anel ]
            ralf.gebhardt Ralf Gebhardt made changes -
            Due Date 2021-09-14
            anel Anel Husakovic made changes -
            Component/s Server [ 13907 ]
            Fix Version/s 10.7.0 [ 26072 ]
            Fix Version/s 10.7 [ 24805 ]
            Resolution Fixed [ 1 ]
            Status Stalled [ 10000 ] Closed [ 6 ]
            anel Anel Husakovic made changes -
            Assignee Anel Husakovic [ anel ] Vladislav Vaintroub [ wlad ]
            Resolution Fixed [ 1 ]
            Status Closed [ 6 ] Stalled [ 10000 ]
            ralf.gebhardt Ralf Gebhardt made changes -
            Fix Version/s 10.7 [ 24805 ]
            Fix Version/s 10.7.0 [ 26072 ]
            serg Sergei Golubchik made changes -
            Assignee Vladislav Vaintroub [ wlad ] Elena Stepanova [ elenst ]
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            Assignee Elena Stepanova [ elenst ] Sergei Golubchik [ serg ]
            serg Sergei Golubchik made changes -
            Assignee Sergei Golubchik [ serg ] Vladislav Vaintroub [ wlad ]
            wlad Vladislav Vaintroub made changes -
            Fix Version/s 10.7.1 [ 26120 ]
            Fix Version/s 10.7 [ 24805 ]
            Resolution Fixed [ 1 ]
            Status Stalled [ 10000 ] Closed [ 6 ]
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 61595 ] MariaDB v4 [ 132162 ]
            ralf.gebhardt Ralf Gebhardt made changes -
            Labels Preview_10.7

            People

              wlad Vladislav Vaintroub
              rspadim roberto spadim
              Votes:
              2 Vote for this issue
              Watchers:
              13 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.