[bug fix] ECPG: fails to recognize embedded parameters
Hello,
This is an actual problem that our customer hit. In ECPG, opening a cursor fails which is declared as follows:
EXEC SQL DECLARE cur CURSOR FOR
SELECT oid, datname
FROM pg_database
WHERE datname LIKE 'post%' ESCAPE '\' AND datconnlimit = :connlimit;
sqlstate: 07001
sqlerrm.sqlerrmc: too many arguments on line 30
The cause is that next_insert() in ecpglib unconditionally skips the next character after the backslash.
Could you review and commit the attached patch? I also attached the test program for convenience.
Regards
Takayuki Tsunakawa
Attachments:
ecpg_escape_string.patchapplication/octet-stream; name=ecpg_escape_string.patchDownload
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 50f831a..7776813 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -108,14 +108,14 @@ free_statement(struct statement *stmt)
}
static int
-next_insert(char *text, int pos, bool questionmarks)
+next_insert(char *text, int pos, bool questionmarks, bool std_strings)
{
bool string = false;
int p = pos;
for (; text[p] != '\0'; p++)
{
- if (text[p] == '\\') /* escape character */
+ if (string && !std_strings && text[p] == '\\') /* escape character */
p++;
else if (text[p] == '\'')
string = string ? false : true;
@@ -1109,6 +1109,13 @@ ecpg_build_params(struct statement *stmt)
struct variable *var;
int desc_counter = 0;
int position = 0;
+ const char *value;
+ bool std_strings = false;
+
+ /* Get standard_conforming_strings setting. */
+ value = PQparameterStatus(stmt->connection->connection, "standard_conforming_strings");
+ if (value && strcmp(value, "on") == 0)
+ std_strings = true;
/*
* If the type is one of the fill in types then we take the argument and
@@ -1299,7 +1306,7 @@ ecpg_build_params(struct statement *stmt)
* now tobeinserted points to an area that contains the next
* parameter; now find the position in the string where it belongs
*/
- if ((position = next_insert(stmt->command, position, stmt->questionmarks) + 1) == 0)
+ if ((position = next_insert(stmt->command, position, stmt->questionmarks, std_strings) + 1) == 0)
{
/*
* We have an argument but we dont have the matched up placeholder
@@ -1386,7 +1393,7 @@ ecpg_build_params(struct statement *stmt)
}
/* Check if there are unmatched things left. */
- if (next_insert(stmt->command, position, stmt->questionmarks) >= 0)
+ if (next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0)
{
ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS,
ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
The cause is that next_insert() in ecpglib unconditionally skips the
next character after the backslash.Could you review and commit the attached patch? I also attached the
test program for convenience.
Thanks for spotting and fixing. I just committed your patch to master
and backported to 9.4, 9.5, 9.6 and 10. It doesn't apply cleanly to
9.3. But then it might not be important enough to investigate and
backported to this old a version.
Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Meskes at (Debian|Postgresql) dot Org
Jabber: michael at xmpp dot meskes dot org
VfL Borussia! Força Barça! SF 49ers! Use Debian GNU/Linux, PostgreSQL
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
From: pgsql-hackers-owner@postgresql.org
[mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of Michael Meskes
Thanks for spotting and fixing. I just committed your patch to master and
backported to 9.4, 9.5, 9.6 and 10. It doesn't apply cleanly to 9.3. But
then it might not be important enough to investigate and backported to this
old a version.
Thanks. I'm OK with 9.3.
Regards
Takayuki Tsunakawa
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers