From: drh Date: Tue, 31 May 2016 18:44:33 +0000 (+0000) Subject: Add the columns=N parameter to the CSV extension. X-Git-Tag: version-3.14.0~119 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1fc1a0f280e949736d10debf308c79494b16fe77;p=thirdparty%2Fsqlite.git Add the columns=N parameter to the CSV extension. FossilOrigin-Name: 28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac --- diff --git a/ext/misc/csv.c b/ext/misc/csv.c index d8087664fa..81a1d9ff63 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -315,13 +315,16 @@ static int csv_boolean(const char *z){ /* ** Parameters: ** filename=FILENAME Required -** schema=SCHEMA Optional +** schema=SCHEMA Alternative CSV schema. ** header=YES|NO First row of CSV defines the names of ** columns if "yes". Default "no". +** columns=N Assum the CSV file contains N columns. ** testflags=N Bitmask of test flags. Optional ** -** If header=no and not columns are listed, then the columns are named -** "c0", "c1", "c2", and so forth. +** If schema= is omitted, then the columns are named "c0", "c1", "c2", +** and so forth. If columns=N is omitted, then the file is opened and +** the number of columns in the first row is counted to determine the +** column count. If header=YES, then the first row is skipped. */ static int csvtabConnect( sqlite3 *db, @@ -330,14 +333,16 @@ static int csvtabConnect( sqlite3_vtab **ppVtab, char **pzErr ){ - CsvTable *pNew = 0; - int bHeader = -1; - int rc = SQLITE_OK; - int i; - char *zFilename = 0; - char *zSchema = 0; - int tstFlags = 0; - CsvReader sRdr; + CsvTable *pNew = 0; /* The CsvTable object to construct */ + int bHeader = -1; /* header= flags. -1 means not seen yet */ + int rc = SQLITE_OK; /* Result code from this routine */ + int i; /* Loop counter */ + char *zFilename = 0; /* Value of the filename= parameter */ + char *zSchema = 0; /* Value of the schema= parameter */ + int tstFlags = 0; /* Value of the testflags= parameter */ + int nCol = -99; /* Value of the columns= parameter */ + CsvReader sRdr; /* A CSV file reader used to store an error + ** message and/or to count the number of columns */ memset(&sRdr, 0, sizeof(sRdr)); for(i=3; i0 ){ + csv_errmsg(&sRdr, "more than one 'columns' parameter"); + goto csvtab_connect_error; + } + nCol = atoi(zValue); + if( nCol<=0 ){ + csv_errmsg(&sRdr, "must have at least one column"); + goto csvtab_connect_error; + } + }else { csv_errmsg(&sRdr, "unrecognized parameter '%s'", z); goto csvtab_connect_error; @@ -391,18 +407,22 @@ static int csvtabConnect( csv_errmsg(&sRdr, "missing 'filename' parameter"); goto csvtab_connect_error; } - if( csv_reader_open(&sRdr, zFilename) ){ + if( nCol<=0 && csv_reader_open(&sRdr, zFilename) ){ goto csvtab_connect_error; } pNew = sqlite3_malloc( sizeof(*pNew) ); *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) goto csvtab_connect_oom; memset(pNew, 0, sizeof(*pNew)); - do{ - const char *z = csv_read_one_field(&sRdr); - if( z==0 ) goto csvtab_connect_oom; - pNew->nCol++; - }while( sRdr.cTerm==',' ); + if( nCol>0 ){ + pNew->nCol = nCol; + }else{ + do{ + const char *z = csv_read_one_field(&sRdr); + if( z==0 ) goto csvtab_connect_oom; + pNew->nCol++; + }while( sRdr.cTerm==',' ); + } pNew->zFilename = zFilename; pNew->tstFlags = tstFlags; zFilename = 0; @@ -593,15 +613,26 @@ static int csvtabBestIndex( ){ CsvTable *pTab = (CsvTable*)tab; int i; + int nConst = 0; pIdxInfo->estimatedCost = 1000000; if( (pTab->tstFlags & CSVTEST_FIDX)==0 ){ return SQLITE_OK; } + /* The usual (an sensible) case is to take the "return SQLITE_OK" above. + ** The code below only runs when testflags=1. The following code + ** generates an artifical and unrealistic plan which is useful + ** for testing virtual table logic but is useless for real applications. */ for(i=0; inConstraint; i++){ + unsigned char op; if( pIdxInfo->aConstraint[i].usable==0 ) continue; - if( pIdxInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ ){ + op = pIdxInfo->aConstraint[i].op; + if( op==SQLITE_INDEX_CONSTRAINT_EQ + || op==SQLITE_INDEX_CONSTRAINT_LIKE + || op==SQLITE_INDEX_CONSTRAINT_GLOB + ){ pIdxInfo->estimatedCost = 10; - break; + pIdxInfo->aConstraintUsage[nConst].argvIndex = nConst+1; + nConst++; } } return SQLITE_OK; diff --git a/manifest b/manifest index 6ea00aab63..db47b84b3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\stestflags\sparameter\sto\sthe\scsv\sextension. -D 2016-05-31T18:08:35.263 +C Add\sthe\scolumns=N\sparameter\sto\sthe\sCSV\sextension. +D 2016-05-31T18:44:33.835 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -206,7 +206,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c d9b1dac6e43891174560abdd7d1d68bac20a2277 +F ext/misc/csv.c 39060a352f43e43df575484cc0f23ab61091dac3 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1497,7 +1497,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 00d3570c8bb96469c984903e20de589e998d4636 -R 7c1772dc60b41e0b51f7bd702d450189 +P b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 +R 65e8595850caa2b47ebf66d47e8638e5 U drh -Z ed250383d88d82f9f9e7a2529e3cc23c +Z b14790ed4c9841c10d8b6970f4ae5ca1 diff --git a/manifest.uuid b/manifest.uuid index 52e6a805d6..bc70991975 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 \ No newline at end of file +28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac \ No newline at end of file