xref: /illumos-gate/usr/src/lib/libsqlite/src/copy.c (revision 4c87aefe8930bd07275b8dd2e96ea5f24d93a52e)
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 */
32 void 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 
109 copy_cleanup:
110   sqliteSrcListDelete(pTableName);
111   sqliteFree(zFile);
112   return;
113 }
114