/ Check-in [d9ebe9d7]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Cleanup and simplification of constraint processing. Simplifications to the VM for better test coverage. (CVS 4729)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d9ebe9d78c558af050c44ac4437ce0ef8193a4a8
User & Date: drh 2008-01-19 03:35:59
Context
2008-01-19
20:11
Miscellaneous code simplifications and cleanup and test coverage enhancements. (CVS 4730) check-in: af129b6d user: drh tags: trunk
03:35
Cleanup and simplification of constraint processing. Simplifications to the VM for better test coverage. (CVS 4729) check-in: d9ebe9d7 user: drh tags: trunk
2008-01-18
17:03
Fix test instrumentation problems on shared_err.test. (CVS 4728) check-in: 5aef5b0d user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960



961
962
963
964
965
966
967
....
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
....
1112
1113
1114
1115
1116
1117
1118



1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
....
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.225 2008/01/17 16:22:15 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
/*
** Generate code to do constraint checks prior to an INSERT or an UPDATE.
**
** The input is a range of consecutive registers as follows:
**
**    1.  The rowid of the row to be updated before the update.  This
**        value is omitted unless we are doing an UPDATE that involves a
**        change to the record number. (Or writing to a virtual table.)
**
**    2.  The rowid of the row after the update.
**
**    3.  The data in the first column of the entry after the update.
**
**    i.  Data from middle columns...
**
**    N.  The data in the last column of the entry after the update.
**
** The regRowid parameter is the index of the register containing (2).
**
** The old rowid shown as entry (1) above is omitted unless both isUpdate
** and rowidChng are 1.  isUpdate is true for UPDATEs and false for
** INSERTs and rowidChng is true if the record number is being changed.



**
** The code generated by this routine store new index entries into
** registers identified by aRegIdx[].  No index entry is created for
** indices where aRegIdx[i]==0.  The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
** attached to the table.
**
................................................................................
** for the constraint is used.
**
** The calling routine must open a read/write cursor for pTab with
** cursor number "baseCur".  All indices of pTab must also have open
** read/write cursors with cursor number baseCur+i for the i-th cursor.
** Except, if there is no possibility of a REPLACE action then
** cursors do not need to be open for indices where aRegIdx[i]==0.
**
** If the isUpdate flag is true, it means that the "baseCur" cursor is
** initially pointing to an entry that is being updated.  The isUpdate
** flag causes extra code to be generated so that the "baseCur" cursor
** is still pointing at the same entry after the routine returns.
** Without the isUpdate flag, the "baseCur" cursor might be moved.
*/
void sqlite3GenerateConstraintChecks(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int baseCur,        /* Index of a read/write cursor pointing at pTab */
  int regRowid,       /* Index of the range of input registers */
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  int rowidChng,      /* True if the rowid will change */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int overrideError,  /* Override onError to this if not OE_Default */
  int ignoreDest      /* Jump to this label on an OE_Ignore resolution */
){
  int i;
  Vdbe *v;
  int nCol;
  int onError;
  int j1, j2, j3;     /* Address of jump instructions */
  int regData;        /* Register containing first data column */
  int iCur;
  Index *pIdx;
  int seenReplace = 0;
  int hasTwoRowids = (isUpdate && rowidChng);

  v = sqlite3GetVdbe(pParse);
................................................................................
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    



    if( isUpdate ){
      j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1);
    }
    j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
    switch( onError ){
      default: {
        onError = OE_Abort;
        /* Fall thru into the next case */
      }
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
                         "PRIMARY KEY must be unique", P4_STATIC);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-hasTwoRowids);
        }
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    if( isUpdate ){
      sqlite3VdbeJumpHere(v, j2);
      sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-1);
    }

  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
................................................................................
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowDelete(pParse, pTab, baseCur, regR, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-hasTwoRowids);
        }
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j2);
    sqlite3VdbeJumpHere(v, j3);
    sqlite3ReleaseTempReg(pParse, regR);







|







 







|













|
>
>
>







 







<
<
<
<
<
<







|








|







 







>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
<
|
>







 







<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
....
1008
1009
1010
1011
1012
1013
1014






1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
....
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136



1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

1149
1150
1151
1152
1153
1154
1155
1156
1157
....
1232
1233
1234
1235
1236
1237
1238



