From 1521c5c768aee3a14e7375d70331da360d86d32b Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 18 Feb 2019 13:44:54 +0100 Subject: pdo_oci: backport PDOStatement::getColumnMeta from 7.4 rebuild using libicu62 --- php-7.2.16-pdooci.patch | 279 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 php-7.2.16-pdooci.patch (limited to 'php-7.2.16-pdooci.patch') diff --git a/php-7.2.16-pdooci.patch b/php-7.2.16-pdooci.patch new file mode 100644 index 0000000..3e55119 --- /dev/null +++ b/php-7.2.16-pdooci.patch @@ -0,0 +1,279 @@ +diff --git a/ext/pdo_oci/oci_statement.c b/ext/pdo_oci/oci_statement.c +index 44efa0de0a..79733c2c57 100644 +--- a/ext/pdo_oci/oci_statement.c ++++ b/ext/pdo_oci/oci_statement.c +@@ -2,7 +2,7 @@ + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ +- | Copyright (c) 1997-2018 The PHP Group | ++ | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | +@@ -527,7 +525,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */ + pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data; + OCIParam *param = NULL; + text *colname; +- ub2 dtype, data_size, scale, precis; ++ ub2 dtype, data_size, precis; + ub4 namelen; + struct pdo_column_data *col = &stmt->columns[colno]; + zend_bool dyn = FALSE; +@@ -543,10 +541,6 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */ + STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_DATA_SIZE", + (param, OCI_DTYPE_PARAM, &data_size, 0, OCI_ATTR_DATA_SIZE, S->err)); + +- /* scale ? */ +- STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_SCALE", +- (param, OCI_DTYPE_PARAM, &scale, 0, OCI_ATTR_SCALE, S->err)); +- + /* precision ? */ + STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_PRECISION", + (param, OCI_DTYPE_PARAM, &precis, 0, OCI_ATTR_PRECISION, S->err)); +@@ -555,7 +549,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */ + STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_NAME", + (param, OCI_DTYPE_PARAM, &colname, &namelen, OCI_ATTR_NAME, S->err)); + +- col->precision = scale; ++ col->precision = precis; + col->maxlen = data_size; + col->name = zend_string_init((char *)colname, namelen, 0); + +@@ -600,7 +594,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */ + S->cols[colno].datalen = 1024; + #endif + } else if (dtype == SQLT_BIN) { +- S->cols[colno].datalen = (ub4) col->maxlen * 2; // raw characters to hex digits ++ S->cols[colno].datalen = (ub4) col->maxlen * 2; /* raw characters to hex digits */ + } else { + S->cols[colno].datalen = (ub4) (col->maxlen * S->H->max_char_width); + } +@@ -719,7 +713,7 @@ static int oci_blob_seek(php_stream *stream, zend_off_t offset, int whence, zend + } + } + +-static php_stream_ops oci_blob_stream_ops = { ++static const php_stream_ops oci_blob_stream_ops = { + oci_blob_write, + oci_blob_read, + oci_blob_close, +@@ -795,20 +789,207 @@ static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_t *len + } + } /* }}} */ + +-struct pdo_stmt_methods oci_stmt_methods = { ++ ++static int oci_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value) /* {{{ */ ++{ ++ pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data; ++ OCIParam *param = NULL; ++ ub2 dtype, precis; ++ sb1 scale; ++ zval flags; ++ ub1 isnull, charset_form; ++ if (!S->stmt) { ++ return FAILURE; ++ } ++ if (colno >= stmt->column_count) { ++ /* error invalid column */ ++ return FAILURE; ++ } ++ ++ array_init(return_value); ++ array_init(&flags); ++ ++ /* describe the column */ ++ STMT_CALL(OCIParamGet, (S->stmt, OCI_HTYPE_STMT, S->err, (dvoid*)¶m, colno+1)); ++ ++ /* column data type */ ++ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_DATA_TYPE", ++ (param, OCI_DTYPE_PARAM, &dtype, 0, OCI_ATTR_DATA_TYPE, S->err)); ++ ++ /* column precision */ ++ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_PRECISION", ++ (param, OCI_DTYPE_PARAM, &precis, 0, OCI_ATTR_PRECISION, S->err)); ++ ++ /* column scale */ ++ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_SCALE", ++ (param, OCI_DTYPE_PARAM, &scale, 0, OCI_ATTR_SCALE, S->err)); ++ ++ /* string column charset form */ ++ if (dtype == SQLT_CHR || dtype == SQLT_VCS || dtype == SQLT_AFC || dtype == SQLT_CLOB) { ++ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_CHARSET_FORM", ++ (param, OCI_DTYPE_PARAM, &charset_form, 0, OCI_ATTR_CHARSET_FORM, S->err)); ++ } ++ ++ ++ if (dtype) { ++ /* if there is a declared type */ ++ switch (dtype) { ++#ifdef SQLT_TIMESTAMP ++ case SQLT_TIMESTAMP: ++ add_assoc_string(return_value, "oci:decl_type", "TIMESTAMP"); ++ add_assoc_string(return_value, "native_type", "TIMESTAMP"); ++ break; ++#endif ++#ifdef SQLT_TIMESTAMP_TZ ++ case SQLT_TIMESTAMP_TZ: ++ add_assoc_string(return_value, "oci:decl_type", "TIMESTAMP WITH TIMEZONE"); ++ add_assoc_string(return_value, "native_type", "TIMESTAMP WITH TIMEZONE"); ++ break; ++#endif ++#ifdef SQLT_TIMESTAMP_LTZ ++ case SQLT_TIMESTAMP_LTZ: ++ add_assoc_string(return_value, "oci:decl_type", "TIMESTAMP WITH LOCAL TIMEZONE"); ++ add_assoc_string(return_value, "native_type", "TIMESTAMP WITH LOCAL TIMEZONE"); ++ break; ++#endif ++#ifdef SQLT_INTERVAL_YM ++ case SQLT_INTERVAL_YM: ++ add_assoc_string(return_value, "oci:decl_type", "INTERVAL YEAR TO MONTH"); ++ add_assoc_string(return_value, "native_type", "INTERVAL YEAR TO MONTH"); ++ break; ++#endif ++#ifdef SQLT_INTERVAL_DS ++ case SQLT_INTERVAL_DS: ++ add_assoc_string(return_value, "oci:decl_type", "INTERVAL DAY TO SECOND"); ++ add_assoc_string(return_value, "native_type", "INTERVAL DAY TO SECOND"); ++ break; ++#endif ++ case SQLT_DAT: ++ add_assoc_string(return_value, "oci:decl_type", "DATE"); ++ add_assoc_string(return_value, "native_type", "DATE"); ++ break; ++ case SQLT_FLT : ++ case SQLT_NUM: ++ /* if the precision is nonzero and scale is -127 then it is a FLOAT */ ++ if (scale == -127 && precis != 0) { ++ add_assoc_string(return_value, "oci:decl_type", "FLOAT"); ++ add_assoc_string(return_value, "native_type", "FLOAT"); ++ } else { ++ add_assoc_string(return_value, "oci:decl_type", "NUMBER"); ++ add_assoc_string(return_value, "native_type", "NUMBER"); ++ } ++ break; ++ case SQLT_LNG: ++ add_assoc_string(return_value, "oci:decl_type", "LONG"); ++ add_assoc_string(return_value, "native_type", "LONG"); ++ break; ++ case SQLT_BIN: ++ add_assoc_string(return_value, "oci:decl_type", "RAW"); ++ add_assoc_string(return_value, "native_type", "RAW"); ++ break; ++ case SQLT_LBI: ++ add_assoc_string(return_value, "oci:decl_type", "LONG RAW"); ++ add_assoc_string(return_value, "native_type", "LONG RAW"); ++ break; ++ case SQLT_CHR: ++ case SQLT_VCS: ++ if (charset_form == SQLCS_NCHAR) { ++ add_assoc_string(return_value, "oci:decl_type", "NVARCHAR2"); ++ add_assoc_string(return_value, "native_type", "NVARCHAR2"); ++ } else { ++ add_assoc_string(return_value, "oci:decl_type", "VARCHAR2"); ++ add_assoc_string(return_value, "native_type", "VARCHAR2"); ++ } ++ break; ++ case SQLT_AFC: ++ if (charset_form == SQLCS_NCHAR) { ++ add_assoc_string(return_value, "oci:decl_type", "NCHAR"); ++ add_assoc_string(return_value, "native_type", "NCHAR"); ++ } else { ++ add_assoc_string(return_value, "oci:decl_type", "CHAR"); ++ add_assoc_string(return_value, "native_type", "CHAR"); ++ } ++ break; ++ case SQLT_BLOB: ++ add_assoc_string(return_value, "oci:decl_type", "BLOB"); ++ add_next_index_string(&flags, "blob"); ++ add_assoc_string(return_value, "native_type", "BLOB"); ++ break; ++ case SQLT_CLOB: ++ if (charset_form == SQLCS_NCHAR) { ++ add_assoc_string(return_value, "oci:decl_type", "NCLOB"); ++ add_assoc_string(return_value, "native_type", "NCLOB"); ++ } else { ++ add_assoc_string(return_value, "oci:decl_type", "CLOB"); ++ add_assoc_string(return_value, "native_type", "CLOB"); ++ } ++ add_next_index_string(&flags, "blob"); ++ break; ++ case SQLT_BFILE: ++ add_assoc_string(return_value, "oci:decl_type", "BFILE"); ++ add_next_index_string(&flags, "blob"); ++ add_assoc_string(return_value, "native_type", "BFILE"); ++ break; ++ case SQLT_RDD: ++ add_assoc_string(return_value, "oci:decl_type", "ROWID"); ++ add_assoc_string(return_value, "native_type", "ROWID"); ++ break; ++ case SQLT_BFLOAT: ++ case SQLT_IBFLOAT: ++ add_assoc_string(return_value, "oci:decl_type", "BINARY_FLOAT"); ++ add_assoc_string(return_value, "native_type", "BINARY_FLOAT"); ++ break; ++ case SQLT_BDOUBLE: ++ case SQLT_IBDOUBLE: ++ add_assoc_string(return_value, "oci:decl_type", "BINARY_DOUBLE"); ++ add_assoc_string(return_value, "native_type", "BINARY_DOUBLE"); ++ break; ++ default: ++ add_assoc_long(return_value, "oci:decl_type", dtype); ++ add_assoc_string(return_value, "native_type", "UNKNOWN"); ++ } ++ } else { ++ /* if the column is NULL */ ++ add_assoc_long(return_value, "oci:decl_type", 0); ++ add_assoc_string(return_value, "native_type", "NULL"); ++ } ++ ++ /* column can be null */ ++ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_IS_NULL", ++ (param, OCI_DTYPE_PARAM, &isnull, 0, OCI_ATTR_IS_NULL, S->err)); ++ ++ if (isnull) { ++ add_next_index_string(&flags, "nullable"); ++ } else { ++ add_next_index_string(&flags, "not_null"); ++ } ++ ++ /* PDO type */ ++ switch (dtype) { ++ case SQLT_BFILE: ++ case SQLT_BLOB: ++ case SQLT_CLOB: ++ add_assoc_long(return_value, "pdo_type", PDO_PARAM_LOB); ++ break; ++ default: ++ add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR); ++ } ++ ++ add_assoc_long(return_value, "scale", scale); ++ add_assoc_zval(return_value, "flags", &flags); ++ ++ OCIDescriptorFree(param, OCI_DTYPE_PARAM); ++ return SUCCESS; ++} /* }}} */ ++ ++struct pdo_stmt_methods oci_stmt_methods = { + oci_stmt_dtor, + oci_stmt_execute, + oci_stmt_fetch, + oci_stmt_describe, + oci_stmt_get_col, +- oci_stmt_param_hook ++ oci_stmt_param_hook, ++ NULL, /* set_attr */ ++ NULL, /* get_attr */ ++ oci_stmt_col_meta + }; +- +-/* +- * Local variables: +- * tab-width: 4 +- * c-basic-offset: 4 +- * End: +- * vim600: noet sw=4 ts=4 fdm=marker +- * vim<600: noet sw=4 ts=4 +- */ -- cgit