diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index 419574e9ea..14dcbdb4e3 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -7066,7 +7066,7 @@ EXECUTE IMMEDIATE string
string
- A literal C string or a host variable containing the SQL
+ A literal string or a host variable containing the SQL
statement to be executed.
@@ -7074,6 +7074,30 @@ EXECUTE IMMEDIATE string
+
+ Notes
+
+
+ In typical usage, the string is a host
+ variable reference to a string containing a dynamically-constructed
+ SQL statement. The case of a literal string is not very useful;
+ you might as well just write the SQL statement directly, without
+ the extra typing of EXECUTE IMMEDIATE.
+
+
+
+ If you do use a literal string, keep in mind that any double quotes
+ you might wish to include in the SQL statement must be written as
+ octal escapes (\042) not the usual C
+ idiom \". This is because the string is inside
+ an EXEC SQL section, so the ECPG lexer parses it
+ according to SQL rules not C rules. Any embedded backslashes will
+ later be handled according to C rules; but \"
+ causes an immediate syntax error because it is seen as ending the
+ literal.
+
+
+
Examples
@@ -7388,7 +7412,7 @@ EXEC SQL OPEN :curname1;
-PREPARE name FROM string
+PREPARE prepared_name FROM string
@@ -7421,15 +7445,40 @@ PREPARE name FROM string
- A literal C string or a host variable containing a preparable
- statement, one of the SELECT, INSERT, UPDATE, or
- DELETE.
+ A literal string or a host variable containing a preparable
+ SQL statement, one of SELECT, INSERT, UPDATE, or DELETE.
+ Use question marks (?) for parameter values
+ to be supplied at execution.
+
+ Notes
+
+
+ In typical usage, the string is a host
+ variable reference to a string containing a dynamically-constructed
+ SQL statement. The case of a literal string is not very useful;
+ you might as well just write a direct SQL PREPARE
+ statement.
+
+
+
+ If you do use a literal string, keep in mind that any double quotes
+ you might wish to include in the SQL statement must be written as
+ octal escapes (\042) not the usual C
+ idiom \". This is because the string is inside
+ an EXEC SQL section, so the ECPG lexer parses it
+ according to SQL rules not C rules. Any embedded backslashes will
+ later be handled according to C rules; but \"
+ causes an immediate syntax error because it is seen as ending the
+ literal.
+
+
+
Examples
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index e98aa6c486..91d8b63578 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -715,7 +715,14 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
BEGIN(state_before_str_start);
if (literallen == 0)
mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier");
- /* The backend will truncate the identifier here. We do not as it does not change the result. */
+ /*
+ * The server will truncate the identifier here. We do
+ * not, as (1) it does not change the result; (2) we don't
+ * know what NAMEDATALEN the server might use; (3) this
+ * code path is also taken for literal query strings in
+ * PREPARE and EXECUTE IMMEDIATE, which can certainly be
+ * longer than NAMEDATALEN.
+ */
base_yylval.str = mm_strdup(literalbuf);
return CSTRING;
}
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.c b/src/interfaces/ecpg/test/expected/sql-execute.c
index cac91dc599..10e9ad56b5 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.c
+++ b/src/interfaces/ecpg/test/expected/sql-execute.c
@@ -77,8 +77,8 @@ if (sqlca.sqlcode < 0) sqlprint();}
#line 26 "execute.pgc"
- sprintf(command, "insert into test (name, amount, letter) values ('db: ''r1''', 1, 'f')");
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_immediate, command, ECPGt_EOIT, ECPGt_EORT);
+ /* test handling of embedded quotes in EXECUTE IMMEDIATE "literal" */
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_immediate, "insert into test (name, \042amount\042, letter) values ('db: ''r1''', 1, 'f')", ECPGt_EOIT, ECPGt_EORT);
#line 29 "execute.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.stderr b/src/interfaces/ecpg/test/expected/sql-execute.stderr
index 96b46bd158..d8bc3c6524 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.stderr
+++ b/src/interfaces/ecpg/test/expected/sql-execute.stderr
@@ -10,7 +10,7 @@
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ECPGtrans on line 26: action "commit"; connection "main"
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 29: query: insert into test (name, amount, letter) values ('db: ''r1''', 1, 'f'); with 0 parameter(s) on connection main
+[NO_PID]: ecpg_execute on line 29: query: insert into test (name, "amount", letter) values ('db: ''r1''', 1, 'f'); with 0 parameter(s) on connection main
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 29: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/sql/execute.pgc b/src/interfaces/ecpg/test/sql/execute.pgc
index cc9814e9be..43171bb77c 100644
--- a/src/interfaces/ecpg/test/sql/execute.pgc
+++ b/src/interfaces/ecpg/test/sql/execute.pgc
@@ -25,8 +25,8 @@ exec sql end declare section;
exec sql create table test (name char(8), amount int, letter char(1));
exec sql commit;
- sprintf(command, "insert into test (name, amount, letter) values ('db: ''r1''', 1, 'f')");
- exec sql execute immediate :command;
+ /* test handling of embedded quotes in EXECUTE IMMEDIATE "literal" */
+ exec sql execute immediate "insert into test (name, \042amount\042, letter) values ('db: ''r1''', 1, 'f')";
sprintf(command, "insert into test (name, amount, letter) values ('db: ''r1''', 2, 't')");
exec sql execute immediate :command;