1239
1240
1241
1242
1243
1244
1245
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.226 2008/01/19 03:35:59 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
/*
** Generate code to do constraint checks prior to an INSERT or an UPDATE.
**
** The input is a range of consecutive registers as follows:
**
**    1.  The rowid of the row to be updated before the update.  This
**        value is omitted unless we are doing an UPDATE that involves a
**        change to the record number or writing to a virtual table.
**
**    2.  The rowid of the row after the update.
**
**    3.  The data in the first column of the entry after the update.
**
**    i.  Data from middle columns...
**
**    N.  The data in the last column of the entry after the update.
**
** The regRowid parameter is the index of the register containing (2).
**
** The old rowid shown as entry (1) above is omitted unless both isUpdate
** and rowidChng are 1.  isUpdate is true for UPDATEs and false for
** INSERTs.  RowidChng means that the new rowid is explicitly specified by
** the update or insert statement.  If rowidChng is false, it means that
** the rowid is computed automatically in an insert or that the rowid value
** is not modified by the update.
**
** The code generated by this routine store new index entries into
** registers identified by aRegIdx[].  No index entry is created for
** indices where aRegIdx[i]==0.  The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
** attached to the table.
**
................................................................................
** for the constraint is used.
**
** The calling routine must open a read/write cursor for pTab with
** cursor number "baseCur".  All indices of pTab must also have open
** read/write cursors with cursor number baseCur+i for the i-th cursor.
** Except, if there is no possibility of a REPLACE action then
** cursors do not need to be open for indices where aRegIdx[i]==0.






*/
void sqlite3GenerateConstraintChecks(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int baseCur,        /* Index of a read/write cursor pointing at pTab */
  int regRowid,       /* Index of the range of input registers */
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  int rowidChng,      /* True if the rowid might collide with existing entry */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int overrideError,  /* Override onError to this if not OE_Default */
  int ignoreDest      /* Jump to this label on an OE_Ignore resolution */
){
  int i;
  Vdbe *v;
  int nCol;
  int onError;
  int j1, j2, j3;     /* Addresses of jump instructions */
  int regData;        /* Register containing first data column */
  int iCur;
  Index *pIdx;
  int seenReplace = 0;
  int hasTwoRowids = (isUpdate && rowidChng);

  v = sqlite3GetVdbe(pParse);
................................................................................
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    
    if( onError==OE_Replace && pTab->pIndex==0 ){
      seenReplace = 1;
    }else{
      if( isUpdate ){
        j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1);
      }
      j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
      switch( onError ){
        default: {
          onError = OE_Abort;
          /* Fall thru into the next case */
        }
        case OE_Rollback:
        case OE_Abort:
        case OE_Fail: {
          sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
                           "PRIMARY KEY must be unique", P4_STATIC);
          break;
        }
        case OE_Replace: {
          sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);



          seenReplace = 1;
          break;
        }
        case OE_Ignore: {
          assert( seenReplace==0 );
          sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
          break;
        }
      }
      sqlite3VdbeJumpHere(v, j3);
      if( isUpdate ){
        sqlite3VdbeJumpHere(v, j2);

      }
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
................................................................................
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowDelete(pParse, pTab, baseCur, regR, 0);



        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j2);
    sqlite3VdbeJumpHere(v, j3);
    sqlite3ReleaseTempReg(pParse, regR);

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.405 2008/01/17 17:15:56 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
    }

    /* Construct a record from the query result, but instead of
    ** saving that record, use it as a key to delete elements from
    ** the temporary table iParm.
    */
    case SRT_Except: {
      int addr, r1;
      r1 = sqlite3GetTempReg(pParse);
      addr = sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
      sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);
      sqlite3VdbeAddOp3(v, OP_NotFound, iParm, addr+3, r1);
      sqlite3VdbeAddOp1(v, OP_Delete, iParm);
      sqlite3ReleaseTempReg(pParse, r1);
      break;
    }
#endif

    /* Store the result as data using a unique key.
    */







|







 







|

|

<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
598
599
600
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.406 2008/01/19 03:35:59 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
    }

    /* Construct a record from the query result, but instead of
    ** saving that record, use it as a key to delete elements from
    ** the temporary table iParm.
    */
    case SRT_Except: {
      int r1;
      r1 = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
      sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);

      sqlite3VdbeAddOp2(v, OP_IdxDelete, iParm, r1);
      sqlite3ReleaseTempReg(pParse, r1);
      break;
    }
#endif

    /* Store the result as data using a unique key.
    */

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
98
99
100
101
102
103
104

105
106
107
108
109
110
111
...
500
501
502
503
504
505
506

507
508
509
510
511
512
513

514
515
516
517
518
519
520
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.169 2008/01/17 16:22:15 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  int chngRowid;         /* True if the record number is being changed */
  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
  int openAll = 0;       /* True if all indices need to be opened */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */
  int iDb;               /* Database containing the table being updated */


#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* Trying to update a view */
  int triggers_exist = 0;      /* True if any row triggers exist */
#endif
  int iBeginAfterTrigger;      /* Address of after trigger program */
  int iEndAfterTrigger;        /* Exit of after trigger program */
................................................................................
    */
    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
                                    aRegIdx, chngRowid, 1,
                                    onError, addr);

    /* Delete the old indices for the current record.
    */

    sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);

    /* If changing the record number, delete the old record.
    */
    if( chngRowid ){
      sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
    }


    /* Create the new index entries and the new record.
    */
    sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, 
                             aRegIdx, chngRowid, 1, -1, 0);
  }








|







 







>







 







>







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.170 2008/01/19 03:35:59 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  int chngRowid;         /* True if the record number is being changed */
  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
  int openAll = 0;       /* True if all indices need to be opened */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */
  int iDb;               /* Database containing the table being updated */
  int j1;                /* Addresses of jump instructions */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* Trying to update a view */
  int triggers_exist = 0;      /* True if any row triggers exist */
#endif
  int iBeginAfterTrigger;      /* Address of after trigger program */
  int iEndAfterTrigger;        /* Exit of after trigger program */
................................................................................
    */
    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
                                    aRegIdx, chngRowid, 1,
                                    onError, addr);

    /* Delete the old indices for the current record.
    */
    j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
    sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);

    /* If changing the record number, delete the old record.
    */
    if( chngRowid ){
      sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
    }
    sqlite3VdbeJumpHere(v, j1);

    /* Create the new index entries and the new record.
    */
    sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, 
                             aRegIdx, chngRowid, 1, -1, 0);
  }

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
...
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
....
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
....
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
....
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
....
1876
1877
1878
1879
1880
1881
1882

1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
....
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
....
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
....
2205
2206
2207
2208
2209
2210
2211

2212
2213


2214
2215
2216
2217
2218
2219
2220
2221
2222
....
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
....
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
....
3219
3220
3221
3222
3223
3224
3225

3226
3227
3228
3229




3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
....
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
....
3432
3433
3434
3435
3436
3437
3438

3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
....
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
....
3507
3508
3509
3510
3511
3512
3513

3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
....
3572
3573
3574
3575
3576
3577
3578

3579
3580
3581
3582
3583
3584
3585
3586
....
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
....
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779

3780
3781
3782
3783
3784
3785
3786
3787
3788

3789
3790
3791
3792
3793
3794
3795
3796
....
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
....
4786
4787
4788
4789
4790
4791
4792
4793

