Search code examples
javascriptmysqlsqlnode.jsmysql2

How does MySQL deal with plus sign in phone number?


I'm working on an app with MySQL database. I'm getting odd behavior with phone numbers that start with a plus sign e.g. +13215555555

The issue, of course, is that I'm using Google Firebase phone authentication for part of the project. Firebase stores phone numbers as +13215555555 (Country code plus phone number)

I'm easily able to push phone numbers with the + format to the database. What I'm unable to do is use a phone number with a plus sign to query the record.

Sample data:

id      user       phone            email 
1       Abe        +13215555555     abe@fake_email.com 
2       Beth       13215555556      [email protected] 
3       Charl      321-555-5557     [email protected] 

Data in:

const sql = " INSERT INTO `users` ( `user`, `phone`, `user_email` ) +
            " VALUES (?,?,?)";  
const dataReturn = await promisePool.execute(sql, dataArray); 

Any of the phone number formats above works great for inserting data into the database. The plus sign +3215555555 works great. And what I see above is what is observed in Adminer. The phone data field is structured as varchar(20).

Data Out:

What I'm unable to do is grab a user record via the phone number when the phone number starts with a plus sign.

const sql_ui = "SELECT * FROM `users` WHERE `phone` = ? "
const data_return_ui = await promisePool.execute(sql_ui, [ph_string_value]) 

In this case, I'm unable to get any user result with the value of ph_string_value = "+13215555555" Do note, when I manually create a SQL statement

SELECT * FROM `users` WHERE `phone` = +13215555555

I get exactly the expected results when tested in Adminer. What doesn't work is the query from my program with the ph_string_value with a leading plus sign in the contents. I get a null response to the data set. I'd like to understand the cause of this issue.

Why do queries using a phone number that start with a plus sign fail?

(edit)
Note: When I do a console.log("ph_string_value: ", ph_string_value) immediately before the query, I do see "+13215555555" as expected..

I'm trying to build a simple reproducible issue, using just SQL...

CREATE TABLE `users_SO` (
    `id` int NOT NULL AUTO_INCREMENT,
    `user` varchar(30) NOT NULL,
    `phone` varchar(20) NOT NULL,
    `email` varchar(40) DEFAULT NULL,
    PRIMARY KEY (`phone`),
    KEY `id` (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

INSERT INTO `users_SO` ( `user`, `phone`, `email`) VALUES 
      ("Abe", "+13215555555", "abe@fake_email.com"),
      ("Beth", "13215555556", "[email protected]"),
      ("Charl", "321-555-5557", "[email protected]")

SET @ph_string_value = "+13215555555" ;
# Verify the variable holds what we think it holds...
SELECT @ph_string_value as ph_string_value;
SELECT * FROM `users_SO` WHERE `phone` = @ph_string_value;

SET @ph_string_value2 = "13215555556"
# Verify the variable holds what we think it holds...
SELECT @ph_string_value2 as ph_string_value2;
SELECT * FROM `users_SO` WHERE `phone` = @ph_string_value2

Initially odd results at Adminer SQL tester. Not sure I understand how to use https://dbfiddle.uk/?rdbms=mysql_8.0 Their help screen isn't much help.

Update, now the SQl when tested in Adminer works great. No errors. When tested over at db-fiddle dot com/ I get an odd error:

Query Error: Error: ER_CANT_AGGREGATE_2COLLATIONS: Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='

Question: When setting up the database, which collation setup seems the most robust?


Solution

  • OOps. At one point I do pass the phone number in a fetch call to an internal API routing.

    async function get_user_info(ph_num) {
        try {
            let response = await fetch(
                ENV_OBJ.WEB_URL +
                    "/api/mysql_connect?getType=user_info&ph="+ph_num  <--  Fail
            );
            let user = await response.json();
            if (response.ok) {
                console.log("user: ", user)
                return user;
            }
        } catch (err) {
            console.log("error from get_user_info(): ", err);
        }
    }
    

    And yes, and on arrival at the API server, the plus sign has disappeared from the intended phone string value.

    The fix?

    ENV_OBJ.WEB_URL + "/api/mysql_connect?getType=user_info&ph="+encodeURIComponent(ph_num)