@@ -1660,20 +1660,21 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
16601660 uint32_t arg1_arg_num = mode_arg_num + 1 ;
16611661 uint32_t constructor_arg_num = mode_arg_num + 2 ;
16621662 uint32_t total_num_args = mode_arg_num + variadic_num_args ;
1663-
1664- pdo_stmt_free_default_fetch_mode (stmt );
1665-
1666- stmt -> default_fetch_type = stmt -> dbh -> default_fetch_type ;
1663+ zend_long fetch_type = mode & ~PDO_FETCH_FLAGS ;
1664+ zend_long fetch_column = 0 ;
1665+ zend_class_entry * fetch_class = NULL ;
1666+ HashTable * fetch_ctor_args = NULL ;
1667+ zend_object * fetch_into = NULL ;
1668+ zend_object * old_into = NULL ;
1669+ HashTable * old_ctor_args = NULL ;
16671670
16681671 flags = mode & PDO_FETCH_FLAGS ;
16691672
1670- if (!pdo_verify_fetch_mode (stmt -> default_fetch_type , mode , mode_arg_num , false)) {
1673+ if (!pdo_verify_fetch_mode (stmt -> dbh -> default_fetch_type , mode , mode_arg_num , false)) {
16711674 return false;
16721675 }
16731676
1674- bool use_default = (mode & ~PDO_FETCH_FLAGS ) == PDO_FETCH_USE_DEFAULT ;
1675-
1676- switch (mode & ~PDO_FETCH_FLAGS ) {
1677+ switch (fetch_type ) {
16771678 case PDO_FETCH_USE_DEFAULT :
16781679 case PDO_FETCH_LAZY :
16791680 case PDO_FETCH_ASSOC :
@@ -1708,7 +1709,7 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
17081709 zend_argument_value_error (arg1_arg_num , "must be greater than or equal to 0" );
17091710 return false;
17101711 }
1711- stmt -> fetch . column = Z_LVAL (args [0 ]);
1712+ fetch_column = Z_LVAL (args [0 ]);
17121713 break ;
17131714
17141715 case PDO_FETCH_CLASS : {
@@ -1759,11 +1760,10 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
17591760 zend_argument_value_error (3 , "must be empty when class provided in argument #2 ($class) does not have a constructor" );
17601761 return false;
17611762 }
1762- GC_TRY_ADDREF (Z_ARRVAL (args [1 ]));
1763- stmt -> fetch .cls .ctor_args = Z_ARRVAL (args [1 ]);
1763+ fetch_ctor_args = Z_ARRVAL (args [1 ]);
17641764 }
17651765 }
1766- stmt -> fetch . cls . ce = cep ;
1766+ fetch_class = cep ;
17671767 }
17681768 break ;
17691769 }
@@ -1780,18 +1780,52 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
17801780 return false;
17811781 }
17821782
1783- GC_ADDREF (Z_OBJ (args [0 ]));
1784- stmt -> fetch .into = Z_OBJ (args [0 ]);
1783+ fetch_into = Z_OBJ (args [0 ]);
17851784 break ;
17861785 default :
17871786 zend_argument_value_error (mode_arg_num , "must be one of the PDO::FETCH_* constants" );
17881787 return false;
17891788 }
17901789
1791- if (!use_default ) {
1790+ if ((stmt -> default_fetch_type & ~PDO_FETCH_FLAGS ) == PDO_FETCH_INTO ) {
1791+ old_into = stmt -> fetch .into ;
1792+ } else if ((stmt -> default_fetch_type & ~PDO_FETCH_FLAGS ) == PDO_FETCH_CLASS ) {
1793+ old_ctor_args = stmt -> fetch .cls .ctor_args ;
1794+ }
1795+ memset (& stmt -> fetch , 0 , sizeof (stmt -> fetch ));
1796+
1797+ switch (fetch_type ) {
1798+ case PDO_FETCH_COLUMN :
1799+ stmt -> fetch .column = fetch_column ;
1800+ break ;
1801+ case PDO_FETCH_CLASS :
1802+ stmt -> fetch .cls .ce = fetch_class ;
1803+ if (fetch_ctor_args ) {
1804+ GC_TRY_ADDREF (fetch_ctor_args );
1805+ stmt -> fetch .cls .ctor_args = fetch_ctor_args ;
1806+ }
1807+ break ;
1808+ case PDO_FETCH_INTO :
1809+ GC_ADDREF (fetch_into );
1810+ stmt -> fetch .into = fetch_into ;
1811+ break ;
1812+ default :
1813+ break ;
1814+ }
1815+
1816+ if (fetch_type == PDO_FETCH_USE_DEFAULT ) {
1817+ stmt -> default_fetch_type = stmt -> dbh -> default_fetch_type ;
1818+ } else {
17921819 stmt -> default_fetch_type = mode ;
17931820 }
17941821
1822+ if (old_into ) {
1823+ OBJ_RELEASE (old_into );
1824+ }
1825+ if (old_ctor_args ) {
1826+ zend_array_release (old_ctor_args );
1827+ }
1828+
17951829 return true;
17961830}
17971831
0 commit comments