4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
....
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.699 2008/01/18 14:08:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
      if( db->nProgressOps==nProgressOps ){
        int prc;
        if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
        prc =db->xProgress(db->pProgressArg);
        if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
        if( prc!=0 ){
          rc = SQLITE_INTERRUPT;
          goto vdbe_halt;
        }
        nProgressOps = 0;
      }
      nProgressOps++;
    }
#endif

................................................................................
  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  if( pOp->opcode==OP_Move ){
    rc = sqlite3VdbeMemMove(pOut, pIn1);
  }else{
    Release(pOut);
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    if( pOp->opcode==OP_Copy ){
      Deephemeralize(pOut);
    }
  }
  REGISTER_TRACE(pOp->p2, pOut);
  break;
................................................................................
case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */
case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
  int flags;
  flags = pIn1->flags | pIn2->flags;
  if( (flags & MEM_Null)!=0 ){
    Release(pOut);
    pOut->flags = MEM_Null;
  }else if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
    i64 a, b;
    a = pIn1->u.i;
    b = pIn2->u.i;
    switch( pOp->opcode ){
      case OP_Add:         b += a;       break;
      case OP_Subtract:    b -= a;       break;
      case OP_Multiply:    b *= a;       break;
      case OP_Divide: {
        if( a==0 ) goto divide_by_zero;
        /* Dividing the largest possible negative 64-bit integer (1<<63) by 
        ** -1 returns an integer to large to store in a 64-bit data-type. On
        ** some architectures, the value overflows to (1<<63). On others,
        ** a SIGFPE is issued. The following statement normalizes this
        ** behaviour so that all architectures behave as if integer 
        ** overflow occured.
        */
        if( a==-1 && b==(((i64)1)<<63) ) a = 1;
        b /= a;
        break;
      }
      default: {
        if( a==0 ) goto divide_by_zero;
        if( a==-1 ) a = 1;
        b %= a;
        break;
      }
    }
    Release(pOut);
    pOut->u.i = b;
................................................................................
    a = sqlite3VdbeRealValue(pIn1);
    b = sqlite3VdbeRealValue(pIn2);
    switch( pOp->opcode ){
      case OP_Add:         b += a;       break;
      case OP_Subtract:    b -= a;       break;
      case OP_Multiply:    b *= a;       break;
      case OP_Divide: {
        if( a==0.0 ) goto divide_by_zero;
        b /= a;
        break;
      }
      default: {
        i64 ia = (i64)a;
        i64 ib = (i64)b;
        if( ia==0 ) goto divide_by_zero;
        if( ia==-1 ) ia = 1;
        b = ib % ia;
        break;
      }
    }
    if( sqlite3_isnan(b) ){
      goto divide_by_zero;
    }
    Release(pOut);
    pOut->r = b;
    pOut->flags = MEM_Real;
    if( (flags & MEM_Real)==0 ){
      sqlite3VdbeIntegerAffinity(pOut);
    }
  }
  break;

divide_by_zero:
  Release(pOut);
  pOut->flags = MEM_Null;
  break;
}

/* Opcode: CollSeq * * P4
**
** P4 is a pointer to a CollSeq struct. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
................................................................................
case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
  i64 a, b;

  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
    Release(pOut);
    pOut->flags = MEM_Null;
    break;
  }
  a = sqlite3VdbeIntValue(pIn2);
  b = sqlite3VdbeIntValue(pIn1);
  switch( pOp->opcode ){
    case OP_BitAnd:      a &= b;     break;
    case OP_BitOr:       a |= b;     break;
    case OP_ShiftLeft:   a <<= b;    break;
    case OP_ShiftRight:  a >>= b;    break;
    default:   /* CANT HAPPEN */     break;
  }
  Release(pOut);
  pOut->u.i = a;
  pOut->flags = MEM_Int;
  break;
}

................................................................................
      i64 payloadSize64;
      sqlite3BtreeKeySize(pCrsr, &payloadSize64);
      payloadSize = payloadSize64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &payloadSize);
    }
    nField = pC->nField;

  }else if( pC->pseudoTable ){
    /* The record is the sole entry of a pseudo-table */
    payloadSize = pC->nData;
    zRec = pC->pData;
    pC->cacheStatus = CACHE_STALE;
    assert( payloadSize==0 || zRec!=0 );
    nField = pC->nField;
    pCrsr = 0;
  }else{
    zRec = 0;
    payloadSize = 0;
    pCrsr = 0;
    nField = 0;
  }

  /* If payloadSize is 0, then just store a NULL */
  if( payloadSize==0 ){
    assert( pDest->flags==MEM_Null );
    goto op_column_out;
  }
