1 2#pragma ident "%Z%%M% %I% %E% SMI" 3 4/* 5** 2003 April 6 6** 7** The author disclaims copyright to this source code. In place of 8** a legal notice, here is a blessing: 9** 10** May you do good and not evil. 11** May you find forgiveness for yourself and forgive others. 12** May you share freely, never taking more than you give. 13** 14************************************************************************* 15** This file contains code used to implement the COPY command. 16** 17** $Id: copy.c,v 1.9 2004/02/25 13:47:31 drh Exp $ 18*/ 19#include "sqliteInt.h" 20 21/* 22** The COPY command is for compatibility with PostgreSQL and specificially 23** for the ability to read the output of pg_dump. The format is as 24** follows: 25** 26** COPY table FROM file [USING DELIMITERS string] 27** 28** "table" is an existing table name. We will read lines of code from 29** file to fill this table with data. File might be "stdin". The optional 30** delimiter string identifies the field separators. The default is a tab. 31*/ 32void sqliteCopy( 33 Parse *pParse, /* The parser context */ 34 SrcList *pTableName, /* The name of the table into which we will insert */ 35 Token *pFilename, /* The file from which to obtain information */ 36 Token *pDelimiter, /* Use this as the field delimiter */ 37 int onError /* What to do if a constraint fails */ 38){ 39 Table *pTab; 40 int i; 41 Vdbe *v; 42 int addr, end; 43 char *zFile = 0; 44 const char *zDb; 45 sqlite *db = pParse->db; 46 47 48 if( sqlite_malloc_failed ) goto copy_cleanup; 49 assert( pTableName->nSrc==1 ); 50 pTab = sqliteSrcListLookup(pParse, pTableName); 51 if( pTab==0 || sqliteIsReadOnly(pParse, pTab, 0) ) goto copy_cleanup; 52 zFile = sqliteStrNDup(pFilename->z, pFilename->n); 53 sqliteDequote(zFile); 54 assert( pTab->iDb<db->nDb ); 55 zDb = db->aDb[pTab->iDb].zName; 56 if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) 57 || sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile, zDb) ){ 58 goto copy_cleanup; 59 } 60 v = sqliteGetVdbe(pParse); 61 if( v ){ 62 sqliteBeginWriteOperation(pParse, 1, pTab->iDb); 63 addr = sqliteVdbeOp3(v, OP_FileOpen, 0, 0, pFilename->z, pFilename->n); 64 sqliteVdbeDequoteP3(v, addr); 65 sqliteOpenTableAndIndices(pParse, pTab, 0); 66 if( db->flags & SQLITE_CountRows ){ 67 sqliteVdbeAddOp(v, OP_Integer, 0, 0); /* Initialize the row count */ 68 } 69 end = sqliteVdbeMakeLabel(v); 70 addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end); 71 if( pDelimiter ){ 72 sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n); 73 sqliteVdbeDequoteP3(v, addr); 74 }else{ 75 sqliteVdbeChangeP3(v, addr, "\t", 1); 76 } 77 if( pTab->iPKey>=0 ){ 78 sqliteVdbeAddOp(v, OP_FileColumn, pTab->iPKey, 0); 79 sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0); 80 }else{ 81 sqliteVdbeAddOp(v, OP_NewRecno, 0, 0); 82 } 83 for(i=0; i<pTab->nCol; i++){ 84 if( i==pTab->iPKey ){ 85 /* The integer primary key column is filled with NULL since its 86 ** value is always pulled from the record number */ 87 sqliteVdbeAddOp(v, OP_String, 0, 0); 88 }else{ 89 sqliteVdbeAddOp(v, OP_FileColumn, i, 0); 90 } 91 } 92 sqliteGenerateConstraintChecks(pParse, pTab, 0, 0, pTab->iPKey>=0, 93 0, onError, addr); 94 sqliteCompleteInsertion(pParse, pTab, 0, 0, 0, 0, -1); 95 if( (db->flags & SQLITE_CountRows)!=0 ){ 96 sqliteVdbeAddOp(v, OP_AddImm, 1, 0); /* Increment row count */ 97 } 98 sqliteVdbeAddOp(v, OP_Goto, 0, addr); 99 sqliteVdbeResolveLabel(v, end); 100 sqliteVdbeAddOp(v, OP_Noop, 0, 0); 101 sqliteEndWriteOperation(pParse); 102 if( db->flags & SQLITE_CountRows ){ 103 sqliteVdbeAddOp(v, OP_ColumnName, 0, 1); 104 sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC); 105 sqliteVdbeAddOp(v, OP_Callback, 1, 0); 106 } 107 } 108 109copy_cleanup: 110 sqliteSrcListDelete(pTableName); 111 sqliteFree(zFile); 112 return; 113} 114