php / php/php-src

SQLPutData errors are not handled, causing a function sequence error in SQLParamData

未关闭
#10,847 5 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Bug Extension: pdo_odbc Status: Needs Triage
主要语言
C
星标
40.4k
派生
8.2k
平均合并
2 天 15 小时
30 天内合并 PR
103

描述

Description

Edit: I blamed the wrong extension initially, but the problem remains the same. See the comment I posted for what I actually think is going on now that I understand more here.

A user reported to me an issue where PDO_ODBC procedural ODBC was returning a function sequence error. Unfortunately, it's a little hard to reproduce independently (large Laravel application, large dataset), but I can clearly see what's causing the error, and that it's obscuring another error that's the source of the actual problem.

The relevant part of the unixODBC trace (I'm not posting the full file because it's ~100k lines):

[ODBC][718][1678733794.839656][SQLAllocHandle.c][560]
		Entry:
			Handle Type = 3
			Input Handle = 0x56088464f120
[ODBC][718][1678733794.839724][SQLAllocHandle.c][1105]
		Exit:[SQL_SUCCESS]
			Output Handle = 0x56088467eaa0
[ODBC][718][1678733794.839741][SQLPrepare.c][196]
		Entry:
			Statement = 0x56088467eaa0
			SQL = [select id from new table (insert into documents (id, title, body, keywords, user_id, category_id, role_id, categoryname, created...][length = 198 (SQL_NTS)]
[ODBC][718][1678733794.840339][SQLPrepare.c][377]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840394][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 1
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840414][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840441][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 1
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = -5 SQL_BIGINT
			Col Def = 20
			Scale = 0
			Rgb Value = 0x7f6bcd1ceaf0
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd04d8c0
[ODBC][718][1678733794.840459][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840475][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 2
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840502][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840517][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 2
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = 12 SQL_VARCHAR
			Col Def = 500
			Scale = 0
			Rgb Value = 0x7f6bcd1ce820
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd050460
[ODBC][718][1678733794.840531][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840546][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 3
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840562][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840576][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 3
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = -1 SQL_LONGVARCHAR
			Col Def = 65536
			Scale = 0
			Rgb Value = 0x7f6bcd1ce780
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd04d940
[ODBC][718][1678733794.840592][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840608][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 4
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840624][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840655][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 4
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = -1 SQL_LONGVARCHAR
			Col Def = 65536
			Scale = 0
			Rgb Value = 0x7f6bcd1ce690
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd04df00
[ODBC][718][1678733794.840670][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840686][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 5
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840701][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840715][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 5
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = -5 SQL_BIGINT
			Col Def = 20
			Scale = 0
			Rgb Value = 0x7f6bcd1ce9b0
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd04d800
[ODBC][718][1678733794.840729][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840744][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 6
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840760][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840790][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 6
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = -5 SQL_BIGINT
			Col Def = 20
			Scale = 0
			Rgb Value = 0x7f6bcd1ce8c0
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd041b20
[ODBC][718][1678733794.840806][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840822][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 7
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840847][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840861][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 7
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = -5 SQL_BIGINT
			Col Def = 20
			Scale = 0
			Rgb Value = 0x7f6bcd1ce960
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd0439c0
[ODBC][718][1678733794.840875][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840890][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 8
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840905][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840919][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 8
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = 12 SQL_VARCHAR
			Col Def = 500
			Scale = 0
			Rgb Value = 0x7f6bcd1cea00
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd04d900
[ODBC][718][1678733794.840933][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.840949][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 9
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.840971][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.840985][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 9
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = 93 SQL_TYPE_TIMESTAMP
			Col Def = 26
			Scale = 6
			Rgb Value = 0x7f6bcd1ceb90
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd043c20
[ODBC][718][1678733794.840999][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.841015][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 10
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.841030][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.841044][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 10
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = 93 SQL_TYPE_TIMESTAMP
			Col Def = 26
			Scale = 6
			Rgb Value = 0x7f6bcd1ce4b0
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd041ce0
[ODBC][718][1678733794.841057][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.841072][SQLDescribeParam.c][185]
		Entry:
			Statement = 0x56088467eaa0
			Parameter Number = 11
			SQL Type = 0x7ffc4db00cd2
			Param Def = 0x7ffc4db00cd8
			Scale = 0x7ffc4db00cd4
			Nullable = 0x7ffc4db00cd6
[ODBC][718][1678733794.841088][SQLDescribeParam.c][338]
		Exit:[SQL_SUCCESS]                
			SQL Type = 0x7ffc4db00ba0                
			Param Def = 0x7ffc4db00ab0                
			Scale = 0x7ffc4db009c0                
			Nullable = 0x7ffc4db008d0
[ODBC][718][1678733794.841102][SQLBindParameter.c][217]
		Entry:
			Statement = 0x56088467eaa0
			Param Number = 11
			Param Type = 1
			C Type = 1 SQL_C_CHAR
			SQL Type = 93 SQL_TYPE_TIMESTAMP
			Col Def = 26
			Scale = 6
			Rgb Value = 0x7f6bcd1ce730
			Value Max = 0
			StrLen Or Ind = 0x7f6bcd04d7c0
[ODBC][718][1678733794.841115][SQLBindParameter.c][434]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.841132][SQLExecute.c][187]
		Entry:
			Statement = 0x56088467eaa0
[ODBC][718][1678733794.841148][SQLExecute.c][357]
		Exit:[SQL_NEED_DATA]
[ODBC][718][1678733794.841163][SQLParamData.c][166]
		Entry:
			Statement = 0x56088467eaa0
			Value = 0x7ffc4db00ea0
[ODBC][718][1678733794.841177][SQLParamData.c][362]
		Exit:[SQL_NEED_DATA]
			Value = 0x7f6bcd1ceaf0
[ODBC][718][1678733794.841190][SQLPutData.c][148]
		Entry:
			Statement = 0x56088467eaa0
			Data = 0x7f6bcd04d838
			StrLen = 3
[ODBC][718][1678733794.841205][SQLPutData.c][315]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.841218][SQLParamData.c][166]
		Entry:
			Statement = 0x56088467eaa0
			Value = 0x7ffc4db00ea0
[ODBC][718][1678733794.841231][SQLParamData.c][362]
		Exit:[SQL_NEED_DATA]
			Value = 0x7f6bcd1ce820
[ODBC][718][1678733794.841244][SQLPutData.c][148]
		Entry:
			Statement = 0x56088467eaa0
			Data = 0x7f6bcd1d2be8
			StrLen = 20
[ODBC][718][1678733794.841258][SQLPutData.c][315]
		Exit:[SQL_SUCCESS]
[ODBC][718][1678733794.841271][SQLParamData.c][166]
		Entry:
			Statement = 0x56088467eaa0
			Value = 0x7ffc4db00ea0
[ODBC][718][1678733794.841285][SQLParamData.c][362]
		Exit:[SQL_NEED_DATA]
			Value = 0x7f6bcd1ce780
[ODBC][718][1678733794.841299][SQLPutData.c][148]
		Entry:
			Statement = 0x56088467eaa0
			Data = 0x7f6bcd186e18
			StrLen = 2106
[ODBC][718][1678733794.841808][SQLPutData.c][315]
		Exit:[SQL_ERROR]
[ODBC][718][1678733794.841826][SQLParamData.c][166]
		Entry:
			Statement = 0x56088467eaa0
			Value = 0x7ffc4db00ea0
[ODBC][718][1678733794.841838][SQLParamData.c][189]Error: HY010
[ODBC][718][1678733794.841867][SQLGetDiagRec.c][677]
		Entry:
			Statement = 0x56088467eaa0
			Rec Number = 1
			SQLState = 0x7f6bccf98718
			Native = 0x7f6bccf98920
			Message Text = 0x7f6bccf9871e
			Buffer Length = 511
			Text Len Ptr = 0x7ffc4db00a22
[ODBC][718][1678733794.841887][SQLGetDiagRec.c][726]
		Exit:[SQL_SUCCESS]
			SQLState = HY010
			Native = 0x7f6bccf98920 -> 0 (32 bits)
			Message Text = [[unixODBC][Driver Manager]Function sequence error]
[ODBC][718][1678733794.841901][SQLGetDiagRec.c][677]
		Entry:
			Statement = 0x56088467eaa0
			Rec Number = 2
			SQLState = 0x7ffc4db00a2a
			Native = 0x7ffc4db00a24
			Message Text = 0x7ffc4db00a30
			Buffer Length = 1023
			Text Len Ptr = 0x7ffc4db00a22
[ODBC][718][1678733794.841915][SQLGetDiagRec.c][726]
		Exit:[SQL_NO_DATA]

As you can see, there's some DATA_AT_EXEC going on (the unixODBC trace makes it hard to determine what parameter is bound as such), so PDO_ODBC starts with an SQLParamData, and calls SQLPutData (alternative call site) in a loop as needed.

The problem is that failures in SQLPutData are not correctly handled. As you can see in the trace, one of the later the SQLPutData call is returning an error (unfortunately, unixODBC tracing doesn't decide to find specifics on its own), but PDO_ODBC procedural ODBC doesn't actually do anything with the error code it stores (if it stores it at all) store the error and act on it. Instead, it continues on, calling SQLParamData again, which is now in an invalid state and within its rights to return HY010 (as documented, though it's not clear that only successful SQLPutData or exec calls are valid).

The actual error we care about is for the SQLPutData call, but that's not being surfaced, and the misleading function sequence error is returned instead because it ignores that previous error.

If it helps, I also have the application's Laravel log from trying to insert the rows, although this does include the user's data. I'm also trying to get the schema and mapping from them as well. It's using the Db2i driver as well, but on Linux.

PHP Version

PHP 8.1.16

Operating System

Ubuntu 22.04

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 SQLPutData 和 SQLParamData 周围的过程式 ODBC 执行流程入手,使用 issue 中的 unixODBC 跟踪来跟进报告的序列。如果可能,重现该错误,并确定应如何处理 SQLPutData 错误;完成的标准是暴露底层错误,而不是将其替换为函数序列错误。

由索引模型根据 Issue 内容生成。

评估

技术栈
c, php
领域
backend, databases
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
需要澄清
新手友好度
25/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。