I have an ANT script that I use to deploy PostgreSQL schema. As part of the script I load data into the database using PostgreSQL's COPY statement.
On Unix (both Mac OS X and Linux), I do the following: <tpsqlcmd cmd="COPY Planet FROM STDIN WITH CSV DELIMITER AS ',' QUOTE AS '"' ESCAPE AS '"'" input="${dist.db.data}${file.separator}Planet.csv"/> where tpsqlcmd is a macro I wrote that looks like this: <!-- macro for invoking a PostgreSQL command with terse output --> <macrodef name="tpsqlcmd"> <attribute name="cmd"/> <attribute name="output" default="dont.care"/> <attribute name="input" default="/dev/null"/> <sequential> <exec executable="psql" failonerror="true" outputproperty="@{output}" input="@{input}"> <env key="PGPASSWORD" value="${db.password}"/> <arg value="-q"/> <arg value="-U"/> <arg value="${db.user}"/> <arg value="-d"/> <arg value="${database}"/> <arg value="-t"/> <arg value="-c"/> <arg value="@{cmd}"/> </exec> </sequential> </macrodef> This work fine. On Windows, however, my build was failing. Running with "ant -v" shows the following: install-data: [exec] Current OS is Windows XP [exec] Redirecting input from file [exec] Setting environment variable: PGPASSWORD=<redacted> [exec] Executing 'psql' with arguments: [exec] '-q' [exec] '-U' [exec] 'postgres' [exec] '-d' [exec] 'gm' [exec] '-t' [exec] '-c' [exec] 'COPY Planet FROM STDIN WITH CSV DELIMITER AS ',' QUOTE AS '"' ESCAPE AS '"'' [exec] [exec] The ' characters around the executable and arguments are [exec] not part of the command. [exec] Opening C:\workspaces\GalaxyMaster\DB\Databases\GalaxyMaster\dist\db\Data\Planet.csv [exec] ERROR: COPY quote must be a single one-byte character BUILD FAILED C:\workspaces\GalaxyMaster\DB\Databases\GalaxyMaster\build.xml:244: The following error occurred while executing this line: C:\workspaces\GalaxyMaster\DB\Databases\GalaxyMaster\build.xml:52: exec returned: 1 at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(ProjectHelper.java:508) at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:397) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.Target.execute(Target.java:357) at org.apache.tools.ant.Target.performTasks(Target.java:385) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337) at org.apache.tools.ant.Project.executeTarget(Project.java:1306) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32) at org.apache.tools.ant.Project.executeTargets(Project.java:1189) at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423) at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137) Caused by: C:\workspaces\GalaxyMaster\DB\Databases\GalaxyMaster\build.xml:52: exec returned: 1 at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:636) at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:662) at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:487) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:62) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:394) ... 15 more The workaround is to change the macro invocation as follows: <tpsqlcmd cmd="COPY Planet FROM STDIN WITH CSV DELIMITER AS ',' QUOTE AS '""' ESCAPE AS '""'" input="${dist.db.data}${file.separator}Planet.csv"/> Note that I had to double the " references. Indeeds, if I run the psql command by hand from a C:> prompt, I also have to double the quotes, but I believe that's because I have to specify it like this: C:>psql -q -U postgres -d gm -t -c "COPY Planet FROM STDIN WITH CSV DELIMITER AS ',' QUOTE AS '""' ESCAPE AS '""'" < dist\db\Data\Planet.csv Note that the COPY statement is passed as a single value after the -c switch. I expected that using <exec> and <value> I wouldn't have to do that. Is this a bug in ANT, or do I just not understand how the Windows CreateProcess() call expects its arguments? As indicated, I can work around this, but it requires having OS-dependent targets in my script, which I'm not thrilled with. This is using ANT 1.7.1 inside Eclipse 3.5.2. -- Rick Genter rick.gen...@gmail.com --------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscr...@ant.apache.org For additional commands, e-mail: user-h...@ant.apache.org