................................................................................
  }

  assert( p2<nField );

  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( pC && pC->cacheStatus==p->cacheCtr ){
    aType = pC->aType;
    aOffset = pC->aOffset;
  }else{
    u8 *zIdx;        /* Index into header */
    u8 *zEndHdr;     /* Pointer to first byte after the header */
    u32 offset;      /* Offset into the data */
    int szHdrSz;     /* Size of the header size field at start of record */
................................................................................
  */
  for(pRec=pData0; pRec<=pLast; pRec++){
    int len;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
    }
    if( pRec->flags&MEM_Zero && pRec->n>0 ){
      ExpandBlob(pRec);
    }
    serial_type = sqlite3VdbeSerialType(pRec, file_format);
    len = sqlite3VdbeSerialTypeLen(serial_type);
    nData += len;
    nHdr += sqlite3VarintLen(serial_type);
    if( pRec->flags & MEM_Zero ){
      /* Only pure zero-filled BLOBs can be input to this Opcode.
................................................................................
** commit when the VDBE halts.
**
** The statement is begun on the database file with index P1.  The main
** database file has an index of 0 and the file used for temporary tables
** has an index of 1.
*/
case OP_Statement: {

  int i = pOp->p1;
  Btree *pBt;


  if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt)!=0
        && (db->autoCommit==0 || db->activeVdbeCnt>1) ){
    assert( sqlite3BtreeIsInTrans(pBt) );
    assert( (p->btreeMask & (1<<i))!=0 );
    if( !sqlite3BtreeIsInStmt(pBt) ){
      rc = sqlite3BtreeBeginStmt(pBt);
      p->openedStatement = 1;
    }
  }
................................................................................
    p2 = pIn2->u.i;
    assert( p2>=2 );
  }
  assert( i>=0 );
  pCur = allocateCursor(p, i, iDb);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;
  if( pX==0 ) break;
  /* We always provide a key comparison function.  If the table being
  ** opened is of type INTKEY, the comparision function will be ignored. */
  rc = sqlite3BtreeCursor(pX, p2, wrFlag,
           sqlite3VdbeRecordCompare, pOp->p4.p,
           &pCur->pCursor);
  if( pOp->p4type==P4_KEYINFO ){
    pCur->pKeyInfo = pOp->p4.pKeyInfo;
................................................................................
/* Opcode: Close P1 * * * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {
  int i = pOp->p1;
  if( i>=0 && i<p->nCursor ){
    sqlite3VdbeFreeCursor(p, p->apCsr[i]);
    p->apCsr[i] = 0;
  }
  break;
}

/* Opcode: MoveGe P1 P2 P3 * *
**
** Use the value in register P3 as a key.  Reposition
** cursor P1 so that it points to the smallest entry that is greater
................................................................................
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/
case OP_Insert: {
  Mem *pData = &p->aMem[pOp->p2];
  Mem *pKey = &p->aMem[pOp->p3];


  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );




  REGISTER_TRACE(pOp->p2, pData);
  REGISTER_TRACE(pOp->p3, pKey);
  if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
    i64 iKey;   /* The integer ROWID or key for the record to be inserted */

    assert( pKey->flags & MEM_Int );
    assert( pC->isTable );
    iKey = intToKey(pKey->u.i);

    if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
    if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
    if( pC->nextRowidValid && pKey->u.i>=pC->nextRowid ){
      pC->nextRowidValid = 0;
    }
    if( pData->flags & MEM_Null ){
      pData->z = 0;
      pData->n = 0;
    }else{
      assert( pData->flags & (MEM_Blob|MEM_Str) );
    }
    if( pC->pseudoTable ){
      sqlite3_free(pC->pData);
      pC->iKey = iKey;
      pC->nData = pData->n;
      if( pData->flags & MEM_Dyn ){
        pC->pData = pData->z;
        pData->flags &= ~MEM_Dyn;
        pData->flags |= MEM_Ephem;
      }else{
        pC->pData = sqlite3_malloc( pC->nData+2 );
        if( !pC->pData ) goto no_mem;
        memcpy(pC->pData, pData->z, pC->nData);
        pC->pData[pC->nData] = 0;
        pC->pData[pC->nData+1] = 0;
      }
      pC->nullRow = 0;
    }else{
      int nZero;
      if( pData->flags & MEM_Zero ){
        nZero = pData->u.i;
      }else{
        nZero = 0;
      }
      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                              pData->z, pData->n, nZero,
                              pOp->p5 & OPFLAG_APPEND);
    }
    
    pC->rowidIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;

    /* Invoke the update-hook if required. */
    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
      const char *zDb = db->aDb[pC->iDb].zName;
      const char *zTbl = pOp->p4.z;
      int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
      assert( pC->isTable );
      db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
      assert( pC->iDb>=0 );
    }
  }

  break;
}

/* Opcode: Delete P1 P2 * P4 *
**
** Delete the record at which the P1 cursor is currently pointing.
**
................................................................................
  assert( pC!=0 );
  if( pC->nullRow ){
    pOut->flags = MEM_Null;
  }else if( pC->pCursor!=0 ){
    BtCursor *pCrsr = pC->pCursor;
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->nullRow ){
      pOut->flags = MEM_Null;
      break;
    }else if( pC->isIndex ){
      i64 n64;
      assert( !pC->isTable );
      sqlite3BtreeKeySize(pCrsr, &n64);
      if( n64>SQLITE_MAX_LENGTH ){
        goto too_big;
      }
      n = n64;
................................................................................
      pOut->z = z;
    }
    if( pC->isIndex ){
      rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
    }else{
      rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
    }

  }else if( pC->pseudoTable ){
    pOut->n = pC->nData;
    assert( pC->nData<=SQLITE_MAX_LENGTH );
    pOut->z = pC->pData;
    pOut->flags = MEM_Blob|MEM_Ephem;
  }else{
    pOut->flags = MEM_Null;
  }
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Rowid P1 P2 * * *
................................................................................
  assert( pC!=0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  if( pC->rowidIsValid ){
    v = pC->lastRowid;
  }else if( pC->pseudoTable ){
    v = keyToInt(pC->iKey);
  }else if( pC->nullRow || pC->pCursor==0 ){
    /* Leave the rowid set to a NULL */
    break;
  }else{
    assert( pC->pCursor!=0 );
    sqlite3BtreeKeySize(pC->pCursor, &v);
    v = keyToInt(v);
  }
................................................................................
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {        /* jump */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;


  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    int res;
    rc = sqlite3BtreeLast(pCrsr, &res);
    pC->nullRow = res;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
    if( res && pOp->p2>0 ){
      pc = pOp->p2 - 1;
    }
  }else{
    pC->nullRow = 0;
  }
  break;
}


