[PATCH] Add regression tests of ecpg command notice (error / warning)
Hi hackers,
When I wrote patch of ecpg command notice bug, I recognized needs of
regression tests for ecpg command notices and I say that I write the
tests.
https://commitfest.postgresql.org/52/5497/
/messages/by-id/0efab1f6-5d8d-451f-a7dc-ef9c73ba9e02@oss.nttdata.com
This mail is about patch of the tests.
Patch is attached to this mail : ecpg_cmd_notice_regress_test.patch
This patch passed CI.
https://cirrus-ci.com/build/4861827500212224
And corresponding diff is below.
https://github.com/ryogrid/postgres/compare/0ec3c295e7594ed3af86bca1a4b4be269c2f069d...72329311a75630594bcaa38248255360b7e8e525
I explain about implementation of this patch.
What is this patch
- add regression tests which test ecpg command notices such as warning
and errors
- test notices implemented in ecpg.addons file
Basic policy on implementation
- do in a way that matches the method using the existing pg_regress
command as much as possible
- avoid methods that increase the scope of influence
Next, I list answers to points that are likely to be pointed out in
advance below :)
- shell scripts and bat files is used due to ...
avoid non zero exit code of ecpg command makes tests failure
avoid increasing C code for executing binary which cares cross platform
- python code is used because I couldn't write meson.build
appropriately describe dependency about materials which is used on
tests without it. please help me...
- as you said, kick this kind of tests by pg_regress accompanied with
needless PG server process execution. but pg_regress doesn't execute
test without it and making pg_regress require modification which has
not small scope of influence
---
Great regards,
Ryo Kanbayashi
https://github.com/ryogrid
Attachments:
ecpg_cmd_notice_regress_test.patchapplication/x-patch; name=ecpg_cmd_notice_regress_test.patchDownload
diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule
index 254a0bacc75..e1cc61d8c52 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule
+++ b/src/interfaces/ecpg/test/ecpg_schedule
@@ -31,6 +31,8 @@ test: preproc/variable
test: preproc/outofscope
test: preproc/whenever
test: preproc/whenever_do_continue
+test: preproc/notice_check
+test: preproc/notice_informix_check
test: sql/array
test: sql/binary
test: sql/bytea
diff --git a/src/interfaces/ecpg/test/expected/preproc-check_cmd_notice.stderr b/src/interfaces/ecpg/test/expected/preproc-check_cmd_notice.stderr
new file mode 100644
index 00000000000..31bfbc9f3bd
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-check_cmd_notice.stderr
@@ -0,0 +1,13 @@
+preproc/notice.pgc:16: ERROR: AT option not allowed in CONNECT statement
+preproc/notice.pgc:17: ERROR: AT option not allowed in DISCONNECT statement
+preproc/notice.pgc:18: ERROR: AT option not allowed in SET CONNECTION statement
+preproc/notice.pgc:21: WARNING: COPY FROM STDIN is not implemented
+preproc/notice.pgc:25: ERROR: using variable "cursor_var" in different declare statements is not supported
+preproc/notice.pgc:28: ERROR: cursor "duplicate_cursor" is already defined
+preproc/notice.pgc:31: ERROR: SHOW ALL is not implemented
+preproc/notice.pgc:33: ERROR: AT option not allowed in WHENEVER statement
+preproc/notice.pgc:36: WARNING: no longer supported LIMIT #,# syntax passed to server
+preproc/notice.pgc:39: WARNING: cursor "duplicate_cursor" has been declared but not opened
+preproc/notice.pgc:39: WARNING: cursor "duplicate_cursor" has been declared but not opened
+preproc/notice.pgc:39: WARNING: cursor ":cursor_var" has been declared but not opened
+preproc/notice.pgc:39: WARNING: cursor ":cursor_var" has been declared but not opened
diff --git a/src/interfaces/ecpg/test/expected/preproc-check_cmd_notice_informix.stderr b/src/interfaces/ecpg/test/expected/preproc-check_cmd_notice_informix.stderr
new file mode 100644
index 00000000000..0b9013c126e
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-check_cmd_notice_informix.stderr
@@ -0,0 +1,2 @@
+preproc/notice_informix.pgc:11: ERROR: AT option not allowed in CLOSE DATABASE statement
+preproc/notice_informix.pgc:14: ERROR: "database" cannot be used as cursor name in INFORMIX mode
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_check.stderr b/src/interfaces/ecpg/test/expected/preproc-notice_check.stderr
new file mode 100644
index 00000000000..b31076a2527
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-notice_check.stderr
@@ -0,0 +1,15 @@
+notice.pgc:17: ERROR: AT option not allowed in CONNECT statement
+notice.pgc:18: ERROR: AT option not allowed in DISCONNECT statement
+notice.pgc:19: ERROR: AT option not allowed in SET CONNECTION statement
+notice.pgc:20: ERROR: AT option not allowed in TYPE statement
+notice.pgc:21: ERROR: AT option not allowed in WHENEVER statement
+notice.pgc:22: ERROR: AT option not allowed in VAR statement
+notice.pgc:25: WARNING: COPY FROM STDIN is not implemented
+notice.pgc:29: ERROR: using variable "cursor_var" in different declare statements is not supported
+notice.pgc:33: ERROR: cursor "duplicate_cursor" is already defined
+notice.pgc:36: ERROR: SHOW ALL is not implemented
+notice.pgc:39: WARNING: no longer supported LIMIT #,# syntax passed to server
+notice.pgc:42: WARNING: cursor "duplicate_cursor" has been declared but not opened
+notice.pgc:42: WARNING: cursor "duplicate_cursor" has been declared but not opened
+notice.pgc:42: WARNING: cursor ":cursor_var" has been declared but not opened
+notice.pgc:42: WARNING: cursor ":cursor_var" has been declared but not opened
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_check.stdout b/src/interfaces/ecpg/test/expected/preproc-notice_check.stdout
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stderr b/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stderr
new file mode 100644
index 00000000000..d6386aaa896
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stderr
@@ -0,0 +1,2 @@
+notice_informix.pgc:12: ERROR: AT option not allowed in CLOSE DATABASE statement
+notice_informix.pgc:15: ERROR: "database" cannot be used as cursor name in INFORMIX mode
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stdout b/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stdout
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/interfaces/ecpg/test/pg_regress_ecpg.c b/src/interfaces/ecpg/test/pg_regress_ecpg.c
index ba3477f9dd8..18d8b398a30 100644
--- a/src/interfaces/ecpg/test/pg_regress_ecpg.c
+++ b/src/interfaces/ecpg/test/pg_regress_ecpg.c
@@ -22,6 +22,13 @@
#include "lib/stringinfo.h"
#include "pg_regress.h"
+#define ECPG_CMD_NOTICE_TEST_PREFIX "preproc/notice"
+
+/*
+ * Tests whose prefix is ECPG_CMD_NOTICE_TEST_PREFIX check ecpg command's notice
+ * such as error or warning. Not checking of compiled ECPG programs behavior.
+ * So, we handle these tests differently.
+ */
/*
* Create a filtered copy of sourcefile, removing any path
@@ -115,6 +122,9 @@ ecpg_filter_stderr(const char *resultfile, const char *tmpfile)
{
char *p1 = strstr(linebuf.data, "connection to server ");
+ /* when ecpg command notice test */
+ char *p3 = strstr(linebuf.data, "preproc");
+
if (p1)
{
char *p2 = strstr(p1, "failed: ");
@@ -125,6 +135,18 @@ ecpg_filter_stderr(const char *resultfile, const char *tmpfile)
/* we don't bother to fix up linebuf.len */
}
}
+
+ if (p3)
+ {
+ char *p4 = strstr(p3, "notice");
+
+ if (p4)
+ {
+ memmove(p3, p4, strlen(p4) + 1);
+ /* we don't bother to fix up linebuf.len */
+ }
+ }
+
fputs(linebuf.data, t);
}
@@ -162,9 +184,7 @@ ecpg_start_test(const char *testname,
expectfile_source[MAXPGPATH];
char cmd[MAXPGPATH * 3];
char *appnameenv;
-
- snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
- snprintf(insource, sizeof(insource), "%s/%s.c", inputdir, testname);
+ bool is_ecpg_cmd_notice_test = false;
/* make a version of the test name that has dashes in place of slashes */
initStringInfo(&testname_dash);
@@ -175,15 +195,38 @@ ecpg_start_test(const char *testname,
*c = '-';
}
+ /* check for ECPG_CMD_NOTICE_TEST_PREFIX literal in the beginning */
+ if (strstr(testname, ECPG_CMD_NOTICE_TEST_PREFIX) == testname)
+ {
+ is_ecpg_cmd_notice_test = true;
+ }
+
+ if (is_ecpg_cmd_notice_test)
+ {
+#ifdef WIN32
+ snprintf(inprg, sizeof(inprg), "%s/%s.bat", inputdir, testname);
+#else
+ snprintf(inprg, sizeof(inprg), "%s/%s.sh", inputdir, testname);
+#endif
+ }
+ else
+ {
+ snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
+ snprintf(insource, sizeof(insource), "%s/%s.c", inputdir, testname);
+ }
+
snprintf(expectfile_stdout, sizeof(expectfile_stdout),
"%s/expected/%s.stdout",
expecteddir, testname_dash.data);
snprintf(expectfile_stderr, sizeof(expectfile_stderr),
"%s/expected/%s.stderr",
expecteddir, testname_dash.data);
- snprintf(expectfile_source, sizeof(expectfile_source),
- "%s/expected/%s.c",
- expecteddir, testname_dash.data);
+ if (!is_ecpg_cmd_notice_test)
+ {
+ snprintf(expectfile_source, sizeof(expectfile_source),
+ "%s/expected/%s.c",
+ expecteddir, testname_dash.data);
+ }
snprintf(outfile_stdout, sizeof(outfile_stdout),
"%s/results/%s.stdout",
@@ -191,9 +234,12 @@ ecpg_start_test(const char *testname,
snprintf(outfile_stderr, sizeof(outfile_stderr),
"%s/results/%s.stderr",
outputdir, testname_dash.data);
- snprintf(outfile_source, sizeof(outfile_source),
- "%s/results/%s.c",
- outputdir, testname_dash.data);
+ if (!is_ecpg_cmd_notice_test)
+ {
+ snprintf(outfile_source, sizeof(outfile_source),
+ "%s/results/%s.c",
+ outputdir, testname_dash.data);
+ }
add_stringlist_item(resultfiles, outfile_stdout);
add_stringlist_item(expectfiles, expectfile_stdout);
@@ -203,11 +249,18 @@ ecpg_start_test(const char *testname,
add_stringlist_item(expectfiles, expectfile_stderr);
add_stringlist_item(tags, "stderr");
- add_stringlist_item(resultfiles, outfile_source);
- add_stringlist_item(expectfiles, expectfile_source);
- add_stringlist_item(tags, "source");
+ if (!is_ecpg_cmd_notice_test)
+ {
+ add_stringlist_item(resultfiles, outfile_source);
+ add_stringlist_item(expectfiles, expectfile_source);
+ add_stringlist_item(tags, "source");
+
+ ecpg_filter_source(insource, outfile_source);
+ }
- ecpg_filter_source(insource, outfile_source);
+ appnameenv = psprintf("ecpg/%s", testname_dash.data);
+ setenv("PGAPPNAME", appnameenv, 1);
+ free(appnameenv);
snprintf(cmd, sizeof(cmd),
"\"%s\" >\"%s\" 2>\"%s\"",
@@ -215,10 +268,6 @@ ecpg_start_test(const char *testname,
outfile_stdout,
outfile_stderr);
- appnameenv = psprintf("ecpg/%s", testname_dash.data);
- setenv("PGAPPNAME", appnameenv, 1);
- free(appnameenv);
-
pid = spawn_process(cmd);
if (pid == INVALID_PID)
diff --git a/src/interfaces/ecpg/test/preproc/copy_files.py b/src/interfaces/ecpg/test/preproc/copy_files.py
new file mode 100644
index 00000000000..8678c86e1cd
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/copy_files.py
@@ -0,0 +1,21 @@
+import shutil
+import os
+import sys
+
+def main():
+ if len(sys.argv) < 4:
+ print("Usage: python copy_files.py <src_base> <destination_base> <file1> <file2> ...")
+ sys.exit(1)
+
+ src = sys.argv[1]
+ destination = sys.argv[2]
+ files = sys.argv[3:]
+
+ for file in files:
+ src_path = os.path.join(src, os.path.basename(file))
+ dest_path = os.path.join(destination, os.path.basename(file))
+
+ shutil.copy2(src_path, dest_path)
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/meson.build b/src/interfaces/ecpg/test/preproc/meson.build
index 775502e0102..26bef1f2e73 100644
--- a/src/interfaces/ecpg/test/preproc/meson.build
+++ b/src/interfaces/ecpg/test/preproc/meson.build
@@ -37,3 +37,31 @@ foreach pgc_file : pgc_files
kwargs: ecpg_test_exec_kw,
)
endforeach
+
+# copy materials for ecpg command notice test
+copy_materials = [
+ 'notice.pgc',
+ 'notice_informix.pgc',
+ 'notice_check.bat',
+ 'notice_check.sh',
+ 'notice_informix_check.bat',
+ 'notice_informix_check.sh',
+]
+
+copy_cmdline = [
+ python,
+ meson.current_source_dir() / 'copy_files.py',
+ meson.current_source_dir(),
+ meson.current_build_dir()
+]
+
+foreach file : copy_materials
+ copy_cmdline += file
+endforeach
+
+ecpg_test_dependencies += custom_target('copy_ecpg_test_materials',
+ input: meson.current_source_dir() / 'copy_files.py',
+ output: copy_materials,
+ command: copy_cmdline,
+ build_by_default: false,
+)
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice.pgc b/src/interfaces/ecpg/test/preproc/notice.pgc
new file mode 100644
index 00000000000..03a4f60d5e2
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice.pgc
@@ -0,0 +1,42 @@
+/* Test ECPG notice/warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *cursor_var = "mycursor";
+ short a;
+ EXEC SQL END DECLARE SECTION;
+
+ /* For consistency with other tests */
+ EXEC SQL CONNECT TO testdb AS con1;
+
+ /* Test AT option errors */
+ EXEC SQL AT con1 CONNECT TO testdb2;
+ EXEC SQL AT con1 DISCONNECT;
+ EXEC SQL AT con1 SET CONNECTION TO testdb2;
+ EXEC SQL AT con1 TYPE string IS char[11];
+ EXEC SQL AT con1 WHENEVER NOT FOUND CONTINUE;
+ EXEC SQL AT con1 VAR a IS int;
+
+ /* Test COPY FROM STDIN warning */
+ EXEC SQL COPY test FROM stdin;
+
+ /* Test same variable in multi declare statement */
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+
+ /* Test duplicate cursor declarations */
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+
+ /* Test SHOW ALL error */
+ EXEC SQL SHOW ALL;
+
+ /* Test deprecated LIMIT syntax warning */
+ EXEC SQL SELECT * FROM test LIMIT 10, 5;
+
+ return 0;
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_check.bat b/src/interfaces/ecpg/test/preproc/notice_check.bat
new file mode 100644
index 00000000000..172950897db
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_check.bat
@@ -0,0 +1,7 @@
+@echo off
+
+PATH=..\preproc\;%PATH%
+ecpg -o preproc\notice.c preproc\notice.pgc
+
+REM always return 0 for test purposes
+exit /b 0
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_check.sh b/src/interfaces/ecpg/test/preproc/notice_check.sh
new file mode 100755
index 00000000000..11338bb3ede
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_check.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+PATH=../preproc/:$PATH
+ecpg -c -o preproc/notice.c preproc/notice.pgc
+
+# always return 0 for testing purposes
+exit 0
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_informix.pgc b/src/interfaces/ecpg/test/preproc/notice_informix.pgc
new file mode 100644
index 00000000000..18281f3b9ee
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_informix.pgc
@@ -0,0 +1,18 @@
+/* Test ECPG notice/warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ /* For consistency with other tests */
+ $CONNECT TO testdb AS con1;
+
+ /* Test AT option usage at CLOSE statement in INFORMIX mode */
+ $AT con1 CLOSE database;
+
+ /* Test cursor name errors in INFORMIX mode */
+ $DECLARE database CURSOR FOR SELECT * FROM test;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/preproc/notice_informix_check.bat b/src/interfaces/ecpg/test/preproc/notice_informix_check.bat
new file mode 100644
index 00000000000..fd66da3b67e
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_informix_check.bat
@@ -0,0 +1,7 @@
+@echo off
+
+PATH=..\preproc\;%PATH%
+ecpg -C INFORMIX -o preproc\notice_informix.c preproc\notice_informix.pgc
+
+REM always return 0 for test purposes
+exit /b 0
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_informix_check.sh b/src/interfaces/ecpg/test/preproc/notice_informix_check.sh
new file mode 100755
index 00000000000..ef543e1082e
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_informix_check.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+PATH=../preproc/:$PATH
+ecpg -C INFORMIX -o preproc/notice_informix.c preproc/notice_informix.pgc
+
+# always return 0 for testing purposes
+exit 0
\ No newline at end of file
Import Notes
Reply to msg id not found: CANOn0EwhAEarQxEFe5+zz55ui4cmbNL8CwEQy20xjBceMnNhQg@mail.gmail.comReference msg id not found: CANOn0EwhAEarQxEFe5+zz55ui4cmbNL8CwEQy20xjBceMnNhQg@mail.gmail.com
On Wed, Feb 5, 2025 at 9:31 PM Ryo Kanbayashi <kanbayashi.dev@gmail.com> wrote:
Hi hackers,
When I wrote patch of ecpg command notice bug, I recognized needs of
regression tests for ecpg command notices and I say that I write the
tests.https://commitfest.postgresql.org/52/5497/
/messages/by-id/0efab1f6-5d8d-451f-a7dc-ef9c73ba9e02@oss.nttdata.comThis mail is about patch of the tests.
Patch is attached to this mail : ecpg_cmd_notice_regress_test.patch
This patch passed CI.
https://cirrus-ci.com/build/4861827500212224And corresponding diff is below.
https://github.com/ryogrid/postgres/compare/0ec3c295e7594ed3af86bca1a4b4be269c2f069d...72329311a75630594bcaa38248255360b7e8e525I explain about implementation of this patch.
What is this patch
- add regression tests which test ecpg command notices such as warning
and errors
- test notices implemented in ecpg.addons fileBasic policy on implementation
- do in a way that matches the method using the existing pg_regress
command as much as possible
- avoid methods that increase the scope of influenceNext, I list answers to points that are likely to be pointed out in
advance below :)
- shell scripts and bat files is used due to ...
avoid non zero exit code of ecpg command makes tests failure
avoid increasing C code for executing binary which cares cross platform
- python code is used because I couldn't write meson.build
appropriately describe dependency about materials which is used on
tests without it. please help me...
- as you said, kick this kind of tests by pg_regress accompanied with
needless PG server process execution. but pg_regress doesn't execute
test without it and making pg_regress require modification which has
not small scope of influence
Sorry, I re-send patch because a patch already sent includes needless
stderr output file.
NEW PATCH FILENAME: ecpg_cmd_notice_regress_test2.patch
In addition, diff between patches does not affect test behavior.
---
Sincerely,
Ryo Kanbayashi
https://github.com/ryogrid
On Wed, Feb 5, 2025 at 9:31 PM Ryo Kanbayashi <kanbayashi.dev@gmail.com> wrote:
Hi hackers,
When I wrote patch of ecpg command notice bug, I recognized needs of
regression tests for ecpg command notices and I say that I write the
tests.https://commitfest.postgresql.org/52/5497/
/messages/by-id/0efab1f6-5d8d-451f-a7dc-ef9c73ba9e02@oss.nttdata.comThis mail is about patch of the tests.
Patch is attached to this mail : ecpg_cmd_notice_regress_test.patch
This patch passed CI.
https://cirrus-ci.com/build/4861827500212224And corresponding diff is below.
https://github.com/ryogrid/postgres/compare/0ec3c295e7594ed3af86bca1a4b4be269c2f069d...72329311a75630594bcaa38248255360b7e8e525I explain about implementation of this patch.
What is this patch
- add regression tests which test ecpg command notices such as warning
and errors
- test notices implemented in ecpg.addons fileBasic policy on implementation
- do in a way that matches the method using the existing pg_regress
command as much as possible
- avoid methods that increase the scope of influenceNext, I list answers to points that are likely to be pointed out in
advance below :)
- shell scripts and bat files is used due to ...
avoid non zero exit code of ecpg command makes tests failure
avoid increasing C code for executing binary which cares cross platform
- python code is used because I couldn't write meson.build
appropriately describe dependency about materials which is used on
tests without it. please help me...
- as you said, kick this kind of tests by pg_regress accompanied with
needless PG server process execution. but pg_regress doesn't execute
test without it and making pg_regress require modification which has
not small scope of influence
Sorry, I re-send patch because a patch already sent includes needless
stderr output file.
NEW PATCH FILENAME: ecpg_cmd_notice_regress_test2.patch
In addition, diff between patches does not affect test behavior.
---
Sincerely,
Ryo Kanbayashi
https://github.com/ryogrid
Attachments:
ecpg_cmd_notice_regress_test2.patchapplication/octet-stream; name=ecpg_cmd_notice_regress_test2.patchDownload
diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule
index 254a0bacc75..e1cc61d8c52 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule
+++ b/src/interfaces/ecpg/test/ecpg_schedule
@@ -31,6 +31,8 @@ test: preproc/variable
test: preproc/outofscope
test: preproc/whenever
test: preproc/whenever_do_continue
+test: preproc/notice_check
+test: preproc/notice_informix_check
test: sql/array
test: sql/binary
test: sql/bytea
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_check.stderr b/src/interfaces/ecpg/test/expected/preproc-notice_check.stderr
new file mode 100644
index 00000000000..b31076a2527
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-notice_check.stderr
@@ -0,0 +1,15 @@
+notice.pgc:17: ERROR: AT option not allowed in CONNECT statement
+notice.pgc:18: ERROR: AT option not allowed in DISCONNECT statement
+notice.pgc:19: ERROR: AT option not allowed in SET CONNECTION statement
+notice.pgc:20: ERROR: AT option not allowed in TYPE statement
+notice.pgc:21: ERROR: AT option not allowed in WHENEVER statement
+notice.pgc:22: ERROR: AT option not allowed in VAR statement
+notice.pgc:25: WARNING: COPY FROM STDIN is not implemented
+notice.pgc:29: ERROR: using variable "cursor_var" in different declare statements is not supported
+notice.pgc:33: ERROR: cursor "duplicate_cursor" is already defined
+notice.pgc:36: ERROR: SHOW ALL is not implemented
+notice.pgc:39: WARNING: no longer supported LIMIT #,# syntax passed to server
+notice.pgc:42: WARNING: cursor "duplicate_cursor" has been declared but not opened
+notice.pgc:42: WARNING: cursor "duplicate_cursor" has been declared but not opened
+notice.pgc:42: WARNING: cursor ":cursor_var" has been declared but not opened
+notice.pgc:42: WARNING: cursor ":cursor_var" has been declared but not opened
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_check.stdout b/src/interfaces/ecpg/test/expected/preproc-notice_check.stdout
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stderr b/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stderr
new file mode 100644
index 00000000000..d6386aaa896
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stderr
@@ -0,0 +1,2 @@
+notice_informix.pgc:12: ERROR: AT option not allowed in CLOSE DATABASE statement
+notice_informix.pgc:15: ERROR: "database" cannot be used as cursor name in INFORMIX mode
diff --git a/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stdout b/src/interfaces/ecpg/test/expected/preproc-notice_informix_check.stdout
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/interfaces/ecpg/test/pg_regress_ecpg.c b/src/interfaces/ecpg/test/pg_regress_ecpg.c
index ba3477f9dd8..18d8b398a30 100644
--- a/src/interfaces/ecpg/test/pg_regress_ecpg.c
+++ b/src/interfaces/ecpg/test/pg_regress_ecpg.c
@@ -22,6 +22,13 @@
#include "lib/stringinfo.h"
#include "pg_regress.h"
+#define ECPG_CMD_NOTICE_TEST_PREFIX "preproc/notice"
+
+/*
+ * Tests whose prefix is ECPG_CMD_NOTICE_TEST_PREFIX check ecpg command's notice
+ * such as error or warning. Not checking of compiled ECPG programs behavior.
+ * So, we handle these tests differently.
+ */
/*
* Create a filtered copy of sourcefile, removing any path
@@ -115,6 +122,9 @@ ecpg_filter_stderr(const char *resultfile, const char *tmpfile)
{
char *p1 = strstr(linebuf.data, "connection to server ");
+ /* when ecpg command notice test */
+ char *p3 = strstr(linebuf.data, "preproc");
+
if (p1)
{
char *p2 = strstr(p1, "failed: ");
@@ -125,6 +135,18 @@ ecpg_filter_stderr(const char *resultfile, const char *tmpfile)
/* we don't bother to fix up linebuf.len */
}
}
+
+ if (p3)
+ {
+ char *p4 = strstr(p3, "notice");
+
+ if (p4)
+ {
+ memmove(p3, p4, strlen(p4) + 1);
+ /* we don't bother to fix up linebuf.len */
+ }
+ }
+
fputs(linebuf.data, t);
}
@@ -162,9 +184,7 @@ ecpg_start_test(const char *testname,
expectfile_source[MAXPGPATH];
char cmd[MAXPGPATH * 3];
char *appnameenv;
-
- snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
- snprintf(insource, sizeof(insource), "%s/%s.c", inputdir, testname);
+ bool is_ecpg_cmd_notice_test = false;
/* make a version of the test name that has dashes in place of slashes */
initStringInfo(&testname_dash);
@@ -175,15 +195,38 @@ ecpg_start_test(const char *testname,
*c = '-';
}
+ /* check for ECPG_CMD_NOTICE_TEST_PREFIX literal in the beginning */
+ if (strstr(testname, ECPG_CMD_NOTICE_TEST_PREFIX) == testname)
+ {
+ is_ecpg_cmd_notice_test = true;
+ }
+
+ if (is_ecpg_cmd_notice_test)
+ {
+#ifdef WIN32
+ snprintf(inprg, sizeof(inprg), "%s/%s.bat", inputdir, testname);
+#else
+ snprintf(inprg, sizeof(inprg), "%s/%s.sh", inputdir, testname);
+#endif
+ }
+ else
+ {
+ snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
+ snprintf(insource, sizeof(insource), "%s/%s.c", inputdir, testname);
+ }
+
snprintf(expectfile_stdout, sizeof(expectfile_stdout),
"%s/expected/%s.stdout",
expecteddir, testname_dash.data);
snprintf(expectfile_stderr, sizeof(expectfile_stderr),
"%s/expected/%s.stderr",
expecteddir, testname_dash.data);
- snprintf(expectfile_source, sizeof(expectfile_source),
- "%s/expected/%s.c",
- expecteddir, testname_dash.data);
+ if (!is_ecpg_cmd_notice_test)
+ {
+ snprintf(expectfile_source, sizeof(expectfile_source),
+ "%s/expected/%s.c",
+ expecteddir, testname_dash.data);
+ }
snprintf(outfile_stdout, sizeof(outfile_stdout),
"%s/results/%s.stdout",
@@ -191,9 +234,12 @@ ecpg_start_test(const char *testname,
snprintf(outfile_stderr, sizeof(outfile_stderr),
"%s/results/%s.stderr",
outputdir, testname_dash.data);
- snprintf(outfile_source, sizeof(outfile_source),
- "%s/results/%s.c",
- outputdir, testname_dash.data);
+ if (!is_ecpg_cmd_notice_test)
+ {
+ snprintf(outfile_source, sizeof(outfile_source),
+ "%s/results/%s.c",
+ outputdir, testname_dash.data);
+ }
add_stringlist_item(resultfiles, outfile_stdout);
add_stringlist_item(expectfiles, expectfile_stdout);
@@ -203,11 +249,18 @@ ecpg_start_test(const char *testname,
add_stringlist_item(expectfiles, expectfile_stderr);
add_stringlist_item(tags, "stderr");
- add_stringlist_item(resultfiles, outfile_source);
- add_stringlist_item(expectfiles, expectfile_source);
- add_stringlist_item(tags, "source");
+ if (!is_ecpg_cmd_notice_test)
+ {
+ add_stringlist_item(resultfiles, outfile_source);
+ add_stringlist_item(expectfiles, expectfile_source);
+ add_stringlist_item(tags, "source");
+
+ ecpg_filter_source(insource, outfile_source);
+ }
- ecpg_filter_source(insource, outfile_source);
+ appnameenv = psprintf("ecpg/%s", testname_dash.data);
+ setenv("PGAPPNAME", appnameenv, 1);
+ free(appnameenv);
snprintf(cmd, sizeof(cmd),
"\"%s\" >\"%s\" 2>\"%s\"",
@@ -215,10 +268,6 @@ ecpg_start_test(const char *testname,
outfile_stdout,
outfile_stderr);
- appnameenv = psprintf("ecpg/%s", testname_dash.data);
- setenv("PGAPPNAME", appnameenv, 1);
- free(appnameenv);
-
pid = spawn_process(cmd);
if (pid == INVALID_PID)
diff --git a/src/interfaces/ecpg/test/preproc/copy_files.py b/src/interfaces/ecpg/test/preproc/copy_files.py
new file mode 100644
index 00000000000..8678c86e1cd
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/copy_files.py
@@ -0,0 +1,21 @@
+import shutil
+import os
+import sys
+
+def main():
+ if len(sys.argv) < 4:
+ print("Usage: python copy_files.py <src_base> <destination_base> <file1> <file2> ...")
+ sys.exit(1)
+
+ src = sys.argv[1]
+ destination = sys.argv[2]
+ files = sys.argv[3:]
+
+ for file in files:
+ src_path = os.path.join(src, os.path.basename(file))
+ dest_path = os.path.join(destination, os.path.basename(file))
+
+ shutil.copy2(src_path, dest_path)
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/meson.build b/src/interfaces/ecpg/test/preproc/meson.build
index 775502e0102..26bef1f2e73 100644
--- a/src/interfaces/ecpg/test/preproc/meson.build
+++ b/src/interfaces/ecpg/test/preproc/meson.build
@@ -37,3 +37,31 @@ foreach pgc_file : pgc_files
kwargs: ecpg_test_exec_kw,
)
endforeach
+
+# copy materials for ecpg command notice test
+copy_materials = [
+ 'notice.pgc',
+ 'notice_informix.pgc',
+ 'notice_check.bat',
+ 'notice_check.sh',
+ 'notice_informix_check.bat',
+ 'notice_informix_check.sh',
+]
+
+copy_cmdline = [
+ python,
+ meson.current_source_dir() / 'copy_files.py',
+ meson.current_source_dir(),
+ meson.current_build_dir()
+]
+
+foreach file : copy_materials
+ copy_cmdline += file
+endforeach
+
+ecpg_test_dependencies += custom_target('copy_ecpg_test_materials',
+ input: meson.current_source_dir() / 'copy_files.py',
+ output: copy_materials,
+ command: copy_cmdline,
+ build_by_default: false,
+)
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice.pgc b/src/interfaces/ecpg/test/preproc/notice.pgc
new file mode 100644
index 00000000000..03a4f60d5e2
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice.pgc
@@ -0,0 +1,42 @@
+/* Test ECPG notice/warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *cursor_var = "mycursor";
+ short a;
+ EXEC SQL END DECLARE SECTION;
+
+ /* For consistency with other tests */
+ EXEC SQL CONNECT TO testdb AS con1;
+
+ /* Test AT option errors */
+ EXEC SQL AT con1 CONNECT TO testdb2;
+ EXEC SQL AT con1 DISCONNECT;
+ EXEC SQL AT con1 SET CONNECTION TO testdb2;
+ EXEC SQL AT con1 TYPE string IS char[11];
+ EXEC SQL AT con1 WHENEVER NOT FOUND CONTINUE;
+ EXEC SQL AT con1 VAR a IS int;
+
+ /* Test COPY FROM STDIN warning */
+ EXEC SQL COPY test FROM stdin;
+
+ /* Test same variable in multi declare statement */
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+
+ /* Test duplicate cursor declarations */
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+
+ /* Test SHOW ALL error */
+ EXEC SQL SHOW ALL;
+
+ /* Test deprecated LIMIT syntax warning */
+ EXEC SQL SELECT * FROM test LIMIT 10, 5;
+
+ return 0;
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_check.bat b/src/interfaces/ecpg/test/preproc/notice_check.bat
new file mode 100644
index 00000000000..172950897db
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_check.bat
@@ -0,0 +1,7 @@
+@echo off
+
+PATH=..\preproc\;%PATH%
+ecpg -o preproc\notice.c preproc\notice.pgc
+
+REM always return 0 for test purposes
+exit /b 0
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_check.sh b/src/interfaces/ecpg/test/preproc/notice_check.sh
new file mode 100755
index 00000000000..11338bb3ede
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_check.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+PATH=../preproc/:$PATH
+ecpg -c -o preproc/notice.c preproc/notice.pgc
+
+# always return 0 for testing purposes
+exit 0
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_informix.pgc b/src/interfaces/ecpg/test/preproc/notice_informix.pgc
new file mode 100644
index 00000000000..18281f3b9ee
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_informix.pgc
@@ -0,0 +1,18 @@
+/* Test ECPG notice/warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ /* For consistency with other tests */
+ $CONNECT TO testdb AS con1;
+
+ /* Test AT option usage at CLOSE statement in INFORMIX mode */
+ $AT con1 CLOSE database;
+
+ /* Test cursor name errors in INFORMIX mode */
+ $DECLARE database CURSOR FOR SELECT * FROM test;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/preproc/notice_informix_check.bat b/src/interfaces/ecpg/test/preproc/notice_informix_check.bat
new file mode 100644
index 00000000000..fd66da3b67e
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_informix_check.bat
@@ -0,0 +1,7 @@
+@echo off
+
+PATH=..\preproc\;%PATH%
+ecpg -C INFORMIX -o preproc\notice_informix.c preproc\notice_informix.pgc
+
+REM always return 0 for test purposes
+exit /b 0
\ No newline at end of file
diff --git a/src/interfaces/ecpg/test/preproc/notice_informix_check.sh b/src/interfaces/ecpg/test/preproc/notice_informix_check.sh
new file mode 100755
index 00000000000..ef543e1082e
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/notice_informix_check.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+PATH=../preproc/:$PATH
+ecpg -C INFORMIX -o preproc/notice_informix.c preproc/notice_informix.pgc
+
+# always return 0 for testing purposes
+exit 0
\ No newline at end of file
On 2025/02/06 8:57, Ryo Kanbayashi wrote:
On Wed, Feb 5, 2025 at 9:31 PM Ryo Kanbayashi <kanbayashi.dev@gmail.com> wrote:
Hi hackers,
When I wrote patch of ecpg command notice bug, I recognized needs of
regression tests for ecpg command notices and I say that I write the
tests.
Thanks for working on this!
I explain about implementation of this patch.
What is this patch
- add regression tests which test ecpg command notices such as warning
and errors
- test notices implemented in ecpg.addons fileBasic policy on implementation
- do in a way that matches the method using the existing pg_regress
command as much as possible
- avoid methods that increase the scope of influenceNext, I list answers to points that are likely to be pointed out in
advance below :)
- shell scripts and bat files is used due to ...
avoid non zero exit code of ecpg command makes tests failure
avoid increasing C code for executing binary which cares cross platform
- python code is used because I couldn't write meson.build
appropriately describe dependency about materials which is used on
tests without it. please help me...
- as you said, kick this kind of tests by pg_regress accompanied with
needless PG server process execution. but pg_regress doesn't execute
test without it and making pg_regress require modification which has
not small scope of influence
Wouldn't it be simpler to use the existing TAP test mechanism,
as shown in the attached patch? Please note that this patch is very WIP,
so there would be many places that need further implementation and refinement.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
Attachments:
WIP_ecpg_test_v1.patchtext/plain; charset=UTF-8; name=WIP_ecpg_test_v1.patchDownload
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 84199a9a5d..d0e3852a87 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -81,6 +81,9 @@ ecpg_keywords.o: ecpg_kwlist_d.h
c_keywords.o: c_kwlist_d.h
keywords.o: $(top_srcdir)/src/include/parser/kwlist.h
+check:
+ $(prove_check)
+
install: all installdirs
$(INSTALL_PROGRAM) ecpg$(X) '$(DESTDIR)$(bindir)'
diff --git a/src/interfaces/ecpg/preproc/t/001_ecpg.pl b/src/interfaces/ecpg/preproc/t/001_ecpg.pl
new file mode 100644
index 0000000000..bc52d19a7f
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/001_ecpg.pl
@@ -0,0 +1,37 @@
+
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+program_help_ok('ecpg');
+program_version_ok('ecpg');
+program_options_handling_ok('ecpg');
+command_fails(['ecpg'], 'ecpg without arguments fails');
+
+command_checks_all(
+ [ 'ecpg', 't/notice.pgc' ],
+ 3,
+ [qr//],
+ [
+ qr/ERROR: AT option not allowed in CONNECT statement/,
+ qr/ERROR: AT option not allowed in DISCONNECT statement/,
+ qr/ERROR: AT option not allowed in SET CONNECTION statement/,
+ qr/ERROR: AT option not allowed in TYPE statement/,
+ qr/ERROR: AT option not allowed in WHENEVER statement/,
+ qr/ERROR: AT option not allowed in VAR statement/,
+ qr/WARNING: COPY FROM STDIN is not implemented/,
+ qr/ERROR: using variable "cursor_var" in different declare statements is not supported/,
+ qr/ERROR: cursor "duplicate_cursor" is already defined/,
+ qr/ERROR: SHOW ALL is not implemented/,
+ qr/WARNING: no longer supported LIMIT/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/
+ ],
+ 'ecpg with warnings');
+
+done_testing();
diff --git a/src/interfaces/ecpg/preproc/t/notice.pgc b/src/interfaces/ecpg/preproc/t/notice.pgc
new file mode 100644
index 0000000000..7e54627fcb
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/notice.pgc
@@ -0,0 +1,42 @@
+/* Test ECPG notice/warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *cursor_var = "mycursor";
+ short a;
+ EXEC SQL END DECLARE SECTION;
+
+ /* For consistency with other tests */
+ EXEC SQL CONNECT TO testdb AS con1;
+
+ /* Test AT option errors */
+ EXEC SQL AT con1 CONNECT TO testdb2;
+ EXEC SQL AT con1 DISCONNECT;
+ EXEC SQL AT con1 SET CONNECTION TO testdb2;
+ EXEC SQL AT con1 TYPE string IS char[11];
+ EXEC SQL AT con1 WHENEVER NOT FOUND CONTINUE;
+ EXEC SQL AT con1 VAR a IS int;
+
+ /* Test COPY FROM STDIN warning */
+ EXEC SQL COPY test FROM stdin;
+
+ /* Test same variable in multi declare statement */
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+
+ /* Test duplicate cursor declarations */
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+
+ /* Test SHOW ALL error */
+ EXEC SQL SHOW ALL;
+
+ /* Test deprecated LIMIT syntax warning */
+ EXEC SQL SELECT * FROM test LIMIT 10, 5;
+
+ return 0;
+}
On Thu, Feb 13, 2025 at 10:49 PM Fujii Masao
<masao.fujii@oss.nttdata.com> wrote:
On 2025/02/06 8:57, Ryo Kanbayashi wrote:
On Wed, Feb 5, 2025 at 9:31 PM Ryo Kanbayashi <kanbayashi.dev@gmail.com> wrote:
Hi hackers,
When I wrote patch of ecpg command notice bug, I recognized needs of
regression tests for ecpg command notices and I say that I write the
tests.Thanks for working on this!
I explain about implementation of this patch.
What is this patch
- add regression tests which test ecpg command notices such as warning
and errors
- test notices implemented in ecpg.addons fileBasic policy on implementation
- do in a way that matches the method using the existing pg_regress
command as much as possible
- avoid methods that increase the scope of influenceNext, I list answers to points that are likely to be pointed out in
advance below :)
- shell scripts and bat files is used due to ...
avoid non zero exit code of ecpg command makes tests failure
avoid increasing C code for executing binary which cares cross platform
- python code is used because I couldn't write meson.build
appropriately describe dependency about materials which is used on
tests without it. please help me...
- as you said, kick this kind of tests by pg_regress accompanied with
needless PG server process execution. but pg_regress doesn't execute
test without it and making pg_regress require modification which has
not small scope of influenceWouldn't it be simpler to use the existing TAP test mechanism,
as shown in the attached patch? Please note that this patch is very WIP,
so there would be many places that need further implementation and refinement.
Fujii San,
Thank you for reviewing and indication of better implementation.
I rewrite my patch based on your reference implementation :)
---
Great regards,
Ryo Kanbayashi
NTT Open Source Software Center
On Tue, Feb 18, 2025 at 12:49 PM Ryo Kanbayashi
<kanbayashi.dev@gmail.com> wrote:
On Thu, Feb 13, 2025 at 10:49 PM Fujii Masao
<masao.fujii@oss.nttdata.com> wrote:On 2025/02/06 8:57, Ryo Kanbayashi wrote:
On Wed, Feb 5, 2025 at 9:31 PM Ryo Kanbayashi <kanbayashi.dev@gmail.com> wrote:
Hi hackers,
When I wrote patch of ecpg command notice bug, I recognized needs of
regression tests for ecpg command notices and I say that I write the
tests.Thanks for working on this!
I explain about implementation of this patch.
What is this patch
- add regression tests which test ecpg command notices such as warning
and errors
- test notices implemented in ecpg.addons fileBasic policy on implementation
- do in a way that matches the method using the existing pg_regress
command as much as possible
- avoid methods that increase the scope of influenceNext, I list answers to points that are likely to be pointed out in
advance below :)
- shell scripts and bat files is used due to ...
avoid non zero exit code of ecpg command makes tests failure
avoid increasing C code for executing binary which cares cross platform
- python code is used because I couldn't write meson.build
appropriately describe dependency about materials which is used on
tests without it. please help me...
- as you said, kick this kind of tests by pg_regress accompanied with
needless PG server process execution. but pg_regress doesn't execute
test without it and making pg_regress require modification which has
not small scope of influenceWouldn't it be simpler to use the existing TAP test mechanism,
as shown in the attached patch? Please note that this patch is very WIP,
so there would be many places that need further implementation and refinement.Fujii San,
Thank you for reviewing and indication of better implementation.
I rewrite my patch based on your reference implementation :)
Fujii San and other hackers,
I have rewrote my patch on TAP test sttyle :)
File for build are also updated.
Commitfest entry:
https://commitfest.postgresql.org/patch/5543/
---
Great regards,
Ryo Kanbayashi
NTT Open Source Software Center
Attachments:
ecpg-notice-regress-patch-tap-ver.patchapplication/octet-stream; name=ecpg-notice-regress-patch-tap-ver.patchDownload
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 84199a9a5d..d0e3852a87 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -81,6 +81,9 @@ ecpg_keywords.o: ecpg_kwlist_d.h
c_keywords.o: c_kwlist_d.h
keywords.o: $(top_srcdir)/src/include/parser/kwlist.h
+check:
+ $(prove_check)
+
install: all installdirs
$(INSTALL_PROGRAM) ecpg$(X) '$(DESTDIR)$(bindir)'
diff --git a/src/interfaces/ecpg/preproc/meson.build b/src/interfaces/ecpg/preproc/meson.build
index bfd0ed2efb..223d4e800c 100644
--- a/src/interfaces/ecpg/preproc/meson.build
+++ b/src/interfaces/ecpg/preproc/meson.build
@@ -86,3 +86,16 @@ ecpg_exe = executable('ecpg',
ecpg_targets += ecpg_exe
subdir('po', if_found: libintl)
+
+tests += {
+ 'name': 'ecpg',
+ 'sd': meson.current_source_dir(),
+ 'bd': meson.current_build_dir(),
+ 'tap': {
+ 'tests': [
+ 't/001_ecpg_notice.pl',
+ 't/002_ecpg_notice_informix.pl',
+ ],
+ 'deps': ecpg_exe,
+ },
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/preproc/t/001_ecpg_notice.pl b/src/interfaces/ecpg/preproc/t/001_ecpg_notice.pl
new file mode 100644
index 0000000000..320bd38264
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/001_ecpg_notice.pl
@@ -0,0 +1,37 @@
+
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+program_help_ok('ecpg');
+program_version_ok('ecpg');
+program_options_handling_ok('ecpg');
+command_fails(['ecpg'], 'ecpg without arguments fails');
+
+command_checks_all(
+ [ 'ecpg', 't/notice.pgc' ],
+ 3,
+ [qr//],
+ [
+ qr/ERROR: AT option not allowed in CONNECT statement/,
+ qr/ERROR: AT option not allowed in DISCONNECT statement/,
+ qr/ERROR: AT option not allowed in SET CONNECTION statement/,
+ qr/ERROR: AT option not allowed in TYPE statement/,
+ qr/ERROR: AT option not allowed in WHENEVER statement/,
+ qr/ERROR: AT option not allowed in VAR statement/,
+ qr/WARNING: COPY FROM STDIN is not implemented/,
+ qr/ERROR: using variable "cursor_var" in different declare statements is not supported/,
+ qr/ERROR: cursor "duplicate_cursor" is already defined/,
+ qr/ERROR: SHOW ALL is not implemented/,
+ qr/WARNING: no longer supported LIMIT/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/
+ ],
+ 'ecpg with erros and warnings');
+
+done_testing();
diff --git a/src/interfaces/ecpg/preproc/t/002_ecpg_notice_informix.pl b/src/interfaces/ecpg/preproc/t/002_ecpg_notice_informix.pl
new file mode 100644
index 0000000000..1607a66164
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/002_ecpg_notice_informix.pl
@@ -0,0 +1,24 @@
+
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+program_help_ok('ecpg');
+program_version_ok('ecpg');
+program_options_handling_ok('ecpg');
+command_fails(['ecpg'], 'ecpg without arguments fails');
+
+command_checks_all(
+ [ 'ecpg', '-C', 'INFORMIX', 't/notice_informix.pgc' ],
+ 3,
+ [qr//],
+ [
+ qr/ERROR: AT option not allowed in CLOSE DATABASE statement/,
+ qr/ERROR: "database" cannot be used as cursor name in INFORMIX mode/
+ ],
+ 'ecpg with errors');
+
+done_testing();
diff --git a/src/interfaces/ecpg/preproc/t/notice.pgc b/src/interfaces/ecpg/preproc/t/notice.pgc
new file mode 100644
index 0000000000..7e54627fcb
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/notice.pgc
@@ -0,0 +1,42 @@
+/* Test ECPG notice/warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *cursor_var = "mycursor";
+ short a;
+ EXEC SQL END DECLARE SECTION;
+
+ /* For consistency with other tests */
+ EXEC SQL CONNECT TO testdb AS con1;
+
+ /* Test AT option errors */
+ EXEC SQL AT con1 CONNECT TO testdb2;
+ EXEC SQL AT con1 DISCONNECT;
+ EXEC SQL AT con1 SET CONNECTION TO testdb2;
+ EXEC SQL AT con1 TYPE string IS char[11];
+ EXEC SQL AT con1 WHENEVER NOT FOUND CONTINUE;
+ EXEC SQL AT con1 VAR a IS int;
+
+ /* Test COPY FROM STDIN warning */
+ EXEC SQL COPY test FROM stdin;
+
+ /* Test same variable in multi declare statement */
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+
+ /* Test duplicate cursor declarations */
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+
+ /* Test SHOW ALL error */
+ EXEC SQL SHOW ALL;
+
+ /* Test deprecated LIMIT syntax warning */
+ EXEC SQL SELECT * FROM test LIMIT 10, 5;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/preproc/t/notice_informix.pgc b/src/interfaces/ecpg/preproc/t/notice_informix.pgc
new file mode 100644
index 0000000000..18281f3b9e
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/notice_informix.pgc
@@ -0,0 +1,18 @@
+/* Test ECPG notice/warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ /* For consistency with other tests */
+ $CONNECT TO testdb AS con1;
+
+ /* Test AT option usage at CLOSE statement in INFORMIX mode */
+ $AT con1 CLOSE database;
+
+ /* Test cursor name errors in INFORMIX mode */
+ $DECLARE database CURSOR FOR SELECT * FROM test;
+
+ return 0;
+}
On 2025/02/28 9:24, Ryo Kanbayashi wrote:
I have rewrote my patch on TAP test sttyle :)
File for build are also updated.
Thanks for updating the patch!
+ 'tests': [
+ 't/001_ecpg_notice.pl',
+ 't/002_ecpg_notice_informix.pl',
Since neither test emits "notice" messages, shouldn't the test file
names be revised to reflect this?
Also, I'm unsure if it's ideal to place input files directly under
the "t" directory. I looked for similar TAP tests with input files,
but I couldn't find any examples to guide this decision...
+program_help_ok('ecpg');
+program_version_ok('ecpg');
+program_options_handling_ok('ecpg');
+command_fails(['ecpg'], 'ecpg without arguments fails');
These checks seem unnecessary in 002 since they're already covered in 001.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
On Fri, Feb 28, 2025 at 11:27 PM Fujii Masao
<masao.fujii@oss.nttdata.com> wrote:
On 2025/02/28 9:24, Ryo Kanbayashi wrote:
I have rewrote my patch on TAP test sttyle :)
File for build are also updated.Thanks for updating the patch!
Thanks for review:)
+ 'tests': [ + 't/001_ecpg_notice.pl', + 't/002_ecpg_notice_informix.pl',Since neither test emits "notice" messages, shouldn't the test file
names be revised to reflect this?
I replaced "notice" to "err_warn_msg"
Also, I'm unsure if it's ideal to place input files directly under
the "t" directory. I looked for similar TAP tests with input files,
but I couldn't find any examples to guide this decision...
I couldn't too. So places are not changed.
+program_help_ok('ecpg'); +program_version_ok('ecpg'); +program_options_handling_ok('ecpg'); +command_fails(['ecpg'], 'ecpg without arguments fails');These checks seem unnecessary in 002 since they're already covered in 001.
I reflected above.
---
Great regards,
Ryo Kanbayashi
Attachments:
ecpg-notice-regress-patch-tap-ver-rebased.patchapplication/octet-stream; name=ecpg-notice-regress-patch-tap-ver-rebased.patchDownload
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 84199a9a5d0..d0e3852a878 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -81,6 +81,9 @@ ecpg_keywords.o: ecpg_kwlist_d.h
c_keywords.o: c_kwlist_d.h
keywords.o: $(top_srcdir)/src/include/parser/kwlist.h
+check:
+ $(prove_check)
+
install: all installdirs
$(INSTALL_PROGRAM) ecpg$(X) '$(DESTDIR)$(bindir)'
diff --git a/src/interfaces/ecpg/preproc/meson.build b/src/interfaces/ecpg/preproc/meson.build
index bfd0ed2efb4..01f2ac671ec 100644
--- a/src/interfaces/ecpg/preproc/meson.build
+++ b/src/interfaces/ecpg/preproc/meson.build
@@ -86,3 +86,16 @@ ecpg_exe = executable('ecpg',
ecpg_targets += ecpg_exe
subdir('po', if_found: libintl)
+
+tests += {
+ 'name': 'ecpg',
+ 'sd': meson.current_source_dir(),
+ 'bd': meson.current_build_dir(),
+ 'tap': {
+ 'tests': [
+ 't/001_ecpg_err_warn_msg.pl',
+ 't/002_ecpg_err_warn_msg_informix.pl',
+ ],
+ 'deps': ecpg_exe,
+ },
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/preproc/t/001_ecpg_err_warn_msg.pl b/src/interfaces/ecpg/preproc/t/001_ecpg_err_warn_msg.pl
new file mode 100644
index 00000000000..e0edec7cf7e
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/001_ecpg_err_warn_msg.pl
@@ -0,0 +1,37 @@
+
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+program_help_ok('ecpg');
+program_version_ok('ecpg');
+program_options_handling_ok('ecpg');
+command_fails(['ecpg'], 'ecpg without arguments fails');
+
+command_checks_all(
+ [ 'ecpg', 't/err_warn_msg.pgc' ],
+ 3,
+ [qr//],
+ [
+ qr/ERROR: AT option not allowed in CONNECT statement/,
+ qr/ERROR: AT option not allowed in DISCONNECT statement/,
+ qr/ERROR: AT option not allowed in SET CONNECTION statement/,
+ qr/ERROR: AT option not allowed in TYPE statement/,
+ qr/ERROR: AT option not allowed in WHENEVER statement/,
+ qr/ERROR: AT option not allowed in VAR statement/,
+ qr/WARNING: COPY FROM STDIN is not implemented/,
+ qr/ERROR: using variable "cursor_var" in different declare statements is not supported/,
+ qr/ERROR: cursor "duplicate_cursor" is already defined/,
+ qr/ERROR: SHOW ALL is not implemented/,
+ qr/WARNING: no longer supported LIMIT/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/
+ ],
+ 'ecpg with erros and warnings');
+
+done_testing();
diff --git a/src/interfaces/ecpg/preproc/t/002_ecpg_err_warn_msg_informix.pl b/src/interfaces/ecpg/preproc/t/002_ecpg_err_warn_msg_informix.pl
new file mode 100644
index 00000000000..e67dea1494f
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/002_ecpg_err_warn_msg_informix.pl
@@ -0,0 +1,19 @@
+
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+command_checks_all(
+ [ 'ecpg', '-C', 'INFORMIX', 't/err_warn_msg_informix.pgc' ],
+ 3,
+ [qr//],
+ [
+ qr/ERROR: AT option not allowed in CLOSE DATABASE statement/,
+ qr/ERROR: "database" cannot be used as cursor name in INFORMIX mode/
+ ],
+ 'ecpg with errors');
+
+done_testing();
diff --git a/src/interfaces/ecpg/preproc/t/err_warn_msg.pgc b/src/interfaces/ecpg/preproc/t/err_warn_msg.pgc
new file mode 100644
index 00000000000..5ab0a761866
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/err_warn_msg.pgc
@@ -0,0 +1,42 @@
+/* Test ECPG warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *cursor_var = "mycursor";
+ short a;
+ EXEC SQL END DECLARE SECTION;
+
+ /* For consistency with other tests */
+ EXEC SQL CONNECT TO testdb AS con1;
+
+ /* Test AT option errors */
+ EXEC SQL AT con1 CONNECT TO testdb2;
+ EXEC SQL AT con1 DISCONNECT;
+ EXEC SQL AT con1 SET CONNECTION TO testdb2;
+ EXEC SQL AT con1 TYPE string IS char[11];
+ EXEC SQL AT con1 WHENEVER NOT FOUND CONTINUE;
+ EXEC SQL AT con1 VAR a IS int;
+
+ /* Test COPY FROM STDIN warning */
+ EXEC SQL COPY test FROM stdin;
+
+ /* Test same variable in multi declare statement */
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+
+ /* Test duplicate cursor declarations */
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+
+ /* Test SHOW ALL error */
+ EXEC SQL SHOW ALL;
+
+ /* Test deprecated LIMIT syntax warning */
+ EXEC SQL SELECT * FROM test LIMIT 10, 5;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/preproc/t/err_warn_msg_informix.pgc b/src/interfaces/ecpg/preproc/t/err_warn_msg_informix.pgc
new file mode 100644
index 00000000000..839a023cb98
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/err_warn_msg_informix.pgc
@@ -0,0 +1,18 @@
+/* Test ECPG warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ /* For consistency with other tests */
+ $CONNECT TO testdb AS con1;
+
+ /* Test AT option usage at CLOSE statement in INFORMIX mode */
+ $AT con1 CLOSE database;
+
+ /* Test cursor name errors in INFORMIX mode */
+ $DECLARE database CURSOR FOR SELECT * FROM test;
+
+ return 0;
+}
On 2025/03/01 19:45, Ryo Kanbayashi wrote:
+program_help_ok('ecpg'); +program_version_ok('ecpg'); +program_options_handling_ok('ecpg'); +command_fails(['ecpg'], 'ecpg without arguments fails');These checks seem unnecessary in 002 since they're already covered in 001.
I reflected above.
Thanks for updating the patch!
I've made some minor fixes and cosmetic adjustments.
The updated patch is attached.
Unless there are any objections, I'll commit it.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
Attachments:
v6-0001-ecpg-Add-TAP-test-for-the-ecpg-command.patchtext/plain; charset=UTF-8; name=v6-0001-ecpg-Add-TAP-test-for-the-ecpg-command.patchDownload
From 3d06f586d1f9f4760f8259bc10c11f2152c3266f Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Mon, 3 Mar 2025 09:24:02 +0900
Subject: [PATCH v6] ecpg: Add TAP test for the ecpg command.
This commit adds a TAP test to verify that the ecpg command correctly
detects unsupported or disallowed statements in input files and reports
the appropriate error or warning messages.
This test helps catch bugs like the one introduced in commit 3d009e45bd,
which broke ecpg's handling of unsupported COPY FROM STDIN statements,
later fixed by commit 94b914f601b.
Author: Ryo Kanbayashi <kanbayashi.dev@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/CANOn0EzoMyxA1m-quDS1UeQUq6FNki6+GGiGucgr9tm2R78rKw@mail.gmail.com
---
src/interfaces/ecpg/preproc/Makefile | 3 ++
src/interfaces/ecpg/preproc/meson.build | 13 ++++++
.../ecpg/preproc/t/001_ecpg_err_warn_msg.pl | 40 ++++++++++++++++++
.../t/002_ecpg_err_warn_msg_informix.pl | 22 ++++++++++
.../ecpg/preproc/t/err_warn_msg.pgc | 42 +++++++++++++++++++
.../ecpg/preproc/t/err_warn_msg_informix.pgc | 18 ++++++++
6 files changed, 138 insertions(+)
create mode 100644 src/interfaces/ecpg/preproc/t/001_ecpg_err_warn_msg.pl
create mode 100644 src/interfaces/ecpg/preproc/t/002_ecpg_err_warn_msg_informix.pl
create mode 100644 src/interfaces/ecpg/preproc/t/err_warn_msg.pgc
create mode 100644 src/interfaces/ecpg/preproc/t/err_warn_msg_informix.pgc
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 84199a9a5d0..d0e3852a878 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -81,6 +81,9 @@ ecpg_keywords.o: ecpg_kwlist_d.h
c_keywords.o: c_kwlist_d.h
keywords.o: $(top_srcdir)/src/include/parser/kwlist.h
+check:
+ $(prove_check)
+
install: all installdirs
$(INSTALL_PROGRAM) ecpg$(X) '$(DESTDIR)$(bindir)'
diff --git a/src/interfaces/ecpg/preproc/meson.build b/src/interfaces/ecpg/preproc/meson.build
index bfd0ed2efb4..01f2ac671ec 100644
--- a/src/interfaces/ecpg/preproc/meson.build
+++ b/src/interfaces/ecpg/preproc/meson.build
@@ -86,3 +86,16 @@ ecpg_exe = executable('ecpg',
ecpg_targets += ecpg_exe
subdir('po', if_found: libintl)
+
+tests += {
+ 'name': 'ecpg',
+ 'sd': meson.current_source_dir(),
+ 'bd': meson.current_build_dir(),
+ 'tap': {
+ 'tests': [
+ 't/001_ecpg_err_warn_msg.pl',
+ 't/002_ecpg_err_warn_msg_informix.pl',
+ ],
+ 'deps': ecpg_exe,
+ },
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/preproc/t/001_ecpg_err_warn_msg.pl b/src/interfaces/ecpg/preproc/t/001_ecpg_err_warn_msg.pl
new file mode 100644
index 00000000000..a18e09e6ee8
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/001_ecpg_err_warn_msg.pl
@@ -0,0 +1,40 @@
+
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+program_help_ok('ecpg');
+program_version_ok('ecpg');
+program_options_handling_ok('ecpg');
+command_fails(['ecpg'], 'ecpg without arguments fails');
+
+# Test that the ecpg command correctly detects unsupported or disallowed
+# statements in the input file and reports the appropriate error or
+# warning messages.
+command_checks_all(
+ [ 'ecpg', 't/err_warn_msg.pgc' ],
+ 3,
+ [qr//],
+ [
+ qr/ERROR: AT option not allowed in CONNECT statement/,
+ qr/ERROR: AT option not allowed in DISCONNECT statement/,
+ qr/ERROR: AT option not allowed in SET CONNECTION statement/,
+ qr/ERROR: AT option not allowed in TYPE statement/,
+ qr/ERROR: AT option not allowed in WHENEVER statement/,
+ qr/ERROR: AT option not allowed in VAR statement/,
+ qr/WARNING: COPY FROM STDIN is not implemented/,
+ qr/ERROR: using variable "cursor_var" in different declare statements is not supported/,
+ qr/ERROR: cursor "duplicate_cursor" is already defined/,
+ qr/ERROR: SHOW ALL is not implemented/,
+ qr/WARNING: no longer supported LIMIT/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor "duplicate_cursor" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/,
+ qr/WARNING: cursor ":cursor_var" has been declared but not opened/
+ ],
+ 'ecpg with errors and warnings');
+
+done_testing();
diff --git a/src/interfaces/ecpg/preproc/t/002_ecpg_err_warn_msg_informix.pl b/src/interfaces/ecpg/preproc/t/002_ecpg_err_warn_msg_informix.pl
new file mode 100644
index 00000000000..cb0502dfc2b
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/002_ecpg_err_warn_msg_informix.pl
@@ -0,0 +1,22 @@
+
+# Copyright (c) 2021-2025, PostgreSQL Global Development Group
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+# Test that the ecpg command in INFORMIX mode correctly detects
+# unsupported or disallowed statements in the input file and reports
+# the appropriate error or warning messages.
+command_checks_all(
+ [ 'ecpg', '-C', 'INFORMIX', 't/err_warn_msg_informix.pgc' ],
+ 3,
+ [qr//],
+ [
+ qr/ERROR: AT option not allowed in CLOSE DATABASE statement/,
+ qr/ERROR: "database" cannot be used as cursor name in INFORMIX mode/
+ ],
+ 'ecpg in INFORMIX mode with errors and warnings');
+
+done_testing();
diff --git a/src/interfaces/ecpg/preproc/t/err_warn_msg.pgc b/src/interfaces/ecpg/preproc/t/err_warn_msg.pgc
new file mode 100644
index 00000000000..5ab0a761866
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/err_warn_msg.pgc
@@ -0,0 +1,42 @@
+/* Test ECPG warning/error messages */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *cursor_var = "mycursor";
+ short a;
+ EXEC SQL END DECLARE SECTION;
+
+ /* For consistency with other tests */
+ EXEC SQL CONNECT TO testdb AS con1;
+
+ /* Test AT option errors */
+ EXEC SQL AT con1 CONNECT TO testdb2;
+ EXEC SQL AT con1 DISCONNECT;
+ EXEC SQL AT con1 SET CONNECTION TO testdb2;
+ EXEC SQL AT con1 TYPE string IS char[11];
+ EXEC SQL AT con1 WHENEVER NOT FOUND CONTINUE;
+ EXEC SQL AT con1 VAR a IS int;
+
+ /* Test COPY FROM STDIN warning */
+ EXEC SQL COPY test FROM stdin;
+
+ /* Test same variable in multi declare statement */
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE :cursor_var CURSOR FOR SELECT * FROM test;
+
+ /* Test duplicate cursor declarations */
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+ EXEC SQL DECLARE duplicate_cursor CURSOR FOR SELECT * FROM test;
+
+ /* Test SHOW ALL error */
+ EXEC SQL SHOW ALL;
+
+ /* Test deprecated LIMIT syntax warning */
+ EXEC SQL SELECT * FROM test LIMIT 10, 5;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/preproc/t/err_warn_msg_informix.pgc b/src/interfaces/ecpg/preproc/t/err_warn_msg_informix.pgc
new file mode 100644
index 00000000000..e8db65eefa1
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/t/err_warn_msg_informix.pgc
@@ -0,0 +1,18 @@
+/* Test ECPG warning/error messages in INFORMIX mode */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ /* For consistency with other tests */
+ $CONNECT TO testdb AS con1;
+
+ /* Test AT option usage at CLOSE DATABASE statement in INFORMIX mode */
+ $AT con1 CLOSE DATABASE;
+
+ /* Test cursor name errors in INFORMIX mode */
+ $DECLARE database CURSOR FOR SELECT * FROM test;
+
+ return 0;
+}
--
2.48.1
On Mon, Mar 3, 2025 at 12:23 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
On 2025/03/01 19:45, Ryo Kanbayashi wrote:+program_help_ok('ecpg'); +program_version_ok('ecpg'); +program_options_handling_ok('ecpg'); +command_fails(['ecpg'], 'ecpg without arguments fails');These checks seem unnecessary in 002 since they're already covered in 001.
I reflected above.
Thanks for updating the patch!
I've made some minor fixes and cosmetic adjustments.
The updated patch is attached.Unless there are any objections, I'll commit it.
Thanks for reviewing and adustments.
There is no objections :)
---
Great regards,
Ryo Kanbayashi
NTT Open Source Software Center
On 2025/03/03 14:09, Ryo Kanbayashi wrote:
On Mon, Mar 3, 2025 at 12:23 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
On 2025/03/01 19:45, Ryo Kanbayashi wrote:+program_help_ok('ecpg'); +program_version_ok('ecpg'); +program_options_handling_ok('ecpg'); +command_fails(['ecpg'], 'ecpg without arguments fails');These checks seem unnecessary in 002 since they're already covered in 001.
I reflected above.
Thanks for updating the patch!
I've made some minor fixes and cosmetic adjustments.
The updated patch is attached.Unless there are any objections, I'll commit it.
Thanks for reviewing and adustments.
There is no objections :)
I've pushed the patch. Thanks!
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
On Mon, Mar 3, 2025 at 10:02 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
I've pushed the patch. Thanks!
Hi all,
+tests += { + 'name': 'ecpg', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), + 'tap': { + 'tests': [ + 't/001_ecpg_err_warn_msg.pl', + 't/002_ecpg_err_warn_msg_informix.pl', + ], + 'deps': ecpg_exe, + }, +}
My version of Meson is complaining about this use of 'deps':
../meson.build:3603: WARNING: Project targets '>=0.54' but uses
feature introduced in '0.60.0': list.<plus>. The right hand operand
was not a list.
Adding test "ecpg/001_ecpg_err_warn_msg"
...
ecpg_exe should perhaps be wrapped in a list for now? I.e.
- 'deps': ecpg_exe,
+ 'deps': [ecpg_exe],
Thanks,
--Jacob
On 2025/03/05 7:26, Jacob Champion wrote:
On Mon, Mar 3, 2025 at 10:02 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
I've pushed the patch. Thanks!
Hi all,
+tests += { + 'name': 'ecpg', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), + 'tap': { + 'tests': [ + 't/001_ecpg_err_warn_msg.pl', + 't/002_ecpg_err_warn_msg_informix.pl', + ], + 'deps': ecpg_exe, + }, +}My version of Meson is complaining about this use of 'deps':
../meson.build:3603: WARNING: Project targets '>=0.54' but uses
feature introduced in '0.60.0': list.<plus>. The right hand operand
was not a list.
Adding test "ecpg/001_ecpg_err_warn_msg"
...ecpg_exe should perhaps be wrapped in a list for now? I.e.
- 'deps': ecpg_exe, + 'deps': [ecpg_exe],
Thanks for reporting this and suggesting a fix. I think you're right.
I confirmed that the compiler warning also appears in my environment,
and your fix resolves it. I’ve converted your fix into a patch, which is attached.
Unless there are any objections, I'm thinking to commit it.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
Attachments:
v1-0001-ecpg-Fix-compiler-warning-in-ecpg-build-with-Meso.patchtext/plain; charset=UTF-8; name=v1-0001-ecpg-Fix-compiler-warning-in-ecpg-build-with-Meso.patchDownload
From 0a477edb2528db8b0008e9453a1de084f926e162 Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Wed, 5 Mar 2025 09:23:20 +0900
Subject: [PATCH v1] ecpg: Fix compiler warning in ecpg build with Meson.
Previously, Meson could produce a warning about the use of 'deps' in ecpg:
WARNING: Project targets '>=0.54' but uses a feature introduced in '0.60.0': list.<plus>. The right-hand operand was not a list.
The right-hand operand of 'deps' should be a list. This commit fixes
the warning by wrapping it with square brackets.
This issue was introduced in commit 28f04984f0c.
Author: Jacob Champion <jacob.champion@enterprisedb.com>
Discussion: https://postgr.es/m/CAOYmi+ks8wO06Ymxduw2h_eQJ_D4_jHGeyMK0P=p5Q3psnEdMA@mail.gmail.com
---
src/interfaces/ecpg/preproc/meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/interfaces/ecpg/preproc/meson.build b/src/interfaces/ecpg/preproc/meson.build
index 01f2ac671ec..c9f4035053d 100644
--- a/src/interfaces/ecpg/preproc/meson.build
+++ b/src/interfaces/ecpg/preproc/meson.build
@@ -96,6 +96,6 @@ tests += {
't/001_ecpg_err_warn_msg.pl',
't/002_ecpg_err_warn_msg_informix.pl',
],
- 'deps': ecpg_exe,
+ 'deps': [ecpg_exe],
},
}
\ No newline at end of file
--
2.48.1
On 2025/03/05 9:32, Fujii Masao wrote:
On 2025/03/05 7:26, Jacob Champion wrote:
On Mon, Mar 3, 2025 at 10:02 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
I've pushed the patch. Thanks!
Hi all,
+tests += { + 'name': 'ecpg', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), + 'tap': { + 'tests': [ + 't/001_ecpg_err_warn_msg.pl', + 't/002_ecpg_err_warn_msg_informix.pl', + ], + 'deps': ecpg_exe, + }, +}My version of Meson is complaining about this use of 'deps':
../meson.build:3603: WARNING: Project targets '>=0.54' but uses
feature introduced in '0.60.0': list.<plus>. The right hand operand
was not a list.
Adding test "ecpg/001_ecpg_err_warn_msg"
...ecpg_exe should perhaps be wrapped in a list for now? I.e.
- 'deps': ecpg_exe,
+ 'deps': [ecpg_exe],Thanks for reporting this and suggesting a fix. I think you're right.
I confirmed that the compiler warning also appears in my environment,
and your fix resolves it. I’ve converted your fix into a patch, which is attached.Unless there are any objections, I'm thinking to commit it.
I've pushed the patch. Thanks!
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION