My version of output_Csv (3.5.4) is missing conditional check. 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; for(i=0; z[i]; i++){ if( needCsvQuote[((unsigned char*)z)[i]] ){ i = 0; break; } }
Maybe your runtime library id different than the source code? HTH, Ken Dennis Cote <[EMAIL PROTECTED]> wrote: 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] -----------------------------------------------------------------------------