/* Opcode: Sort P1 P2 * * *
**
................................................................................
    pC->atFirst = res==0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }else{
    res = 1;
  }
  pC->nullRow = res;

  if( res && pOp->p2>0 ){
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Next P1 P2 * * *
**
................................................................................
      pOut->flags = MEM_Int;
      pOut->u.i = rowid;
    }
  }
  break;
}

/* Opcode: IdxGT P1 P2 P3 * *
**
** The value in register P3 is an index entry that omits the ROWID.  Compare
** the value in register P3 against the index that P1 is currently pointing to.
** Ignore the ROWID on the P1 index.
**
** The P3 value might have fewer columns that P1 index.
**
** If the P1 index entry is greater than the value in register P3
** then jump to P2.  Otherwise fall through to the next instruction.
*/
/* Opcode: IdxGE P1 P2 P3 * P5
**
** The value in register P3 is an index entry that omits the ROWID.  Compare
** this value against the index that P1 is currently pointing to.
** Ignore the ROWID on the P1 index.
**
** If the P1 index entry is greater than or equal to the value in 
................................................................................
**
** If P5 is non-zero then the
** index taken from register P3 is temporarily increased by
** an epsilon prior to the comparison.  This makes the opcode work
** like IdxLE.
*/
case OP_IdxLT:          /* jump, in3 */
case OP_IdxGT:          /* jump, in3 */
case OP_IdxGE: {        /* jump, in3 */
  int i= pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
    int res;
 
    assert( pIn3->flags & MEM_Blob );  /* Created using OP_MakeRecord */
    assert( pC->deferredMoveto==0 );
    ExpandBlob(pIn3);

    *pC->pIncrKey = pOp->p5!=0;
    assert( pOp->opcode!=OP_IdxGT || pOp->p5==0 );
    rc = sqlite3VdbeIdxKeyCompare(pC, pIn3->n, (u8*)pIn3->z, &res);
    *pC->pIncrKey = 0;
    if( rc!=SQLITE_OK ){
      break;
    }
    if( pOp->opcode==OP_IdxLT ){
      res = -res;

    }else if( pOp->opcode==OP_IdxGE ){
      res++;
    }
    if( res>0 ){
      pc = pOp->p2 - 1 ;
    }
  }
  break;
................................................................................
  }
  aRoot[j] = 0;
  assert( pOp->p5<db->nDb );
  assert( (p->btreeMask & (1<<pOp->p5))!=0 );
  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
                                 pnErr->u.i, &nErr);
  pnErr->u.i -= nErr;
  Release(pIn1);
  if( nErr==0 ){
    assert( z==0 );
    pIn1->flags = MEM_Null;
  }else{
    pIn1->z = z;
    pIn1->n = strlen(z);
    pIn1->flags = MEM_Str | MEM_Dyn | MEM_Term;
    pIn1->xDel = 0;
  }
  pIn1->enc = SQLITE_UTF8;
................................................................................
        registerTrace(p->trace, pOp->p3, pOut);
      }
    }
#endif  /* SQLITE_DEBUG */
#endif  /* NDEBUG */
  }  /* The end of the for(;;) loop the loops through opcodes */

  /* If we reach this point, it means that execution is finished.

  */
vdbe_halt:
  if( rc ){
    p->rc = rc;
    rc = SQLITE_ERROR;
  }else{
    rc = SQLITE_DONE;
  }
  sqlite3VdbeHalt(p);

  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  sqlite3BtreeMutexArrayLeave(&p->aMutex);
................................................................................

  /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
  ** is encountered.
  */
too_big:
  sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);
  rc = SQLITE_TOOBIG;
  goto vdbe_halt;

  /* Jump to here if a malloc() fails.
  */
no_mem:
  db->mallocFailed = 1;
  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
  rc = SQLITE_NOMEM;
  goto vdbe_halt;

  /* Jump to here for an SQLITE_MISUSE error.
  */
abort_due_to_misuse:
  rc = SQLITE_MISUSE;
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  if( p->zErrMsg==0 ){
    if( db->mallocFailed ) rc = SQLITE_NOMEM;
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  }
  goto vdbe_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */
abort_due_to_interrupt:
  assert( db->u1.isInterrupted );
  if( db->magic!=SQLITE_MAGIC_BUSY ){
    rc = SQLITE_MISUSE;
  }else{
    rc = SQLITE_INTERRUPT;
  }
  p->rc = rc;
  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  goto vdbe_halt;
}







|







 







|







 







<







 







|
<
<
|








|












|







 







|






|






|










|
|
<







 







|
<








|
|







 







>
|







<
<
<
<
<







 







|







 







|







 







>
|
|
>
>
|
<







 







<







 







|
|
|
<







 







>



|
>
>
>
>


<
<

<
<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
<
<







 







<
<
<
|







 







>
|




<
<







 







|







 







>




|
|
|
|
|
|
|
|
<
<
<







 







>
|







 







<
<
<
<
<
<
<
<
<
<
<







 







<












>
|
<







>
|







 







|


<







 







|
>

|
|
|
|
<
<
<







 







|







|











|
|
|
<
|













|

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
...
946
947
948
949
950
951
952

953
954
955
956
957
958
959
....
1069
1070
1071
1072
1073
1074
1075
1076


1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
....
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143

1144
1145
1146
1147
1148
1149
1150
....
1287
1288
1289
1290
1291
1292
1293
1294

1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
....
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886





1887
1888
1889
1890
1891
1892
1893
....
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
....
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
....
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208

2209
2210
2211
2212
2213
2214
2215
....
2522
2523
2524
2525
2526
2527
2528

2529
2530
2531
2532
2533
2534
2535
....
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688

2689
2690
2691
2692
2693
2694
2695
....
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227


3228


3229

3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281


3282
3283
3284
3285
3286
3287
3288
....
3388
3389
3390
3391
3392
3393
3394



3395
3396
3397
3398
3399
3400
3401
3402
....
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430


3431
3432
3433
3434
3435
3436
3437
....
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
....
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511



3512
3513
3514
3515
3516
3517
3518
....
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
....
3702
3703
3704
3705
3706
3707
3708











3709
3710
3711
3712
3713
3714
3715
....
3733
3734
3735
3736
3737
3738
3739

