Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the sqlite3_value_nochange() API, usable from within the xUpdate method of a virtual table to discover whether or not a column was unchanged at the SQL level. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
dec3ea4e4e6c4b1761ddc883a29eaa50 |
User & Date: | drh 2018-01-12 23:38:10.473 |
Context
2018-01-13
| ||
01:53 | Add the new "nochange" APIs to the extension loading mechanism. (check-in: cd7c42699e user: drh tags: trunk) | |
2018-01-12
| ||
23:38 | Add the sqlite3_value_nochange() API, usable from within the xUpdate method of a virtual table to discover whether or not a column was unchanged at the SQL level. (check-in: dec3ea4e4e user: drh tags: trunk) | |
23:18 | Improved comments. Slightly tighter implementation, but no big changes. (Closed-Leaf check-in: a1b3f28569 user: drh tags: sqlite3_value_nochange) | |
19:33 | Simplification to the implementation of OP_Insert. (check-in: 6acbdba59e user: drh tags: trunk) | |
Changes
Changes to src/sqlite.h.in.
︙ | ︙ | |||
4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 | ** <tr><td><b>sqlite3_value_bytes16 </b> ** <td>→ <td>Size of UTF-16 ** TEXT in bytes ** <tr><td><b>sqlite3_value_type</b><td>→<td>Default ** datatype of the value ** <tr><td><b>sqlite3_value_numeric_type </b> ** <td>→ <td>Best numeric datatype of the value ** </table></blockquote> ** ** <b>Details:</b> ** ** These routines extract type, size, and content information from ** [protected sqlite3_value] objects. Protected sqlite3_value objects ** are used to pass parameter information into implementation of | > > > | 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 | ** <tr><td><b>sqlite3_value_bytes16 </b> ** <td>→ <td>Size of UTF-16 ** TEXT in bytes ** <tr><td><b>sqlite3_value_type</b><td>→<td>Default ** datatype of the value ** <tr><td><b>sqlite3_value_numeric_type </b> ** <td>→ <td>Best numeric datatype of the value ** <tr><td><b>sqlite3_value_nochange </b> ** <td>→ <td>True if the column is unchanged in an UPDATE ** against a virtual table. ** </table></blockquote> ** ** <b>Details:</b> ** ** These routines extract type, size, and content information from ** [protected sqlite3_value] objects. Protected sqlite3_value objects ** are used to pass parameter information into implementation of |
︙ | ︙ | |||
4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 | ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If ** such a conversion is possible without loss of information (in other ** words, if the value is a string that looks like a number) ** then the conversion is performed. Otherwise no conversion occurs. ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** ** Please pay particular attention to the fact that the pointer returned ** from [sqlite3_value_blob()], [sqlite3_value_text()], or ** [sqlite3_value_text16()] can be invalidated by a subsequent call to ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], ** or [sqlite3_value_text16()]. ** | > > > > > > > > > > > > > | 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 | ** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If ** such a conversion is possible without loss of information (in other ** words, if the value is a string that looks like a number) ** then the conversion is performed. Otherwise no conversion occurs. ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** ** ^Within the [xUpdate] method of a [virtual table], the ** sqlite3_value_nochange(X) interface returns true if and only if ** the column corresponding to X is unchanged by the UPDATE operation ** that the xUpdate method call was invoked to implement and if ** and the prior [xColumn] method call that was invoked to extracted ** the value for that column returned without setting a result (probably ** because it queried [sqlite3_vtab_nochange()] and found that the column ** was unchanging). ^Within an [xUpdate] method, any value for which ** sqlite3_value_nochange(X) is true will in all other respects appear ** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other ** than within an [xUpdate] method call for an UPDATE statement, then ** the return value is arbitrary and meaningless. ** ** Please pay particular attention to the fact that the pointer returned ** from [sqlite3_value_blob()], [sqlite3_value_text()], or ** [sqlite3_value_text16()] can be invalidated by a subsequent call to ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], ** or [sqlite3_value_text16()]. ** |
︙ | ︙ | |||
4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 | const void *sqlite3_value_text16(sqlite3_value*); const void *sqlite3_value_text16le(sqlite3_value*); const void *sqlite3_value_text16be(sqlite3_value*); int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); int sqlite3_value_numeric_type(sqlite3_value*); /* ** CAPI3REF: Finding The Subtype Of SQL Values ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype | > | 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 | const void *sqlite3_value_text16(sqlite3_value*); const void *sqlite3_value_text16le(sqlite3_value*); const void *sqlite3_value_text16be(sqlite3_value*); int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); int sqlite3_value_numeric_type(sqlite3_value*); int sqlite3_value_nochange(sqlite3_value*); /* ** CAPI3REF: Finding The Subtype Of SQL Values ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype |
︙ | ︙ | |||
8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 | ** ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] ** method of a [virtual table], then it returns true if and only if the ** column is being fetched as part of an UPDATE operation during which the ** column value will not change. Applications might use this to substitute ** a lighter-weight value to return that the corresponding [xUpdate] method ** understands as a "no-change" value. */ int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint ** ** This function may only be called from within a call to the [xBestIndex] | > > > > > > > | 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 | ** ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] ** method of a [virtual table], then it returns true if and only if the ** column is being fetched as part of an UPDATE operation during which the ** column value will not change. Applications might use this to substitute ** a lighter-weight value to return that the corresponding [xUpdate] method ** understands as a "no-change" value. ** ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that ** the column is not changed by the UPDATE statement, they the xColumn ** method can optionally return without setting a result, without calling ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** In that case, [sqlite3_value_nochange(X)] will return true for the ** same column in the [xUpdate] method. */ int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint ** ** This function may only be called from within a call to the [xBestIndex] |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ #define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ /* * Each trigger present in the database schema is stored as an instance of * struct Trigger. * * Pointers to instances of struct Trigger are stored in two ways. * 1. In the "trigHash" hash table (part of the sqlite3* that represents the | > | 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ #define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ /* * Each trigger present in the database schema is stored as an instance of * struct Trigger. * * Pointers to instances of struct Trigger are stored in two ways. * 1. In the "trigHash" hash table (part of the sqlite3* that represents the |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
823 824 825 826 827 828 829 | if( pWInfo==0 ) return; /* Populate the argument registers. */ for(i=0; i<pTab->nCol; i++){ if( aXRef[i]>=0 ){ sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ | | > | 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 | if( pWInfo==0 ) return; /* Populate the argument registers. */ for(i=0; i<pTab->nCol; i++){ if( aXRef[i]>=0 ){ sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */ } } if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); if( pRowid ){ sqlite3ExprCode(pParse, pRowid, regArg+1); }else{ |
︙ | ︙ | |||
858 859 860 861 862 863 864 865 866 867 868 869 870 871 | if( sqlite3IsToplevel(pParse) ){ pParse->isMultiWrite = 0; } }else{ /* Create a record from the argument register contents and insert it into ** the ephemeral table. */ sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); } if( bOnePass==0 ){ /* End the virtual table scan */ | > > > > > | 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | if( sqlite3IsToplevel(pParse) ){ pParse->isMultiWrite = 0; } }else{ /* Create a record from the argument register contents and insert it into ** the ephemeral table. */ sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); #ifdef SQLITE_DEBUG /* Signal an assert() within OP_MakeRecord that it is allowed to ** accept no-change records with serial_type 10 */ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); #endif sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); } if( bOnePass==0 ){ /* End the virtual table scan */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
460 461 462 463 464 465 466 | /* ** Print the value of a register for tracing purposes: */ static void memTracePrint(Mem *p){ if( p->flags & MEM_Undefined ){ printf(" undefined"); }else if( p->flags & MEM_Null ){ | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | /* ** Print the value of a register for tracing purposes: */ static void memTracePrint(Mem *p){ if( p->flags & MEM_Undefined ){ printf(" undefined"); }else if( p->flags & MEM_Null ){ printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ printf(" si:%lld", p->u.i); }else if( p->flags & MEM_Int ){ printf(" i:%lld", p->u.i); #ifndef SQLITE_OMIT_FLOATING_POINT }else if( p->flags & MEM_Real ){ printf(" r:%g", p->u.r); |
︙ | ︙ | |||
2788 2789 2790 2791 2792 2793 2794 | /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ pRec = pLast; do{ assert( memIsValid(pRec) ); | | > > > > > > > > > | > | 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 | /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ pRec = pLast; do{ assert( memIsValid(pRec) ); serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); if( pRec->flags & MEM_Zero ){ if( serial_type==0 ){ /* Values with MEM_Null and MEM_Zero are created by xColumn virtual ** table methods that never invoke sqlite3_result_xxxxx() while ** computing an unchanging column value in an UPDATE statement. ** Give such values a special internal-use-only serial-type of 10 ** so that they can be passed through to xUpdate and have ** a true sqlite3_value_nochange(). */ assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB ); serial_type = 10; }else if( nData ){ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; }else{ nZero += pRec->u.nZero; len -= pRec->u.nZero; } } nData += len; testcase( serial_type==127 ); testcase( serial_type==128 ); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); pRec->uTemp = serial_type; if( pRec==pData0 ) break; pRec--; }while(1); /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint ** which determines the total number of bytes in the header. The varint ** value is the size of the header in bytes including the size varint |
︙ | ︙ | |||
6693 6694 6695 6696 6697 6698 6699 | VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE | | | | | 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 | VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VColumn P1 P2 P3 * P5 ** Synopsis: r[P3]=vcolumn(P2) ** ** Store in register P3 the value of the P2-th column of ** the current row of the virtual-table of cursor P1. ** ** If the VColumn opcode is being used to fetch the value of ** an unchanging column during an UPDATE operation, then the P5 ** value is 1. Otherwise, P5 is 0. The P5 value is returned ** by sqlite3_vtab_nochange() routine can can be used ** by virtual table implementations to return special "no-change" ** marks which can be more efficient, depending on the virtual table. */ case OP_VColumn: { sqlite3_vtab *pVtab; const sqlite3_module *pModule; |
︙ | ︙ | |||
6726 6727 6728 6729 6730 6731 6732 | break; } pVtab = pCur->uc.pVCur->pVtab; pModule = pVtab->pModule; assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; | | > > > > | > | 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 | break; } pVtab = pCur->uc.pVCur->pVtab; pModule = pVtab->pModule; assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; if( pOp->p5 ){ sqlite3VdbeMemSetNull(pDest); pDest->flags = MEM_Null|MEM_Zero; pDest->u.nZero = 0; }else{ MemSetTypeFlag(pDest, MEM_Null); } rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); sqlite3VtabImportErrmsg(p, pVtab); if( sContext.isError ){ rc = sContext.isError; } sqlite3VdbeChangeEncoding(pDest, encoding); REGISTER_TRACE(pOp->p3, pDest); |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
220 221 222 223 224 225 226 227 228 229 230 231 232 233 | /* One or more of the following flags are set to indicate the validOK ** representations of the value stored in the Mem struct. ** ** If the MEM_Null flag is set, then the value is an SQL NULL value. ** For a pointer type created using sqlite3_bind_pointer() or ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. ** ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main ** database (see below for exceptions). If the MEM_Term flag is also ** set, then the string is nul terminated. The MEM_Int and MEM_Real ** flags may coexist with the MEM_Str flag. */ | > > | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | /* One or more of the following flags are set to indicate the validOK ** representations of the value stored in the Mem struct. ** ** If the MEM_Null flag is set, then the value is an SQL NULL value. ** For a pointer type created using sqlite3_bind_pointer() or ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. ** If both MEM_Null and MEM_Zero are set, that means that the value is ** an unchanging column value from VColumn. ** ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main ** database (see below for exceptions). If the MEM_Term flag is also ** set, then the string is nul terminated. The MEM_Int and MEM_Real ** flags may coexist with the MEM_Str flag. */ |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
263 264 265 266 267 268 269 270 271 272 273 274 275 276 | SQLITE_INTEGER, /* 0x1c */ SQLITE_NULL, /* 0x1d */ SQLITE_INTEGER, /* 0x1e */ SQLITE_NULL, /* 0x1f */ }; return aType[pVal->flags&MEM_AffMask]; } /* Make a copy of an sqlite3_value object */ sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ sqlite3_value *pNew; if( pOrig==0 ) return 0; pNew = sqlite3_malloc( sizeof(*pNew) ); | > > > > > | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | SQLITE_INTEGER, /* 0x1c */ SQLITE_NULL, /* 0x1d */ SQLITE_INTEGER, /* 0x1e */ SQLITE_NULL, /* 0x1f */ }; return aType[pVal->flags&MEM_AffMask]; } /* Return true if a parameter to xUpdate represents an unchanged column */ int sqlite3_value_nochange(sqlite3_value *pVal){ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); } /* Make a copy of an sqlite3_value object */ sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ sqlite3_value *pNew; if( pOrig==0 ) return 0; pNew = sqlite3_malloc( sizeof(*pNew) ); |
︙ | ︙ | |||
757 758 759 760 761 762 763 | ** ** Virtual table implements might use this routine to optimize their ** performance by substituting a NULL result, or some other light-weight ** value, as a signal to the xUpdate routine that the column is unchanged. */ int sqlite3_vtab_nochange(sqlite3_context *p){ assert( p ); | | | 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 | ** ** Virtual table implements might use this routine to optimize their ** performance by substituting a NULL result, or some other light-weight ** value, as a signal to the xUpdate routine that the column is unchanged. */ int sqlite3_vtab_nochange(sqlite3_context *p){ assert( p ); return sqlite3_value_nochange(p->pOut); } /* ** Return the current time for a statement. If the current time ** is requested more than once within the same run of a single prepared ** statement, the exact same time is returned for each invocation regardless ** of the amount of time that elapses between invocations. In other words, |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
3450 3451 3452 3453 3454 3455 3456 | } u32 sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ ){ switch( serial_type ){ | | > > > > | 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 | } u32 sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ ){ switch( serial_type ){ case 10: { /* Internal use only: NULL with virtual table ** UPDATE no-change flag set */ pMem->flags = MEM_Null|MEM_Zero; break; } case 11: /* Reserved for future use */ case 0: { /* Null */ /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ pMem->flags = MEM_Null; break; } case 1: { |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | /* Cannot be both MEM_Int and MEM_Real at the same time */ assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); if( p->flags & MEM_Null ){ /* Cannot be both MEM_Null and some other type */ assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* Cannot be both MEM_Int and MEM_Real at the same time */ assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); if( p->flags & MEM_Null ){ /* Cannot be both MEM_Null and some other type */ assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob |MEM_RowSet|MEM_Frame|MEM_Agg))==0 ); /* If MEM_Null is set, then either the value is a pure NULL (the usual ** case) or it is a pointer set using sqlite3_bind_pointer() or ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be ** set. */ if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){ |
︙ | ︙ |