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 '&quot;' ESCAPE AS '&quot;'" 
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 '&quot;&quot;' ESCAPE AS '&quot;&quot;'" 
input="${dist.db.data}${file.separator}Planet.csv"/>

Note that I had to double the &quot; 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

Reply via email to