3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753

3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
....
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034

4035
4036
4037
4038
4039
4040
4041
....
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771



4772
4773
4774
4775
4776
4777
4778
....
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809

4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.700 2008/01/19 03:35:59 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
      if( db->nProgressOps==nProgressOps ){
        int prc;
        if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
        prc =db->xProgress(db->pProgressArg);
        if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
        if( prc!=0 ){
          rc = SQLITE_INTERRUPT;
          goto vdbe_error_halt;
        }
        nProgressOps = 0;
      }
      nProgressOps++;
    }
#endif

................................................................................
  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  if( pOp->opcode==OP_Move ){
    rc = sqlite3VdbeMemMove(pOut, pIn1);
  }else{

    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    if( pOp->opcode==OP_Copy ){
      Deephemeralize(pOut);
    }
  }
  REGISTER_TRACE(pOp->p2, pOut);
  break;
................................................................................
case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */
case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
  int flags;
  flags = pIn1->flags | pIn2->flags;
  if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;


  if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
    i64 a, b;
    a = pIn1->u.i;
    b = pIn2->u.i;
    switch( pOp->opcode ){
      case OP_Add:         b += a;       break;
      case OP_Subtract:    b -= a;       break;
      case OP_Multiply:    b *= a;       break;
      case OP_Divide: {
        if( a==0 ) goto arithmetic_result_is_null;
        /* Dividing the largest possible negative 64-bit integer (1<<63) by 
        ** -1 returns an integer to large to store in a 64-bit data-type. On
        ** some architectures, the value overflows to (1<<63). On others,
        ** a SIGFPE is issued. The following statement normalizes this
        ** behaviour so that all architectures behave as if integer 
        ** overflow occured.
        */
        if( a==-1 && b==(((i64)1)<<63) ) a = 1;
        b /= a;
        break;
      }
      default: {
        if( a==0 ) goto arithmetic_result_is_null;
        if( a==-1 ) a = 1;
        b %= a;
        break;
      }
    }
    Release(pOut);
    pOut->u.i = b;
................................................................................
    a = sqlite3VdbeRealValue(pIn1);
    b = sqlite3VdbeRealValue(pIn2);
    switch( pOp->opcode ){
      case OP_Add:         b += a;       break;
      case OP_Subtract:    b -= a;       break;
      case OP_Multiply:    b *= a;       break;
      case OP_Divide: {
        if( a==0.0 ) goto arithmetic_result_is_null;
        b /= a;
        break;
      }
      default: {
        i64 ia = (i64)a;
        i64 ib = (i64)b;
        if( ia==0 ) goto arithmetic_result_is_null;
        if( ia==-1 ) ia = 1;
        b = ib % ia;
        break;
      }
    }
    if( sqlite3_isnan(b) ){
      goto arithmetic_result_is_null;
    }
    Release(pOut);
    pOut->r = b;
    pOut->flags = MEM_Real;
    if( (flags & MEM_Real)==0 ){
      sqlite3VdbeIntegerAffinity(pOut);
    }
  }
  break;

arithmetic_result_is_null:
  sqlite3VdbeMemSetNull(pOut);

  break;
}

/* Opcode: CollSeq * * P4
**
** P4 is a pointer to a CollSeq struct. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
................................................................................
case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
  i64 a, b;

  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
    sqlite3VdbeMemSetNull(pOut);

    break;
  }
  a = sqlite3VdbeIntValue(pIn2);
  b = sqlite3VdbeIntValue(pIn1);
  switch( pOp->opcode ){
    case OP_BitAnd:      a &= b;     break;
    case OP_BitOr:       a |= b;     break;
    case OP_ShiftLeft:   a <<= b;    break;
    default:  assert( pOp->opcode==OP_ShiftRight );
                         a >>= b;    break;
  }
  Release(pOut);
  pOut->u.i = a;
  pOut->flags = MEM_Int;
  break;
}

................................................................................
      i64 payloadSize64;
      sqlite3BtreeKeySize(pCrsr, &payloadSize64);
      payloadSize = payloadSize64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &payloadSize);
    }
    nField = pC->nField;
  }else{
    assert( pC->pseudoTable );
    /* The record is the sole entry of a pseudo-table */
    payloadSize = pC->nData;
    zRec = pC->pData;
    pC->cacheStatus = CACHE_STALE;
    assert( payloadSize==0 || zRec!=0 );
    nField = pC->nField;
    pCrsr = 0;





  }

  /* If payloadSize is 0, then just store a NULL */
  if( payloadSize==0 ){
    assert( pDest->flags==MEM_Null );
    goto op_column_out;
  }
