Frank van Vugt wrote:
I'll look into it tomorrow, but was under the impression that:
* when using .mode csv, the separator _always_ is a comma
* when one wants a different separator, one has to use .separator ... in
combination with .mode list
needCsvQuote() is called from output_csv(), which is called when in csv-mode
only
Frank,
You are on to something here.
The following trace from sqlite shows the problem.
SQLite version 3.5.4
Enter ".help" for instructions
sqlite> create table t(a, b, c);
sqlite> insert into t values(1, 2, 3);
sqlite> insert into t values('10', '200', '3000');
sqlite> insert into t values('1,000', '2,000', '3,000');
sqlite> insert into t values(1.0, '20 0' , '3|0');
sqlite> insert into t values( 'one_with,a_comma', 'long "quoted" bit''s
& pieces
', 'one with a
...> CR');
sqlite> .mode csv
sqlite> select * from t;
1,2,3
10,200,3000
1,000,2,000,3,000
1.0,"20 0",3|0
one_with,a_comma,"long ""quoted"" bit's & pieces","one with a
CR"
sqlite> select typeof(a), typeof(b), typeof(c) from t;
integer,integer,integer
text,text,text
text,text,text
real,text,text
text,text,text
The third and fifth rows contains strings with embedded commas that are
not quoted in the output even though they should be.
SQLite does indeed seem to be quoting only fields that contain
characters in the needCsvQuote array (as in the fourth and fifth rows),
even though the code in output_csv() does seem to check for the
separator correctly.
static void output_csv(struct callback_data *p, const char *z, int bSep){
FILE *out = p->out;
if( z==0 ){
fprintf(out,"%s",p->nullvalue);
}else{
int i;
int nSep = strlen(p->separator);
for(i=0; z[i]; i++){
if( needCsvQuote[((unsigned char*)z)[i]]
|| (z[i]==p->separator[0] &&
(nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
i = 0;
break;
}
}
if( i==0 ){
putc('"', out);
for(i=0; z[i]; i++){
if( z[i]=='"' ) putc('"', out);
putc(z[i], out);
}
putc('"', out);
}else{
fprintf(out, "%s", z);
}
}
if( bSep ){
fprintf(p->out, p->separator);
}
}
It is using the correct separator string, a single comma, since the
commas in the output are produced by the last fprintf() call at the end
of output_csv(). I can't see where the logic is wrong. It should be
caught by the combination of the z[i]==p->separator[0] test and the
nSep==1 test, but the output is definitely wrong.
Can someone else spot the error?
During a bad call p->Separator is "," and z is "1,000", but the output
appears to come from the fprintf(out, "%s", z) line.
BTW, as a minor style issue, I think the last fprintf() call should use
out rather than p->out for the first argument for consistency reasons if
nothing else.
Dennis Cote
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------