]> granicus.if.org Git - php/commitdiff
PDO MySQL: Use mysqlnd column names
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 16 Dec 2020 14:17:13 +0000 (15:17 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 16 Dec 2020 14:17:13 +0000 (15:17 +0100)
mysqlnd already creates interned zend_strings for us, so let's
make use of them.

This also required updating the PDO case changing code to work
with potentially shared strings. For the lowercasing, use the
optimized zend_string_tolower() implementation.

Zend/zend_string.h
ext/pdo/pdo_stmt.c
ext/pdo_mysql/mysql_statement.c

index 557042b3e31c757613603e9ff8bf1b65d75c2974..96f1a6f4a072dc3e466ef04dc33cc48302c9f431 100644 (file)
@@ -195,6 +195,19 @@ static zend_always_inline zend_string *zend_string_dup(zend_string *s, bool pers
        }
 }
 
+static zend_always_inline zend_string *zend_string_separate(zend_string *s, bool persistent)
+{
+       if (ZSTR_IS_INTERNED(s) || GC_REFCOUNT(s) > 1) {
+               if (!ZSTR_IS_INTERNED(s)) {
+                       GC_DELREF(s);
+               }
+               return zend_string_init(ZSTR_VAL(s), ZSTR_LEN(s), persistent);
+       }
+
+       zend_string_forget_hash_val(s);
+       return s;
+}
+
 static zend_always_inline zend_string *zend_string_realloc(zend_string *s, size_t len, bool persistent)
 {
        zend_string *ret;
index a172ae27c54da240fb6b0feb706b9e1a99c7f29e..80b50605b9230a35945ab617d06b3b1736ead9b7 100644 (file)
@@ -138,23 +138,22 @@ int pdo_stmt_describe_columns(pdo_stmt_t *stmt) /* {{{ */
 
                /* if we are applying case conversions on column names, do so now */
                if (stmt->dbh->native_case != stmt->dbh->desired_case && stmt->dbh->desired_case != PDO_CASE_NATURAL) {
-                       char *s = ZSTR_VAL(stmt->columns[col].name);
-
+                       zend_string *orig_name = stmt->columns[col].name;
                        switch (stmt->dbh->desired_case) {
-                               case PDO_CASE_UPPER:
-                                       while (*s != '\0') {
-                                               *s = toupper(*s);
-                                               s++;
-                                       }
-                                       break;
                                case PDO_CASE_LOWER:
+                                       stmt->columns[col].name = zend_string_tolower(orig_name);
+                                       zend_string_release(orig_name);
+                                       break;
+                               case PDO_CASE_UPPER: {
+                                       stmt->columns[col].name = zend_string_separate(orig_name, 0);
+                                       char *s = ZSTR_VAL(stmt->columns[col].name);
                                        while (*s != '\0') {
-                                               *s = tolower(*s);
+                                               *s = toupper(*s);
                                                s++;
                                        }
                                        break;
-                               default:
-                                       ;
+                               }
+                               EMPTY_SWITCH_DEFAULT_CASE()
                        }
                }
 
index 871b7f9c7c854c76ac16c4346d6353a9d9c4c44c..180a4616ef8281b5bacec8fb4f5f15cc547a24ce 100644 (file)
@@ -619,7 +619,11 @@ static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
                if (S->H->fetch_table_names) {
                        cols[i].name = strpprintf(0, "%s.%s", S->fields[i].table, S->fields[i].name);
                } else {
+#ifdef PDO_USE_MYSQLND
+                       cols[i].name = zend_string_copy(S->fields[i].sname);
+#else
                        cols[i].name = zend_string_init(S->fields[i].name, S->fields[i].name_length, 0);
+#endif
                }
 
                cols[i].precision = S->fields[i].decimals;