................................................................................
  }

  assert( p2<nField );

  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( pC->cacheStatus==p->cacheCtr ){
    aType = pC->aType;
    aOffset = pC->aOffset;
  }else{
    u8 *zIdx;        /* Index into header */
    u8 *zEndHdr;     /* Pointer to first byte after the header */
    u32 offset;      /* Offset into the data */
    int szHdrSz;     /* Size of the header size field at start of record */
................................................................................
  */
  for(pRec=pData0; pRec<=pLast; pRec++){
    int len;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
    }
    if( pRec->flags&MEM_Zero && pRec->n>0 ){
      sqlite3VdbeMemExpandBlob(pRec);
    }
    serial_type = sqlite3VdbeSerialType(pRec, file_format);
    len = sqlite3VdbeSerialTypeLen(serial_type);
    nData += len;
    nHdr += sqlite3VarintLen(serial_type);
    if( pRec->flags & MEM_Zero ){
      /* Only pure zero-filled BLOBs can be input to this Opcode.
................................................................................
** commit when the VDBE halts.
**
** The statement is begun on the database file with index P1.  The main
** database file has an index of 0 and the file used for temporary tables
** has an index of 1.
*/
case OP_Statement: {
  if( db->autoCommit==0 || db->activeVdbeCnt>1 ){
    int i = pOp->p1;
    Btree *pBt;
    assert( i>=0 && i<db->nDb );
    assert( db->aDb[i].pBt!=0 );
    pBt = db->aDb[i].pBt;

    assert( sqlite3BtreeIsInTrans(pBt) );
    assert( (p->btreeMask & (1<<i))!=0 );
    if( !sqlite3BtreeIsInStmt(pBt) ){
      rc = sqlite3BtreeBeginStmt(pBt);
      p->openedStatement = 1;
    }
  }
................................................................................
    p2 = pIn2->u.i;
    assert( p2>=2 );
  }
  assert( i>=0 );
  pCur = allocateCursor(p, i, iDb);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;

  /* We always provide a key comparison function.  If the table being
  ** opened is of type INTKEY, the comparision function will be ignored. */
  rc = sqlite3BtreeCursor(pX, p2, wrFlag,
           sqlite3VdbeRecordCompare, pOp->p4.p,
           &pCur->pCursor);
  if( pOp->p4type==P4_KEYINFO ){
    pCur->pKeyInfo = pOp->p4.pKeyInfo;
................................................................................
/* Opcode: Close P1 * * * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {
  int i = pOp->p1;
  assert( i>=0 && i<p->nCursor );
  sqlite3VdbeFreeCursor(p, p->apCsr[i]);
  p->apCsr[i] = 0;

  break;
}

/* Opcode: MoveGe P1 P2 P3 * *
**
** Use the value in register P3 as a key.  Reposition
** cursor P1 so that it points to the smallest entry that is greater
................................................................................
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/
case OP_Insert: {
  Mem *pData = &p->aMem[pOp->p2];
  Mem *pKey = &p->aMem[pOp->p3];

  i64 iKey;   /* The integer ROWID or key for the record to be inserted */
  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  assert( pC->pCursor!=0 || pC->pseudoTable );
  assert( pKey->flags & MEM_Int );
  assert( pC->isTable );
  REGISTER_TRACE(pOp->p2, pData);
  REGISTER_TRACE(pOp->p3, pKey);





  iKey = intToKey(pKey->u.i);

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
  if( pC->nextRowidValid && pKey->u.i>=pC->nextRowid ){
    pC->nextRowidValid = 0;
  }
  if( pData->flags & MEM_Null ){
    pData->z = 0;
    pData->n = 0;
  }else{
    assert( pData->flags & (MEM_Blob|MEM_Str) );
  }
  if( pC->pseudoTable ){
    sqlite3_free(pC->pData);
    pC->iKey = iKey;
    pC->nData = pData->n;
    if( pData->flags & MEM_Dyn ){
      pC->pData = pData->z;
      pData->flags &= ~MEM_Dyn;
      pData->flags |= MEM_Ephem;
    }else{
      pC->pData = sqlite3_malloc( pC->nData+2 );
      if( !pC->pData ) goto no_mem;
      memcpy(pC->pData, pData->z, pC->nData);
      pC->pData[pC->nData] = 0;
      pC->pData[pC->nData+1] = 0;
    }
    pC->nullRow = 0;
  }else{
    int nZero;
    if( pData->flags & MEM_Zero ){
      nZero = pData->u.i;
    }else{
      nZero = 0;
    }
    rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                            pData->z, pData->n, nZero,
                            pOp->p5 & OPFLAG_APPEND);
  }
  
  pC->rowidIsValid = 0;
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
    const char *zDb = db->aDb[pC->iDb].zName;
    const char *zTbl = pOp->p4.z;
    int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
    assert( pC->isTable );
    db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
    assert( pC->iDb>=0 );
  }


  break;
}

/* Opcode: Delete P1 P2 * P4 *
**
** Delete the record at which the P1 cursor is currently pointing.
**
................................................................................
  assert( pC!=0 );
  if( pC->nullRow ){
    pOut->flags = MEM_Null;
  }else if( pC->pCursor!=0 ){
    BtCursor *pCrsr = pC->pCursor;
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;



    if( pC->isIndex ){
      i64 n64;
      assert( !pC->isTable );
      sqlite3BtreeKeySize(pCrsr, &n64);
      if( n64>SQLITE_MAX_LENGTH ){
        goto too_big;
      }
      n = n64;
................................................................................
      pOut->z = z;
    }
    if( pC->isIndex ){
      rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
    }else{
      rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
    }
  }else{
    assert( pC->pseudoTable );
    pOut->n = pC->nData;
    assert( pC->nData<=SQLITE_MAX_LENGTH );
    pOut->z = pC->pData;
    pOut->flags = MEM_Blob|MEM_Ephem;


  }
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Rowid P1 P2 * * *
................................................................................
  assert( pC!=0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  if( pC->rowidIsValid ){
    v = pC->lastRowid;
  }else if( pC->pseudoTable ){
    v = keyToInt(pC->iKey);
  }else if( pC->nullRow ){
    /* Leave the rowid set to a NULL */
    break;
  }else{
    assert( pC->pCursor!=0 );
    sqlite3BtreeKeySize(pC->pCursor, &v);
    v = keyToInt(v);
  }
................................................................................
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {        /* jump */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  int res;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  pCrsr = pC->pCursor;
  assert( pCrsr!=0 );
  rc = sqlite3BtreeLast(pCrsr, &res);
  pC->nullRow = res;
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;
  if( res && pOp->p2>0 ){
    pc = pOp->p2 - 1;



  }
  break;
}


