-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Feature: Output correct error message from pdo_firebird
#12669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Output correct error message from pdo_firebird
#12669
Conversation
9c2cc79
to
12fc53b
Compare
pdo_firebird
pdo_firebird
12fc53b
to
7bfb5e6
Compare
Sorry for the change in order, but first, I would like to ask you to review this PR. |
I found some unnecessary parts, so I'll edit them. |
5d5b183
to
c252527
Compare
done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me and only have some suggestions
ext/pdo_firebird/firebird_driver.c
Outdated
buf[read_len - 1] = '\0'; | ||
} | ||
|
||
einfo->errmsg = pestrdup(buf, dbh->is_persistent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this duplicate 512 bytes every time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Judging from the implementation of pestrdup, it looks fine.
Line 2684 in a35a69f
ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
However, considering the balance with other changes, it seemed better to use pestrndup
, so I changed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has nothing to do with this change, but I'm a little concerned that it haven't given +1 here.
Line 2706 in a35a69f
memcpy(p, s, length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's the opposite. +1 to potentially lost the terminating null
Here, _estrdup
is getting the length, so there seems to be no problem. Excuse me, I understand.
typedef struct { | ||
int sqlcode; | ||
char *errmsg; | ||
} pdo_firebird_error_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add the length component so that we don't need to recompute known lengths when converting this to zend_string ?
typedef struct { | |
int sqlcode; | |
char *errmsg; | |
} pdo_firebird_error_info; | |
typedef struct { | |
int sqlcode; | |
char *errmsg; | |
size_t errmsg_length; | |
} pdo_firebird_error_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea. Changed pdo_firebird_fetch_error_func
to use add_next_index_stringl
.
c252527
to
9a435f3
Compare
@Girgias |
9a435f3
to
2ca4077
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for being slow, but possibly some more improvements (but they could also be left for later)
ext/pdo_firebird/firebird_driver.c
Outdated
} | ||
#endif | ||
} else if (msg) { | ||
einfo->errmsg_length = strlen(msg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the msg argument is always constant at the call site. Precomputing the length at call site and passing it as an argument should allow the compiler to precompute it instead of needing a runtime strlen() in the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to require length in argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you meant writing the numbers directly in the code without using strlen at all? I may have misunderstood something.
ext/pdo_firebird/firebird_driver.c
Outdated
if (state) { | ||
strcpy(*error_code, state); | ||
} else { | ||
strcpy(*error_code, "HY000"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here, we can precompute the length of the strings and potentially use memcpy()
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to require length in argument, and to explicitly pass HY000 where NULL was passed to state
2ca4077
to
9ae039c
Compare
@Girgias My changes may be inappropriate to save runtime overhead. |
9ae039c
to
4810a72
Compare
I fixed, I think I've eliminated runtime overhead as much as possible. |
ext/pdo_firebird/firebird_driver.c
Outdated
if (state && state_len && state_len < sizeof(pdo_error_type)) { | ||
memcpy(*error_code, state, state_len + 1); | ||
} else { | ||
memcpy(*error_code, "HY000", 6); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be better AFAIK
memcpy(*error_code, "HY000", 6); | |
memcpy(*error_code, "HY000", sizeof("HY000"); |
ext/pdo_firebird/firebird_driver.c
Outdated
@@ -848,7 +904,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * | |||
if (bval) { | |||
/* turning on auto_commit with an open transaction is illegal, because | |||
we won't know what to do with it */ | |||
H->last_app_error = "Cannot enable auto-commit while a transaction is already open"; | |||
firebird_error_with_info(dbh, "HY000", 5, "Cannot enable auto-commit while a transaction is already open", 61); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using sizeof of strlen is better, the compiler will fill in the integer constant by itself
@@ -325,7 +322,7 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, zval *result, ISC_QU | |||
|
|||
if (item == isc_info_end || item == isc_info_truncated || item == isc_info_error | |||
|| i >= sizeof(bl_info)) { | |||
H->last_app_error = "Couldn't determine BLOB size"; | |||
firebird_error_stmt_with_info(stmt, "HY000", 5, "Couldn't determine BLOB size", 28); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
4810a72
to
700f92a
Compare
Thank you, I didn't even consider the behavior of the compiler. I'm looking into it while studying while looking at the assembly code. |
@@ -848,7 +904,8 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * | |||
if (bval) { | |||
/* turning on auto_commit with an open transaction is illegal, because | |||
we won't know what to do with it */ | |||
H->last_app_error = "Cannot enable auto-commit while a transaction is already open"; | |||
const char *msg = "Cannot enable auto-commit while a transaction is already open"; | |||
firebird_error_with_info(dbh, "HY000", strlen("HY000"), msg, strlen(msg)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nielsdos just to sanity check, but this is sensible right? The compiler will replace at compile time the strlen call by the actual value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it does
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you both! I was able to understand it a little. I'll learn some more.
What I wanted to say was a little different.
Although I understand the content, I am still not very good at reading the differences in assembly code, so I will learn to read assembly code better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried various things. I understand that strlen("HY000")
will be replaced, but strlen(msg)
will not be replaced, is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because msg
is a variable, where the content is only known at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thank you. Should msg
be replaced as well? I feel the msg
is a little too long for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't look at this specific case, but in this one the compiler should be smart enough :)
Thank you! |
The current implementation does not retrieve
sqlstatus
from the DB, and any errors will be treated as General errors.So I changed it to get the SQL state and error messages from the vendor driver.
I also used the same naming conventions as other PDO drivers for function names, etc.
Other changes require error handling, so I'd be happy if I could merge them from this PR.