Bug #80790 [Com]: PDO ODBC cannot insert BLOB records to Oracle database

From: Date: Tue, 23 Feb 2021 11:49:34 +0000
Subject: Bug #80790 [Com]: PDO ODBC cannot insert BLOB records to Oracle database
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-232346@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80790&edit=1 ID: 80790 Comment by: horvath dot szabolcs at t-systems dot hu Reported by: horvath dot szabolcs at t-systems dot hu Summary: PDO ODBC cannot insert BLOB records to Oracle database Status: Open Type: Bug Package: PDO ODBC Operating System: Red Hat Enterprise Linux Server PHP Version: 7.3.27 Block user comment: N Private report: N New Comment: odbc-100.log (OK) [ODBC][9792][1614079677.410236][SQLConnect.c][3721] Entry: Connection = 0x55e8d43f3990 Server Name = [ORACLETEST][length = 11 (SQL_NTS)] User Name = [eberjegyzek][length = 11 (SQL_NTS)] Authentication = [********][length = 8 (SQL_NTS)] UNICODE Using encoding ASCII 'UTF-8' and UNICODE 'UTF16LE' [ODBC][9792][1614079677.517168][SQLConnect.c][4299] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.518316][SQLAllocHandle.c][540] Entry: Handle Type = 3 Input Handle = 0x55e8d43f3990 [ODBC][9792][1614079677.518526][SQLAllocHandle.c][1085] Exit:[SQL_SUCCESS] Output Handle = 0x55e8d43dc500 [ODBC][9792][1614079677.518650][SQLGetInfo.c][236] Entry: Connection = 0x55e8d43f3990 Info Type = SQL_FETCH_DIRECTION (8) Info Value = 0x7ffcaf54737c Buffer Length = 4 StrLen = (nil) [ODBC][9792][1614079677.518795][SQLSetStmtOption.c][197] Entry: Statement = 0x55e8d43dc500 Option = SQL_ATTR_CURSOR_TYPE Value = 3 [ODBC][9792][1614079677.519281][SQLSetStmtOption.c][477] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.519409][SQLPrepare.c][196] Entry: Statement = 0x55e8d43dc500 SQL = [INSERT INTO HSZ (ID, PDF) VALUES (SEQ_HSZ.NEXTVAL, ?)][length = 53 (SQL_NTS)] [ODBC][9792][1614079677.521374][SQLPrepare.c][377] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.521520][SQLNumParams.c][144] Entry: Statement = 0x55e8d43dc500 Param Count = 0x7f70520024e2 [ODBC][9792][1614079677.521644][SQLNumParams.c][231] Exit:[SQL_SUCCESS] Count = 0x7f70520024e2 -> 1 [ODBC][9792][1614079677.521738][SQLNumResultCols.c][156] Entry: Statement = 0x55e8d43dc500 Column Count = 0x7f70520024e0 [ODBC][9792][1614079677.522371][SQLNumResultCols.c][251] Exit:[SQL_SUCCESS] Count = 0x7f70520024e0 -> 0 [ODBC][9792][1614079677.522502][SQLDescribeParam.c][185] Entry: Statement = 0x55e8d43dc500 Parameter Number = 1 SQL Type = 0x7f7052076010 Param Def = 0x7f7052076018 Scale = 0x7f7052076012 Nullable = 0x7f7052076014 [ODBC][9792][1614079677.522627][SQLDescribeParam.c][338] Exit:[SQL_SUCCESS] SQL Type = 0x7ffcaf546e80 Param Def = 0x7ffcaf546f70 Scale = 0x7ffcaf547060 Nullable = 0x7ffcaf547150 [ODBC][9792][1614079677.522795][SQLBindParameter.c][217] Entry: Statement = 0x55e8d43dc500 Param Number = 1 Param Type = 1 C Type = -2 SQL_C_BINARY SQL Type = -4 SQL_LONGVARBINARY Col Def = 2147483647 Scale = 0 Rgb Value = 0x7f7052070098 Value Max = 0 StrLen Or Ind = 0x7f7052076020 [ODBC][9792][1614079677.522945][SQLBindParameter.c][434] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.523060][SQLFreeStmt.c][144] Entry: Statement = 0x55e8d43dc500 Option = 0 [ODBC][9792][1614079677.523234][SQLFreeStmt.c][266] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.523351][SQLExecute.c][187] Entry: Statement = 0x55e8d43dc500 [ODBC][9792][1614079677.533720][SQLExecute.c][357] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.533925][SQLFreeStmt.c][144] Entry: Statement = 0x55e8d43dc500 Option = 3 [ODBC][9792][1614079677.534414][SQLFreeStmt.c][266] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.534545][SQLNumResultCols.c][156] Entry: Statement = 0x55e8d43dc500 Column Count = 0x7f70520024e0 [ODBC][9792][1614079677.534675][SQLNumResultCols.c][251] Exit:[SQL_SUCCESS] Count = 0x7f70520024e0 -> 0 [ODBC][9792][1614079677.535041][SQLFreeStmt.c][144] Entry: Statement = 0x55e8d43dc500 Option = 1 [ODBC][9792][1614079677.535170][SQLFreeHandle.c][387] Entry: Handle Type = 3 Input Handle = 0x55e8d43dc500 [ODBC][9792][1614079677.535321][SQLFreeHandle.c][490] Exit:[SQL_SUCCESS] [ODBC][9792][1614079677.535448][SQLDisconnect.c][208] Entry: Connection = 0x55e8d43f3990 [ODBC][9792][1614079678.502042][SQLDisconnect.c][379] Exit:[SQL_SUCCESS] [ODBC][9792][1614079678.502154][SQLFreeHandle.c][290] Entry: Handle Type = 2 Input Handle = 0x55e8d43f3990 [ODBC][9792][1614079678.502207][SQLFreeHandle.c][339] Exit:[SQL_SUCCESS] [ODBC][9792][1614079678.502257][SQLFreeHandle.c][220] Entry: Handle Type = 1 Input Handle = 0x55e8d43f3390 odbc-10000.log (OK) [ODBC][9791][1614079733.784531][SQLConnect.c][3721] Entry: Connection = 0x55e8d43d9f50 Server Name = [ORACLETEST][length = 11 (SQL_NTS)] User Name = [eberjegyzek][length = 11 (SQL_NTS)] Authentication = [********][length = 8 (SQL_NTS)] UNICODE Using encoding ASCII 'UTF-8' and UNICODE 'UTF16LE' [ODBC][9791][1614079733.898430][SQLConnect.c][4299] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.899600][SQLAllocHandle.c][540] Entry: Handle Type = 3 Input Handle = 0x55e8d43d9f50 [ODBC][9791][1614079733.899794][SQLAllocHandle.c][1085] Exit:[SQL_SUCCESS] Output Handle = 0x55e8d4412450 [ODBC][9791][1614079733.899930][SQLGetInfo.c][236] Entry: Connection = 0x55e8d43d9f50 Info Type = SQL_FETCH_DIRECTION (8) Info Value = 0x7ffcaf54737c Buffer Length = 4 StrLen = (nil) [ODBC][9791][1614079733.900055][SQLSetStmtOption.c][197] Entry: Statement = 0x55e8d4412450 Option = SQL_ATTR_CURSOR_TYPE Value = 3 [ODBC][9791][1614079733.900171][SQLSetStmtOption.c][477] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.900286][SQLPrepare.c][196] Entry: Statement = 0x55e8d4412450 SQL = [INSERT INTO HSZ (ID, PDF) VALUES (SEQ_HSZ.NEXTVAL, ?)][length = 53 (SQL_NTS)] [ODBC][9791][1614079733.902089][SQLPrepare.c][377] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.902233][SQLNumParams.c][144] Entry: Statement = 0x55e8d4412450 Param Count = 0x7f70520024e2 [ODBC][9791][1614079733.902332][SQLNumParams.c][231] Exit:[SQL_SUCCESS] Count = 0x7f70520024e2 -> 1 [ODBC][9791][1614079733.902445][SQLNumResultCols.c][156] Entry: Statement = 0x55e8d4412450 Column Count = 0x7f70520024e0 [ODBC][9791][1614079733.902637][SQLNumResultCols.c][251] Exit:[SQL_SUCCESS] Count = 0x7f70520024e0 -> 0 [ODBC][9791][1614079733.902809][SQLDescribeParam.c][185] Entry: Statement = 0x55e8d4412450 Parameter Number = 1 SQL Type = 0x7f7052076010 Param Def = 0x7f7052076018 Scale = 0x7f7052076012 Nullable = 0x7f7052076014 [ODBC][9791][1614079733.902966][SQLDescribeParam.c][338] Exit:[SQL_SUCCESS] SQL Type = 0x7ffcaf546e80 Param Def = 0x7ffcaf546f70 Scale = 0x7ffcaf547060 Nullable = 0x7ffcaf547150 [ODBC][9791][1614079733.903108][SQLBindParameter.c][217] Entry: Statement = 0x55e8d4412450 Param Number = 1 Param Type = 1 C Type = -2 SQL_C_BINARY SQL Type = -4 SQL_LONGVARBINARY Col Def = 2147483647 Scale = 0 Rgb Value = 0x7f7052083018 Value Max = 0 StrLen Or Ind = 0x7f7052076020 [ODBC][9791][1614079733.903229][SQLBindParameter.c][434] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.903342][SQLFreeStmt.c][144] Entry: Statement = 0x55e8d4412450 Option = 0 [ODBC][9791][1614079733.903458][SQLFreeStmt.c][266] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.903552][SQLExecute.c][187] Entry: Statement = 0x55e8d4412450 [ODBC][9791][1614079733.913946][SQLExecute.c][357] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.914025][SQLFreeStmt.c][144] Entry: Statement = 0x55e8d4412450 Option = 3 [ODBC][9791][1614079733.914086][SQLFreeStmt.c][266] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.914135][SQLNumResultCols.c][156] Entry: Statement = 0x55e8d4412450 Column Count = 0x7f70520024e0 [ODBC][9791][1614079733.914188][SQLNumResultCols.c][251] Exit:[SQL_SUCCESS] Count = 0x7f70520024e0 -> 0 [ODBC][9791][1614079733.914322][SQLFreeStmt.c][144] Entry: Statement = 0x55e8d4412450 Option = 1 [ODBC][9791][1614079733.914377][SQLFreeHandle.c][387] Entry: Handle Type = 3 Input Handle = 0x55e8d4412450 [ODBC][9791][1614079733.914448][SQLFreeHandle.c][490] Exit:[SQL_SUCCESS] [ODBC][9791][1614079733.914507][SQLDisconnect.c][208] Entry: Connection = 0x55e8d43d9f50 [ODBC][9791][1614079734.880471][SQLDisconnect.c][379] Exit:[SQL_SUCCESS] [ODBC][9791][1614079734.880686][SQLFreeHandle.c][290] Entry: Handle Type = 2 Input Handle = 0x55e8d43d9f50 [ODBC][9791][1614079734.880859][SQLFreeHandle.c][339] Exit:[SQL_SUCCESS] [ODBC][9791][1614079734.881011][SQLFreeHandle.c][220] Entry: Handle Type = 1 Input Handle = 0x55e8d43d9950 Previous Comments: ------------------------------------------------------------------------ [2021-02-23 11:48:18] horvath dot szabolcs at t-systems dot hu Description: ------------ Hi, We're using PHP 7.3.20 from Red Hat Software Collections. Although 7.3.27 is out there, I read thoroughly the changelog and haven't found similar bug between 7.3.20 and 7.3.27. There is a BLOB column in the database (Oracle 19c) which can be inserted with php-odbc and can't with php-pdo. We have a test case (see next chapter). The Oracle ODBC trace outputs for both PDO and ODBC version have been attached. Testfile: dd if=/dev/urandom of=testfile.txt bs={desired_size} count=1 We try to upload blob content the way as outlined in the manual (https://www.php.net/manual/en/pdo.lobs.php - Example #3 Inserting an image into a database: Oracle) There are at least two different problems: 1) php-pdo blob inserts silenty fails when the blob content is smaller than 3997 bytes. The manual says "It's also essential that you perform the insert under a transaction, otherwise your newly inserted LOB will be committed with a zero-length as part of the implicit commit that happens when the query is executed" ....okay, but we inserted under a transaction. What are we missing here? 2) php-pdo blob inserts fails with "[[Oracle][ODBC][Ora]ORA-01461: can bind a LONG value only for insert into a LONG column" error messages when the blob content is greater (or equal) than 3997 bytes. Test script: --------------- -- ODBC test script: -- $conn = odbc_connect("ORACLETEST", "eberjegyzek", "secret"); $imageBlob = file_get_contents("testfile.txt"); $query = "INSERT INTO HSZ (ID, PDF) VALUES (SEQ_HSZ.NEXTVAL, ?)"; $stmt = odbc_prepare($conn, $query); odbc_execute($stmt, [$imageBlob]) or die('Error, query failed'); -- PDO test script: -- $db = new \PDO("odbc:ORACLETEST", "eberjegyzek", "secret"); $stmt = $db->prepare("INSERT INTO HSZ(ID, PDF) VALUES(SEQ_HSZ.NEXTVAL, EMPTY_BLOB()) RETURNING PDF INTO ?"); $imageBlob = file_get_contents("testfile.txt"); $stmt->bindParam(1, $imageBlob, PDO::PARAM_LOB); $db->beginTransaction(); $stmt->execute(); $db->commit(); Test cases: SQL> select id, length(pdf), dbms_lob.getlength(pdf) FROM hsz order by ID; +---------+--------------+-------------------------+ | ID | LENGTH(PDF) | DBMS_LOB.GETLENGTH(PDF) | +------------------------+-------------------------+ | 376693 | 100 | 100 | Test case #1 php-odbc with 100 bytes of input (OK) | 376694 | 10000 | 10000 | Test case #2 php-odbc with 10000 bytes of input (OK) | 376695 | 0 | 0 | Test case #3 php-pdo with 100 bytes of input (not OK, there is no data in the PDF column) | 376696 | 0 | 0 | Test case #4 php-pdo with 3996 bytes of input (not OK, there is no data in the PDF columns) Test case #5 php-pdo with 3997 bytes of input (completely missing from the table, ORA-01461: can bind a LONG value only for insert into a LONG column) +---------+--------------+-------------------------+ Expected result: ---------------- see above (Test cases) Actual result: -------------- see above (Test cases) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=80790&edit=1

« previous php.bugs (#232346) next »