/* Opcode: Sort P1 P2 * * *
**
................................................................................
    pC->atFirst = res==0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }else{
    res = 1;
  }
  pC->nullRow = res;
  assert( pOp->p2>0 && pOp->p2<p->nOp );
  if( res ){
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Next P1 P2 * * *
**
................................................................................
      pOut->flags = MEM_Int;
      pOut->u.i = rowid;
    }
  }
  break;
}












/* Opcode: IdxGE P1 P2 P3 * P5
**
** The value in register P3 is an index entry that omits the ROWID.  Compare
** this value against the index that P1 is currently pointing to.
** Ignore the ROWID on the P1 index.
**
** If the P1 index entry is greater than or equal to the value in 
................................................................................
**
** If P5 is non-zero then the
** index taken from register P3 is temporarily increased by
** an epsilon prior to the comparison.  This makes the opcode work
** like IdxLE.
*/
case OP_IdxLT:          /* jump, in3 */

case OP_IdxGE: {        /* jump, in3 */
  int i= pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
    int res;
 
    assert( pIn3->flags & MEM_Blob );  /* Created using OP_MakeRecord */
    assert( pC->deferredMoveto==0 );
    ExpandBlob(pIn3);
    assert( pOp->p5==0 || pOp->p5==1 );
    *pC->pIncrKey = pOp->p5;

    rc = sqlite3VdbeIdxKeyCompare(pC, pIn3->n, (u8*)pIn3->z, &res);
    *pC->pIncrKey = 0;
    if( rc!=SQLITE_OK ){
      break;
    }
    if( pOp->opcode==OP_IdxLT ){
      res = -res;
    }else{
      assert( pOp->opcode==OP_IdxGE );
      res++;
    }
    if( res>0 ){
      pc = pOp->p2 - 1 ;
    }
  }
  break;
................................................................................
  }
  aRoot[j] = 0;
  assert( pOp->p5<db->nDb );
  assert( (p->btreeMask & (1<<pOp->p5))!=0 );
  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
                                 pnErr->u.i, &nErr);
  pnErr->u.i -= nErr;
  sqlite3VdbeMemSetNull(pIn1);
  if( nErr==0 ){
    assert( z==0 );

  }else{
    pIn1->z = z;
    pIn1->n = strlen(z);
    pIn1->flags = MEM_Str | MEM_Dyn | MEM_Term;
    pIn1->xDel = 0;
  }
  pIn1->enc = SQLITE_UTF8;
................................................................................
        registerTrace(p->trace, pOp->p3, pOut);
      }
    }
#endif  /* SQLITE_DEBUG */
#endif  /* NDEBUG */
  }  /* The end of the for(;;) loop the loops through opcodes */

  /* If we reach this point, it means that execution is finished with
  ** an error of some kind.
  */
vdbe_error_halt:
  assert( rc );
  p->rc = rc;
  rc = SQLITE_ERROR;



  sqlite3VdbeHalt(p);

  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  sqlite3BtreeMutexArrayLeave(&p->aMutex);
................................................................................

  /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
  ** is encountered.
  */
too_big:
  sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);
  rc = SQLITE_TOOBIG;
  goto vdbe_error_halt;

  /* Jump to here if a malloc() fails.
  */
no_mem:
  db->mallocFailed = 1;
  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
  rc = SQLITE_NOMEM;
  goto vdbe_error_halt;

  /* Jump to here for an SQLITE_MISUSE error.
  */
abort_due_to_misuse:
  rc = SQLITE_MISUSE;
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  assert( p->zErrMsg==0 );
  if( db->mallocFailed ) rc = SQLITE_NOMEM;
  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);

  goto vdbe_error_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */
abort_due_to_interrupt:
  assert( db->u1.isInterrupted );
  if( db->magic!=SQLITE_MAGIC_BUSY ){
    rc = SQLITE_MISUSE;
  }else{
    rc = SQLITE_INTERRUPT;
  }
  p->rc = rc;
  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  goto vdbe_error_halt;
}

Changes to src/vdbemem.c.

504
505
506
507
508
509
510
511
512
513
514
515

516
517
518
519
520
521
522
...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
    return n>SQLITE_MAX_LENGTH;
  }
  return 0; 
}

/*
** Make an shallow copy of pFrom into pTo.  Prior contents of
** pTo are overwritten.  The pFrom->z field is not duplicated.  If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){

  memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort));
  pTo->xDel = 0;
  if( pTo->flags & (MEM_Str|MEM_Blob) ){
    pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem);
    assert( srcType==MEM_Ephem || srcType==MEM_Static );
    pTo->flags |= srcType;
  }
................................................................................

/*
** Make a full copy of pFrom into pTo.  Prior contents of pTo are
** freed before the copy is made.
*/
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
  int rc;
  if( pTo->flags & MEM_Dyn ){
    sqlite3VdbeMemRelease(pTo);
  }
  sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
  if( pTo->flags & MEM_Ephem ){
    rc = sqlite3VdbeMemMakeWriteable(pTo);
  }else{
    rc = SQLITE_OK;
  }
  return rc;







|




>







 







<
<
<







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
...
525
526
527
528
529
530
531



532
533
534
535
536
537
538
    return n>SQLITE_MAX_LENGTH;
  }
  return 0; 
}

/*
** Make an shallow copy of pFrom into pTo.  Prior contents of
** pTo are freed.  The pFrom->z field is not duplicated.  If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
  sqlite3VdbeMemRelease(pTo);
  memcpy(pTo, pFrom, sizeof(*pFrom)-sizeof(pFrom->zShort));
  pTo->xDel = 0;
  if( pTo->flags & (MEM_Str|MEM_Blob) ){
    pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short|MEM_Ephem);
    assert( srcType==MEM_Ephem || srcType==MEM_Static );
    pTo->flags |= srcType;
  }
................................................................................

/*
** Make a full copy of pFrom into pTo.  Prior contents of pTo are
** freed before the copy is made.
*/
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
  int rc;



  sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
  if( pTo->flags & MEM_Ephem ){
    rc = sqlite3VdbeMemMakeWriteable(pTo);
  }else{
    rc = SQLITE_OK;
  }
  return rc;