| | @@ -1156,11 +1156,11 @@ |
| 1156 | 1156 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 1157 | 1157 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 1158 | 1158 | */ |
| 1159 | 1159 | #define SQLITE_VERSION "3.25.0" |
| 1160 | 1160 | #define SQLITE_VERSION_NUMBER 3025000 |
| 1161 | | -#define SQLITE_SOURCE_ID "2018-08-16 16:24:24 456842924bb33c0af8af29402f06e5f25b6791f698a0d12a080258b20b0cfb61" |
| 1161 | +#define SQLITE_SOURCE_ID "2018-08-30 01:52:10 58078c0d2647a194279fa80e032670441b296ffc3acee692901faa5beca460b7" |
| 1162 | 1162 | |
| 1163 | 1163 | /* |
| 1164 | 1164 | ** CAPI3REF: Run-Time Library Version Numbers |
| 1165 | 1165 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 1166 | 1166 | ** |
| | @@ -7471,10 +7471,11 @@ |
| 7471 | 7471 | #define SQLITE_INDEX_CONSTRAINT_NE 68 |
| 7472 | 7472 | #define SQLITE_INDEX_CONSTRAINT_ISNOT 69 |
| 7473 | 7473 | #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 |
| 7474 | 7474 | #define SQLITE_INDEX_CONSTRAINT_ISNULL 71 |
| 7475 | 7475 | #define SQLITE_INDEX_CONSTRAINT_IS 72 |
| 7476 | +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 |
| 7476 | 7477 | |
| 7477 | 7478 | /* |
| 7478 | 7479 | ** CAPI3REF: Register A Virtual Table Implementation |
| 7479 | 7480 | ** METHOD: sqlite3 |
| 7480 | 7481 | ** |
| | @@ -13727,11 +13728,12 @@ |
| 13727 | 13728 | */ |
| 13728 | 13729 | #ifndef SQLITE_PTRSIZE |
| 13729 | 13730 | # if defined(__SIZEOF_POINTER__) |
| 13730 | 13731 | # define SQLITE_PTRSIZE __SIZEOF_POINTER__ |
| 13731 | 13732 | # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
| 13732 | | - defined(_M_ARM) || defined(__arm__) || defined(__x86) |
| 13733 | + defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ |
| 13734 | + (defined(__TOS_AIX__) && !defined(__64BIT__)) |
| 13733 | 13735 | # define SQLITE_PTRSIZE 4 |
| 13734 | 13736 | # else |
| 13735 | 13737 | # define SQLITE_PTRSIZE 8 |
| 13736 | 13738 | # endif |
| 13737 | 13739 | #endif |
| | @@ -13768,11 +13770,11 @@ |
| 13768 | 13770 | */ |
| 13769 | 13771 | #ifndef SQLITE_BYTEORDER |
| 13770 | 13772 | # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
| 13771 | 13773 | defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ |
| 13772 | 13774 | defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ |
| 13773 | | - defined(__arm__) |
| 13775 | + defined(__arm__) || defined(_M_ARM64) |
| 13774 | 13776 | # define SQLITE_BYTEORDER 1234 |
| 13775 | 13777 | # elif defined(sparc) || defined(__ppc__) |
| 13776 | 13778 | # define SQLITE_BYTEORDER 4321 |
| 13777 | 13779 | # else |
| 13778 | 13780 | # define SQLITE_BYTEORDER 0 |
| | @@ -18552,12 +18554,13 @@ |
| 18552 | 18554 | SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*); |
| 18553 | 18555 | #ifndef SQLITE_UNTESTABLE |
| 18554 | 18556 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); |
| 18555 | 18557 | #endif |
| 18556 | 18558 | |
| 18557 | | -SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); |
| 18558 | | -SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); |
| 18559 | +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*); |
| 18560 | +SQLITE_PRIVATE void sqlite3RowSetDelete(void*); |
| 18561 | +SQLITE_PRIVATE void sqlite3RowSetClear(void*); |
| 18559 | 18562 | SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); |
| 18560 | 18563 | SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); |
| 18561 | 18564 | SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); |
| 18562 | 18565 | |
| 18563 | 18566 | SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); |
| | @@ -19785,10 +19788,13 @@ |
| 19785 | 19788 | VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ |
| 19786 | 19789 | u8 *aOnce; /* Bitmask used by OP_Once */ |
| 19787 | 19790 | void *token; /* Copy of SubProgram.token */ |
| 19788 | 19791 | i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ |
| 19789 | 19792 | AuxData *pAuxData; /* Linked list of auxdata allocations */ |
| 19793 | +#if SQLITE_DEBUG |
| 19794 | + u32 iFrameMagic; /* magic number for sanity checking */ |
| 19795 | +#endif |
| 19790 | 19796 | int nCursor; /* Number of entries in apCsr */ |
| 19791 | 19797 | int pc; /* Program Counter in parent (calling) frame */ |
| 19792 | 19798 | int nOp; /* Size of aOp array */ |
| 19793 | 19799 | int nMem; /* Number of entries in aMem */ |
| 19794 | 19800 | int nChildMem; /* Number of memory cells for child frame */ |
| | @@ -19795,10 +19801,17 @@ |
| 19795 | 19801 | int nChildCsr; /* Number of cursors for child frame */ |
| 19796 | 19802 | int nChange; /* Statement changes (Vdbe.nChange) */ |
| 19797 | 19803 | int nDbChange; /* Value of db->nChange */ |
| 19798 | 19804 | }; |
| 19799 | 19805 | |
| 19806 | +/* Magic number for sanity checking on VdbeFrame objects */ |
| 19807 | +#define SQLITE_FRAME_MAGIC 0x879fb71e |
| 19808 | + |
| 19809 | +/* |
| 19810 | +** Return a pointer to the array of registers allocated for use |
| 19811 | +** by a VdbeFrame. |
| 19812 | +*/ |
| 19800 | 19813 | #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) |
| 19801 | 19814 | |
| 19802 | 19815 | /* |
| 19803 | 19816 | ** Internally, the vdbe manipulates nearly all SQL values as Mem |
| 19804 | 19817 | ** structures. Each Mem struct may cache multiple representations (string, |
| | @@ -19809,12 +19822,10 @@ |
| 19809 | 19822 | double r; /* Real value used when MEM_Real is set in flags */ |
| 19810 | 19823 | i64 i; /* Integer value used when MEM_Int is set in flags */ |
| 19811 | 19824 | int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ |
| 19812 | 19825 | const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ |
| 19813 | 19826 | FuncDef *pDef; /* Used only when flags==MEM_Agg */ |
| 19814 | | - RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ |
| 19815 | | - VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ |
| 19816 | 19827 | } u; |
| 19817 | 19828 | u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ |
| 19818 | 19829 | u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ |
| 19819 | 19830 | u8 eSubtype; /* Subtype for this value */ |
| 19820 | 19831 | int n; /* Number of characters in string value, excluding '\0' */ |
| | @@ -19854,12 +19865,12 @@ |
| 19854 | 19865 | #define MEM_Str 0x0002 /* Value is a string */ |
| 19855 | 19866 | #define MEM_Int 0x0004 /* Value is an integer */ |
| 19856 | 19867 | #define MEM_Real 0x0008 /* Value is a real number */ |
| 19857 | 19868 | #define MEM_Blob 0x0010 /* Value is a BLOB */ |
| 19858 | 19869 | #define MEM_AffMask 0x001f /* Mask of affinity bits */ |
| 19859 | | -#define MEM_RowSet 0x0020 /* Value is a RowSet object */ |
| 19860 | | -#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ |
| 19870 | +/* Available 0x0020 */ |
| 19871 | +/* Available 0x0040 */ |
| 19861 | 19872 | #define MEM_Undefined 0x0080 /* Value is undefined */ |
| 19862 | 19873 | #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ |
| 19863 | 19874 | #define MEM_TypeMask 0xc1ff /* Mask of type bits */ |
| 19864 | 19875 | |
| 19865 | 19876 | |
| | @@ -19882,11 +19893,11 @@ |
| 19882 | 19893 | |
| 19883 | 19894 | /* Return TRUE if Mem X contains dynamically allocated content - anything |
| 19884 | 19895 | ** that needs to be deallocated to avoid a leak. |
| 19885 | 19896 | */ |
| 19886 | 19897 | #define VdbeMemDynamic(X) \ |
| 19887 | | - (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) |
| 19898 | + (((X)->flags&(MEM_Agg|MEM_Dyn))!=0) |
| 19888 | 19899 | |
| 19889 | 19900 | /* |
| 19890 | 19901 | ** Clear any existing type flags from a Mem and replace them with f |
| 19891 | 19902 | */ |
| 19892 | 19903 | #define MemSetTypeFlag(p, f) \ |
| | @@ -20095,11 +20106,14 @@ |
| 20095 | 20106 | #endif |
| 20096 | 20107 | SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); |
| 20097 | 20108 | SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); |
| 20098 | 20109 | SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); |
| 20099 | 20110 | SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); |
| 20100 | | -SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); |
| 20111 | +#ifdef SQLITE_DEBUG |
| 20112 | +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); |
| 20113 | +#endif |
| 20114 | +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); |
| 20101 | 20115 | SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); |
| 20102 | 20116 | SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); |
| 20103 | 20117 | SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); |
| 20104 | 20118 | SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); |
| 20105 | 20119 | SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); |
| | @@ -20116,11 +20130,15 @@ |
| 20116 | 20130 | #endif |
| 20117 | 20131 | SQLITE_PRIVATE const char *sqlite3OpcodeName(int); |
| 20118 | 20132 | SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); |
| 20119 | 20133 | SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); |
| 20120 | 20134 | SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); |
| 20121 | | -SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); |
| 20135 | +#ifdef SQLITE_DEBUG |
| 20136 | +SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*); |
| 20137 | +#endif |
| 20138 | +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ |
| 20139 | +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ |
| 20122 | 20140 | SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); |
| 20123 | 20141 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
| 20124 | 20142 | SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); |
| 20125 | 20143 | #endif |
| 20126 | 20144 | SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); |
| | @@ -49478,43 +49496,37 @@ |
| 49478 | 49496 | */ |
| 49479 | 49497 | #define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ |
| 49480 | 49498 | #define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ |
| 49481 | 49499 | |
| 49482 | 49500 | /* |
| 49483 | | -** Turn bulk memory into a RowSet object. N bytes of memory |
| 49484 | | -** are available at pSpace. The db pointer is used as a memory context |
| 49485 | | -** for any subsequent allocations that need to occur. |
| 49486 | | -** Return a pointer to the new RowSet object. |
| 49487 | | -** |
| 49488 | | -** It must be the case that N is sufficient to make a Rowset. If not |
| 49489 | | -** an assertion fault occurs. |
| 49490 | | -** |
| 49491 | | -** If N is larger than the minimum, use the surplus as an initial |
| 49492 | | -** allocation of entries available to be filled. |
| 49501 | +** Allocate a RowSet object. Return NULL if a memory allocation |
| 49502 | +** error occurs. |
| 49493 | 49503 | */ |
| 49494 | | -SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ |
| 49495 | | - RowSet *p; |
| 49496 | | - assert( N >= ROUND8(sizeof(*p)) ); |
| 49497 | | - p = pSpace; |
| 49498 | | - p->pChunk = 0; |
| 49499 | | - p->db = db; |
| 49500 | | - p->pEntry = 0; |
| 49501 | | - p->pLast = 0; |
| 49502 | | - p->pForest = 0; |
| 49503 | | - p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); |
| 49504 | | - p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); |
| 49505 | | - p->rsFlags = ROWSET_SORTED; |
| 49506 | | - p->iBatch = 0; |
| 49504 | +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){ |
| 49505 | + RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p)); |
| 49506 | + if( p ){ |
| 49507 | + int N = sqlite3DbMallocSize(db, p); |
| 49508 | + p->pChunk = 0; |
| 49509 | + p->db = db; |
| 49510 | + p->pEntry = 0; |
| 49511 | + p->pLast = 0; |
| 49512 | + p->pForest = 0; |
| 49513 | + p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); |
| 49514 | + p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); |
| 49515 | + p->rsFlags = ROWSET_SORTED; |
| 49516 | + p->iBatch = 0; |
| 49517 | + } |
| 49507 | 49518 | return p; |
| 49508 | 49519 | } |
| 49509 | 49520 | |
| 49510 | 49521 | /* |
| 49511 | 49522 | ** Deallocate all chunks from a RowSet. This frees all memory that |
| 49512 | 49523 | ** the RowSet has allocated over its lifetime. This routine is |
| 49513 | 49524 | ** the destructor for the RowSet. |
| 49514 | 49525 | */ |
| 49515 | | -SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){ |
| 49526 | +SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){ |
| 49527 | + RowSet *p = (RowSet*)pArg; |
| 49516 | 49528 | struct RowSetChunk *pChunk, *pNextChunk; |
| 49517 | 49529 | for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ |
| 49518 | 49530 | pNextChunk = pChunk->pNextChunk; |
| 49519 | 49531 | sqlite3DbFree(p->db, pChunk); |
| 49520 | 49532 | } |
| | @@ -49523,10 +49535,20 @@ |
| 49523 | 49535 | p->pEntry = 0; |
| 49524 | 49536 | p->pLast = 0; |
| 49525 | 49537 | p->pForest = 0; |
| 49526 | 49538 | p->rsFlags = ROWSET_SORTED; |
| 49527 | 49539 | } |
| 49540 | + |
| 49541 | +/* |
| 49542 | +** Deallocate all chunks from a RowSet. This frees all memory that |
| 49543 | +** the RowSet has allocated over its lifetime. This routine is |
| 49544 | +** the destructor for the RowSet. |
| 49545 | +*/ |
| 49546 | +SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){ |
| 49547 | + sqlite3RowSetClear(pArg); |
| 49548 | + sqlite3DbFree(((RowSet*)pArg)->db, pArg); |
| 49549 | +} |
| 49528 | 49550 | |
| 49529 | 49551 | /* |
| 49530 | 49552 | ** Allocate a new RowSetEntry object that is associated with the |
| 49531 | 49553 | ** given RowSet. Return a pointer to the new and completely uninitialized |
| 49532 | 49554 | ** objected. |
| | @@ -60515,10 +60537,11 @@ |
| 60515 | 60537 | rc = SQLITE_BUSY_SNAPSHOT; |
| 60516 | 60538 | } |
| 60517 | 60539 | |
| 60518 | 60540 | /* Release the shared CKPT lock obtained above. */ |
| 60519 | 60541 | walUnlockShared(pWal, WAL_CKPT_LOCK); |
| 60542 | + pWal->minFrame = 1; |
| 60520 | 60543 | } |
| 60521 | 60544 | |
| 60522 | 60545 | |
| 60523 | 60546 | if( rc!=SQLITE_OK ){ |
| 60524 | 60547 | sqlite3WalEndReadTransaction(pWal); |
| | @@ -73614,12 +73637,11 @@ |
| 73614 | 73637 | /* Cannot be both MEM_Int and MEM_Real at the same time */ |
| 73615 | 73638 | assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); |
| 73616 | 73639 | |
| 73617 | 73640 | if( p->flags & MEM_Null ){ |
| 73618 | 73641 | /* Cannot be both MEM_Null and some other type */ |
| 73619 | | - assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob |
| 73620 | | - |MEM_RowSet|MEM_Frame|MEM_Agg))==0 ); |
| 73642 | + assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); |
| 73621 | 73643 | |
| 73622 | 73644 | /* If MEM_Null is set, then either the value is a pure NULL (the usual |
| 73623 | 73645 | ** case) or it is a pointer set using sqlite3_bind_pointer() or |
| 73624 | 73646 | ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be |
| 73625 | 73647 | ** set. |
| | @@ -73728,11 +73750,11 @@ |
| 73728 | 73750 | */ |
| 73729 | 73751 | SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ |
| 73730 | 73752 | #ifndef SQLITE_OMIT_UTF16 |
| 73731 | 73753 | int rc; |
| 73732 | 73754 | #endif |
| 73733 | | - assert( (pMem->flags&MEM_RowSet)==0 ); |
| 73755 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 73734 | 73756 | assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE |
| 73735 | 73757 | || desiredEnc==SQLITE_UTF16BE ); |
| 73736 | 73758 | if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ |
| 73737 | 73759 | return SQLITE_OK; |
| 73738 | 73760 | } |
| | @@ -73761,11 +73783,11 @@ |
| 73761 | 73783 | ** blob if bPreserve is true. If bPreserve is false, any prior content |
| 73762 | 73784 | ** in pMem->z is discarded. |
| 73763 | 73785 | */ |
| 73764 | 73786 | SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ |
| 73765 | 73787 | assert( sqlite3VdbeCheckMemInvariants(pMem) ); |
| 73766 | | - assert( (pMem->flags&MEM_RowSet)==0 ); |
| 73788 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 73767 | 73789 | testcase( pMem->db==0 ); |
| 73768 | 73790 | |
| 73769 | 73791 | /* If the bPreserve flag is set to true, then the memory cell must already |
| 73770 | 73792 | ** contain a valid string or blob value. */ |
| 73771 | 73793 | assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); |
| | @@ -73849,11 +73871,11 @@ |
| 73849 | 73871 | ** |
| 73850 | 73872 | ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. |
| 73851 | 73873 | */ |
| 73852 | 73874 | SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ |
| 73853 | 73875 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 73854 | | - assert( (pMem->flags&MEM_RowSet)==0 ); |
| 73876 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 73855 | 73877 | if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ |
| 73856 | 73878 | if( ExpandBlob(pMem) ) return SQLITE_NOMEM; |
| 73857 | 73879 | if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ |
| 73858 | 73880 | int rc = vdbeMemAddTerminator(pMem); |
| 73859 | 73881 | if( rc ) return rc; |
| | @@ -73874,11 +73896,11 @@ |
| 73874 | 73896 | #ifndef SQLITE_OMIT_INCRBLOB |
| 73875 | 73897 | SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ |
| 73876 | 73898 | int nByte; |
| 73877 | 73899 | assert( pMem->flags & MEM_Zero ); |
| 73878 | 73900 | assert( pMem->flags&MEM_Blob ); |
| 73879 | | - assert( (pMem->flags&MEM_RowSet)==0 ); |
| 73901 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 73880 | 73902 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 73881 | 73903 | |
| 73882 | 73904 | /* Set nByte to the number of bytes required to store the expanded blob. */ |
| 73883 | 73905 | nByte = pMem->n + pMem->u.nZero; |
| 73884 | 73906 | if( nByte<=0 ){ |
| | @@ -73929,11 +73951,11 @@ |
| 73929 | 73951 | |
| 73930 | 73952 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 73931 | 73953 | assert( !(fg&MEM_Zero) ); |
| 73932 | 73954 | assert( !(fg&(MEM_Str|MEM_Blob)) ); |
| 73933 | 73955 | assert( fg&(MEM_Int|MEM_Real) ); |
| 73934 | | - assert( (pMem->flags&MEM_RowSet)==0 ); |
| 73956 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 73935 | 73957 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 73936 | 73958 | |
| 73937 | 73959 | |
| 73938 | 73960 | if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| 73939 | 73961 | pMem->enc = 0; |
| | @@ -74034,19 +74056,12 @@ |
| 74034 | 74056 | sqlite3VdbeMemFinalize(p, p->u.pDef); |
| 74035 | 74057 | assert( (p->flags & MEM_Agg)==0 ); |
| 74036 | 74058 | testcase( p->flags & MEM_Dyn ); |
| 74037 | 74059 | } |
| 74038 | 74060 | if( p->flags&MEM_Dyn ){ |
| 74039 | | - assert( (p->flags&MEM_RowSet)==0 ); |
| 74040 | 74061 | assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); |
| 74041 | 74062 | p->xDel((void *)p->z); |
| 74042 | | - }else if( p->flags&MEM_RowSet ){ |
| 74043 | | - sqlite3RowSetClear(p->u.pRowSet); |
| 74044 | | - }else if( p->flags&MEM_Frame ){ |
| 74045 | | - VdbeFrame *pFrame = p->u.pFrame; |
| 74046 | | - pFrame->pParent = pFrame->v->pDelFrame; |
| 74047 | | - pFrame->v->pDelFrame = pFrame; |
| 74048 | 74063 | } |
| 74049 | 74064 | p->flags = MEM_Null; |
| 74050 | 74065 | } |
| 74051 | 74066 | |
| 74052 | 74067 | /* |
| | @@ -74190,11 +74205,11 @@ |
| 74190 | 74205 | ** MEM_Int if we can. |
| 74191 | 74206 | */ |
| 74192 | 74207 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ |
| 74193 | 74208 | i64 ix; |
| 74194 | 74209 | assert( pMem->flags & MEM_Real ); |
| 74195 | | - assert( (pMem->flags & MEM_RowSet)==0 ); |
| 74210 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 74196 | 74211 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 74197 | 74212 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 74198 | 74213 | |
| 74199 | 74214 | ix = doubleToInt64(pMem->u.r); |
| 74200 | 74215 | |
| | @@ -74217,11 +74232,11 @@ |
| 74217 | 74232 | /* |
| 74218 | 74233 | ** Convert pMem to type integer. Invalidate any prior representations. |
| 74219 | 74234 | */ |
| 74220 | 74235 | SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ |
| 74221 | 74236 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 74222 | | - assert( (pMem->flags & MEM_RowSet)==0 ); |
| 74237 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 74223 | 74238 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 74224 | 74239 | |
| 74225 | 74240 | pMem->u.i = sqlite3VdbeIntValue(pMem); |
| 74226 | 74241 | MemSetTypeFlag(pMem, MEM_Int); |
| 74227 | 74242 | return SQLITE_OK; |
| | @@ -74435,30 +74450,40 @@ |
| 74435 | 74450 | pMem->flags = MEM_Real; |
| 74436 | 74451 | } |
| 74437 | 74452 | } |
| 74438 | 74453 | #endif |
| 74439 | 74454 | |
| 74455 | +#ifdef SQLITE_DEBUG |
| 74456 | +/* |
| 74457 | +** Return true if the Mem holds a RowSet object. This routine is intended |
| 74458 | +** for use inside of assert() statements. |
| 74459 | +*/ |
| 74460 | +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){ |
| 74461 | + return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn) |
| 74462 | + && pMem->xDel==sqlite3RowSetDelete; |
| 74463 | +} |
| 74464 | +#endif |
| 74465 | + |
| 74440 | 74466 | /* |
| 74441 | 74467 | ** Delete any previous value and set the value of pMem to be an |
| 74442 | 74468 | ** empty boolean index. |
| 74469 | +** |
| 74470 | +** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation |
| 74471 | +** error occurs. |
| 74443 | 74472 | */ |
| 74444 | | -SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ |
| 74473 | +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){ |
| 74445 | 74474 | sqlite3 *db = pMem->db; |
| 74475 | + RowSet *p; |
| 74446 | 74476 | assert( db!=0 ); |
| 74447 | | - assert( (pMem->flags & MEM_RowSet)==0 ); |
| 74477 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 74448 | 74478 | sqlite3VdbeMemRelease(pMem); |
| 74449 | | - pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); |
| 74450 | | - if( db->mallocFailed ){ |
| 74451 | | - pMem->flags = MEM_Null; |
| 74452 | | - pMem->szMalloc = 0; |
| 74453 | | - }else{ |
| 74454 | | - assert( pMem->zMalloc ); |
| 74455 | | - pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); |
| 74456 | | - pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); |
| 74457 | | - assert( pMem->u.pRowSet!=0 ); |
| 74458 | | - pMem->flags = MEM_RowSet; |
| 74459 | | - } |
| 74479 | + p = sqlite3RowSetInit(db); |
| 74480 | + if( p==0 ) return SQLITE_NOMEM; |
| 74481 | + pMem->z = (char*)p; |
| 74482 | + pMem->flags = MEM_Blob|MEM_Dyn; |
| 74483 | + pMem->xDel = sqlite3RowSetDelete; |
| 74484 | + return SQLITE_OK; |
| 74460 | 74485 | } |
| 74461 | 74486 | |
| 74462 | 74487 | /* |
| 74463 | 74488 | ** Return true if the Mem object contains a TEXT or BLOB that is |
| 74464 | 74489 | ** too large - whose size exceeds SQLITE_MAX_LENGTH. |
| | @@ -74522,11 +74547,11 @@ |
| 74522 | 74547 | vdbeMemClearExternAndSetNull(pTo); |
| 74523 | 74548 | assert( !VdbeMemDynamic(pTo) ); |
| 74524 | 74549 | sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); |
| 74525 | 74550 | } |
| 74526 | 74551 | SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ |
| 74527 | | - assert( (pFrom->flags & MEM_RowSet)==0 ); |
| 74552 | + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); |
| 74528 | 74553 | assert( pTo->db==pFrom->db ); |
| 74529 | 74554 | if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } |
| 74530 | 74555 | memcpy(pTo, pFrom, MEMCELLSIZE); |
| 74531 | 74556 | if( (pFrom->flags&MEM_Static)==0 ){ |
| 74532 | 74557 | pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); |
| | @@ -74540,11 +74565,11 @@ |
| 74540 | 74565 | ** freed before the copy is made. |
| 74541 | 74566 | */ |
| 74542 | 74567 | SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ |
| 74543 | 74568 | int rc = SQLITE_OK; |
| 74544 | 74569 | |
| 74545 | | - assert( (pFrom->flags & MEM_RowSet)==0 ); |
| 74570 | + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); |
| 74546 | 74571 | if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); |
| 74547 | 74572 | memcpy(pTo, pFrom, MEMCELLSIZE); |
| 74548 | 74573 | pTo->flags &= ~MEM_Dyn; |
| 74549 | 74574 | if( pTo->flags&(MEM_Str|MEM_Blob) ){ |
| 74550 | 74575 | if( 0==(pFrom->flags&MEM_Static) ){ |
| | @@ -74598,11 +74623,11 @@ |
| 74598 | 74623 | int nByte = n; /* New value for pMem->n */ |
| 74599 | 74624 | int iLimit; /* Maximum allowed string or blob size */ |
| 74600 | 74625 | u16 flags = 0; /* New value for pMem->flags */ |
| 74601 | 74626 | |
| 74602 | 74627 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 74603 | | - assert( (pMem->flags & MEM_RowSet)==0 ); |
| 74628 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 74604 | 74629 | |
| 74605 | 74630 | /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ |
| 74606 | 74631 | if( !z ){ |
| 74607 | 74632 | sqlite3VdbeMemSetNull(pMem); |
| 74608 | 74633 | return SQLITE_OK; |
| | @@ -74720,11 +74745,11 @@ |
| 74720 | 74745 | assert( sqlite3BtreeCursorIsValid(pCur) ); |
| 74721 | 74746 | assert( !VdbeMemDynamic(pMem) ); |
| 74722 | 74747 | |
| 74723 | 74748 | /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() |
| 74724 | 74749 | ** that both the BtShared and database handle mutexes are held. */ |
| 74725 | | - assert( (pMem->flags & MEM_RowSet)==0 ); |
| 74750 | + assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 74726 | 74751 | zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); |
| 74727 | 74752 | assert( zData!=0 ); |
| 74728 | 74753 | |
| 74729 | 74754 | if( offset+amt<=available ){ |
| 74730 | 74755 | pMem->z = &zData[offset]; |
| | @@ -74744,11 +74769,11 @@ |
| 74744 | 74769 | */ |
| 74745 | 74770 | static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ |
| 74746 | 74771 | assert( pVal!=0 ); |
| 74747 | 74772 | assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); |
| 74748 | 74773 | assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); |
| 74749 | | - assert( (pVal->flags & MEM_RowSet)==0 ); |
| 74774 | + assert( !sqlite3VdbeMemIsRowSet(pVal) ); |
| 74750 | 74775 | assert( (pVal->flags & (MEM_Null))==0 ); |
| 74751 | 74776 | if( pVal->flags & (MEM_Blob|MEM_Str) ){ |
| 74752 | 74777 | if( ExpandBlob(pVal) ) return 0; |
| 74753 | 74778 | pVal->flags |= MEM_Str; |
| 74754 | 74779 | if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ |
| | @@ -74787,11 +74812,11 @@ |
| 74787 | 74812 | */ |
| 74788 | 74813 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ |
| 74789 | 74814 | if( !pVal ) return 0; |
| 74790 | 74815 | assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); |
| 74791 | 74816 | assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); |
| 74792 | | - assert( (pVal->flags & MEM_RowSet)==0 ); |
| 74817 | + assert( !sqlite3VdbeMemIsRowSet(pVal) ); |
| 74793 | 74818 | if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ |
| 74794 | 74819 | assert( sqlite3VdbeMemConsistentDualRep(pVal) ); |
| 74795 | 74820 | return pVal->z; |
| 74796 | 74821 | } |
| 74797 | 74822 | if( pVal->flags&MEM_Null ){ |
| | @@ -75354,15 +75379,15 @@ |
| 75354 | 75379 | const void *pRec, /* Pointer to buffer containing record */ |
| 75355 | 75380 | int nRec, /* Size of buffer pRec in bytes */ |
| 75356 | 75381 | int iCol, /* Column to extract */ |
| 75357 | 75382 | sqlite3_value **ppVal /* OUT: Extracted value */ |
| 75358 | 75383 | ){ |
| 75359 | | - u32 t; /* a column type code */ |
| 75384 | + u32 t = 0; /* a column type code */ |
| 75360 | 75385 | int nHdr; /* Size of the header in the record */ |
| 75361 | 75386 | int iHdr; /* Next unread header byte */ |
| 75362 | 75387 | int iField; /* Next unread data byte */ |
| 75363 | | - int szField; /* Size of the current data field */ |
| 75388 | + int szField = 0; /* Size of the current data field */ |
| 75364 | 75389 | int i; /* Column index */ |
| 75365 | 75390 | u8 *a = (u8*)pRec; /* Typecast byte array */ |
| 75366 | 75391 | Mem *pMem = *ppVal; /* Write result into this Mem object */ |
| 75367 | 75392 | |
| 75368 | 75393 | assert( iCol>0 ); |
| | @@ -75774,11 +75799,11 @@ |
| 75774 | 75799 | ** subsequent Explains until sqlite3VdbeExplainPop() is called. |
| 75775 | 75800 | */ |
| 75776 | 75801 | SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ |
| 75777 | 75802 | if( pParse->explain==2 ){ |
| 75778 | 75803 | char *zMsg; |
| 75779 | | - Vdbe *v = pParse->pVdbe; |
| 75804 | + Vdbe *v; |
| 75780 | 75805 | va_list ap; |
| 75781 | 75806 | int iThis; |
| 75782 | 75807 | va_start(ap, zFmt); |
| 75783 | 75808 | zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); |
| 75784 | 75809 | va_end(ap); |
| | @@ -77119,13 +77144,13 @@ |
| 77119 | 77144 | ** with no indexes using a single prepared INSERT statement, bind() |
| 77120 | 77145 | ** and reset(). Inserts are grouped into a transaction. |
| 77121 | 77146 | */ |
| 77122 | 77147 | testcase( p->flags & MEM_Agg ); |
| 77123 | 77148 | testcase( p->flags & MEM_Dyn ); |
| 77124 | | - testcase( p->flags & MEM_Frame ); |
| 77149 | + testcase( p->xDel==sqlite3VdbeFrameMemDel ); |
| 77125 | 77150 | testcase( p->flags & MEM_RowSet ); |
| 77126 | | - if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ |
| 77151 | + if( p->flags&(MEM_Agg|MEM_Dyn) ){ |
| 77127 | 77152 | sqlite3VdbeMemRelease(p); |
| 77128 | 77153 | }else if( p->szMalloc ){ |
| 77129 | 77154 | sqlite3DbFreeNN(db, p->zMalloc); |
| 77130 | 77155 | p->szMalloc = 0; |
| 77131 | 77156 | } |
| | @@ -77132,19 +77157,49 @@ |
| 77132 | 77157 | |
| 77133 | 77158 | p->flags = MEM_Undefined; |
| 77134 | 77159 | }while( (++p)<pEnd ); |
| 77135 | 77160 | } |
| 77136 | 77161 | } |
| 77162 | + |
| 77163 | +#ifdef SQLITE_DEBUG |
| 77164 | +/* |
| 77165 | +** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is |
| 77166 | +** and false if something is wrong. |
| 77167 | +** |
| 77168 | +** This routine is intended for use inside of assert() statements only. |
| 77169 | +*/ |
| 77170 | +SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){ |
| 77171 | + if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0; |
| 77172 | + return 1; |
| 77173 | +} |
| 77174 | +#endif |
| 77175 | + |
| 77176 | + |
| 77177 | +/* |
| 77178 | +** This is a destructor on a Mem object (which is really an sqlite3_value) |
| 77179 | +** that deletes the Frame object that is attached to it as a blob. |
| 77180 | +** |
| 77181 | +** This routine does not delete the Frame right away. It merely adds the |
| 77182 | +** frame to a list of frames to be deleted when the Vdbe halts. |
| 77183 | +*/ |
| 77184 | +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){ |
| 77185 | + VdbeFrame *pFrame = (VdbeFrame*)pArg; |
| 77186 | + assert( sqlite3VdbeFrameIsValid(pFrame) ); |
| 77187 | + pFrame->pParent = pFrame->v->pDelFrame; |
| 77188 | + pFrame->v->pDelFrame = pFrame; |
| 77189 | +} |
| 77190 | + |
| 77137 | 77191 | |
| 77138 | 77192 | /* |
| 77139 | 77193 | ** Delete a VdbeFrame object and its contents. VdbeFrame objects are |
| 77140 | 77194 | ** allocated by the OP_Program opcode in sqlite3VdbeExec(). |
| 77141 | 77195 | */ |
| 77142 | 77196 | SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){ |
| 77143 | 77197 | int i; |
| 77144 | 77198 | Mem *aMem = VdbeFrameMem(p); |
| 77145 | 77199 | VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; |
| 77200 | + assert( sqlite3VdbeFrameIsValid(p) ); |
| 77146 | 77201 | for(i=0; i<p->nChildCsr; i++){ |
| 77147 | 77202 | sqlite3VdbeFreeCursor(p->v, apCsr[i]); |
| 77148 | 77203 | } |
| 77149 | 77204 | releaseMemArray(aMem, p->nChildMem); |
| 77150 | 77205 | sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); |
| | @@ -79419,11 +79474,11 @@ |
| 79419 | 79474 | int combined_flags; |
| 79420 | 79475 | |
| 79421 | 79476 | f1 = pMem1->flags; |
| 79422 | 79477 | f2 = pMem2->flags; |
| 79423 | 79478 | combined_flags = f1|f2; |
| 79424 | | - assert( (combined_flags & MEM_RowSet)==0 ); |
| 79479 | + assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); |
| 79425 | 79480 | |
| 79426 | 79481 | /* If one value is NULL, it is less than the other. If both values |
| 79427 | 79482 | ** are NULL, return 0. |
| 79428 | 79483 | */ |
| 79429 | 79484 | if( combined_flags&MEM_Null ){ |
| | @@ -82955,11 +83010,11 @@ |
| 82955 | 83010 | printf(" i:%lld", p->u.i); |
| 82956 | 83011 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 82957 | 83012 | }else if( p->flags & MEM_Real ){ |
| 82958 | 83013 | printf(" r:%g", p->u.r); |
| 82959 | 83014 | #endif |
| 82960 | | - }else if( p->flags & MEM_RowSet ){ |
| 83015 | + }else if( sqlite3VdbeMemIsRowSet(p) ){ |
| 82961 | 83016 | printf(" (rowset)"); |
| 82962 | 83017 | }else{ |
| 82963 | 83018 | char zBuf[200]; |
| 82964 | 83019 | sqlite3VdbeMemPrettyPrint(p, zBuf); |
| 82965 | 83020 | printf(" %s", zBuf); |
| | @@ -88445,15 +88500,15 @@ |
| 88445 | 88500 | */ |
| 88446 | 88501 | case OP_RowSetAdd: { /* in1, in2 */ |
| 88447 | 88502 | pIn1 = &aMem[pOp->p1]; |
| 88448 | 88503 | pIn2 = &aMem[pOp->p2]; |
| 88449 | 88504 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 88450 | | - if( (pIn1->flags & MEM_RowSet)==0 ){ |
| 88451 | | - sqlite3VdbeMemSetRowSet(pIn1); |
| 88452 | | - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 88505 | + if( (pIn1->flags & MEM_Blob)==0 ){ |
| 88506 | + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; |
| 88453 | 88507 | } |
| 88454 | | - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i); |
| 88508 | + assert( sqlite3VdbeMemIsRowSet(pIn1) ); |
| 88509 | + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); |
| 88455 | 88510 | break; |
| 88456 | 88511 | } |
| 88457 | 88512 | |
| 88458 | 88513 | /* Opcode: RowSetRead P1 P2 P3 * * |
| 88459 | 88514 | ** Synopsis: r[P3]=rowset(P1) |
| | @@ -88465,12 +88520,13 @@ |
| 88465 | 88520 | */ |
| 88466 | 88521 | case OP_RowSetRead: { /* jump, in1, out3 */ |
| 88467 | 88522 | i64 val; |
| 88468 | 88523 | |
| 88469 | 88524 | pIn1 = &aMem[pOp->p1]; |
| 88470 | | - if( (pIn1->flags & MEM_RowSet)==0 |
| 88471 | | - || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 |
| 88525 | + assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); |
| 88526 | + if( (pIn1->flags & MEM_Blob)==0 |
| 88527 | + || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 |
| 88472 | 88528 | ){ |
| 88473 | 88529 | /* The boolean index is empty */ |
| 88474 | 88530 | sqlite3VdbeMemSetNull(pIn1); |
| 88475 | 88531 | VdbeBranchTaken(1,2); |
| 88476 | 88532 | goto jump_to_p2_and_check_for_interrupt; |
| | @@ -88515,24 +88571,23 @@ |
| 88515 | 88571 | assert( pIn3->flags&MEM_Int ); |
| 88516 | 88572 | |
| 88517 | 88573 | /* If there is anything other than a rowset object in memory cell P1, |
| 88518 | 88574 | ** delete it now and initialize P1 with an empty rowset |
| 88519 | 88575 | */ |
| 88520 | | - if( (pIn1->flags & MEM_RowSet)==0 ){ |
| 88521 | | - sqlite3VdbeMemSetRowSet(pIn1); |
| 88522 | | - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 88576 | + if( (pIn1->flags & MEM_Blob)==0 ){ |
| 88577 | + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; |
| 88523 | 88578 | } |
| 88524 | | - |
| 88579 | + assert( sqlite3VdbeMemIsRowSet(pIn1) ); |
| 88525 | 88580 | assert( pOp->p4type==P4_INT32 ); |
| 88526 | 88581 | assert( iSet==-1 || iSet>=0 ); |
| 88527 | 88582 | if( iSet ){ |
| 88528 | | - exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); |
| 88583 | + exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); |
| 88529 | 88584 | VdbeBranchTaken(exists!=0,2); |
| 88530 | 88585 | if( exists ) goto jump_to_p2; |
| 88531 | 88586 | } |
| 88532 | 88587 | if( iSet>=0 ){ |
| 88533 | | - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); |
| 88588 | + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); |
| 88534 | 88589 | } |
| 88535 | 88590 | break; |
| 88536 | 88591 | } |
| 88537 | 88592 | |
| 88538 | 88593 | |
| | @@ -88592,11 +88647,11 @@ |
| 88592 | 88647 | |
| 88593 | 88648 | /* Register pRt is used to store the memory required to save the state |
| 88594 | 88649 | ** of the current program, and the memory required at runtime to execute |
| 88595 | 88650 | ** the trigger program. If this trigger has been fired before, then pRt |
| 88596 | 88651 | ** is already allocated. Otherwise, it must be initialized. */ |
| 88597 | | - if( (pRt->flags&MEM_Frame)==0 ){ |
| 88652 | + if( (pRt->flags&MEM_Blob)==0 ){ |
| 88598 | 88653 | /* SubProgram.nMem is set to the number of memory cells used by the |
| 88599 | 88654 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 88600 | 88655 | ** cell is required for each cursor used by the program. Set local |
| 88601 | 88656 | ** variable nMem (and later, VdbeFrame.nChildMem) to this value. |
| 88602 | 88657 | */ |
| | @@ -88610,12 +88665,14 @@ |
| 88610 | 88665 | pFrame = sqlite3DbMallocZero(db, nByte); |
| 88611 | 88666 | if( !pFrame ){ |
| 88612 | 88667 | goto no_mem; |
| 88613 | 88668 | } |
| 88614 | 88669 | sqlite3VdbeMemRelease(pRt); |
| 88615 | | - pRt->flags = MEM_Frame; |
| 88616 | | - pRt->u.pFrame = pFrame; |
| 88670 | + pRt->flags = MEM_Blob|MEM_Dyn; |
| 88671 | + pRt->z = (char*)pFrame; |
| 88672 | + pRt->n = nByte; |
| 88673 | + pRt->xDel = sqlite3VdbeFrameMemDel; |
| 88617 | 88674 | |
| 88618 | 88675 | pFrame->v = p; |
| 88619 | 88676 | pFrame->nChildMem = nMem; |
| 88620 | 88677 | pFrame->nChildCsr = pProgram->nCsr; |
| 88621 | 88678 | pFrame->pc = (int)(pOp - aOp); |
| | @@ -88627,18 +88684,22 @@ |
| 88627 | 88684 | pFrame->nOp = p->nOp; |
| 88628 | 88685 | pFrame->token = pProgram->token; |
| 88629 | 88686 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 88630 | 88687 | pFrame->anExec = p->anExec; |
| 88631 | 88688 | #endif |
| 88689 | +#ifdef SQLITE_DEBUG |
| 88690 | + pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; |
| 88691 | +#endif |
| 88632 | 88692 | |
| 88633 | 88693 | pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; |
| 88634 | 88694 | for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ |
| 88635 | 88695 | pMem->flags = MEM_Undefined; |
| 88636 | 88696 | pMem->db = db; |
| 88637 | 88697 | } |
| 88638 | 88698 | }else{ |
| 88639 | | - pFrame = pRt->u.pFrame; |
| 88699 | + pFrame = (VdbeFrame*)pRt->z; |
| 88700 | + assert( pRt->xDel==sqlite3VdbeFrameMemDel ); |
| 88640 | 88701 | assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem |
| 88641 | 88702 | || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); |
| 88642 | 88703 | assert( pProgram->nCsr==pFrame->nChildCsr ); |
| 88643 | 88704 | assert( (int)(pOp - aOp)==pFrame->pc ); |
| 88644 | 88705 | } |
| | @@ -92718,19 +92779,24 @@ |
| 92718 | 92779 | MergeEngine *pMerger, /* MergeEngine to initialize */ |
| 92719 | 92780 | int eMode /* One of the INCRINIT_XXX constants */ |
| 92720 | 92781 | ){ |
| 92721 | 92782 | int rc = SQLITE_OK; /* Return code */ |
| 92722 | 92783 | int i; /* For looping over PmaReader objects */ |
| 92723 | | - int nTree = pMerger->nTree; |
| 92784 | + int nTree; /* Number of subtrees to merge */ |
| 92785 | + |
| 92786 | + /* Failure to allocate the merge would have been detected prior to |
| 92787 | + ** invoking this routine */ |
| 92788 | + assert( pMerger!=0 ); |
| 92724 | 92789 | |
| 92725 | 92790 | /* eMode is always INCRINIT_NORMAL in single-threaded mode */ |
| 92726 | 92791 | assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); |
| 92727 | 92792 | |
| 92728 | 92793 | /* Verify that the MergeEngine is assigned to a single thread */ |
| 92729 | 92794 | assert( pMerger->pTask==0 ); |
| 92730 | 92795 | pMerger->pTask = pTask; |
| 92731 | 92796 | |
| 92797 | + nTree = pMerger->nTree; |
| 92732 | 92798 | for(i=0; i<nTree; i++){ |
| 92733 | 92799 | if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){ |
| 92734 | 92800 | /* PmaReaders should be normally initialized in order, as if they are |
| 92735 | 92801 | ** reading from the same temp file this makes for more linear file IO. |
| 92736 | 92802 | ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is |
| | @@ -99364,11 +99430,11 @@ |
| 99364 | 99430 | ** control overloading) ends up as the second argument to the |
| 99365 | 99431 | ** function. The expression "A glob B" is equivalent to |
| 99366 | 99432 | ** "glob(B,A). We want to use the A in "A glob B" to test |
| 99367 | 99433 | ** for function overloading. But we use the B term in "glob(B,A)". |
| 99368 | 99434 | */ |
| 99369 | | - if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ |
| 99435 | + if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){ |
| 99370 | 99436 | pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); |
| 99371 | 99437 | }else if( nFarg>0 ){ |
| 99372 | 99438 | pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); |
| 99373 | 99439 | } |
| 99374 | 99440 | #endif |
| | @@ -120913,11 +120979,10 @@ |
| 120913 | 120979 | sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]); |
| 120914 | 120980 | cSep = ','; |
| 120915 | 120981 | } |
| 120916 | 120982 | if( i==0 ){ |
| 120917 | 120983 | sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); |
| 120918 | | - cSep = ','; |
| 120919 | 120984 | i++; |
| 120920 | 120985 | } |
| 120921 | 120986 | j = 0; |
| 120922 | 120987 | if( pPragma->mPragFlg & PragFlg_Result1 ){ |
| 120923 | 120988 | sqlite3_str_appendall(&acc, ",arg HIDDEN"); |
| | @@ -131184,14 +131249,16 @@ |
| 131184 | 131249 | int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */ |
| 131185 | 131250 | ){ |
| 131186 | 131251 | Vdbe *v = pParse->pVdbe; |
| 131187 | 131252 | sqlite3 *db = pParse->db; |
| 131188 | 131253 | SrcList *pSrc; /* FROM clause for the UPDATE */ |
| 131189 | | - int iDataCur = pUpsert->iDataCur; |
| 131254 | + int iDataCur; |
| 131190 | 131255 | |
| 131191 | 131256 | assert( v!=0 ); |
| 131257 | + assert( pUpsert!=0 ); |
| 131192 | 131258 | VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); |
| 131259 | + iDataCur = pUpsert->iDataCur; |
| 131193 | 131260 | if( pIdx && iCur!=iDataCur ){ |
| 131194 | 131261 | if( HasRowid(pTab) ){ |
| 131195 | 131262 | int regRowid = sqlite3GetTempReg(pParse); |
| 131196 | 131263 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid); |
| 131197 | 131264 | sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid); |
| | @@ -136007,10 +136074,11 @@ |
| 136007 | 136074 | ** of virtual table in forms (5) or (7) then return 2. |
| 136008 | 136075 | ** |
| 136009 | 136076 | ** If the expression matches none of the patterns above, return 0. |
| 136010 | 136077 | */ |
| 136011 | 136078 | static int isAuxiliaryVtabOperator( |
| 136079 | + sqlite3 *db, /* Parsing context */ |
| 136012 | 136080 | Expr *pExpr, /* Test this expression */ |
| 136013 | 136081 | unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ |
| 136014 | 136082 | Expr **ppLeft, /* Column expression to left of MATCH/op2 */ |
| 136015 | 136083 | Expr **ppRight /* Expression to left of MATCH/op2 */ |
| 136016 | 136084 | ){ |
| | @@ -136030,20 +136098,58 @@ |
| 136030 | 136098 | |
| 136031 | 136099 | pList = pExpr->x.pList; |
| 136032 | 136100 | if( pList==0 || pList->nExpr!=2 ){ |
| 136033 | 136101 | return 0; |
| 136034 | 136102 | } |
| 136103 | + |
| 136104 | + /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a |
| 136105 | + ** virtual table on their second argument, which is the same as |
| 136106 | + ** the left-hand side operand in their in-fix form. |
| 136107 | + ** |
| 136108 | + ** vtab_column MATCH expression |
| 136109 | + ** MATCH(expression,vtab_column) |
| 136110 | + */ |
| 136035 | 136111 | pCol = pList->a[1].pExpr; |
| 136036 | | - if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){ |
| 136037 | | - return 0; |
| 136038 | | - } |
| 136039 | | - for(i=0; i<ArraySize(aOp); i++){ |
| 136040 | | - if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ |
| 136041 | | - *peOp2 = aOp[i].eOp2; |
| 136042 | | - *ppRight = pList->a[0].pExpr; |
| 136043 | | - *ppLeft = pCol; |
| 136044 | | - return 1; |
| 136112 | + if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){ |
| 136113 | + for(i=0; i<ArraySize(aOp); i++){ |
| 136114 | + if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ |
| 136115 | + *peOp2 = aOp[i].eOp2; |
| 136116 | + *ppRight = pList->a[0].pExpr; |
| 136117 | + *ppLeft = pCol; |
| 136118 | + return 1; |
| 136119 | + } |
| 136120 | + } |
| 136121 | + } |
| 136122 | + |
| 136123 | + /* We can also match against the first column of overloaded |
| 136124 | + ** functions where xFindFunction returns a value of at least |
| 136125 | + ** SQLITE_INDEX_CONSTRAINT_FUNCTION. |
| 136126 | + ** |
| 136127 | + ** OVERLOADED(vtab_column,expression) |
| 136128 | + ** |
| 136129 | + ** Historically, xFindFunction expected to see lower-case function |
| 136130 | + ** names. But for this use case, xFindFunction is expected to deal |
| 136131 | + ** with function names in an arbitrary case. |
| 136132 | + */ |
| 136133 | + pCol = pList->a[0].pExpr; |
| 136134 | + if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){ |
| 136135 | + sqlite3_vtab *pVtab; |
| 136136 | + sqlite3_module *pMod; |
| 136137 | + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); |
| 136138 | + void *pNotUsed; |
| 136139 | + pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab; |
| 136140 | + assert( pVtab!=0 ); |
| 136141 | + assert( pVtab->pModule!=0 ); |
| 136142 | + pMod = (sqlite3_module *)pVtab->pModule; |
| 136143 | + if( pMod->xFindFunction!=0 ){ |
| 136144 | + i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); |
| 136145 | + if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ |
| 136146 | + *peOp2 = i; |
| 136147 | + *ppRight = pList->a[1].pExpr; |
| 136148 | + *ppLeft = pCol; |
| 136149 | + return 1; |
| 136150 | + } |
| 136045 | 136151 | } |
| 136046 | 136152 | } |
| 136047 | 136153 | }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ |
| 136048 | 136154 | int res = 0; |
| 136049 | 136155 | Expr *pLeft = pExpr->pLeft; |
| | @@ -136487,11 +136593,11 @@ |
| 136487 | 136593 | assert( !ExprHasProperty(pNew, EP_xIsSelect) ); |
| 136488 | 136594 | pNew->x.pList = pList; |
| 136489 | 136595 | idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); |
| 136490 | 136596 | testcase( idxNew==0 ); |
| 136491 | 136597 | exprAnalyze(pSrc, pWC, idxNew); |
| 136492 | | - pTerm = &pWC->a[idxTerm]; |
| 136598 | + /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */ |
| 136493 | 136599 | markTermAsChild(pWC, idxNew, idxTerm); |
| 136494 | 136600 | }else{ |
| 136495 | 136601 | sqlite3ExprListDelete(db, pList); |
| 136496 | 136602 | } |
| 136497 | 136603 | } |
| | @@ -136904,11 +137010,11 @@ |
| 136904 | 137010 | ** virtual tables. The native query optimizer does not attempt |
| 136905 | 137011 | ** to do anything with MATCH functions. |
| 136906 | 137012 | */ |
| 136907 | 137013 | if( pWC->op==TK_AND ){ |
| 136908 | 137014 | Expr *pRight = 0, *pLeft = 0; |
| 136909 | | - int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight); |
| 137015 | + int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); |
| 136910 | 137016 | while( res-- > 0 ){ |
| 136911 | 137017 | int idxNew; |
| 136912 | 137018 | WhereTerm *pNewTerm; |
| 136913 | 137019 | Bitmask prereqColumn, prereqExpr; |
| 136914 | 137020 | |
| | @@ -174363,10 +174469,2530 @@ |
| 174363 | 174469 | } |
| 174364 | 174470 | #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 174365 | 174471 | #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ |
| 174366 | 174472 | |
| 174367 | 174473 | /************** End of fts3_unicode2.c ***************************************/ |
| 174474 | +/************** Begin file json1.c *******************************************/ |
| 174475 | +/* |
| 174476 | +** 2015-08-12 |
| 174477 | +** |
| 174478 | +** The author disclaims copyright to this source code. In place of |
| 174479 | +** a legal notice, here is a blessing: |
| 174480 | +** |
| 174481 | +** May you do good and not evil. |
| 174482 | +** May you find forgiveness for yourself and forgive others. |
| 174483 | +** May you share freely, never taking more than you give. |
| 174484 | +** |
| 174485 | +****************************************************************************** |
| 174486 | +** |
| 174487 | +** This SQLite extension implements JSON functions. The interface is |
| 174488 | +** modeled after MySQL JSON functions: |
| 174489 | +** |
| 174490 | +** https://dev.mysql.com/doc/refman/5.7/en/json.html |
| 174491 | +** |
| 174492 | +** For the time being, all JSON is stored as pure text. (We might add |
| 174493 | +** a JSONB type in the future which stores a binary encoding of JSON in |
| 174494 | +** a BLOB, but there is no support for JSONB in the current implementation. |
| 174495 | +** This implementation parses JSON text at 250 MB/s, so it is hard to see |
| 174496 | +** how JSONB might improve on that.) |
| 174497 | +*/ |
| 174498 | +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) |
| 174499 | +#if !defined(SQLITEINT_H) |
| 174500 | +/* #include "sqlite3ext.h" */ |
| 174501 | +#endif |
| 174502 | +SQLITE_EXTENSION_INIT1 |
| 174503 | +/* #include <assert.h> */ |
| 174504 | +/* #include <string.h> */ |
| 174505 | +/* #include <stdlib.h> */ |
| 174506 | +/* #include <stdarg.h> */ |
| 174507 | + |
| 174508 | +/* Mark a function parameter as unused, to suppress nuisance compiler |
| 174509 | +** warnings. */ |
| 174510 | +#ifndef UNUSED_PARAM |
| 174511 | +# define UNUSED_PARAM(X) (void)(X) |
| 174512 | +#endif |
| 174513 | + |
| 174514 | +#ifndef LARGEST_INT64 |
| 174515 | +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) |
| 174516 | +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) |
| 174517 | +#endif |
| 174518 | + |
| 174519 | +/* |
| 174520 | +** Versions of isspace(), isalnum() and isdigit() to which it is safe |
| 174521 | +** to pass signed char values. |
| 174522 | +*/ |
| 174523 | +#ifdef sqlite3Isdigit |
| 174524 | + /* Use the SQLite core versions if this routine is part of the |
| 174525 | + ** SQLite amalgamation */ |
| 174526 | +# define safe_isdigit(x) sqlite3Isdigit(x) |
| 174527 | +# define safe_isalnum(x) sqlite3Isalnum(x) |
| 174528 | +# define safe_isxdigit(x) sqlite3Isxdigit(x) |
| 174529 | +#else |
| 174530 | + /* Use the standard library for separate compilation */ |
| 174531 | +#include <ctype.h> /* amalgamator: keep */ |
| 174532 | +# define safe_isdigit(x) isdigit((unsigned char)(x)) |
| 174533 | +# define safe_isalnum(x) isalnum((unsigned char)(x)) |
| 174534 | +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) |
| 174535 | +#endif |
| 174536 | + |
| 174537 | +/* |
| 174538 | +** Growing our own isspace() routine this way is twice as fast as |
| 174539 | +** the library isspace() function, resulting in a 7% overall performance |
| 174540 | +** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). |
| 174541 | +*/ |
| 174542 | +static const char jsonIsSpace[] = { |
| 174543 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, |
| 174544 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174545 | + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174546 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174547 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174548 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174549 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174550 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174551 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174552 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174553 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174554 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174555 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174556 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174557 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174558 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 174559 | +}; |
| 174560 | +#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) |
| 174561 | + |
| 174562 | +#ifndef SQLITE_AMALGAMATION |
| 174563 | + /* Unsigned integer types. These are already defined in the sqliteInt.h, |
| 174564 | + ** but the definitions need to be repeated for separate compilation. */ |
| 174565 | + typedef sqlite3_uint64 u64; |
| 174566 | + typedef unsigned int u32; |
| 174567 | + typedef unsigned short int u16; |
| 174568 | + typedef unsigned char u8; |
| 174569 | +#endif |
| 174570 | + |
| 174571 | +/* Objects */ |
| 174572 | +typedef struct JsonString JsonString; |
| 174573 | +typedef struct JsonNode JsonNode; |
| 174574 | +typedef struct JsonParse JsonParse; |
| 174575 | + |
| 174576 | +/* An instance of this object represents a JSON string |
| 174577 | +** under construction. Really, this is a generic string accumulator |
| 174578 | +** that can be and is used to create strings other than JSON. |
| 174579 | +*/ |
| 174580 | +struct JsonString { |
| 174581 | + sqlite3_context *pCtx; /* Function context - put error messages here */ |
| 174582 | + char *zBuf; /* Append JSON content here */ |
| 174583 | + u64 nAlloc; /* Bytes of storage available in zBuf[] */ |
| 174584 | + u64 nUsed; /* Bytes of zBuf[] currently used */ |
| 174585 | + u8 bStatic; /* True if zBuf is static space */ |
| 174586 | + u8 bErr; /* True if an error has been encountered */ |
| 174587 | + char zSpace[100]; /* Initial static space */ |
| 174588 | +}; |
| 174589 | + |
| 174590 | +/* JSON type values |
| 174591 | +*/ |
| 174592 | +#define JSON_NULL 0 |
| 174593 | +#define JSON_TRUE 1 |
| 174594 | +#define JSON_FALSE 2 |
| 174595 | +#define JSON_INT 3 |
| 174596 | +#define JSON_REAL 4 |
| 174597 | +#define JSON_STRING 5 |
| 174598 | +#define JSON_ARRAY 6 |
| 174599 | +#define JSON_OBJECT 7 |
| 174600 | + |
| 174601 | +/* The "subtype" set for JSON values */ |
| 174602 | +#define JSON_SUBTYPE 74 /* Ascii for "J" */ |
| 174603 | + |
| 174604 | +/* |
| 174605 | +** Names of the various JSON types: |
| 174606 | +*/ |
| 174607 | +static const char * const jsonType[] = { |
| 174608 | + "null", "true", "false", "integer", "real", "text", "array", "object" |
| 174609 | +}; |
| 174610 | + |
| 174611 | +/* Bit values for the JsonNode.jnFlag field |
| 174612 | +*/ |
| 174613 | +#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ |
| 174614 | +#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ |
| 174615 | +#define JNODE_REMOVE 0x04 /* Do not output */ |
| 174616 | +#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ |
| 174617 | +#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ |
| 174618 | +#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ |
| 174619 | +#define JNODE_LABEL 0x40 /* Is a label of an object */ |
| 174620 | + |
| 174621 | + |
| 174622 | +/* A single node of parsed JSON |
| 174623 | +*/ |
| 174624 | +struct JsonNode { |
| 174625 | + u8 eType; /* One of the JSON_ type values */ |
| 174626 | + u8 jnFlags; /* JNODE flags */ |
| 174627 | + u32 n; /* Bytes of content, or number of sub-nodes */ |
| 174628 | + union { |
| 174629 | + const char *zJContent; /* Content for INT, REAL, and STRING */ |
| 174630 | + u32 iAppend; /* More terms for ARRAY and OBJECT */ |
| 174631 | + u32 iKey; /* Key for ARRAY objects in json_tree() */ |
| 174632 | + u32 iReplace; /* Replacement content for JNODE_REPLACE */ |
| 174633 | + JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ |
| 174634 | + } u; |
| 174635 | +}; |
| 174636 | + |
| 174637 | +/* A completely parsed JSON string |
| 174638 | +*/ |
| 174639 | +struct JsonParse { |
| 174640 | + u32 nNode; /* Number of slots of aNode[] used */ |
| 174641 | + u32 nAlloc; /* Number of slots of aNode[] allocated */ |
| 174642 | + JsonNode *aNode; /* Array of nodes containing the parse */ |
| 174643 | + const char *zJson; /* Original JSON string */ |
| 174644 | + u32 *aUp; /* Index of parent of each node */ |
| 174645 | + u8 oom; /* Set to true if out of memory */ |
| 174646 | + u8 nErr; /* Number of errors seen */ |
| 174647 | + u16 iDepth; /* Nesting depth */ |
| 174648 | + int nJson; /* Length of the zJson string in bytes */ |
| 174649 | + u32 iHold; /* Replace cache line with the lowest iHold value */ |
| 174650 | +}; |
| 174651 | + |
| 174652 | +/* |
| 174653 | +** Maximum nesting depth of JSON for this implementation. |
| 174654 | +** |
| 174655 | +** This limit is needed to avoid a stack overflow in the recursive |
| 174656 | +** descent parser. A depth of 2000 is far deeper than any sane JSON |
| 174657 | +** should go. |
| 174658 | +*/ |
| 174659 | +#define JSON_MAX_DEPTH 2000 |
| 174660 | + |
| 174661 | +/************************************************************************** |
| 174662 | +** Utility routines for dealing with JsonString objects |
| 174663 | +**************************************************************************/ |
| 174664 | + |
| 174665 | +/* Set the JsonString object to an empty string |
| 174666 | +*/ |
| 174667 | +static void jsonZero(JsonString *p){ |
| 174668 | + p->zBuf = p->zSpace; |
| 174669 | + p->nAlloc = sizeof(p->zSpace); |
| 174670 | + p->nUsed = 0; |
| 174671 | + p->bStatic = 1; |
| 174672 | +} |
| 174673 | + |
| 174674 | +/* Initialize the JsonString object |
| 174675 | +*/ |
| 174676 | +static void jsonInit(JsonString *p, sqlite3_context *pCtx){ |
| 174677 | + p->pCtx = pCtx; |
| 174678 | + p->bErr = 0; |
| 174679 | + jsonZero(p); |
| 174680 | +} |
| 174681 | + |
| 174682 | + |
| 174683 | +/* Free all allocated memory and reset the JsonString object back to its |
| 174684 | +** initial state. |
| 174685 | +*/ |
| 174686 | +static void jsonReset(JsonString *p){ |
| 174687 | + if( !p->bStatic ) sqlite3_free(p->zBuf); |
| 174688 | + jsonZero(p); |
| 174689 | +} |
| 174690 | + |
| 174691 | + |
| 174692 | +/* Report an out-of-memory (OOM) condition |
| 174693 | +*/ |
| 174694 | +static void jsonOom(JsonString *p){ |
| 174695 | + p->bErr = 1; |
| 174696 | + sqlite3_result_error_nomem(p->pCtx); |
| 174697 | + jsonReset(p); |
| 174698 | +} |
| 174699 | + |
| 174700 | +/* Enlarge pJson->zBuf so that it can hold at least N more bytes. |
| 174701 | +** Return zero on success. Return non-zero on an OOM error |
| 174702 | +*/ |
| 174703 | +static int jsonGrow(JsonString *p, u32 N){ |
| 174704 | + u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10; |
| 174705 | + char *zNew; |
| 174706 | + if( p->bStatic ){ |
| 174707 | + if( p->bErr ) return 1; |
| 174708 | + zNew = sqlite3_malloc64(nTotal); |
| 174709 | + if( zNew==0 ){ |
| 174710 | + jsonOom(p); |
| 174711 | + return SQLITE_NOMEM; |
| 174712 | + } |
| 174713 | + memcpy(zNew, p->zBuf, (size_t)p->nUsed); |
| 174714 | + p->zBuf = zNew; |
| 174715 | + p->bStatic = 0; |
| 174716 | + }else{ |
| 174717 | + zNew = sqlite3_realloc64(p->zBuf, nTotal); |
| 174718 | + if( zNew==0 ){ |
| 174719 | + jsonOom(p); |
| 174720 | + return SQLITE_NOMEM; |
| 174721 | + } |
| 174722 | + p->zBuf = zNew; |
| 174723 | + } |
| 174724 | + p->nAlloc = nTotal; |
| 174725 | + return SQLITE_OK; |
| 174726 | +} |
| 174727 | + |
| 174728 | +/* Append N bytes from zIn onto the end of the JsonString string. |
| 174729 | +*/ |
| 174730 | +static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ |
| 174731 | + if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; |
| 174732 | + memcpy(p->zBuf+p->nUsed, zIn, N); |
| 174733 | + p->nUsed += N; |
| 174734 | +} |
| 174735 | + |
| 174736 | +/* Append formatted text (not to exceed N bytes) to the JsonString. |
| 174737 | +*/ |
| 174738 | +static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ |
| 174739 | + va_list ap; |
| 174740 | + if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; |
| 174741 | + va_start(ap, zFormat); |
| 174742 | + sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); |
| 174743 | + va_end(ap); |
| 174744 | + p->nUsed += (int)strlen(p->zBuf+p->nUsed); |
| 174745 | +} |
| 174746 | + |
| 174747 | +/* Append a single character |
| 174748 | +*/ |
| 174749 | +static void jsonAppendChar(JsonString *p, char c){ |
| 174750 | + if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; |
| 174751 | + p->zBuf[p->nUsed++] = c; |
| 174752 | +} |
| 174753 | + |
| 174754 | +/* Append a comma separator to the output buffer, if the previous |
| 174755 | +** character is not '[' or '{'. |
| 174756 | +*/ |
| 174757 | +static void jsonAppendSeparator(JsonString *p){ |
| 174758 | + char c; |
| 174759 | + if( p->nUsed==0 ) return; |
| 174760 | + c = p->zBuf[p->nUsed-1]; |
| 174761 | + if( c!='[' && c!='{' ) jsonAppendChar(p, ','); |
| 174762 | +} |
| 174763 | + |
| 174764 | +/* Append the N-byte string in zIn to the end of the JsonString string |
| 174765 | +** under construction. Enclose the string in "..." and escape |
| 174766 | +** any double-quotes or backslash characters contained within the |
| 174767 | +** string. |
| 174768 | +*/ |
| 174769 | +static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ |
| 174770 | + u32 i; |
| 174771 | + if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; |
| 174772 | + p->zBuf[p->nUsed++] = '"'; |
| 174773 | + for(i=0; i<N; i++){ |
| 174774 | + unsigned char c = ((unsigned const char*)zIn)[i]; |
| 174775 | + if( c=='"' || c=='\\' ){ |
| 174776 | + json_simple_escape: |
| 174777 | + if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; |
| 174778 | + p->zBuf[p->nUsed++] = '\\'; |
| 174779 | + }else if( c<=0x1f ){ |
| 174780 | + static const char aSpecial[] = { |
| 174781 | + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, |
| 174782 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 174783 | + }; |
| 174784 | + assert( sizeof(aSpecial)==32 ); |
| 174785 | + assert( aSpecial['\b']=='b' ); |
| 174786 | + assert( aSpecial['\f']=='f' ); |
| 174787 | + assert( aSpecial['\n']=='n' ); |
| 174788 | + assert( aSpecial['\r']=='r' ); |
| 174789 | + assert( aSpecial['\t']=='t' ); |
| 174790 | + if( aSpecial[c] ){ |
| 174791 | + c = aSpecial[c]; |
| 174792 | + goto json_simple_escape; |
| 174793 | + } |
| 174794 | + if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; |
| 174795 | + p->zBuf[p->nUsed++] = '\\'; |
| 174796 | + p->zBuf[p->nUsed++] = 'u'; |
| 174797 | + p->zBuf[p->nUsed++] = '0'; |
| 174798 | + p->zBuf[p->nUsed++] = '0'; |
| 174799 | + p->zBuf[p->nUsed++] = '0' + (c>>4); |
| 174800 | + c = "0123456789abcdef"[c&0xf]; |
| 174801 | + } |
| 174802 | + p->zBuf[p->nUsed++] = c; |
| 174803 | + } |
| 174804 | + p->zBuf[p->nUsed++] = '"'; |
| 174805 | + assert( p->nUsed<p->nAlloc ); |
| 174806 | +} |
| 174807 | + |
| 174808 | +/* |
| 174809 | +** Append a function parameter value to the JSON string under |
| 174810 | +** construction. |
| 174811 | +*/ |
| 174812 | +static void jsonAppendValue( |
| 174813 | + JsonString *p, /* Append to this JSON string */ |
| 174814 | + sqlite3_value *pValue /* Value to append */ |
| 174815 | +){ |
| 174816 | + switch( sqlite3_value_type(pValue) ){ |
| 174817 | + case SQLITE_NULL: { |
| 174818 | + jsonAppendRaw(p, "null", 4); |
| 174819 | + break; |
| 174820 | + } |
| 174821 | + case SQLITE_INTEGER: |
| 174822 | + case SQLITE_FLOAT: { |
| 174823 | + const char *z = (const char*)sqlite3_value_text(pValue); |
| 174824 | + u32 n = (u32)sqlite3_value_bytes(pValue); |
| 174825 | + jsonAppendRaw(p, z, n); |
| 174826 | + break; |
| 174827 | + } |
| 174828 | + case SQLITE_TEXT: { |
| 174829 | + const char *z = (const char*)sqlite3_value_text(pValue); |
| 174830 | + u32 n = (u32)sqlite3_value_bytes(pValue); |
| 174831 | + if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ |
| 174832 | + jsonAppendRaw(p, z, n); |
| 174833 | + }else{ |
| 174834 | + jsonAppendString(p, z, n); |
| 174835 | + } |
| 174836 | + break; |
| 174837 | + } |
| 174838 | + default: { |
| 174839 | + if( p->bErr==0 ){ |
| 174840 | + sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); |
| 174841 | + p->bErr = 2; |
| 174842 | + jsonReset(p); |
| 174843 | + } |
| 174844 | + break; |
| 174845 | + } |
| 174846 | + } |
| 174847 | +} |
| 174848 | + |
| 174849 | + |
| 174850 | +/* Make the JSON in p the result of the SQL function. |
| 174851 | +*/ |
| 174852 | +static void jsonResult(JsonString *p){ |
| 174853 | + if( p->bErr==0 ){ |
| 174854 | + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, |
| 174855 | + p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, |
| 174856 | + SQLITE_UTF8); |
| 174857 | + jsonZero(p); |
| 174858 | + } |
| 174859 | + assert( p->bStatic ); |
| 174860 | +} |
| 174861 | + |
| 174862 | +/************************************************************************** |
| 174863 | +** Utility routines for dealing with JsonNode and JsonParse objects |
| 174864 | +**************************************************************************/ |
| 174865 | + |
| 174866 | +/* |
| 174867 | +** Return the number of consecutive JsonNode slots need to represent |
| 174868 | +** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and |
| 174869 | +** OBJECT types, the number might be larger. |
| 174870 | +** |
| 174871 | +** Appended elements are not counted. The value returned is the number |
| 174872 | +** by which the JsonNode counter should increment in order to go to the |
| 174873 | +** next peer value. |
| 174874 | +*/ |
| 174875 | +static u32 jsonNodeSize(JsonNode *pNode){ |
| 174876 | + return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; |
| 174877 | +} |
| 174878 | + |
| 174879 | +/* |
| 174880 | +** Reclaim all memory allocated by a JsonParse object. But do not |
| 174881 | +** delete the JsonParse object itself. |
| 174882 | +*/ |
| 174883 | +static void jsonParseReset(JsonParse *pParse){ |
| 174884 | + sqlite3_free(pParse->aNode); |
| 174885 | + pParse->aNode = 0; |
| 174886 | + pParse->nNode = 0; |
| 174887 | + pParse->nAlloc = 0; |
| 174888 | + sqlite3_free(pParse->aUp); |
| 174889 | + pParse->aUp = 0; |
| 174890 | +} |
| 174891 | + |
| 174892 | +/* |
| 174893 | +** Free a JsonParse object that was obtained from sqlite3_malloc(). |
| 174894 | +*/ |
| 174895 | +static void jsonParseFree(JsonParse *pParse){ |
| 174896 | + jsonParseReset(pParse); |
| 174897 | + sqlite3_free(pParse); |
| 174898 | +} |
| 174899 | + |
| 174900 | +/* |
| 174901 | +** Convert the JsonNode pNode into a pure JSON string and |
| 174902 | +** append to pOut. Subsubstructure is also included. Return |
| 174903 | +** the number of JsonNode objects that are encoded. |
| 174904 | +*/ |
| 174905 | +static void jsonRenderNode( |
| 174906 | + JsonNode *pNode, /* The node to render */ |
| 174907 | + JsonString *pOut, /* Write JSON here */ |
| 174908 | + sqlite3_value **aReplace /* Replacement values */ |
| 174909 | +){ |
| 174910 | + if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ |
| 174911 | + if( pNode->jnFlags & JNODE_REPLACE ){ |
| 174912 | + jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); |
| 174913 | + return; |
| 174914 | + } |
| 174915 | + pNode = pNode->u.pPatch; |
| 174916 | + } |
| 174917 | + switch( pNode->eType ){ |
| 174918 | + default: { |
| 174919 | + assert( pNode->eType==JSON_NULL ); |
| 174920 | + jsonAppendRaw(pOut, "null", 4); |
| 174921 | + break; |
| 174922 | + } |
| 174923 | + case JSON_TRUE: { |
| 174924 | + jsonAppendRaw(pOut, "true", 4); |
| 174925 | + break; |
| 174926 | + } |
| 174927 | + case JSON_FALSE: { |
| 174928 | + jsonAppendRaw(pOut, "false", 5); |
| 174929 | + break; |
| 174930 | + } |
| 174931 | + case JSON_STRING: { |
| 174932 | + if( pNode->jnFlags & JNODE_RAW ){ |
| 174933 | + jsonAppendString(pOut, pNode->u.zJContent, pNode->n); |
| 174934 | + break; |
| 174935 | + } |
| 174936 | + /* Fall through into the next case */ |
| 174937 | + } |
| 174938 | + case JSON_REAL: |
| 174939 | + case JSON_INT: { |
| 174940 | + jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); |
| 174941 | + break; |
| 174942 | + } |
| 174943 | + case JSON_ARRAY: { |
| 174944 | + u32 j = 1; |
| 174945 | + jsonAppendChar(pOut, '['); |
| 174946 | + for(;;){ |
| 174947 | + while( j<=pNode->n ){ |
| 174948 | + if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ |
| 174949 | + jsonAppendSeparator(pOut); |
| 174950 | + jsonRenderNode(&pNode[j], pOut, aReplace); |
| 174951 | + } |
| 174952 | + j += jsonNodeSize(&pNode[j]); |
| 174953 | + } |
| 174954 | + if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; |
| 174955 | + pNode = &pNode[pNode->u.iAppend]; |
| 174956 | + j = 1; |
| 174957 | + } |
| 174958 | + jsonAppendChar(pOut, ']'); |
| 174959 | + break; |
| 174960 | + } |
| 174961 | + case JSON_OBJECT: { |
| 174962 | + u32 j = 1; |
| 174963 | + jsonAppendChar(pOut, '{'); |
| 174964 | + for(;;){ |
| 174965 | + while( j<=pNode->n ){ |
| 174966 | + if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ |
| 174967 | + jsonAppendSeparator(pOut); |
| 174968 | + jsonRenderNode(&pNode[j], pOut, aReplace); |
| 174969 | + jsonAppendChar(pOut, ':'); |
| 174970 | + jsonRenderNode(&pNode[j+1], pOut, aReplace); |
| 174971 | + } |
| 174972 | + j += 1 + jsonNodeSize(&pNode[j+1]); |
| 174973 | + } |
| 174974 | + if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; |
| 174975 | + pNode = &pNode[pNode->u.iAppend]; |
| 174976 | + j = 1; |
| 174977 | + } |
| 174978 | + jsonAppendChar(pOut, '}'); |
| 174979 | + break; |
| 174980 | + } |
| 174981 | + } |
| 174982 | +} |
| 174983 | + |
| 174984 | +/* |
| 174985 | +** Return a JsonNode and all its descendents as a JSON string. |
| 174986 | +*/ |
| 174987 | +static void jsonReturnJson( |
| 174988 | + JsonNode *pNode, /* Node to return */ |
| 174989 | + sqlite3_context *pCtx, /* Return value for this function */ |
| 174990 | + sqlite3_value **aReplace /* Array of replacement values */ |
| 174991 | +){ |
| 174992 | + JsonString s; |
| 174993 | + jsonInit(&s, pCtx); |
| 174994 | + jsonRenderNode(pNode, &s, aReplace); |
| 174995 | + jsonResult(&s); |
| 174996 | + sqlite3_result_subtype(pCtx, JSON_SUBTYPE); |
| 174997 | +} |
| 174998 | + |
| 174999 | +/* |
| 175000 | +** Make the JsonNode the return value of the function. |
| 175001 | +*/ |
| 175002 | +static void jsonReturn( |
| 175003 | + JsonNode *pNode, /* Node to return */ |
| 175004 | + sqlite3_context *pCtx, /* Return value for this function */ |
| 175005 | + sqlite3_value **aReplace /* Array of replacement values */ |
| 175006 | +){ |
| 175007 | + switch( pNode->eType ){ |
| 175008 | + default: { |
| 175009 | + assert( pNode->eType==JSON_NULL ); |
| 175010 | + sqlite3_result_null(pCtx); |
| 175011 | + break; |
| 175012 | + } |
| 175013 | + case JSON_TRUE: { |
| 175014 | + sqlite3_result_int(pCtx, 1); |
| 175015 | + break; |
| 175016 | + } |
| 175017 | + case JSON_FALSE: { |
| 175018 | + sqlite3_result_int(pCtx, 0); |
| 175019 | + break; |
| 175020 | + } |
| 175021 | + case JSON_INT: { |
| 175022 | + sqlite3_int64 i = 0; |
| 175023 | + const char *z = pNode->u.zJContent; |
| 175024 | + if( z[0]=='-' ){ z++; } |
| 175025 | + while( z[0]>='0' && z[0]<='9' ){ |
| 175026 | + unsigned v = *(z++) - '0'; |
| 175027 | + if( i>=LARGEST_INT64/10 ){ |
| 175028 | + if( i>LARGEST_INT64/10 ) goto int_as_real; |
| 175029 | + if( z[0]>='0' && z[0]<='9' ) goto int_as_real; |
| 175030 | + if( v==9 ) goto int_as_real; |
| 175031 | + if( v==8 ){ |
| 175032 | + if( pNode->u.zJContent[0]=='-' ){ |
| 175033 | + sqlite3_result_int64(pCtx, SMALLEST_INT64); |
| 175034 | + goto int_done; |
| 175035 | + }else{ |
| 175036 | + goto int_as_real; |
| 175037 | + } |
| 175038 | + } |
| 175039 | + } |
| 175040 | + i = i*10 + v; |
| 175041 | + } |
| 175042 | + if( pNode->u.zJContent[0]=='-' ){ i = -i; } |
| 175043 | + sqlite3_result_int64(pCtx, i); |
| 175044 | + int_done: |
| 175045 | + break; |
| 175046 | + int_as_real: /* fall through to real */; |
| 175047 | + } |
| 175048 | + case JSON_REAL: { |
| 175049 | + double r; |
| 175050 | +#ifdef SQLITE_AMALGAMATION |
| 175051 | + const char *z = pNode->u.zJContent; |
| 175052 | + sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); |
| 175053 | +#else |
| 175054 | + r = strtod(pNode->u.zJContent, 0); |
| 175055 | +#endif |
| 175056 | + sqlite3_result_double(pCtx, r); |
| 175057 | + break; |
| 175058 | + } |
| 175059 | + case JSON_STRING: { |
| 175060 | +#if 0 /* Never happens because JNODE_RAW is only set by json_set(), |
| 175061 | + ** json_insert() and json_replace() and those routines do not |
| 175062 | + ** call jsonReturn() */ |
| 175063 | + if( pNode->jnFlags & JNODE_RAW ){ |
| 175064 | + sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, |
| 175065 | + SQLITE_TRANSIENT); |
| 175066 | + }else |
| 175067 | +#endif |
| 175068 | + assert( (pNode->jnFlags & JNODE_RAW)==0 ); |
| 175069 | + if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ |
| 175070 | + /* JSON formatted without any backslash-escapes */ |
| 175071 | + sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, |
| 175072 | + SQLITE_TRANSIENT); |
| 175073 | + }else{ |
| 175074 | + /* Translate JSON formatted string into raw text */ |
| 175075 | + u32 i; |
| 175076 | + u32 n = pNode->n; |
| 175077 | + const char *z = pNode->u.zJContent; |
| 175078 | + char *zOut; |
| 175079 | + u32 j; |
| 175080 | + zOut = sqlite3_malloc( n+1 ); |
| 175081 | + if( zOut==0 ){ |
| 175082 | + sqlite3_result_error_nomem(pCtx); |
| 175083 | + break; |
| 175084 | + } |
| 175085 | + for(i=1, j=0; i<n-1; i++){ |
| 175086 | + char c = z[i]; |
| 175087 | + if( c!='\\' ){ |
| 175088 | + zOut[j++] = c; |
| 175089 | + }else{ |
| 175090 | + c = z[++i]; |
| 175091 | + if( c=='u' ){ |
| 175092 | + u32 v = 0, k; |
| 175093 | + for(k=0; k<4; i++, k++){ |
| 175094 | + assert( i<n-2 ); |
| 175095 | + c = z[i+1]; |
| 175096 | + assert( safe_isxdigit(c) ); |
| 175097 | + if( c<='9' ) v = v*16 + c - '0'; |
| 175098 | + else if( c<='F' ) v = v*16 + c - 'A' + 10; |
| 175099 | + else v = v*16 + c - 'a' + 10; |
| 175100 | + } |
| 175101 | + if( v==0 ) break; |
| 175102 | + if( v<=0x7f ){ |
| 175103 | + zOut[j++] = (char)v; |
| 175104 | + }else if( v<=0x7ff ){ |
| 175105 | + zOut[j++] = (char)(0xc0 | (v>>6)); |
| 175106 | + zOut[j++] = 0x80 | (v&0x3f); |
| 175107 | + }else{ |
| 175108 | + zOut[j++] = (char)(0xe0 | (v>>12)); |
| 175109 | + zOut[j++] = 0x80 | ((v>>6)&0x3f); |
| 175110 | + zOut[j++] = 0x80 | (v&0x3f); |
| 175111 | + } |
| 175112 | + }else{ |
| 175113 | + if( c=='b' ){ |
| 175114 | + c = '\b'; |
| 175115 | + }else if( c=='f' ){ |
| 175116 | + c = '\f'; |
| 175117 | + }else if( c=='n' ){ |
| 175118 | + c = '\n'; |
| 175119 | + }else if( c=='r' ){ |
| 175120 | + c = '\r'; |
| 175121 | + }else if( c=='t' ){ |
| 175122 | + c = '\t'; |
| 175123 | + } |
| 175124 | + zOut[j++] = c; |
| 175125 | + } |
| 175126 | + } |
| 175127 | + } |
| 175128 | + zOut[j] = 0; |
| 175129 | + sqlite3_result_text(pCtx, zOut, j, sqlite3_free); |
| 175130 | + } |
| 175131 | + break; |
| 175132 | + } |
| 175133 | + case JSON_ARRAY: |
| 175134 | + case JSON_OBJECT: { |
| 175135 | + jsonReturnJson(pNode, pCtx, aReplace); |
| 175136 | + break; |
| 175137 | + } |
| 175138 | + } |
| 175139 | +} |
| 175140 | + |
| 175141 | +/* Forward reference */ |
| 175142 | +static int jsonParseAddNode(JsonParse*,u32,u32,const char*); |
| 175143 | + |
| 175144 | +/* |
| 175145 | +** A macro to hint to the compiler that a function should not be |
| 175146 | +** inlined. |
| 175147 | +*/ |
| 175148 | +#if defined(__GNUC__) |
| 175149 | +# define JSON_NOINLINE __attribute__((noinline)) |
| 175150 | +#elif defined(_MSC_VER) && _MSC_VER>=1310 |
| 175151 | +# define JSON_NOINLINE __declspec(noinline) |
| 175152 | +#else |
| 175153 | +# define JSON_NOINLINE |
| 175154 | +#endif |
| 175155 | + |
| 175156 | + |
| 175157 | +static JSON_NOINLINE int jsonParseAddNodeExpand( |
| 175158 | + JsonParse *pParse, /* Append the node to this object */ |
| 175159 | + u32 eType, /* Node type */ |
| 175160 | + u32 n, /* Content size or sub-node count */ |
| 175161 | + const char *zContent /* Content */ |
| 175162 | +){ |
| 175163 | + u32 nNew; |
| 175164 | + JsonNode *pNew; |
| 175165 | + assert( pParse->nNode>=pParse->nAlloc ); |
| 175166 | + if( pParse->oom ) return -1; |
| 175167 | + nNew = pParse->nAlloc*2 + 10; |
| 175168 | + pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew); |
| 175169 | + if( pNew==0 ){ |
| 175170 | + pParse->oom = 1; |
| 175171 | + return -1; |
| 175172 | + } |
| 175173 | + pParse->nAlloc = nNew; |
| 175174 | + pParse->aNode = pNew; |
| 175175 | + assert( pParse->nNode<pParse->nAlloc ); |
| 175176 | + return jsonParseAddNode(pParse, eType, n, zContent); |
| 175177 | +} |
| 175178 | + |
| 175179 | +/* |
| 175180 | +** Create a new JsonNode instance based on the arguments and append that |
| 175181 | +** instance to the JsonParse. Return the index in pParse->aNode[] of the |
| 175182 | +** new node, or -1 if a memory allocation fails. |
| 175183 | +*/ |
| 175184 | +static int jsonParseAddNode( |
| 175185 | + JsonParse *pParse, /* Append the node to this object */ |
| 175186 | + u32 eType, /* Node type */ |
| 175187 | + u32 n, /* Content size or sub-node count */ |
| 175188 | + const char *zContent /* Content */ |
| 175189 | +){ |
| 175190 | + JsonNode *p; |
| 175191 | + if( pParse->nNode>=pParse->nAlloc ){ |
| 175192 | + return jsonParseAddNodeExpand(pParse, eType, n, zContent); |
| 175193 | + } |
| 175194 | + p = &pParse->aNode[pParse->nNode]; |
| 175195 | + p->eType = (u8)eType; |
| 175196 | + p->jnFlags = 0; |
| 175197 | + p->n = n; |
| 175198 | + p->u.zJContent = zContent; |
| 175199 | + return pParse->nNode++; |
| 175200 | +} |
| 175201 | + |
| 175202 | +/* |
| 175203 | +** Return true if z[] begins with 4 (or more) hexadecimal digits |
| 175204 | +*/ |
| 175205 | +static int jsonIs4Hex(const char *z){ |
| 175206 | + int i; |
| 175207 | + for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; |
| 175208 | + return 1; |
| 175209 | +} |
| 175210 | + |
| 175211 | +/* |
| 175212 | +** Parse a single JSON value which begins at pParse->zJson[i]. Return the |
| 175213 | +** index of the first character past the end of the value parsed. |
| 175214 | +** |
| 175215 | +** Return negative for a syntax error. Special cases: return -2 if the |
| 175216 | +** first non-whitespace character is '}' and return -3 if the first |
| 175217 | +** non-whitespace character is ']'. |
| 175218 | +*/ |
| 175219 | +static int jsonParseValue(JsonParse *pParse, u32 i){ |
| 175220 | + char c; |
| 175221 | + u32 j; |
| 175222 | + int iThis; |
| 175223 | + int x; |
| 175224 | + JsonNode *pNode; |
| 175225 | + const char *z = pParse->zJson; |
| 175226 | + while( safe_isspace(z[i]) ){ i++; } |
| 175227 | + if( (c = z[i])=='{' ){ |
| 175228 | + /* Parse object */ |
| 175229 | + iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); |
| 175230 | + if( iThis<0 ) return -1; |
| 175231 | + for(j=i+1;;j++){ |
| 175232 | + while( safe_isspace(z[j]) ){ j++; } |
| 175233 | + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; |
| 175234 | + x = jsonParseValue(pParse, j); |
| 175235 | + if( x<0 ){ |
| 175236 | + pParse->iDepth--; |
| 175237 | + if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; |
| 175238 | + return -1; |
| 175239 | + } |
| 175240 | + if( pParse->oom ) return -1; |
| 175241 | + pNode = &pParse->aNode[pParse->nNode-1]; |
| 175242 | + if( pNode->eType!=JSON_STRING ) return -1; |
| 175243 | + pNode->jnFlags |= JNODE_LABEL; |
| 175244 | + j = x; |
| 175245 | + while( safe_isspace(z[j]) ){ j++; } |
| 175246 | + if( z[j]!=':' ) return -1; |
| 175247 | + j++; |
| 175248 | + x = jsonParseValue(pParse, j); |
| 175249 | + pParse->iDepth--; |
| 175250 | + if( x<0 ) return -1; |
| 175251 | + j = x; |
| 175252 | + while( safe_isspace(z[j]) ){ j++; } |
| 175253 | + c = z[j]; |
| 175254 | + if( c==',' ) continue; |
| 175255 | + if( c!='}' ) return -1; |
| 175256 | + break; |
| 175257 | + } |
| 175258 | + pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; |
| 175259 | + return j+1; |
| 175260 | + }else if( c=='[' ){ |
| 175261 | + /* Parse array */ |
| 175262 | + iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); |
| 175263 | + if( iThis<0 ) return -1; |
| 175264 | + for(j=i+1;;j++){ |
| 175265 | + while( safe_isspace(z[j]) ){ j++; } |
| 175266 | + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; |
| 175267 | + x = jsonParseValue(pParse, j); |
| 175268 | + pParse->iDepth--; |
| 175269 | + if( x<0 ){ |
| 175270 | + if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; |
| 175271 | + return -1; |
| 175272 | + } |
| 175273 | + j = x; |
| 175274 | + while( safe_isspace(z[j]) ){ j++; } |
| 175275 | + c = z[j]; |
| 175276 | + if( c==',' ) continue; |
| 175277 | + if( c!=']' ) return -1; |
| 175278 | + break; |
| 175279 | + } |
| 175280 | + pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; |
| 175281 | + return j+1; |
| 175282 | + }else if( c=='"' ){ |
| 175283 | + /* Parse string */ |
| 175284 | + u8 jnFlags = 0; |
| 175285 | + j = i+1; |
| 175286 | + for(;;){ |
| 175287 | + c = z[j]; |
| 175288 | + if( (c & ~0x1f)==0 ){ |
| 175289 | + /* Control characters are not allowed in strings */ |
| 175290 | + return -1; |
| 175291 | + } |
| 175292 | + if( c=='\\' ){ |
| 175293 | + c = z[++j]; |
| 175294 | + if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' |
| 175295 | + || c=='n' || c=='r' || c=='t' |
| 175296 | + || (c=='u' && jsonIs4Hex(z+j+1)) ){ |
| 175297 | + jnFlags = JNODE_ESCAPE; |
| 175298 | + }else{ |
| 175299 | + return -1; |
| 175300 | + } |
| 175301 | + }else if( c=='"' ){ |
| 175302 | + break; |
| 175303 | + } |
| 175304 | + j++; |
| 175305 | + } |
| 175306 | + jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); |
| 175307 | + if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; |
| 175308 | + return j+1; |
| 175309 | + }else if( c=='n' |
| 175310 | + && strncmp(z+i,"null",4)==0 |
| 175311 | + && !safe_isalnum(z[i+4]) ){ |
| 175312 | + jsonParseAddNode(pParse, JSON_NULL, 0, 0); |
| 175313 | + return i+4; |
| 175314 | + }else if( c=='t' |
| 175315 | + && strncmp(z+i,"true",4)==0 |
| 175316 | + && !safe_isalnum(z[i+4]) ){ |
| 175317 | + jsonParseAddNode(pParse, JSON_TRUE, 0, 0); |
| 175318 | + return i+4; |
| 175319 | + }else if( c=='f' |
| 175320 | + && strncmp(z+i,"false",5)==0 |
| 175321 | + && !safe_isalnum(z[i+5]) ){ |
| 175322 | + jsonParseAddNode(pParse, JSON_FALSE, 0, 0); |
| 175323 | + return i+5; |
| 175324 | + }else if( c=='-' || (c>='0' && c<='9') ){ |
| 175325 | + /* Parse number */ |
| 175326 | + u8 seenDP = 0; |
| 175327 | + u8 seenE = 0; |
| 175328 | + assert( '-' < '0' ); |
| 175329 | + if( c<='0' ){ |
| 175330 | + j = c=='-' ? i+1 : i; |
| 175331 | + if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; |
| 175332 | + } |
| 175333 | + j = i+1; |
| 175334 | + for(;; j++){ |
| 175335 | + c = z[j]; |
| 175336 | + if( c>='0' && c<='9' ) continue; |
| 175337 | + if( c=='.' ){ |
| 175338 | + if( z[j-1]=='-' ) return -1; |
| 175339 | + if( seenDP ) return -1; |
| 175340 | + seenDP = 1; |
| 175341 | + continue; |
| 175342 | + } |
| 175343 | + if( c=='e' || c=='E' ){ |
| 175344 | + if( z[j-1]<'0' ) return -1; |
| 175345 | + if( seenE ) return -1; |
| 175346 | + seenDP = seenE = 1; |
| 175347 | + c = z[j+1]; |
| 175348 | + if( c=='+' || c=='-' ){ |
| 175349 | + j++; |
| 175350 | + c = z[j+1]; |
| 175351 | + } |
| 175352 | + if( c<'0' || c>'9' ) return -1; |
| 175353 | + continue; |
| 175354 | + } |
| 175355 | + break; |
| 175356 | + } |
| 175357 | + if( z[j-1]<'0' ) return -1; |
| 175358 | + jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, |
| 175359 | + j - i, &z[i]); |
| 175360 | + return j; |
| 175361 | + }else if( c=='}' ){ |
| 175362 | + return -2; /* End of {...} */ |
| 175363 | + }else if( c==']' ){ |
| 175364 | + return -3; /* End of [...] */ |
| 175365 | + }else if( c==0 ){ |
| 175366 | + return 0; /* End of file */ |
| 175367 | + }else{ |
| 175368 | + return -1; /* Syntax error */ |
| 175369 | + } |
| 175370 | +} |
| 175371 | + |
| 175372 | +/* |
| 175373 | +** Parse a complete JSON string. Return 0 on success or non-zero if there |
| 175374 | +** are any errors. If an error occurs, free all memory associated with |
| 175375 | +** pParse. |
| 175376 | +** |
| 175377 | +** pParse is uninitialized when this routine is called. |
| 175378 | +*/ |
| 175379 | +static int jsonParse( |
| 175380 | + JsonParse *pParse, /* Initialize and fill this JsonParse object */ |
| 175381 | + sqlite3_context *pCtx, /* Report errors here */ |
| 175382 | + const char *zJson /* Input JSON text to be parsed */ |
| 175383 | +){ |
| 175384 | + int i; |
| 175385 | + memset(pParse, 0, sizeof(*pParse)); |
| 175386 | + if( zJson==0 ) return 1; |
| 175387 | + pParse->zJson = zJson; |
| 175388 | + i = jsonParseValue(pParse, 0); |
| 175389 | + if( pParse->oom ) i = -1; |
| 175390 | + if( i>0 ){ |
| 175391 | + assert( pParse->iDepth==0 ); |
| 175392 | + while( safe_isspace(zJson[i]) ) i++; |
| 175393 | + if( zJson[i] ) i = -1; |
| 175394 | + } |
| 175395 | + if( i<=0 ){ |
| 175396 | + if( pCtx!=0 ){ |
| 175397 | + if( pParse->oom ){ |
| 175398 | + sqlite3_result_error_nomem(pCtx); |
| 175399 | + }else{ |
| 175400 | + sqlite3_result_error(pCtx, "malformed JSON", -1); |
| 175401 | + } |
| 175402 | + } |
| 175403 | + jsonParseReset(pParse); |
| 175404 | + return 1; |
| 175405 | + } |
| 175406 | + return 0; |
| 175407 | +} |
| 175408 | + |
| 175409 | +/* Mark node i of pParse as being a child of iParent. Call recursively |
| 175410 | +** to fill in all the descendants of node i. |
| 175411 | +*/ |
| 175412 | +static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ |
| 175413 | + JsonNode *pNode = &pParse->aNode[i]; |
| 175414 | + u32 j; |
| 175415 | + pParse->aUp[i] = iParent; |
| 175416 | + switch( pNode->eType ){ |
| 175417 | + case JSON_ARRAY: { |
| 175418 | + for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ |
| 175419 | + jsonParseFillInParentage(pParse, i+j, i); |
| 175420 | + } |
| 175421 | + break; |
| 175422 | + } |
| 175423 | + case JSON_OBJECT: { |
| 175424 | + for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ |
| 175425 | + pParse->aUp[i+j] = i; |
| 175426 | + jsonParseFillInParentage(pParse, i+j+1, i); |
| 175427 | + } |
| 175428 | + break; |
| 175429 | + } |
| 175430 | + default: { |
| 175431 | + break; |
| 175432 | + } |
| 175433 | + } |
| 175434 | +} |
| 175435 | + |
| 175436 | +/* |
| 175437 | +** Compute the parentage of all nodes in a completed parse. |
| 175438 | +*/ |
| 175439 | +static int jsonParseFindParents(JsonParse *pParse){ |
| 175440 | + u32 *aUp; |
| 175441 | + assert( pParse->aUp==0 ); |
| 175442 | + aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode ); |
| 175443 | + if( aUp==0 ){ |
| 175444 | + pParse->oom = 1; |
| 175445 | + return SQLITE_NOMEM; |
| 175446 | + } |
| 175447 | + jsonParseFillInParentage(pParse, 0, 0); |
| 175448 | + return SQLITE_OK; |
| 175449 | +} |
| 175450 | + |
| 175451 | +/* |
| 175452 | +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() |
| 175453 | +*/ |
| 175454 | +#define JSON_CACHE_ID (-429938) /* First cache entry */ |
| 175455 | +#define JSON_CACHE_SZ 4 /* Max number of cache entries */ |
| 175456 | + |
| 175457 | +/* |
| 175458 | +** Obtain a complete parse of the JSON found in the first argument |
| 175459 | +** of the argv array. Use the sqlite3_get_auxdata() cache for this |
| 175460 | +** parse if it is available. If the cache is not available or if it |
| 175461 | +** is no longer valid, parse the JSON again and return the new parse, |
| 175462 | +** and also register the new parse so that it will be available for |
| 175463 | +** future sqlite3_get_auxdata() calls. |
| 175464 | +*/ |
| 175465 | +static JsonParse *jsonParseCached( |
| 175466 | + sqlite3_context *pCtx, |
| 175467 | + sqlite3_value **argv, |
| 175468 | + sqlite3_context *pErrCtx |
| 175469 | +){ |
| 175470 | + const char *zJson = (const char*)sqlite3_value_text(argv[0]); |
| 175471 | + int nJson = sqlite3_value_bytes(argv[0]); |
| 175472 | + JsonParse *p; |
| 175473 | + JsonParse *pMatch = 0; |
| 175474 | + int iKey; |
| 175475 | + int iMinKey = 0; |
| 175476 | + u32 iMinHold = 0xffffffff; |
| 175477 | + u32 iMaxHold = 0; |
| 175478 | + if( zJson==0 ) return 0; |
| 175479 | + for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){ |
| 175480 | + p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey); |
| 175481 | + if( p==0 ){ |
| 175482 | + iMinKey = iKey; |
| 175483 | + break; |
| 175484 | + } |
| 175485 | + if( pMatch==0 |
| 175486 | + && p->nJson==nJson |
| 175487 | + && memcmp(p->zJson,zJson,nJson)==0 |
| 175488 | + ){ |
| 175489 | + p->nErr = 0; |
| 175490 | + pMatch = p; |
| 175491 | + }else if( p->iHold<iMinHold ){ |
| 175492 | + iMinHold = p->iHold; |
| 175493 | + iMinKey = iKey; |
| 175494 | + } |
| 175495 | + if( p->iHold>iMaxHold ){ |
| 175496 | + iMaxHold = p->iHold; |
| 175497 | + } |
| 175498 | + } |
| 175499 | + if( pMatch ){ |
| 175500 | + pMatch->nErr = 0; |
| 175501 | + pMatch->iHold = iMaxHold+1; |
| 175502 | + return pMatch; |
| 175503 | + } |
| 175504 | + p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); |
| 175505 | + if( p==0 ){ |
| 175506 | + sqlite3_result_error_nomem(pCtx); |
| 175507 | + return 0; |
| 175508 | + } |
| 175509 | + memset(p, 0, sizeof(*p)); |
| 175510 | + p->zJson = (char*)&p[1]; |
| 175511 | + memcpy((char*)p->zJson, zJson, nJson+1); |
| 175512 | + if( jsonParse(p, pErrCtx, p->zJson) ){ |
| 175513 | + sqlite3_free(p); |
| 175514 | + return 0; |
| 175515 | + } |
| 175516 | + p->nJson = nJson; |
| 175517 | + p->iHold = iMaxHold+1; |
| 175518 | + sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, |
| 175519 | + (void(*)(void*))jsonParseFree); |
| 175520 | + return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); |
| 175521 | +} |
| 175522 | + |
| 175523 | +/* |
| 175524 | +** Compare the OBJECT label at pNode against zKey,nKey. Return true on |
| 175525 | +** a match. |
| 175526 | +*/ |
| 175527 | +static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ |
| 175528 | + if( pNode->jnFlags & JNODE_RAW ){ |
| 175529 | + if( pNode->n!=nKey ) return 0; |
| 175530 | + return strncmp(pNode->u.zJContent, zKey, nKey)==0; |
| 175531 | + }else{ |
| 175532 | + if( pNode->n!=nKey+2 ) return 0; |
| 175533 | + return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; |
| 175534 | + } |
| 175535 | +} |
| 175536 | + |
| 175537 | +/* forward declaration */ |
| 175538 | +static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); |
| 175539 | + |
| 175540 | +/* |
| 175541 | +** Search along zPath to find the node specified. Return a pointer |
| 175542 | +** to that node, or NULL if zPath is malformed or if there is no such |
| 175543 | +** node. |
| 175544 | +** |
| 175545 | +** If pApnd!=0, then try to append new nodes to complete zPath if it is |
| 175546 | +** possible to do so and if no existing node corresponds to zPath. If |
| 175547 | +** new nodes are appended *pApnd is set to 1. |
| 175548 | +*/ |
| 175549 | +static JsonNode *jsonLookupStep( |
| 175550 | + JsonParse *pParse, /* The JSON to search */ |
| 175551 | + u32 iRoot, /* Begin the search at this node */ |
| 175552 | + const char *zPath, /* The path to search */ |
| 175553 | + int *pApnd, /* Append nodes to complete path if not NULL */ |
| 175554 | + const char **pzErr /* Make *pzErr point to any syntax error in zPath */ |
| 175555 | +){ |
| 175556 | + u32 i, j, nKey; |
| 175557 | + const char *zKey; |
| 175558 | + JsonNode *pRoot = &pParse->aNode[iRoot]; |
| 175559 | + if( zPath[0]==0 ) return pRoot; |
| 175560 | + if( zPath[0]=='.' ){ |
| 175561 | + if( pRoot->eType!=JSON_OBJECT ) return 0; |
| 175562 | + zPath++; |
| 175563 | + if( zPath[0]=='"' ){ |
| 175564 | + zKey = zPath + 1; |
| 175565 | + for(i=1; zPath[i] && zPath[i]!='"'; i++){} |
| 175566 | + nKey = i-1; |
| 175567 | + if( zPath[i] ){ |
| 175568 | + i++; |
| 175569 | + }else{ |
| 175570 | + *pzErr = zPath; |
| 175571 | + return 0; |
| 175572 | + } |
| 175573 | + }else{ |
| 175574 | + zKey = zPath; |
| 175575 | + for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} |
| 175576 | + nKey = i; |
| 175577 | + } |
| 175578 | + if( nKey==0 ){ |
| 175579 | + *pzErr = zPath; |
| 175580 | + return 0; |
| 175581 | + } |
| 175582 | + j = 1; |
| 175583 | + for(;;){ |
| 175584 | + while( j<=pRoot->n ){ |
| 175585 | + if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ |
| 175586 | + return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); |
| 175587 | + } |
| 175588 | + j++; |
| 175589 | + j += jsonNodeSize(&pRoot[j]); |
| 175590 | + } |
| 175591 | + if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; |
| 175592 | + iRoot += pRoot->u.iAppend; |
| 175593 | + pRoot = &pParse->aNode[iRoot]; |
| 175594 | + j = 1; |
| 175595 | + } |
| 175596 | + if( pApnd ){ |
| 175597 | + u32 iStart, iLabel; |
| 175598 | + JsonNode *pNode; |
| 175599 | + iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); |
| 175600 | + iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath); |
| 175601 | + zPath += i; |
| 175602 | + pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); |
| 175603 | + if( pParse->oom ) return 0; |
| 175604 | + if( pNode ){ |
| 175605 | + pRoot = &pParse->aNode[iRoot]; |
| 175606 | + pRoot->u.iAppend = iStart - iRoot; |
| 175607 | + pRoot->jnFlags |= JNODE_APPEND; |
| 175608 | + pParse->aNode[iLabel].jnFlags |= JNODE_RAW; |
| 175609 | + } |
| 175610 | + return pNode; |
| 175611 | + } |
| 175612 | + }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ |
| 175613 | + if( pRoot->eType!=JSON_ARRAY ) return 0; |
| 175614 | + i = 0; |
| 175615 | + j = 1; |
| 175616 | + while( safe_isdigit(zPath[j]) ){ |
| 175617 | + i = i*10 + zPath[j] - '0'; |
| 175618 | + j++; |
| 175619 | + } |
| 175620 | + if( zPath[j]!=']' ){ |
| 175621 | + *pzErr = zPath; |
| 175622 | + return 0; |
| 175623 | + } |
| 175624 | + zPath += j + 1; |
| 175625 | + j = 1; |
| 175626 | + for(;;){ |
| 175627 | + while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ |
| 175628 | + if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; |
| 175629 | + j += jsonNodeSize(&pRoot[j]); |
| 175630 | + } |
| 175631 | + if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; |
| 175632 | + iRoot += pRoot->u.iAppend; |
| 175633 | + pRoot = &pParse->aNode[iRoot]; |
| 175634 | + j = 1; |
| 175635 | + } |
| 175636 | + if( j<=pRoot->n ){ |
| 175637 | + return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); |
| 175638 | + } |
| 175639 | + if( i==0 && pApnd ){ |
| 175640 | + u32 iStart; |
| 175641 | + JsonNode *pNode; |
| 175642 | + iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); |
| 175643 | + pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); |
| 175644 | + if( pParse->oom ) return 0; |
| 175645 | + if( pNode ){ |
| 175646 | + pRoot = &pParse->aNode[iRoot]; |
| 175647 | + pRoot->u.iAppend = iStart - iRoot; |
| 175648 | + pRoot->jnFlags |= JNODE_APPEND; |
| 175649 | + } |
| 175650 | + return pNode; |
| 175651 | + } |
| 175652 | + }else{ |
| 175653 | + *pzErr = zPath; |
| 175654 | + } |
| 175655 | + return 0; |
| 175656 | +} |
| 175657 | + |
| 175658 | +/* |
| 175659 | +** Append content to pParse that will complete zPath. Return a pointer |
| 175660 | +** to the inserted node, or return NULL if the append fails. |
| 175661 | +*/ |
| 175662 | +static JsonNode *jsonLookupAppend( |
| 175663 | + JsonParse *pParse, /* Append content to the JSON parse */ |
| 175664 | + const char *zPath, /* Description of content to append */ |
| 175665 | + int *pApnd, /* Set this flag to 1 */ |
| 175666 | + const char **pzErr /* Make this point to any syntax error */ |
| 175667 | +){ |
| 175668 | + *pApnd = 1; |
| 175669 | + if( zPath[0]==0 ){ |
| 175670 | + jsonParseAddNode(pParse, JSON_NULL, 0, 0); |
| 175671 | + return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; |
| 175672 | + } |
| 175673 | + if( zPath[0]=='.' ){ |
| 175674 | + jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); |
| 175675 | + }else if( strncmp(zPath,"[0]",3)==0 ){ |
| 175676 | + jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); |
| 175677 | + }else{ |
| 175678 | + return 0; |
| 175679 | + } |
| 175680 | + if( pParse->oom ) return 0; |
| 175681 | + return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); |
| 175682 | +} |
| 175683 | + |
| 175684 | +/* |
| 175685 | +** Return the text of a syntax error message on a JSON path. Space is |
| 175686 | +** obtained from sqlite3_malloc(). |
| 175687 | +*/ |
| 175688 | +static char *jsonPathSyntaxError(const char *zErr){ |
| 175689 | + return sqlite3_mprintf("JSON path error near '%q'", zErr); |
| 175690 | +} |
| 175691 | + |
| 175692 | +/* |
| 175693 | +** Do a node lookup using zPath. Return a pointer to the node on success. |
| 175694 | +** Return NULL if not found or if there is an error. |
| 175695 | +** |
| 175696 | +** On an error, write an error message into pCtx and increment the |
| 175697 | +** pParse->nErr counter. |
| 175698 | +** |
| 175699 | +** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if |
| 175700 | +** nodes are appended. |
| 175701 | +*/ |
| 175702 | +static JsonNode *jsonLookup( |
| 175703 | + JsonParse *pParse, /* The JSON to search */ |
| 175704 | + const char *zPath, /* The path to search */ |
| 175705 | + int *pApnd, /* Append nodes to complete path if not NULL */ |
| 175706 | + sqlite3_context *pCtx /* Report errors here, if not NULL */ |
| 175707 | +){ |
| 175708 | + const char *zErr = 0; |
| 175709 | + JsonNode *pNode = 0; |
| 175710 | + char *zMsg; |
| 175711 | + |
| 175712 | + if( zPath==0 ) return 0; |
| 175713 | + if( zPath[0]!='$' ){ |
| 175714 | + zErr = zPath; |
| 175715 | + goto lookup_err; |
| 175716 | + } |
| 175717 | + zPath++; |
| 175718 | + pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); |
| 175719 | + if( zErr==0 ) return pNode; |
| 175720 | + |
| 175721 | +lookup_err: |
| 175722 | + pParse->nErr++; |
| 175723 | + assert( zErr!=0 && pCtx!=0 ); |
| 175724 | + zMsg = jsonPathSyntaxError(zErr); |
| 175725 | + if( zMsg ){ |
| 175726 | + sqlite3_result_error(pCtx, zMsg, -1); |
| 175727 | + sqlite3_free(zMsg); |
| 175728 | + }else{ |
| 175729 | + sqlite3_result_error_nomem(pCtx); |
| 175730 | + } |
| 175731 | + return 0; |
| 175732 | +} |
| 175733 | + |
| 175734 | + |
| 175735 | +/* |
| 175736 | +** Report the wrong number of arguments for json_insert(), json_replace() |
| 175737 | +** or json_set(). |
| 175738 | +*/ |
| 175739 | +static void jsonWrongNumArgs( |
| 175740 | + sqlite3_context *pCtx, |
| 175741 | + const char *zFuncName |
| 175742 | +){ |
| 175743 | + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", |
| 175744 | + zFuncName); |
| 175745 | + sqlite3_result_error(pCtx, zMsg, -1); |
| 175746 | + sqlite3_free(zMsg); |
| 175747 | +} |
| 175748 | + |
| 175749 | +/* |
| 175750 | +** Mark all NULL entries in the Object passed in as JNODE_REMOVE. |
| 175751 | +*/ |
| 175752 | +static void jsonRemoveAllNulls(JsonNode *pNode){ |
| 175753 | + int i, n; |
| 175754 | + assert( pNode->eType==JSON_OBJECT ); |
| 175755 | + n = pNode->n; |
| 175756 | + for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ |
| 175757 | + switch( pNode[i].eType ){ |
| 175758 | + case JSON_NULL: |
| 175759 | + pNode[i].jnFlags |= JNODE_REMOVE; |
| 175760 | + break; |
| 175761 | + case JSON_OBJECT: |
| 175762 | + jsonRemoveAllNulls(&pNode[i]); |
| 175763 | + break; |
| 175764 | + } |
| 175765 | + } |
| 175766 | +} |
| 175767 | + |
| 175768 | + |
| 175769 | +/**************************************************************************** |
| 175770 | +** SQL functions used for testing and debugging |
| 175771 | +****************************************************************************/ |
| 175772 | + |
| 175773 | +#ifdef SQLITE_DEBUG |
| 175774 | +/* |
| 175775 | +** The json_parse(JSON) function returns a string which describes |
| 175776 | +** a parse of the JSON provided. Or it returns NULL if JSON is not |
| 175777 | +** well-formed. |
| 175778 | +*/ |
| 175779 | +static void jsonParseFunc( |
| 175780 | + sqlite3_context *ctx, |
| 175781 | + int argc, |
| 175782 | + sqlite3_value **argv |
| 175783 | +){ |
| 175784 | + JsonString s; /* Output string - not real JSON */ |
| 175785 | + JsonParse x; /* The parse */ |
| 175786 | + u32 i; |
| 175787 | + |
| 175788 | + assert( argc==1 ); |
| 175789 | + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 175790 | + jsonParseFindParents(&x); |
| 175791 | + jsonInit(&s, ctx); |
| 175792 | + for(i=0; i<x.nNode; i++){ |
| 175793 | + const char *zType; |
| 175794 | + if( x.aNode[i].jnFlags & JNODE_LABEL ){ |
| 175795 | + assert( x.aNode[i].eType==JSON_STRING ); |
| 175796 | + zType = "label"; |
| 175797 | + }else{ |
| 175798 | + zType = jsonType[x.aNode[i].eType]; |
| 175799 | + } |
| 175800 | + jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d", |
| 175801 | + i, zType, x.aNode[i].n, x.aUp[i]); |
| 175802 | + if( x.aNode[i].u.zJContent!=0 ){ |
| 175803 | + jsonAppendRaw(&s, " ", 1); |
| 175804 | + jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n); |
| 175805 | + } |
| 175806 | + jsonAppendRaw(&s, "\n", 1); |
| 175807 | + } |
| 175808 | + jsonParseReset(&x); |
| 175809 | + jsonResult(&s); |
| 175810 | +} |
| 175811 | + |
| 175812 | +/* |
| 175813 | +** The json_test1(JSON) function return true (1) if the input is JSON |
| 175814 | +** text generated by another json function. It returns (0) if the input |
| 175815 | +** is not known to be JSON. |
| 175816 | +*/ |
| 175817 | +static void jsonTest1Func( |
| 175818 | + sqlite3_context *ctx, |
| 175819 | + int argc, |
| 175820 | + sqlite3_value **argv |
| 175821 | +){ |
| 175822 | + UNUSED_PARAM(argc); |
| 175823 | + sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); |
| 175824 | +} |
| 175825 | +#endif /* SQLITE_DEBUG */ |
| 175826 | + |
| 175827 | +/**************************************************************************** |
| 175828 | +** Scalar SQL function implementations |
| 175829 | +****************************************************************************/ |
| 175830 | + |
| 175831 | +/* |
| 175832 | +** Implementation of the json_QUOTE(VALUE) function. Return a JSON value |
| 175833 | +** corresponding to the SQL value input. Mostly this means putting |
| 175834 | +** double-quotes around strings and returning the unquoted string "null" |
| 175835 | +** when given a NULL input. |
| 175836 | +*/ |
| 175837 | +static void jsonQuoteFunc( |
| 175838 | + sqlite3_context *ctx, |
| 175839 | + int argc, |
| 175840 | + sqlite3_value **argv |
| 175841 | +){ |
| 175842 | + JsonString jx; |
| 175843 | + UNUSED_PARAM(argc); |
| 175844 | + |
| 175845 | + jsonInit(&jx, ctx); |
| 175846 | + jsonAppendValue(&jx, argv[0]); |
| 175847 | + jsonResult(&jx); |
| 175848 | + sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 175849 | +} |
| 175850 | + |
| 175851 | +/* |
| 175852 | +** Implementation of the json_array(VALUE,...) function. Return a JSON |
| 175853 | +** array that contains all values given in arguments. Or if any argument |
| 175854 | +** is a BLOB, throw an error. |
| 175855 | +*/ |
| 175856 | +static void jsonArrayFunc( |
| 175857 | + sqlite3_context *ctx, |
| 175858 | + int argc, |
| 175859 | + sqlite3_value **argv |
| 175860 | +){ |
| 175861 | + int i; |
| 175862 | + JsonString jx; |
| 175863 | + |
| 175864 | + jsonInit(&jx, ctx); |
| 175865 | + jsonAppendChar(&jx, '['); |
| 175866 | + for(i=0; i<argc; i++){ |
| 175867 | + jsonAppendSeparator(&jx); |
| 175868 | + jsonAppendValue(&jx, argv[i]); |
| 175869 | + } |
| 175870 | + jsonAppendChar(&jx, ']'); |
| 175871 | + jsonResult(&jx); |
| 175872 | + sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 175873 | +} |
| 175874 | + |
| 175875 | + |
| 175876 | +/* |
| 175877 | +** json_array_length(JSON) |
| 175878 | +** json_array_length(JSON, PATH) |
| 175879 | +** |
| 175880 | +** Return the number of elements in the top-level JSON array. |
| 175881 | +** Return 0 if the input is not a well-formed JSON array. |
| 175882 | +*/ |
| 175883 | +static void jsonArrayLengthFunc( |
| 175884 | + sqlite3_context *ctx, |
| 175885 | + int argc, |
| 175886 | + sqlite3_value **argv |
| 175887 | +){ |
| 175888 | + JsonParse *p; /* The parse */ |
| 175889 | + sqlite3_int64 n = 0; |
| 175890 | + u32 i; |
| 175891 | + JsonNode *pNode; |
| 175892 | + |
| 175893 | + p = jsonParseCached(ctx, argv, ctx); |
| 175894 | + if( p==0 ) return; |
| 175895 | + assert( p->nNode ); |
| 175896 | + if( argc==2 ){ |
| 175897 | + const char *zPath = (const char*)sqlite3_value_text(argv[1]); |
| 175898 | + pNode = jsonLookup(p, zPath, 0, ctx); |
| 175899 | + }else{ |
| 175900 | + pNode = p->aNode; |
| 175901 | + } |
| 175902 | + if( pNode==0 ){ |
| 175903 | + return; |
| 175904 | + } |
| 175905 | + if( pNode->eType==JSON_ARRAY ){ |
| 175906 | + assert( (pNode->jnFlags & JNODE_APPEND)==0 ); |
| 175907 | + for(i=1; i<=pNode->n; n++){ |
| 175908 | + i += jsonNodeSize(&pNode[i]); |
| 175909 | + } |
| 175910 | + } |
| 175911 | + sqlite3_result_int64(ctx, n); |
| 175912 | +} |
| 175913 | + |
| 175914 | +/* |
| 175915 | +** json_extract(JSON, PATH, ...) |
| 175916 | +** |
| 175917 | +** Return the element described by PATH. Return NULL if there is no |
| 175918 | +** PATH element. If there are multiple PATHs, then return a JSON array |
| 175919 | +** with the result from each path. Throw an error if the JSON or any PATH |
| 175920 | +** is malformed. |
| 175921 | +*/ |
| 175922 | +static void jsonExtractFunc( |
| 175923 | + sqlite3_context *ctx, |
| 175924 | + int argc, |
| 175925 | + sqlite3_value **argv |
| 175926 | +){ |
| 175927 | + JsonParse *p; /* The parse */ |
| 175928 | + JsonNode *pNode; |
| 175929 | + const char *zPath; |
| 175930 | + JsonString jx; |
| 175931 | + int i; |
| 175932 | + |
| 175933 | + if( argc<2 ) return; |
| 175934 | + p = jsonParseCached(ctx, argv, ctx); |
| 175935 | + if( p==0 ) return; |
| 175936 | + jsonInit(&jx, ctx); |
| 175937 | + jsonAppendChar(&jx, '['); |
| 175938 | + for(i=1; i<argc; i++){ |
| 175939 | + zPath = (const char*)sqlite3_value_text(argv[i]); |
| 175940 | + pNode = jsonLookup(p, zPath, 0, ctx); |
| 175941 | + if( p->nErr ) break; |
| 175942 | + if( argc>2 ){ |
| 175943 | + jsonAppendSeparator(&jx); |
| 175944 | + if( pNode ){ |
| 175945 | + jsonRenderNode(pNode, &jx, 0); |
| 175946 | + }else{ |
| 175947 | + jsonAppendRaw(&jx, "null", 4); |
| 175948 | + } |
| 175949 | + }else if( pNode ){ |
| 175950 | + jsonReturn(pNode, ctx, 0); |
| 175951 | + } |
| 175952 | + } |
| 175953 | + if( argc>2 && i==argc ){ |
| 175954 | + jsonAppendChar(&jx, ']'); |
| 175955 | + jsonResult(&jx); |
| 175956 | + sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 175957 | + } |
| 175958 | + jsonReset(&jx); |
| 175959 | +} |
| 175960 | + |
| 175961 | +/* This is the RFC 7396 MergePatch algorithm. |
| 175962 | +*/ |
| 175963 | +static JsonNode *jsonMergePatch( |
| 175964 | + JsonParse *pParse, /* The JSON parser that contains the TARGET */ |
| 175965 | + u32 iTarget, /* Node of the TARGET in pParse */ |
| 175966 | + JsonNode *pPatch /* The PATCH */ |
| 175967 | +){ |
| 175968 | + u32 i, j; |
| 175969 | + u32 iRoot; |
| 175970 | + JsonNode *pTarget; |
| 175971 | + if( pPatch->eType!=JSON_OBJECT ){ |
| 175972 | + return pPatch; |
| 175973 | + } |
| 175974 | + assert( iTarget>=0 && iTarget<pParse->nNode ); |
| 175975 | + pTarget = &pParse->aNode[iTarget]; |
| 175976 | + assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); |
| 175977 | + if( pTarget->eType!=JSON_OBJECT ){ |
| 175978 | + jsonRemoveAllNulls(pPatch); |
| 175979 | + return pPatch; |
| 175980 | + } |
| 175981 | + iRoot = iTarget; |
| 175982 | + for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){ |
| 175983 | + u32 nKey; |
| 175984 | + const char *zKey; |
| 175985 | + assert( pPatch[i].eType==JSON_STRING ); |
| 175986 | + assert( pPatch[i].jnFlags & JNODE_LABEL ); |
| 175987 | + nKey = pPatch[i].n; |
| 175988 | + zKey = pPatch[i].u.zJContent; |
| 175989 | + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); |
| 175990 | + for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ |
| 175991 | + assert( pTarget[j].eType==JSON_STRING ); |
| 175992 | + assert( pTarget[j].jnFlags & JNODE_LABEL ); |
| 175993 | + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); |
| 175994 | + if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ |
| 175995 | + if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; |
| 175996 | + if( pPatch[i+1].eType==JSON_NULL ){ |
| 175997 | + pTarget[j+1].jnFlags |= JNODE_REMOVE; |
| 175998 | + }else{ |
| 175999 | + JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); |
| 176000 | + if( pNew==0 ) return 0; |
| 176001 | + pTarget = &pParse->aNode[iTarget]; |
| 176002 | + if( pNew!=&pTarget[j+1] ){ |
| 176003 | + pTarget[j+1].u.pPatch = pNew; |
| 176004 | + pTarget[j+1].jnFlags |= JNODE_PATCH; |
| 176005 | + } |
| 176006 | + } |
| 176007 | + break; |
| 176008 | + } |
| 176009 | + } |
| 176010 | + if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ |
| 176011 | + int iStart, iPatch; |
| 176012 | + iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); |
| 176013 | + jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); |
| 176014 | + iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); |
| 176015 | + if( pParse->oom ) return 0; |
| 176016 | + jsonRemoveAllNulls(pPatch); |
| 176017 | + pTarget = &pParse->aNode[iTarget]; |
| 176018 | + pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; |
| 176019 | + pParse->aNode[iRoot].u.iAppend = iStart - iRoot; |
| 176020 | + iRoot = iStart; |
| 176021 | + pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; |
| 176022 | + pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; |
| 176023 | + } |
| 176024 | + } |
| 176025 | + return pTarget; |
| 176026 | +} |
| 176027 | + |
| 176028 | +/* |
| 176029 | +** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON |
| 176030 | +** object that is the result of running the RFC 7396 MergePatch() algorithm |
| 176031 | +** on the two arguments. |
| 176032 | +*/ |
| 176033 | +static void jsonPatchFunc( |
| 176034 | + sqlite3_context *ctx, |
| 176035 | + int argc, |
| 176036 | + sqlite3_value **argv |
| 176037 | +){ |
| 176038 | + JsonParse x; /* The JSON that is being patched */ |
| 176039 | + JsonParse y; /* The patch */ |
| 176040 | + JsonNode *pResult; /* The result of the merge */ |
| 176041 | + |
| 176042 | + UNUSED_PARAM(argc); |
| 176043 | + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 176044 | + if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ |
| 176045 | + jsonParseReset(&x); |
| 176046 | + return; |
| 176047 | + } |
| 176048 | + pResult = jsonMergePatch(&x, 0, y.aNode); |
| 176049 | + assert( pResult!=0 || x.oom ); |
| 176050 | + if( pResult ){ |
| 176051 | + jsonReturnJson(pResult, ctx, 0); |
| 176052 | + }else{ |
| 176053 | + sqlite3_result_error_nomem(ctx); |
| 176054 | + } |
| 176055 | + jsonParseReset(&x); |
| 176056 | + jsonParseReset(&y); |
| 176057 | +} |
| 176058 | + |
| 176059 | + |
| 176060 | +/* |
| 176061 | +** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON |
| 176062 | +** object that contains all name/value given in arguments. Or if any name |
| 176063 | +** is not a string or if any value is a BLOB, throw an error. |
| 176064 | +*/ |
| 176065 | +static void jsonObjectFunc( |
| 176066 | + sqlite3_context *ctx, |
| 176067 | + int argc, |
| 176068 | + sqlite3_value **argv |
| 176069 | +){ |
| 176070 | + int i; |
| 176071 | + JsonString jx; |
| 176072 | + const char *z; |
| 176073 | + u32 n; |
| 176074 | + |
| 176075 | + if( argc&1 ){ |
| 176076 | + sqlite3_result_error(ctx, "json_object() requires an even number " |
| 176077 | + "of arguments", -1); |
| 176078 | + return; |
| 176079 | + } |
| 176080 | + jsonInit(&jx, ctx); |
| 176081 | + jsonAppendChar(&jx, '{'); |
| 176082 | + for(i=0; i<argc; i+=2){ |
| 176083 | + if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){ |
| 176084 | + sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1); |
| 176085 | + jsonReset(&jx); |
| 176086 | + return; |
| 176087 | + } |
| 176088 | + jsonAppendSeparator(&jx); |
| 176089 | + z = (const char*)sqlite3_value_text(argv[i]); |
| 176090 | + n = (u32)sqlite3_value_bytes(argv[i]); |
| 176091 | + jsonAppendString(&jx, z, n); |
| 176092 | + jsonAppendChar(&jx, ':'); |
| 176093 | + jsonAppendValue(&jx, argv[i+1]); |
| 176094 | + } |
| 176095 | + jsonAppendChar(&jx, '}'); |
| 176096 | + jsonResult(&jx); |
| 176097 | + sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 176098 | +} |
| 176099 | + |
| 176100 | + |
| 176101 | +/* |
| 176102 | +** json_remove(JSON, PATH, ...) |
| 176103 | +** |
| 176104 | +** Remove the named elements from JSON and return the result. malformed |
| 176105 | +** JSON or PATH arguments result in an error. |
| 176106 | +*/ |
| 176107 | +static void jsonRemoveFunc( |
| 176108 | + sqlite3_context *ctx, |
| 176109 | + int argc, |
| 176110 | + sqlite3_value **argv |
| 176111 | +){ |
| 176112 | + JsonParse x; /* The parse */ |
| 176113 | + JsonNode *pNode; |
| 176114 | + const char *zPath; |
| 176115 | + u32 i; |
| 176116 | + |
| 176117 | + if( argc<1 ) return; |
| 176118 | + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 176119 | + assert( x.nNode ); |
| 176120 | + for(i=1; i<(u32)argc; i++){ |
| 176121 | + zPath = (const char*)sqlite3_value_text(argv[i]); |
| 176122 | + if( zPath==0 ) goto remove_done; |
| 176123 | + pNode = jsonLookup(&x, zPath, 0, ctx); |
| 176124 | + if( x.nErr ) goto remove_done; |
| 176125 | + if( pNode ) pNode->jnFlags |= JNODE_REMOVE; |
| 176126 | + } |
| 176127 | + if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ |
| 176128 | + jsonReturnJson(x.aNode, ctx, 0); |
| 176129 | + } |
| 176130 | +remove_done: |
| 176131 | + jsonParseReset(&x); |
| 176132 | +} |
| 176133 | + |
| 176134 | +/* |
| 176135 | +** json_replace(JSON, PATH, VALUE, ...) |
| 176136 | +** |
| 176137 | +** Replace the value at PATH with VALUE. If PATH does not already exist, |
| 176138 | +** this routine is a no-op. If JSON or PATH is malformed, throw an error. |
| 176139 | +*/ |
| 176140 | +static void jsonReplaceFunc( |
| 176141 | + sqlite3_context *ctx, |
| 176142 | + int argc, |
| 176143 | + sqlite3_value **argv |
| 176144 | +){ |
| 176145 | + JsonParse x; /* The parse */ |
| 176146 | + JsonNode *pNode; |
| 176147 | + const char *zPath; |
| 176148 | + u32 i; |
| 176149 | + |
| 176150 | + if( argc<1 ) return; |
| 176151 | + if( (argc&1)==0 ) { |
| 176152 | + jsonWrongNumArgs(ctx, "replace"); |
| 176153 | + return; |
| 176154 | + } |
| 176155 | + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 176156 | + assert( x.nNode ); |
| 176157 | + for(i=1; i<(u32)argc; i+=2){ |
| 176158 | + zPath = (const char*)sqlite3_value_text(argv[i]); |
| 176159 | + pNode = jsonLookup(&x, zPath, 0, ctx); |
| 176160 | + if( x.nErr ) goto replace_err; |
| 176161 | + if( pNode ){ |
| 176162 | + pNode->jnFlags |= (u8)JNODE_REPLACE; |
| 176163 | + pNode->u.iReplace = i + 1; |
| 176164 | + } |
| 176165 | + } |
| 176166 | + if( x.aNode[0].jnFlags & JNODE_REPLACE ){ |
| 176167 | + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); |
| 176168 | + }else{ |
| 176169 | + jsonReturnJson(x.aNode, ctx, argv); |
| 176170 | + } |
| 176171 | +replace_err: |
| 176172 | + jsonParseReset(&x); |
| 176173 | +} |
| 176174 | + |
| 176175 | +/* |
| 176176 | +** json_set(JSON, PATH, VALUE, ...) |
| 176177 | +** |
| 176178 | +** Set the value at PATH to VALUE. Create the PATH if it does not already |
| 176179 | +** exist. Overwrite existing values that do exist. |
| 176180 | +** If JSON or PATH is malformed, throw an error. |
| 176181 | +** |
| 176182 | +** json_insert(JSON, PATH, VALUE, ...) |
| 176183 | +** |
| 176184 | +** Create PATH and initialize it to VALUE. If PATH already exists, this |
| 176185 | +** routine is a no-op. If JSON or PATH is malformed, throw an error. |
| 176186 | +*/ |
| 176187 | +static void jsonSetFunc( |
| 176188 | + sqlite3_context *ctx, |
| 176189 | + int argc, |
| 176190 | + sqlite3_value **argv |
| 176191 | +){ |
| 176192 | + JsonParse x; /* The parse */ |
| 176193 | + JsonNode *pNode; |
| 176194 | + const char *zPath; |
| 176195 | + u32 i; |
| 176196 | + int bApnd; |
| 176197 | + int bIsSet = *(int*)sqlite3_user_data(ctx); |
| 176198 | + |
| 176199 | + if( argc<1 ) return; |
| 176200 | + if( (argc&1)==0 ) { |
| 176201 | + jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); |
| 176202 | + return; |
| 176203 | + } |
| 176204 | + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 176205 | + assert( x.nNode ); |
| 176206 | + for(i=1; i<(u32)argc; i+=2){ |
| 176207 | + zPath = (const char*)sqlite3_value_text(argv[i]); |
| 176208 | + bApnd = 0; |
| 176209 | + pNode = jsonLookup(&x, zPath, &bApnd, ctx); |
| 176210 | + if( x.oom ){ |
| 176211 | + sqlite3_result_error_nomem(ctx); |
| 176212 | + goto jsonSetDone; |
| 176213 | + }else if( x.nErr ){ |
| 176214 | + goto jsonSetDone; |
| 176215 | + }else if( pNode && (bApnd || bIsSet) ){ |
| 176216 | + pNode->jnFlags |= (u8)JNODE_REPLACE; |
| 176217 | + pNode->u.iReplace = i + 1; |
| 176218 | + } |
| 176219 | + } |
| 176220 | + if( x.aNode[0].jnFlags & JNODE_REPLACE ){ |
| 176221 | + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); |
| 176222 | + }else{ |
| 176223 | + jsonReturnJson(x.aNode, ctx, argv); |
| 176224 | + } |
| 176225 | +jsonSetDone: |
| 176226 | + jsonParseReset(&x); |
| 176227 | +} |
| 176228 | + |
| 176229 | +/* |
| 176230 | +** json_type(JSON) |
| 176231 | +** json_type(JSON, PATH) |
| 176232 | +** |
| 176233 | +** Return the top-level "type" of a JSON string. Throw an error if |
| 176234 | +** either the JSON or PATH inputs are not well-formed. |
| 176235 | +*/ |
| 176236 | +static void jsonTypeFunc( |
| 176237 | + sqlite3_context *ctx, |
| 176238 | + int argc, |
| 176239 | + sqlite3_value **argv |
| 176240 | +){ |
| 176241 | + JsonParse *p; /* The parse */ |
| 176242 | + const char *zPath; |
| 176243 | + JsonNode *pNode; |
| 176244 | + |
| 176245 | + p = jsonParseCached(ctx, argv, ctx); |
| 176246 | + if( p==0 ) return; |
| 176247 | + if( argc==2 ){ |
| 176248 | + zPath = (const char*)sqlite3_value_text(argv[1]); |
| 176249 | + pNode = jsonLookup(p, zPath, 0, ctx); |
| 176250 | + }else{ |
| 176251 | + pNode = p->aNode; |
| 176252 | + } |
| 176253 | + if( pNode ){ |
| 176254 | + sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); |
| 176255 | + } |
| 176256 | +} |
| 176257 | + |
| 176258 | +/* |
| 176259 | +** json_valid(JSON) |
| 176260 | +** |
| 176261 | +** Return 1 if JSON is a well-formed JSON string according to RFC-7159. |
| 176262 | +** Return 0 otherwise. |
| 176263 | +*/ |
| 176264 | +static void jsonValidFunc( |
| 176265 | + sqlite3_context *ctx, |
| 176266 | + int argc, |
| 176267 | + sqlite3_value **argv |
| 176268 | +){ |
| 176269 | + JsonParse *p; /* The parse */ |
| 176270 | + UNUSED_PARAM(argc); |
| 176271 | + p = jsonParseCached(ctx, argv, 0); |
| 176272 | + sqlite3_result_int(ctx, p!=0); |
| 176273 | +} |
| 176274 | + |
| 176275 | + |
| 176276 | +/**************************************************************************** |
| 176277 | +** Aggregate SQL function implementations |
| 176278 | +****************************************************************************/ |
| 176279 | +/* |
| 176280 | +** json_group_array(VALUE) |
| 176281 | +** |
| 176282 | +** Return a JSON array composed of all values in the aggregate. |
| 176283 | +*/ |
| 176284 | +static void jsonArrayStep( |
| 176285 | + sqlite3_context *ctx, |
| 176286 | + int argc, |
| 176287 | + sqlite3_value **argv |
| 176288 | +){ |
| 176289 | + JsonString *pStr; |
| 176290 | + UNUSED_PARAM(argc); |
| 176291 | + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 176292 | + if( pStr ){ |
| 176293 | + if( pStr->zBuf==0 ){ |
| 176294 | + jsonInit(pStr, ctx); |
| 176295 | + jsonAppendChar(pStr, '['); |
| 176296 | + }else{ |
| 176297 | + jsonAppendChar(pStr, ','); |
| 176298 | + pStr->pCtx = ctx; |
| 176299 | + } |
| 176300 | + jsonAppendValue(pStr, argv[0]); |
| 176301 | + } |
| 176302 | +} |
| 176303 | +static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ |
| 176304 | + JsonString *pStr; |
| 176305 | + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 176306 | + if( pStr ){ |
| 176307 | + pStr->pCtx = ctx; |
| 176308 | + jsonAppendChar(pStr, ']'); |
| 176309 | + if( pStr->bErr ){ |
| 176310 | + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); |
| 176311 | + assert( pStr->bStatic ); |
| 176312 | + }else if( isFinal ){ |
| 176313 | + sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, |
| 176314 | + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); |
| 176315 | + pStr->bStatic = 1; |
| 176316 | + }else{ |
| 176317 | + sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, SQLITE_TRANSIENT); |
| 176318 | + pStr->nUsed--; |
| 176319 | + } |
| 176320 | + }else{ |
| 176321 | + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); |
| 176322 | + } |
| 176323 | + sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 176324 | +} |
| 176325 | +static void jsonArrayValue(sqlite3_context *ctx){ |
| 176326 | + jsonArrayCompute(ctx, 0); |
| 176327 | +} |
| 176328 | +static void jsonArrayFinal(sqlite3_context *ctx){ |
| 176329 | + jsonArrayCompute(ctx, 1); |
| 176330 | +} |
| 176331 | + |
| 176332 | +#ifndef SQLITE_OMIT_WINDOWFUNC |
| 176333 | +/* |
| 176334 | +** This method works for both json_group_array() and json_group_object(). |
| 176335 | +** It works by removing the first element of the group by searching forward |
| 176336 | +** to the first comma (",") that is not within a string and deleting all |
| 176337 | +** text through that comma. |
| 176338 | +*/ |
| 176339 | +static void jsonGroupInverse( |
| 176340 | + sqlite3_context *ctx, |
| 176341 | + int argc, |
| 176342 | + sqlite3_value **argv |
| 176343 | +){ |
| 176344 | + int i; |
| 176345 | + int inStr = 0; |
| 176346 | + char *z; |
| 176347 | + JsonString *pStr; |
| 176348 | + UNUSED_PARAM(argc); |
| 176349 | + UNUSED_PARAM(argv); |
| 176350 | + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 176351 | +#ifdef NEVER |
| 176352 | + /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will |
| 176353 | + ** always have been called to initalize it */ |
| 176354 | + if( NEVER(!pStr) ) return; |
| 176355 | +#endif |
| 176356 | + z = pStr->zBuf; |
| 176357 | + for(i=1; z[i]!=',' || inStr; i++){ |
| 176358 | + assert( i<pStr->nUsed ); |
| 176359 | + if( z[i]=='"' ){ |
| 176360 | + inStr = !inStr; |
| 176361 | + }else if( z[i]=='\\' ){ |
| 176362 | + i++; |
| 176363 | + } |
| 176364 | + } |
| 176365 | + pStr->nUsed -= i; |
| 176366 | + memmove(&z[1], &z[i+1], pStr->nUsed-1); |
| 176367 | +} |
| 176368 | +#else |
| 176369 | +# define jsonGroupInverse 0 |
| 176370 | +#endif |
| 176371 | + |
| 176372 | + |
| 176373 | +/* |
| 176374 | +** json_group_obj(NAME,VALUE) |
| 176375 | +** |
| 176376 | +** Return a JSON object composed of all names and values in the aggregate. |
| 176377 | +*/ |
| 176378 | +static void jsonObjectStep( |
| 176379 | + sqlite3_context *ctx, |
| 176380 | + int argc, |
| 176381 | + sqlite3_value **argv |
| 176382 | +){ |
| 176383 | + JsonString *pStr; |
| 176384 | + const char *z; |
| 176385 | + u32 n; |
| 176386 | + UNUSED_PARAM(argc); |
| 176387 | + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 176388 | + if( pStr ){ |
| 176389 | + if( pStr->zBuf==0 ){ |
| 176390 | + jsonInit(pStr, ctx); |
| 176391 | + jsonAppendChar(pStr, '{'); |
| 176392 | + }else{ |
| 176393 | + jsonAppendChar(pStr, ','); |
| 176394 | + pStr->pCtx = ctx; |
| 176395 | + } |
| 176396 | + z = (const char*)sqlite3_value_text(argv[0]); |
| 176397 | + n = (u32)sqlite3_value_bytes(argv[0]); |
| 176398 | + jsonAppendString(pStr, z, n); |
| 176399 | + jsonAppendChar(pStr, ':'); |
| 176400 | + jsonAppendValue(pStr, argv[1]); |
| 176401 | + } |
| 176402 | +} |
| 176403 | +static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 176404 | + JsonString *pStr; |
| 176405 | + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 176406 | + if( pStr ){ |
| 176407 | + jsonAppendChar(pStr, '}'); |
| 176408 | + if( pStr->bErr ){ |
| 176409 | + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); |
| 176410 | + assert( pStr->bStatic ); |
| 176411 | + }else if( isFinal ){ |
| 176412 | + sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, |
| 176413 | + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); |
| 176414 | + pStr->bStatic = 1; |
| 176415 | + }else{ |
| 176416 | + sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, SQLITE_TRANSIENT); |
| 176417 | + pStr->nUsed--; |
| 176418 | + } |
| 176419 | + }else{ |
| 176420 | + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); |
| 176421 | + } |
| 176422 | + sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 176423 | +} |
| 176424 | +static void jsonObjectValue(sqlite3_context *ctx){ |
| 176425 | + jsonObjectCompute(ctx, 0); |
| 176426 | +} |
| 176427 | +static void jsonObjectFinal(sqlite3_context *ctx){ |
| 176428 | + jsonObjectCompute(ctx, 1); |
| 176429 | +} |
| 176430 | + |
| 176431 | + |
| 176432 | + |
| 176433 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 176434 | +/**************************************************************************** |
| 176435 | +** The json_each virtual table |
| 176436 | +****************************************************************************/ |
| 176437 | +typedef struct JsonEachCursor JsonEachCursor; |
| 176438 | +struct JsonEachCursor { |
| 176439 | + sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 176440 | + u32 iRowid; /* The rowid */ |
| 176441 | + u32 iBegin; /* The first node of the scan */ |
| 176442 | + u32 i; /* Index in sParse.aNode[] of current row */ |
| 176443 | + u32 iEnd; /* EOF when i equals or exceeds this value */ |
| 176444 | + u8 eType; /* Type of top-level element */ |
| 176445 | + u8 bRecursive; /* True for json_tree(). False for json_each() */ |
| 176446 | + char *zJson; /* Input JSON */ |
| 176447 | + char *zRoot; /* Path by which to filter zJson */ |
| 176448 | + JsonParse sParse; /* Parse of the input JSON */ |
| 176449 | +}; |
| 176450 | + |
| 176451 | +/* Constructor for the json_each virtual table */ |
| 176452 | +static int jsonEachConnect( |
| 176453 | + sqlite3 *db, |
| 176454 | + void *pAux, |
| 176455 | + int argc, const char *const*argv, |
| 176456 | + sqlite3_vtab **ppVtab, |
| 176457 | + char **pzErr |
| 176458 | +){ |
| 176459 | + sqlite3_vtab *pNew; |
| 176460 | + int rc; |
| 176461 | + |
| 176462 | +/* Column numbers */ |
| 176463 | +#define JEACH_KEY 0 |
| 176464 | +#define JEACH_VALUE 1 |
| 176465 | +#define JEACH_TYPE 2 |
| 176466 | +#define JEACH_ATOM 3 |
| 176467 | +#define JEACH_ID 4 |
| 176468 | +#define JEACH_PARENT 5 |
| 176469 | +#define JEACH_FULLKEY 6 |
| 176470 | +#define JEACH_PATH 7 |
| 176471 | +#define JEACH_JSON 8 |
| 176472 | +#define JEACH_ROOT 9 |
| 176473 | + |
| 176474 | + UNUSED_PARAM(pzErr); |
| 176475 | + UNUSED_PARAM(argv); |
| 176476 | + UNUSED_PARAM(argc); |
| 176477 | + UNUSED_PARAM(pAux); |
| 176478 | + rc = sqlite3_declare_vtab(db, |
| 176479 | + "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," |
| 176480 | + "json HIDDEN,root HIDDEN)"); |
| 176481 | + if( rc==SQLITE_OK ){ |
| 176482 | + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); |
| 176483 | + if( pNew==0 ) return SQLITE_NOMEM; |
| 176484 | + memset(pNew, 0, sizeof(*pNew)); |
| 176485 | + } |
| 176486 | + return rc; |
| 176487 | +} |
| 176488 | + |
| 176489 | +/* destructor for json_each virtual table */ |
| 176490 | +static int jsonEachDisconnect(sqlite3_vtab *pVtab){ |
| 176491 | + sqlite3_free(pVtab); |
| 176492 | + return SQLITE_OK; |
| 176493 | +} |
| 176494 | + |
| 176495 | +/* constructor for a JsonEachCursor object for json_each(). */ |
| 176496 | +static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
| 176497 | + JsonEachCursor *pCur; |
| 176498 | + |
| 176499 | + UNUSED_PARAM(p); |
| 176500 | + pCur = sqlite3_malloc( sizeof(*pCur) ); |
| 176501 | + if( pCur==0 ) return SQLITE_NOMEM; |
| 176502 | + memset(pCur, 0, sizeof(*pCur)); |
| 176503 | + *ppCursor = &pCur->base; |
| 176504 | + return SQLITE_OK; |
| 176505 | +} |
| 176506 | + |
| 176507 | +/* constructor for a JsonEachCursor object for json_tree(). */ |
| 176508 | +static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
| 176509 | + int rc = jsonEachOpenEach(p, ppCursor); |
| 176510 | + if( rc==SQLITE_OK ){ |
| 176511 | + JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; |
| 176512 | + pCur->bRecursive = 1; |
| 176513 | + } |
| 176514 | + return rc; |
| 176515 | +} |
| 176516 | + |
| 176517 | +/* Reset a JsonEachCursor back to its original state. Free any memory |
| 176518 | +** held. */ |
| 176519 | +static void jsonEachCursorReset(JsonEachCursor *p){ |
| 176520 | + sqlite3_free(p->zJson); |
| 176521 | + sqlite3_free(p->zRoot); |
| 176522 | + jsonParseReset(&p->sParse); |
| 176523 | + p->iRowid = 0; |
| 176524 | + p->i = 0; |
| 176525 | + p->iEnd = 0; |
| 176526 | + p->eType = 0; |
| 176527 | + p->zJson = 0; |
| 176528 | + p->zRoot = 0; |
| 176529 | +} |
| 176530 | + |
| 176531 | +/* Destructor for a jsonEachCursor object */ |
| 176532 | +static int jsonEachClose(sqlite3_vtab_cursor *cur){ |
| 176533 | + JsonEachCursor *p = (JsonEachCursor*)cur; |
| 176534 | + jsonEachCursorReset(p); |
| 176535 | + sqlite3_free(cur); |
| 176536 | + return SQLITE_OK; |
| 176537 | +} |
| 176538 | + |
| 176539 | +/* Return TRUE if the jsonEachCursor object has been advanced off the end |
| 176540 | +** of the JSON object */ |
| 176541 | +static int jsonEachEof(sqlite3_vtab_cursor *cur){ |
| 176542 | + JsonEachCursor *p = (JsonEachCursor*)cur; |
| 176543 | + return p->i >= p->iEnd; |
| 176544 | +} |
| 176545 | + |
| 176546 | +/* Advance the cursor to the next element for json_tree() */ |
| 176547 | +static int jsonEachNext(sqlite3_vtab_cursor *cur){ |
| 176548 | + JsonEachCursor *p = (JsonEachCursor*)cur; |
| 176549 | + if( p->bRecursive ){ |
| 176550 | + if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; |
| 176551 | + p->i++; |
| 176552 | + p->iRowid++; |
| 176553 | + if( p->i<p->iEnd ){ |
| 176554 | + u32 iUp = p->sParse.aUp[p->i]; |
| 176555 | + JsonNode *pUp = &p->sParse.aNode[iUp]; |
| 176556 | + p->eType = pUp->eType; |
| 176557 | + if( pUp->eType==JSON_ARRAY ){ |
| 176558 | + if( iUp==p->i-1 ){ |
| 176559 | + pUp->u.iKey = 0; |
| 176560 | + }else{ |
| 176561 | + pUp->u.iKey++; |
| 176562 | + } |
| 176563 | + } |
| 176564 | + } |
| 176565 | + }else{ |
| 176566 | + switch( p->eType ){ |
| 176567 | + case JSON_ARRAY: { |
| 176568 | + p->i += jsonNodeSize(&p->sParse.aNode[p->i]); |
| 176569 | + p->iRowid++; |
| 176570 | + break; |
| 176571 | + } |
| 176572 | + case JSON_OBJECT: { |
| 176573 | + p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); |
| 176574 | + p->iRowid++; |
| 176575 | + break; |
| 176576 | + } |
| 176577 | + default: { |
| 176578 | + p->i = p->iEnd; |
| 176579 | + break; |
| 176580 | + } |
| 176581 | + } |
| 176582 | + } |
| 176583 | + return SQLITE_OK; |
| 176584 | +} |
| 176585 | + |
| 176586 | +/* Append the name of the path for element i to pStr |
| 176587 | +*/ |
| 176588 | +static void jsonEachComputePath( |
| 176589 | + JsonEachCursor *p, /* The cursor */ |
| 176590 | + JsonString *pStr, /* Write the path here */ |
| 176591 | + u32 i /* Path to this element */ |
| 176592 | +){ |
| 176593 | + JsonNode *pNode, *pUp; |
| 176594 | + u32 iUp; |
| 176595 | + if( i==0 ){ |
| 176596 | + jsonAppendChar(pStr, '$'); |
| 176597 | + return; |
| 176598 | + } |
| 176599 | + iUp = p->sParse.aUp[i]; |
| 176600 | + jsonEachComputePath(p, pStr, iUp); |
| 176601 | + pNode = &p->sParse.aNode[i]; |
| 176602 | + pUp = &p->sParse.aNode[iUp]; |
| 176603 | + if( pUp->eType==JSON_ARRAY ){ |
| 176604 | + jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); |
| 176605 | + }else{ |
| 176606 | + assert( pUp->eType==JSON_OBJECT ); |
| 176607 | + if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; |
| 176608 | + assert( pNode->eType==JSON_STRING ); |
| 176609 | + assert( pNode->jnFlags & JNODE_LABEL ); |
| 176610 | + jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); |
| 176611 | + } |
| 176612 | +} |
| 176613 | + |
| 176614 | +/* Return the value of a column */ |
| 176615 | +static int jsonEachColumn( |
| 176616 | + sqlite3_vtab_cursor *cur, /* The cursor */ |
| 176617 | + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
| 176618 | + int i /* Which column to return */ |
| 176619 | +){ |
| 176620 | + JsonEachCursor *p = (JsonEachCursor*)cur; |
| 176621 | + JsonNode *pThis = &p->sParse.aNode[p->i]; |
| 176622 | + switch( i ){ |
| 176623 | + case JEACH_KEY: { |
| 176624 | + if( p->i==0 ) break; |
| 176625 | + if( p->eType==JSON_OBJECT ){ |
| 176626 | + jsonReturn(pThis, ctx, 0); |
| 176627 | + }else if( p->eType==JSON_ARRAY ){ |
| 176628 | + u32 iKey; |
| 176629 | + if( p->bRecursive ){ |
| 176630 | + if( p->iRowid==0 ) break; |
| 176631 | + iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; |
| 176632 | + }else{ |
| 176633 | + iKey = p->iRowid; |
| 176634 | + } |
| 176635 | + sqlite3_result_int64(ctx, (sqlite3_int64)iKey); |
| 176636 | + } |
| 176637 | + break; |
| 176638 | + } |
| 176639 | + case JEACH_VALUE: { |
| 176640 | + if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 176641 | + jsonReturn(pThis, ctx, 0); |
| 176642 | + break; |
| 176643 | + } |
| 176644 | + case JEACH_TYPE: { |
| 176645 | + if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 176646 | + sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); |
| 176647 | + break; |
| 176648 | + } |
| 176649 | + case JEACH_ATOM: { |
| 176650 | + if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 176651 | + if( pThis->eType>=JSON_ARRAY ) break; |
| 176652 | + jsonReturn(pThis, ctx, 0); |
| 176653 | + break; |
| 176654 | + } |
| 176655 | + case JEACH_ID: { |
| 176656 | + sqlite3_result_int64(ctx, |
| 176657 | + (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); |
| 176658 | + break; |
| 176659 | + } |
| 176660 | + case JEACH_PARENT: { |
| 176661 | + if( p->i>p->iBegin && p->bRecursive ){ |
| 176662 | + sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); |
| 176663 | + } |
| 176664 | + break; |
| 176665 | + } |
| 176666 | + case JEACH_FULLKEY: { |
| 176667 | + JsonString x; |
| 176668 | + jsonInit(&x, ctx); |
| 176669 | + if( p->bRecursive ){ |
| 176670 | + jsonEachComputePath(p, &x, p->i); |
| 176671 | + }else{ |
| 176672 | + if( p->zRoot ){ |
| 176673 | + jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); |
| 176674 | + }else{ |
| 176675 | + jsonAppendChar(&x, '$'); |
| 176676 | + } |
| 176677 | + if( p->eType==JSON_ARRAY ){ |
| 176678 | + jsonPrintf(30, &x, "[%d]", p->iRowid); |
| 176679 | + }else if( p->eType==JSON_OBJECT ){ |
| 176680 | + jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); |
| 176681 | + } |
| 176682 | + } |
| 176683 | + jsonResult(&x); |
| 176684 | + break; |
| 176685 | + } |
| 176686 | + case JEACH_PATH: { |
| 176687 | + if( p->bRecursive ){ |
| 176688 | + JsonString x; |
| 176689 | + jsonInit(&x, ctx); |
| 176690 | + jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); |
| 176691 | + jsonResult(&x); |
| 176692 | + break; |
| 176693 | + } |
| 176694 | + /* For json_each() path and root are the same so fall through |
| 176695 | + ** into the root case */ |
| 176696 | + } |
| 176697 | + default: { |
| 176698 | + const char *zRoot = p->zRoot; |
| 176699 | + if( zRoot==0 ) zRoot = "$"; |
| 176700 | + sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); |
| 176701 | + break; |
| 176702 | + } |
| 176703 | + case JEACH_JSON: { |
| 176704 | + assert( i==JEACH_JSON ); |
| 176705 | + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); |
| 176706 | + break; |
| 176707 | + } |
| 176708 | + } |
| 176709 | + return SQLITE_OK; |
| 176710 | +} |
| 176711 | + |
| 176712 | +/* Return the current rowid value */ |
| 176713 | +static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 176714 | + JsonEachCursor *p = (JsonEachCursor*)cur; |
| 176715 | + *pRowid = p->iRowid; |
| 176716 | + return SQLITE_OK; |
| 176717 | +} |
| 176718 | + |
| 176719 | +/* The query strategy is to look for an equality constraint on the json |
| 176720 | +** column. Without such a constraint, the table cannot operate. idxNum is |
| 176721 | +** 1 if the constraint is found, 3 if the constraint and zRoot are found, |
| 176722 | +** and 0 otherwise. |
| 176723 | +*/ |
| 176724 | +static int jsonEachBestIndex( |
| 176725 | + sqlite3_vtab *tab, |
| 176726 | + sqlite3_index_info *pIdxInfo |
| 176727 | +){ |
| 176728 | + int i; |
| 176729 | + int jsonIdx = -1; |
| 176730 | + int rootIdx = -1; |
| 176731 | + const struct sqlite3_index_constraint *pConstraint; |
| 176732 | + |
| 176733 | + UNUSED_PARAM(tab); |
| 176734 | + pConstraint = pIdxInfo->aConstraint; |
| 176735 | + for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 176736 | + if( pConstraint->usable==0 ) continue; |
| 176737 | + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
| 176738 | + switch( pConstraint->iColumn ){ |
| 176739 | + case JEACH_JSON: jsonIdx = i; break; |
| 176740 | + case JEACH_ROOT: rootIdx = i; break; |
| 176741 | + default: /* no-op */ break; |
| 176742 | + } |
| 176743 | + } |
| 176744 | + if( jsonIdx<0 ){ |
| 176745 | + pIdxInfo->idxNum = 0; |
| 176746 | + pIdxInfo->estimatedCost = 1e99; |
| 176747 | + }else{ |
| 176748 | + pIdxInfo->estimatedCost = 1.0; |
| 176749 | + pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1; |
| 176750 | + pIdxInfo->aConstraintUsage[jsonIdx].omit = 1; |
| 176751 | + if( rootIdx<0 ){ |
| 176752 | + pIdxInfo->idxNum = 1; |
| 176753 | + }else{ |
| 176754 | + pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2; |
| 176755 | + pIdxInfo->aConstraintUsage[rootIdx].omit = 1; |
| 176756 | + pIdxInfo->idxNum = 3; |
| 176757 | + } |
| 176758 | + } |
| 176759 | + return SQLITE_OK; |
| 176760 | +} |
| 176761 | + |
| 176762 | +/* Start a search on a new JSON string */ |
| 176763 | +static int jsonEachFilter( |
| 176764 | + sqlite3_vtab_cursor *cur, |
| 176765 | + int idxNum, const char *idxStr, |
| 176766 | + int argc, sqlite3_value **argv |
| 176767 | +){ |
| 176768 | + JsonEachCursor *p = (JsonEachCursor*)cur; |
| 176769 | + const char *z; |
| 176770 | + const char *zRoot = 0; |
| 176771 | + sqlite3_int64 n; |
| 176772 | + |
| 176773 | + UNUSED_PARAM(idxStr); |
| 176774 | + UNUSED_PARAM(argc); |
| 176775 | + jsonEachCursorReset(p); |
| 176776 | + if( idxNum==0 ) return SQLITE_OK; |
| 176777 | + z = (const char*)sqlite3_value_text(argv[0]); |
| 176778 | + if( z==0 ) return SQLITE_OK; |
| 176779 | + n = sqlite3_value_bytes(argv[0]); |
| 176780 | + p->zJson = sqlite3_malloc64( n+1 ); |
| 176781 | + if( p->zJson==0 ) return SQLITE_NOMEM; |
| 176782 | + memcpy(p->zJson, z, (size_t)n+1); |
| 176783 | + if( jsonParse(&p->sParse, 0, p->zJson) ){ |
| 176784 | + int rc = SQLITE_NOMEM; |
| 176785 | + if( p->sParse.oom==0 ){ |
| 176786 | + sqlite3_free(cur->pVtab->zErrMsg); |
| 176787 | + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); |
| 176788 | + if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; |
| 176789 | + } |
| 176790 | + jsonEachCursorReset(p); |
| 176791 | + return rc; |
| 176792 | + }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ |
| 176793 | + jsonEachCursorReset(p); |
| 176794 | + return SQLITE_NOMEM; |
| 176795 | + }else{ |
| 176796 | + JsonNode *pNode = 0; |
| 176797 | + if( idxNum==3 ){ |
| 176798 | + const char *zErr = 0; |
| 176799 | + zRoot = (const char*)sqlite3_value_text(argv[1]); |
| 176800 | + if( zRoot==0 ) return SQLITE_OK; |
| 176801 | + n = sqlite3_value_bytes(argv[1]); |
| 176802 | + p->zRoot = sqlite3_malloc64( n+1 ); |
| 176803 | + if( p->zRoot==0 ) return SQLITE_NOMEM; |
| 176804 | + memcpy(p->zRoot, zRoot, (size_t)n+1); |
| 176805 | + if( zRoot[0]!='$' ){ |
| 176806 | + zErr = zRoot; |
| 176807 | + }else{ |
| 176808 | + pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); |
| 176809 | + } |
| 176810 | + if( zErr ){ |
| 176811 | + sqlite3_free(cur->pVtab->zErrMsg); |
| 176812 | + cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); |
| 176813 | + jsonEachCursorReset(p); |
| 176814 | + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; |
| 176815 | + }else if( pNode==0 ){ |
| 176816 | + return SQLITE_OK; |
| 176817 | + } |
| 176818 | + }else{ |
| 176819 | + pNode = p->sParse.aNode; |
| 176820 | + } |
| 176821 | + p->iBegin = p->i = (int)(pNode - p->sParse.aNode); |
| 176822 | + p->eType = pNode->eType; |
| 176823 | + if( p->eType>=JSON_ARRAY ){ |
| 176824 | + pNode->u.iKey = 0; |
| 176825 | + p->iEnd = p->i + pNode->n + 1; |
| 176826 | + if( p->bRecursive ){ |
| 176827 | + p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; |
| 176828 | + if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ |
| 176829 | + p->i--; |
| 176830 | + } |
| 176831 | + }else{ |
| 176832 | + p->i++; |
| 176833 | + } |
| 176834 | + }else{ |
| 176835 | + p->iEnd = p->i+1; |
| 176836 | + } |
| 176837 | + } |
| 176838 | + return SQLITE_OK; |
| 176839 | +} |
| 176840 | + |
| 176841 | +/* The methods of the json_each virtual table */ |
| 176842 | +static sqlite3_module jsonEachModule = { |
| 176843 | + 0, /* iVersion */ |
| 176844 | + 0, /* xCreate */ |
| 176845 | + jsonEachConnect, /* xConnect */ |
| 176846 | + jsonEachBestIndex, /* xBestIndex */ |
| 176847 | + jsonEachDisconnect, /* xDisconnect */ |
| 176848 | + 0, /* xDestroy */ |
| 176849 | + jsonEachOpenEach, /* xOpen - open a cursor */ |
| 176850 | + jsonEachClose, /* xClose - close a cursor */ |
| 176851 | + jsonEachFilter, /* xFilter - configure scan constraints */ |
| 176852 | + jsonEachNext, /* xNext - advance a cursor */ |
| 176853 | + jsonEachEof, /* xEof - check for end of scan */ |
| 176854 | + jsonEachColumn, /* xColumn - read data */ |
| 176855 | + jsonEachRowid, /* xRowid - read data */ |
| 176856 | + 0, /* xUpdate */ |
| 176857 | + 0, /* xBegin */ |
| 176858 | + 0, /* xSync */ |
| 176859 | + 0, /* xCommit */ |
| 176860 | + 0, /* xRollback */ |
| 176861 | + 0, /* xFindMethod */ |
| 176862 | + 0, /* xRename */ |
| 176863 | + 0, /* xSavepoint */ |
| 176864 | + 0, /* xRelease */ |
| 176865 | + 0 /* xRollbackTo */ |
| 176866 | +}; |
| 176867 | + |
| 176868 | +/* The methods of the json_tree virtual table. */ |
| 176869 | +static sqlite3_module jsonTreeModule = { |
| 176870 | + 0, /* iVersion */ |
| 176871 | + 0, /* xCreate */ |
| 176872 | + jsonEachConnect, /* xConnect */ |
| 176873 | + jsonEachBestIndex, /* xBestIndex */ |
| 176874 | + jsonEachDisconnect, /* xDisconnect */ |
| 176875 | + 0, /* xDestroy */ |
| 176876 | + jsonEachOpenTree, /* xOpen - open a cursor */ |
| 176877 | + jsonEachClose, /* xClose - close a cursor */ |
| 176878 | + jsonEachFilter, /* xFilter - configure scan constraints */ |
| 176879 | + jsonEachNext, /* xNext - advance a cursor */ |
| 176880 | + jsonEachEof, /* xEof - check for end of scan */ |
| 176881 | + jsonEachColumn, /* xColumn - read data */ |
| 176882 | + jsonEachRowid, /* xRowid - read data */ |
| 176883 | + 0, /* xUpdate */ |
| 176884 | + 0, /* xBegin */ |
| 176885 | + 0, /* xSync */ |
| 176886 | + 0, /* xCommit */ |
| 176887 | + 0, /* xRollback */ |
| 176888 | + 0, /* xFindMethod */ |
| 176889 | + 0, /* xRename */ |
| 176890 | + 0, /* xSavepoint */ |
| 176891 | + 0, /* xRelease */ |
| 176892 | + 0 /* xRollbackTo */ |
| 176893 | +}; |
| 176894 | +#endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 176895 | + |
| 176896 | +/**************************************************************************** |
| 176897 | +** The following routines are the only publically visible identifiers in this |
| 176898 | +** file. Call the following routines in order to register the various SQL |
| 176899 | +** functions and the virtual table implemented by this file. |
| 176900 | +****************************************************************************/ |
| 176901 | + |
| 176902 | +SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ |
| 176903 | + int rc = SQLITE_OK; |
| 176904 | + unsigned int i; |
| 176905 | + static const struct { |
| 176906 | + const char *zName; |
| 176907 | + int nArg; |
| 176908 | + int flag; |
| 176909 | + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); |
| 176910 | + } aFunc[] = { |
| 176911 | + { "json", 1, 0, jsonRemoveFunc }, |
| 176912 | + { "json_array", -1, 0, jsonArrayFunc }, |
| 176913 | + { "json_array_length", 1, 0, jsonArrayLengthFunc }, |
| 176914 | + { "json_array_length", 2, 0, jsonArrayLengthFunc }, |
| 176915 | + { "json_extract", -1, 0, jsonExtractFunc }, |
| 176916 | + { "json_insert", -1, 0, jsonSetFunc }, |
| 176917 | + { "json_object", -1, 0, jsonObjectFunc }, |
| 176918 | + { "json_patch", 2, 0, jsonPatchFunc }, |
| 176919 | + { "json_quote", 1, 0, jsonQuoteFunc }, |
| 176920 | + { "json_remove", -1, 0, jsonRemoveFunc }, |
| 176921 | + { "json_replace", -1, 0, jsonReplaceFunc }, |
| 176922 | + { "json_set", -1, 1, jsonSetFunc }, |
| 176923 | + { "json_type", 1, 0, jsonTypeFunc }, |
| 176924 | + { "json_type", 2, 0, jsonTypeFunc }, |
| 176925 | + { "json_valid", 1, 0, jsonValidFunc }, |
| 176926 | + |
| 176927 | +#if SQLITE_DEBUG |
| 176928 | + /* DEBUG and TESTING functions */ |
| 176929 | + { "json_parse", 1, 0, jsonParseFunc }, |
| 176930 | + { "json_test1", 1, 0, jsonTest1Func }, |
| 176931 | +#endif |
| 176932 | + }; |
| 176933 | + static const struct { |
| 176934 | + const char *zName; |
| 176935 | + int nArg; |
| 176936 | + void (*xStep)(sqlite3_context*,int,sqlite3_value**); |
| 176937 | + void (*xFinal)(sqlite3_context*); |
| 176938 | + void (*xValue)(sqlite3_context*); |
| 176939 | + } aAgg[] = { |
| 176940 | + { "json_group_array", 1, |
| 176941 | + jsonArrayStep, jsonArrayFinal, jsonArrayValue }, |
| 176942 | + { "json_group_object", 2, |
| 176943 | + jsonObjectStep, jsonObjectFinal, jsonObjectValue }, |
| 176944 | + }; |
| 176945 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 176946 | + static const struct { |
| 176947 | + const char *zName; |
| 176948 | + sqlite3_module *pModule; |
| 176949 | + } aMod[] = { |
| 176950 | + { "json_each", &jsonEachModule }, |
| 176951 | + { "json_tree", &jsonTreeModule }, |
| 176952 | + }; |
| 176953 | +#endif |
| 176954 | + for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ |
| 176955 | + rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, |
| 176956 | + SQLITE_UTF8 | SQLITE_DETERMINISTIC, |
| 176957 | + (void*)&aFunc[i].flag, |
| 176958 | + aFunc[i].xFunc, 0, 0); |
| 176959 | + } |
| 176960 | +#ifndef SQLITE_OMIT_WINDOWFUNC |
| 176961 | + for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ |
| 176962 | + rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg, |
| 176963 | + SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, |
| 176964 | + aAgg[i].xStep, aAgg[i].xFinal, |
| 176965 | + aAgg[i].xValue, jsonGroupInverse, 0); |
| 176966 | + } |
| 176967 | +#endif |
| 176968 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 176969 | + for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){ |
| 176970 | + rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0); |
| 176971 | + } |
| 176972 | +#endif |
| 176973 | + return rc; |
| 176974 | +} |
| 176975 | + |
| 176976 | + |
| 176977 | +#ifndef SQLITE_CORE |
| 176978 | +#ifdef _WIN32 |
| 176979 | +__declspec(dllexport) |
| 176980 | +#endif |
| 176981 | +SQLITE_API int sqlite3_json_init( |
| 176982 | + sqlite3 *db, |
| 176983 | + char **pzErrMsg, |
| 176984 | + const sqlite3_api_routines *pApi |
| 176985 | +){ |
| 176986 | + SQLITE_EXTENSION_INIT2(pApi); |
| 176987 | + (void)pzErrMsg; /* Unused parameter */ |
| 176988 | + return sqlite3Json1Init(db); |
| 176989 | +} |
| 176990 | +#endif |
| 176991 | +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */ |
| 176992 | + |
| 176993 | +/************** End of json1.c ***********************************************/ |
| 174368 | 176994 | /************** Begin file rtree.c *******************************************/ |
| 174369 | 176995 | /* |
| 174370 | 176996 | ** 2001 September 15 |
| 174371 | 176997 | ** |
| 174372 | 176998 | ** The author disclaims copyright to this source code. In place of |
| | @@ -174493,10 +177119,11 @@ |
| 174493 | 177119 | u8 nDim2; /* Twice the number of dimensions */ |
| 174494 | 177120 | u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ |
| 174495 | 177121 | u8 nBytesPerCell; /* Bytes consumed per cell */ |
| 174496 | 177122 | u8 inWrTrans; /* True if inside write transaction */ |
| 174497 | 177123 | u8 nAux; /* # of auxiliary columns in %_rowid */ |
| 177124 | + u8 nAuxNotNull; /* Number of initial not-null aux columns */ |
| 174498 | 177125 | int iDepth; /* Current depth of the r-tree structure */ |
| 174499 | 177126 | char *zDb; /* Name of database containing r-tree table */ |
| 174500 | 177127 | char *zName; /* Name of r-tree table */ |
| 174501 | 177128 | u32 nBusy; /* Current number of users of this structure */ |
| 174502 | 177129 | i64 nRowEst; /* Estimated number of rows in this table */ |
| | @@ -177259,11 +179886,11 @@ |
| 177259 | 179886 | } |
| 177260 | 179887 | |
| 177261 | 179888 | /* |
| 177262 | 179889 | ** Select a currently unused rowid for a new r-tree record. |
| 177263 | 179890 | */ |
| 177264 | | -static int newRowid(Rtree *pRtree, i64 *piRowid){ |
| 179891 | +static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){ |
| 177265 | 179892 | int rc; |
| 177266 | 179893 | sqlite3_bind_null(pRtree->pWriteRowid, 1); |
| 177267 | 179894 | sqlite3_bind_null(pRtree->pWriteRowid, 2); |
| 177268 | 179895 | sqlite3_step(pRtree->pWriteRowid); |
| 177269 | 179896 | rc = sqlite3_reset(pRtree->pWriteRowid); |
| | @@ -177546,11 +180173,11 @@ |
| 177546 | 180173 | /* Insert the new record into the r-tree */ |
| 177547 | 180174 | RtreeNode *pLeaf = 0; |
| 177548 | 180175 | |
| 177549 | 180176 | /* Figure out the rowid of the new row. */ |
| 177550 | 180177 | if( bHaveRowid==0 ){ |
| 177551 | | - rc = newRowid(pRtree, &cell.iRowid); |
| 180178 | + rc = rtreeNewRowid(pRtree, &cell.iRowid); |
| 177552 | 180179 | } |
| 177553 | 180180 | *pRowid = cell.iRowid; |
| 177554 | 180181 | |
| 177555 | 180182 | if( rc==SQLITE_OK ){ |
| 177556 | 180183 | rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); |
| | @@ -177819,11 +180446,15 @@ |
| 177819 | 180446 | int ii; |
| 177820 | 180447 | char *zSql; |
| 177821 | 180448 | sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); |
| 177822 | 180449 | for(ii=0; ii<pRtree->nAux; ii++){ |
| 177823 | 180450 | if( ii ) sqlite3_str_append(p, ",", 1); |
| 177824 | | - sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); |
| 180451 | + if( ii<pRtree->nAuxNotNull ){ |
| 180452 | + sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); |
| 180453 | + }else{ |
| 180454 | + sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); |
| 180455 | + } |
| 177825 | 180456 | } |
| 177826 | 180457 | sqlite3_str_appendf(p, " WHERE rowid=?1"); |
| 177827 | 180458 | zSql = sqlite3_str_finish(p); |
| 177828 | 180459 | if( zSql==0 ){ |
| 177829 | 180460 | rc = SQLITE_NOMEM; |
| | @@ -178588,10 +181219,1677 @@ |
| 178588 | 181219 | } |
| 178589 | 181220 | sqlite3_free(zReport); |
| 178590 | 181221 | } |
| 178591 | 181222 | } |
| 178592 | 181223 | |
| 181224 | +/* Conditionally include the geopoly code */ |
| 181225 | +#ifdef SQLITE_ENABLE_GEOPOLY |
| 181226 | +/************** Include geopoly.c in the middle of rtree.c *******************/ |
| 181227 | +/************** Begin file geopoly.c *****************************************/ |
| 181228 | +/* |
| 181229 | +** 2018-05-25 |
| 181230 | +** |
| 181231 | +** The author disclaims copyright to this source code. In place of |
| 181232 | +** a legal notice, here is a blessing: |
| 181233 | +** |
| 181234 | +** May you do good and not evil. |
| 181235 | +** May you find forgiveness for yourself and forgive others. |
| 181236 | +** May you share freely, never taking more than you give. |
| 181237 | +** |
| 181238 | +****************************************************************************** |
| 181239 | +** |
| 181240 | +** This file implements an alternative R-Tree virtual table that |
| 181241 | +** uses polygons to express the boundaries of 2-dimensional objects. |
| 181242 | +** |
| 181243 | +** This file is #include-ed onto the end of "rtree.c" so that it has |
| 181244 | +** access to all of the R-Tree internals. |
| 181245 | +*/ |
| 181246 | +/* #include <stdlib.h> */ |
| 181247 | + |
| 181248 | +/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */ |
| 181249 | +#ifdef GEOPOLY_ENABLE_DEBUG |
| 181250 | + static int geo_debug = 0; |
| 181251 | +# define GEODEBUG(X) if(geo_debug)printf X |
| 181252 | +#else |
| 181253 | +# define GEODEBUG(X) |
| 181254 | +#endif |
| 181255 | + |
| 181256 | +#ifndef JSON_NULL /* The following stuff repeats things found in json1 */ |
| 181257 | +/* |
| 181258 | +** Versions of isspace(), isalnum() and isdigit() to which it is safe |
| 181259 | +** to pass signed char values. |
| 181260 | +*/ |
| 181261 | +#ifdef sqlite3Isdigit |
| 181262 | + /* Use the SQLite core versions if this routine is part of the |
| 181263 | + ** SQLite amalgamation */ |
| 181264 | +# define safe_isdigit(x) sqlite3Isdigit(x) |
| 181265 | +# define safe_isalnum(x) sqlite3Isalnum(x) |
| 181266 | +# define safe_isxdigit(x) sqlite3Isxdigit(x) |
| 181267 | +#else |
| 181268 | + /* Use the standard library for separate compilation */ |
| 181269 | +#include <ctype.h> /* amalgamator: keep */ |
| 181270 | +# define safe_isdigit(x) isdigit((unsigned char)(x)) |
| 181271 | +# define safe_isalnum(x) isalnum((unsigned char)(x)) |
| 181272 | +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) |
| 181273 | +#endif |
| 181274 | + |
| 181275 | +/* |
| 181276 | +** Growing our own isspace() routine this way is twice as fast as |
| 181277 | +** the library isspace() function. |
| 181278 | +*/ |
| 181279 | +static const char geopolyIsSpace[] = { |
| 181280 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, |
| 181281 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181282 | + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181283 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181284 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181285 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181286 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181287 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181288 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181289 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181290 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181291 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181292 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181293 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181294 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181295 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 181296 | +}; |
| 181297 | +#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x]) |
| 181298 | +#endif /* JSON NULL - back to original code */ |
| 181299 | + |
| 181300 | +/* Compiler and version */ |
| 181301 | +#ifndef GCC_VERSION |
| 181302 | +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) |
| 181303 | +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) |
| 181304 | +#else |
| 181305 | +# define GCC_VERSION 0 |
| 181306 | +#endif |
| 181307 | +#endif |
| 181308 | +#ifndef MSVC_VERSION |
| 181309 | +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) |
| 181310 | +# define MSVC_VERSION _MSC_VER |
| 181311 | +#else |
| 181312 | +# define MSVC_VERSION 0 |
| 181313 | +#endif |
| 181314 | +#endif |
| 181315 | + |
| 181316 | +/* Datatype for coordinates |
| 181317 | +*/ |
| 181318 | +typedef float GeoCoord; |
| 181319 | + |
| 181320 | +/* |
| 181321 | +** Internal representation of a polygon. |
| 181322 | +** |
| 181323 | +** The polygon consists of a sequence of vertexes. There is a line |
| 181324 | +** segment between each pair of vertexes, and one final segment from |
| 181325 | +** the last vertex back to the first. (This differs from the GeoJSON |
| 181326 | +** standard in which the final vertex is a repeat of the first.) |
| 181327 | +** |
| 181328 | +** The polygon follows the right-hand rule. The area to the right of |
| 181329 | +** each segment is "outside" and the area to the left is "inside". |
| 181330 | +** |
| 181331 | +** The on-disk representation consists of a 4-byte header followed by |
| 181332 | +** the values. The 4-byte header is: |
| 181333 | +** |
| 181334 | +** encoding (1 byte) 0=big-endian, 1=little-endian |
| 181335 | +** nvertex (3 bytes) Number of vertexes as a big-endian integer |
| 181336 | +*/ |
| 181337 | +typedef struct GeoPoly GeoPoly; |
| 181338 | +struct GeoPoly { |
| 181339 | + int nVertex; /* Number of vertexes */ |
| 181340 | + unsigned char hdr[4]; /* Header for on-disk representation */ |
| 181341 | + GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */ |
| 181342 | +}; |
| 181343 | + |
| 181344 | +/* |
| 181345 | +** State of a parse of a GeoJSON input. |
| 181346 | +*/ |
| 181347 | +typedef struct GeoParse GeoParse; |
| 181348 | +struct GeoParse { |
| 181349 | + const unsigned char *z; /* Unparsed input */ |
| 181350 | + int nVertex; /* Number of vertexes in a[] */ |
| 181351 | + int nAlloc; /* Space allocated to a[] */ |
| 181352 | + int nErr; /* Number of errors encountered */ |
| 181353 | + GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */ |
| 181354 | +}; |
| 181355 | + |
| 181356 | +/* Do a 4-byte byte swap */ |
| 181357 | +static void geopolySwab32(unsigned char *a){ |
| 181358 | + unsigned char t = a[0]; |
| 181359 | + a[0] = a[3]; |
| 181360 | + a[3] = t; |
| 181361 | + t = a[1]; |
| 181362 | + a[1] = a[2]; |
| 181363 | + a[2] = t; |
| 181364 | +} |
| 181365 | + |
| 181366 | +/* Skip whitespace. Return the next non-whitespace character. */ |
| 181367 | +static char geopolySkipSpace(GeoParse *p){ |
| 181368 | + while( p->z[0] && safe_isspace(p->z[0]) ) p->z++; |
| 181369 | + return p->z[0]; |
| 181370 | +} |
| 181371 | + |
| 181372 | +/* Parse out a number. Write the value into *pVal if pVal!=0. |
| 181373 | +** return non-zero on success and zero if the next token is not a number. |
| 181374 | +*/ |
| 181375 | +static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ |
| 181376 | + char c = geopolySkipSpace(p); |
| 181377 | + const unsigned char *z = p->z; |
| 181378 | + int j = 0; |
| 181379 | + int seenDP = 0; |
| 181380 | + int seenE = 0; |
| 181381 | + if( c=='-' ){ |
| 181382 | + j = 1; |
| 181383 | + c = z[j]; |
| 181384 | + } |
| 181385 | + if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0; |
| 181386 | + for(;; j++){ |
| 181387 | + c = z[j]; |
| 181388 | + if( c>='0' && c<='9' ) continue; |
| 181389 | + if( c=='.' ){ |
| 181390 | + if( z[j-1]=='-' ) return 0; |
| 181391 | + if( seenDP ) return 0; |
| 181392 | + seenDP = 1; |
| 181393 | + continue; |
| 181394 | + } |
| 181395 | + if( c=='e' || c=='E' ){ |
| 181396 | + if( z[j-1]<'0' ) return 0; |
| 181397 | + if( seenE ) return -1; |
| 181398 | + seenDP = seenE = 1; |
| 181399 | + c = z[j+1]; |
| 181400 | + if( c=='+' || c=='-' ){ |
| 181401 | + j++; |
| 181402 | + c = z[j+1]; |
| 181403 | + } |
| 181404 | + if( c<'0' || c>'9' ) return 0; |
| 181405 | + continue; |
| 181406 | + } |
| 181407 | + break; |
| 181408 | + } |
| 181409 | + if( z[j-1]<'0' ) return 0; |
| 181410 | + if( pVal ) *pVal = atof((const char*)p->z); |
| 181411 | + p->z += j; |
| 181412 | + return 1; |
| 181413 | +} |
| 181414 | + |
| 181415 | +/* |
| 181416 | +** If the input is a well-formed JSON array of coordinates with at least |
| 181417 | +** four coordinates and where each coordinate is itself a two-value array, |
| 181418 | +** then convert the JSON into a GeoPoly object and return a pointer to |
| 181419 | +** that object. |
| 181420 | +** |
| 181421 | +** If any error occurs, return NULL. |
| 181422 | +*/ |
| 181423 | +static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ |
| 181424 | + GeoParse s; |
| 181425 | + int rc = SQLITE_OK; |
| 181426 | + memset(&s, 0, sizeof(s)); |
| 181427 | + s.z = z; |
| 181428 | + if( geopolySkipSpace(&s)=='[' ){ |
| 181429 | + s.z++; |
| 181430 | + while( geopolySkipSpace(&s)=='[' ){ |
| 181431 | + int ii = 0; |
| 181432 | + char c; |
| 181433 | + s.z++; |
| 181434 | + if( s.nVertex<=s.nAlloc ){ |
| 181435 | + GeoCoord *aNew; |
| 181436 | + s.nAlloc = s.nAlloc*2 + 16; |
| 181437 | + aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); |
| 181438 | + if( aNew==0 ){ |
| 181439 | + rc = SQLITE_NOMEM; |
| 181440 | + s.nErr++; |
| 181441 | + break; |
| 181442 | + } |
| 181443 | + s.a = aNew; |
| 181444 | + } |
| 181445 | + while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ |
| 181446 | + ii++; |
| 181447 | + if( ii==2 ) s.nVertex++; |
| 181448 | + c = geopolySkipSpace(&s); |
| 181449 | + s.z++; |
| 181450 | + if( c==',' ) continue; |
| 181451 | + if( c==']' && ii>=2 ) break; |
| 181452 | + s.nErr++; |
| 181453 | + rc = SQLITE_ERROR; |
| 181454 | + goto parse_json_err; |
| 181455 | + } |
| 181456 | + if( geopolySkipSpace(&s)==',' ){ |
| 181457 | + s.z++; |
| 181458 | + continue; |
| 181459 | + } |
| 181460 | + break; |
| 181461 | + } |
| 181462 | + if( geopolySkipSpace(&s)==']' |
| 181463 | + && s.nVertex>=4 |
| 181464 | + && s.a[0]==s.a[s.nVertex*2-2] |
| 181465 | + && s.a[1]==s.a[s.nVertex*2-1] |
| 181466 | + && (s.z++, geopolySkipSpace(&s)==0) |
| 181467 | + ){ |
| 181468 | + int nByte; |
| 181469 | + GeoPoly *pOut; |
| 181470 | + int x = 1; |
| 181471 | + s.nVertex--; /* Remove the redundant vertex at the end */ |
| 181472 | + nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord); |
| 181473 | + pOut = sqlite3_malloc64( nByte ); |
| 181474 | + x = 1; |
| 181475 | + if( pOut==0 ) goto parse_json_err; |
| 181476 | + pOut->nVertex = s.nVertex; |
| 181477 | + memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord)); |
| 181478 | + pOut->hdr[0] = *(unsigned char*)&x; |
| 181479 | + pOut->hdr[1] = (s.nVertex>>16)&0xff; |
| 181480 | + pOut->hdr[2] = (s.nVertex>>8)&0xff; |
| 181481 | + pOut->hdr[3] = s.nVertex&0xff; |
| 181482 | + sqlite3_free(s.a); |
| 181483 | + if( pRc ) *pRc = SQLITE_OK; |
| 181484 | + return pOut; |
| 181485 | + }else{ |
| 181486 | + s.nErr++; |
| 181487 | + rc = SQLITE_ERROR; |
| 181488 | + } |
| 181489 | + } |
| 181490 | +parse_json_err: |
| 181491 | + if( pRc ) *pRc = rc; |
| 181492 | + sqlite3_free(s.a); |
| 181493 | + return 0; |
| 181494 | +} |
| 181495 | + |
| 181496 | +/* |
| 181497 | +** Given a function parameter, try to interpret it as a polygon, either |
| 181498 | +** in the binary format or JSON text. Compute a GeoPoly object and |
| 181499 | +** return a pointer to that object. Or if the input is not a well-formed |
| 181500 | +** polygon, put an error message in sqlite3_context and return NULL. |
| 181501 | +*/ |
| 181502 | +static GeoPoly *geopolyFuncParam( |
| 181503 | + sqlite3_context *pCtx, /* Context for error messages */ |
| 181504 | + sqlite3_value *pVal, /* The value to decode */ |
| 181505 | + int *pRc /* Write error here */ |
| 181506 | +){ |
| 181507 | + GeoPoly *p = 0; |
| 181508 | + int nByte; |
| 181509 | + if( sqlite3_value_type(pVal)==SQLITE_BLOB |
| 181510 | + && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) |
| 181511 | + ){ |
| 181512 | + const unsigned char *a = sqlite3_value_blob(pVal); |
| 181513 | + int nVertex; |
| 181514 | + nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; |
| 181515 | + if( (a[0]==0 || a[0]==1) |
| 181516 | + && (nVertex*2*sizeof(GeoCoord) + 4)==nByte |
| 181517 | + ){ |
| 181518 | + p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); |
| 181519 | + if( p==0 ){ |
| 181520 | + if( pRc ) *pRc = SQLITE_NOMEM; |
| 181521 | + if( pCtx ) sqlite3_result_error_nomem(pCtx); |
| 181522 | + }else{ |
| 181523 | + int x = 1; |
| 181524 | + p->nVertex = nVertex; |
| 181525 | + memcpy(p->hdr, a, nByte); |
| 181526 | + if( a[0] != *(unsigned char*)&x ){ |
| 181527 | + int ii; |
| 181528 | + for(ii=0; ii<nVertex*2; ii++){ |
| 181529 | + geopolySwab32((unsigned char*)&p->a[ii]); |
| 181530 | + } |
| 181531 | + p->hdr[0] ^= 1; |
| 181532 | + } |
| 181533 | + } |
| 181534 | + } |
| 181535 | + if( pRc ) *pRc = SQLITE_OK; |
| 181536 | + return p; |
| 181537 | + }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ |
| 181538 | + const unsigned char *zJson = sqlite3_value_text(pVal); |
| 181539 | + if( zJson==0 ){ |
| 181540 | + if( pRc ) *pRc = SQLITE_NOMEM; |
| 181541 | + return 0; |
| 181542 | + } |
| 181543 | + return geopolyParseJson(zJson, pRc); |
| 181544 | + }else{ |
| 181545 | + if( pRc ) *pRc = SQLITE_ERROR; |
| 181546 | + return 0; |
| 181547 | + } |
| 181548 | +} |
| 181549 | + |
| 181550 | +/* |
| 181551 | +** Implementation of the geopoly_blob(X) function. |
| 181552 | +** |
| 181553 | +** If the input is a well-formed Geopoly BLOB or JSON string |
| 181554 | +** then return the BLOB representation of the polygon. Otherwise |
| 181555 | +** return NULL. |
| 181556 | +*/ |
| 181557 | +static void geopolyBlobFunc( |
| 181558 | + sqlite3_context *context, |
| 181559 | + int argc, |
| 181560 | + sqlite3_value **argv |
| 181561 | +){ |
| 181562 | + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 181563 | + if( p ){ |
| 181564 | + sqlite3_result_blob(context, p->hdr, |
| 181565 | + 4+8*p->nVertex, SQLITE_TRANSIENT); |
| 181566 | + sqlite3_free(p); |
| 181567 | + } |
| 181568 | +} |
| 181569 | + |
| 181570 | +/* |
| 181571 | +** SQL function: geopoly_json(X) |
| 181572 | +** |
| 181573 | +** Interpret X as a polygon and render it as a JSON array |
| 181574 | +** of coordinates. Or, if X is not a valid polygon, return NULL. |
| 181575 | +*/ |
| 181576 | +static void geopolyJsonFunc( |
| 181577 | + sqlite3_context *context, |
| 181578 | + int argc, |
| 181579 | + sqlite3_value **argv |
| 181580 | +){ |
| 181581 | + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 181582 | + if( p ){ |
| 181583 | + sqlite3 *db = sqlite3_context_db_handle(context); |
| 181584 | + sqlite3_str *x = sqlite3_str_new(db); |
| 181585 | + int i; |
| 181586 | + sqlite3_str_append(x, "[", 1); |
| 181587 | + for(i=0; i<p->nVertex; i++){ |
| 181588 | + sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]); |
| 181589 | + } |
| 181590 | + sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]); |
| 181591 | + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); |
| 181592 | + sqlite3_free(p); |
| 181593 | + } |
| 181594 | +} |
| 181595 | + |
| 181596 | +/* |
| 181597 | +** SQL function: geopoly_svg(X, ....) |
| 181598 | +** |
| 181599 | +** Interpret X as a polygon and render it as a SVG <polyline>. |
| 181600 | +** Additional arguments are added as attributes to the <polyline>. |
| 181601 | +*/ |
| 181602 | +static void geopolySvgFunc( |
| 181603 | + sqlite3_context *context, |
| 181604 | + int argc, |
| 181605 | + sqlite3_value **argv |
| 181606 | +){ |
| 181607 | + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 181608 | + if( p ){ |
| 181609 | + sqlite3 *db = sqlite3_context_db_handle(context); |
| 181610 | + sqlite3_str *x = sqlite3_str_new(db); |
| 181611 | + int i; |
| 181612 | + char cSep = '\''; |
| 181613 | + sqlite3_str_appendf(x, "<polyline points="); |
| 181614 | + for(i=0; i<p->nVertex; i++){ |
| 181615 | + sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]); |
| 181616 | + cSep = ' '; |
| 181617 | + } |
| 181618 | + sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]); |
| 181619 | + for(i=1; i<argc; i++){ |
| 181620 | + const char *z = (const char*)sqlite3_value_text(argv[i]); |
| 181621 | + if( z && z[0] ){ |
| 181622 | + sqlite3_str_appendf(x, " %s", z); |
| 181623 | + } |
| 181624 | + } |
| 181625 | + sqlite3_str_appendf(x, "></polyline>"); |
| 181626 | + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); |
| 181627 | + sqlite3_free(p); |
| 181628 | + } |
| 181629 | +} |
| 181630 | + |
| 181631 | +/* |
| 181632 | +** SQL Function: geopoly_xform(poly, A, B, C, D, E, F) |
| 181633 | +** |
| 181634 | +** Transform and/or translate a polygon as follows: |
| 181635 | +** |
| 181636 | +** x1 = A*x0 + B*y0 + E |
| 181637 | +** y1 = C*x0 + D*y0 + F |
| 181638 | +** |
| 181639 | +** For a translation: |
| 181640 | +** |
| 181641 | +** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset) |
| 181642 | +** |
| 181643 | +** Rotate by R around the point (0,0): |
| 181644 | +** |
| 181645 | +** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0) |
| 181646 | +*/ |
| 181647 | +static void geopolyXformFunc( |
| 181648 | + sqlite3_context *context, |
| 181649 | + int argc, |
| 181650 | + sqlite3_value **argv |
| 181651 | +){ |
| 181652 | + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 181653 | + double A = sqlite3_value_double(argv[1]); |
| 181654 | + double B = sqlite3_value_double(argv[2]); |
| 181655 | + double C = sqlite3_value_double(argv[3]); |
| 181656 | + double D = sqlite3_value_double(argv[4]); |
| 181657 | + double E = sqlite3_value_double(argv[5]); |
| 181658 | + double F = sqlite3_value_double(argv[6]); |
| 181659 | + GeoCoord x1, y1, x0, y0; |
| 181660 | + int ii; |
| 181661 | + if( p ){ |
| 181662 | + for(ii=0; ii<p->nVertex; ii++){ |
| 181663 | + x0 = p->a[ii*2]; |
| 181664 | + y0 = p->a[ii*2+1]; |
| 181665 | + x1 = A*x0 + B*y0 + E; |
| 181666 | + y1 = C*x0 + D*y0 + F; |
| 181667 | + p->a[ii*2] = x1; |
| 181668 | + p->a[ii*2+1] = y1; |
| 181669 | + } |
| 181670 | + sqlite3_result_blob(context, p->hdr, |
| 181671 | + 4+8*p->nVertex, SQLITE_TRANSIENT); |
| 181672 | + sqlite3_free(p); |
| 181673 | + } |
| 181674 | +} |
| 181675 | + |
| 181676 | +/* |
| 181677 | +** Implementation of the geopoly_area(X) function. |
| 181678 | +** |
| 181679 | +** If the input is a well-formed Geopoly BLOB then return the area |
| 181680 | +** enclosed by the polygon. If the polygon circulates clockwise instead |
| 181681 | +** of counterclockwise (as it should) then return the negative of the |
| 181682 | +** enclosed area. Otherwise return NULL. |
| 181683 | +*/ |
| 181684 | +static void geopolyAreaFunc( |
| 181685 | + sqlite3_context *context, |
| 181686 | + int argc, |
| 181687 | + sqlite3_value **argv |
| 181688 | +){ |
| 181689 | + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 181690 | + if( p ){ |
| 181691 | + double rArea = 0.0; |
| 181692 | + int ii; |
| 181693 | + for(ii=0; ii<p->nVertex-1; ii++){ |
| 181694 | + rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ |
| 181695 | + * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ |
| 181696 | + * 0.5; |
| 181697 | + } |
| 181698 | + rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ |
| 181699 | + * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ |
| 181700 | + * 0.5; |
| 181701 | + sqlite3_result_double(context, rArea); |
| 181702 | + sqlite3_free(p); |
| 181703 | + } |
| 181704 | +} |
| 181705 | + |
| 181706 | +/* |
| 181707 | +** If pPoly is a polygon, compute its bounding box. Then: |
| 181708 | +** |
| 181709 | +** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL |
| 181710 | +** (2) otherwise, compute a GeoPoly for the bounding box and return the |
| 181711 | +** new GeoPoly |
| 181712 | +** |
| 181713 | +** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from |
| 181714 | +** the bounding box in aCoord and return a pointer to that GeoPoly. |
| 181715 | +*/ |
| 181716 | +static GeoPoly *geopolyBBox( |
| 181717 | + sqlite3_context *context, /* For recording the error */ |
| 181718 | + sqlite3_value *pPoly, /* The polygon */ |
| 181719 | + RtreeCoord *aCoord, /* Results here */ |
| 181720 | + int *pRc /* Error code here */ |
| 181721 | +){ |
| 181722 | + GeoPoly *pOut = 0; |
| 181723 | + GeoPoly *p; |
| 181724 | + float mnX, mxX, mnY, mxY; |
| 181725 | + if( pPoly==0 && aCoord!=0 ){ |
| 181726 | + p = 0; |
| 181727 | + mnX = aCoord[0].f; |
| 181728 | + mxX = aCoord[1].f; |
| 181729 | + mnY = aCoord[2].f; |
| 181730 | + mxY = aCoord[3].f; |
| 181731 | + goto geopolyBboxFill; |
| 181732 | + }else{ |
| 181733 | + p = geopolyFuncParam(context, pPoly, pRc); |
| 181734 | + } |
| 181735 | + if( p ){ |
| 181736 | + int ii; |
| 181737 | + mnX = mxX = p->a[0]; |
| 181738 | + mnY = mxY = p->a[1]; |
| 181739 | + for(ii=1; ii<p->nVertex; ii++){ |
| 181740 | + double r = p->a[ii*2]; |
| 181741 | + if( r<mnX ) mnX = r; |
| 181742 | + else if( r>mxX ) mxX = r; |
| 181743 | + r = p->a[ii*2+1]; |
| 181744 | + if( r<mnY ) mnY = r; |
| 181745 | + else if( r>mxY ) mxY = r; |
| 181746 | + } |
| 181747 | + if( pRc ) *pRc = SQLITE_OK; |
| 181748 | + if( aCoord==0 ){ |
| 181749 | + geopolyBboxFill: |
| 181750 | + pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6); |
| 181751 | + if( pOut==0 ){ |
| 181752 | + sqlite3_free(p); |
| 181753 | + if( context ) sqlite3_result_error_nomem(context); |
| 181754 | + if( pRc ) *pRc = SQLITE_NOMEM; |
| 181755 | + return 0; |
| 181756 | + } |
| 181757 | + pOut->nVertex = 4; |
| 181758 | + ii = 1; |
| 181759 | + pOut->hdr[0] = *(unsigned char*)ⅈ |
| 181760 | + pOut->hdr[1] = 0; |
| 181761 | + pOut->hdr[2] = 0; |
| 181762 | + pOut->hdr[3] = 4; |
| 181763 | + pOut->a[0] = mnX; |
| 181764 | + pOut->a[1] = mnY; |
| 181765 | + pOut->a[2] = mxX; |
| 181766 | + pOut->a[3] = mnY; |
| 181767 | + pOut->a[4] = mxX; |
| 181768 | + pOut->a[5] = mxY; |
| 181769 | + pOut->a[6] = mnX; |
| 181770 | + pOut->a[7] = mxY; |
| 181771 | + }else{ |
| 181772 | + sqlite3_free(p); |
| 181773 | + aCoord[0].f = mnX; |
| 181774 | + aCoord[1].f = mxX; |
| 181775 | + aCoord[2].f = mnY; |
| 181776 | + aCoord[3].f = mxY; |
| 181777 | + } |
| 181778 | + } |
| 181779 | + return pOut; |
| 181780 | +} |
| 181781 | + |
| 181782 | +/* |
| 181783 | +** Implementation of the geopoly_bbox(X) SQL function. |
| 181784 | +*/ |
| 181785 | +static void geopolyBBoxFunc( |
| 181786 | + sqlite3_context *context, |
| 181787 | + int argc, |
| 181788 | + sqlite3_value **argv |
| 181789 | +){ |
| 181790 | + GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); |
| 181791 | + if( p ){ |
| 181792 | + sqlite3_result_blob(context, p->hdr, |
| 181793 | + 4+8*p->nVertex, SQLITE_TRANSIENT); |
| 181794 | + sqlite3_free(p); |
| 181795 | + } |
| 181796 | +} |
| 181797 | + |
| 181798 | +/* |
| 181799 | +** State vector for the geopoly_group_bbox() aggregate function. |
| 181800 | +*/ |
| 181801 | +typedef struct GeoBBox GeoBBox; |
| 181802 | +struct GeoBBox { |
| 181803 | + int isInit; |
| 181804 | + RtreeCoord a[4]; |
| 181805 | +}; |
| 181806 | + |
| 181807 | + |
| 181808 | +/* |
| 181809 | +** Implementation of the geopoly_group_bbox(X) aggregate SQL function. |
| 181810 | +*/ |
| 181811 | +static void geopolyBBoxStep( |
| 181812 | + sqlite3_context *context, |
| 181813 | + int argc, |
| 181814 | + sqlite3_value **argv |
| 181815 | +){ |
| 181816 | + RtreeCoord a[4]; |
| 181817 | + int rc = SQLITE_OK; |
| 181818 | + (void)geopolyBBox(context, argv[0], a, &rc); |
| 181819 | + if( rc==SQLITE_OK ){ |
| 181820 | + GeoBBox *pBBox; |
| 181821 | + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); |
| 181822 | + if( pBBox==0 ) return; |
| 181823 | + if( pBBox->isInit==0 ){ |
| 181824 | + pBBox->isInit = 1; |
| 181825 | + memcpy(pBBox->a, a, sizeof(RtreeCoord)*4); |
| 181826 | + }else{ |
| 181827 | + if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0]; |
| 181828 | + if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1]; |
| 181829 | + if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2]; |
| 181830 | + if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3]; |
| 181831 | + } |
| 181832 | + } |
| 181833 | +} |
| 181834 | +static void geopolyBBoxFinal( |
| 181835 | + sqlite3_context *context |
| 181836 | +){ |
| 181837 | + GeoPoly *p; |
| 181838 | + GeoBBox *pBBox; |
| 181839 | + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0); |
| 181840 | + if( pBBox==0 ) return; |
| 181841 | + p = geopolyBBox(context, 0, pBBox->a, 0); |
| 181842 | + if( p ){ |
| 181843 | + sqlite3_result_blob(context, p->hdr, |
| 181844 | + 4+8*p->nVertex, SQLITE_TRANSIENT); |
| 181845 | + sqlite3_free(p); |
| 181846 | + } |
| 181847 | +} |
| 181848 | + |
| 181849 | + |
| 181850 | +/* |
| 181851 | +** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). |
| 181852 | +** Returns: |
| 181853 | +** |
| 181854 | +** +2 x0,y0 is on the line segement |
| 181855 | +** |
| 181856 | +** +1 x0,y0 is beneath line segment |
| 181857 | +** |
| 181858 | +** 0 x0,y0 is not on or beneath the line segment or the line segment |
| 181859 | +** is vertical and x0,y0 is not on the line segment |
| 181860 | +** |
| 181861 | +** The left-most coordinate min(x1,x2) is not considered to be part of |
| 181862 | +** the line segment for the purposes of this analysis. |
| 181863 | +*/ |
| 181864 | +static int pointBeneathLine( |
| 181865 | + double x0, double y0, |
| 181866 | + double x1, double y1, |
| 181867 | + double x2, double y2 |
| 181868 | +){ |
| 181869 | + double y; |
| 181870 | + if( x0==x1 && y0==y1 ) return 2; |
| 181871 | + if( x1<x2 ){ |
| 181872 | + if( x0<=x1 || x0>x2 ) return 0; |
| 181873 | + }else if( x1>x2 ){ |
| 181874 | + if( x0<=x2 || x0>x1 ) return 0; |
| 181875 | + }else{ |
| 181876 | + /* Vertical line segment */ |
| 181877 | + if( x0!=x1 ) return 0; |
| 181878 | + if( y0<y1 && y0<y2 ) return 0; |
| 181879 | + if( y0>y1 && y0>y2 ) return 0; |
| 181880 | + return 2; |
| 181881 | + } |
| 181882 | + y = y1 + (y2-y1)*(x0-x1)/(x2-x1); |
| 181883 | + if( y0==y ) return 2; |
| 181884 | + if( y0<y ) return 1; |
| 181885 | + return 0; |
| 181886 | +} |
| 181887 | + |
| 181888 | +/* |
| 181889 | +** SQL function: geopoly_contains_point(P,X,Y) |
| 181890 | +** |
| 181891 | +** Return +2 if point X,Y is within polygon P. |
| 181892 | +** Return +1 if point X,Y is on the polygon boundary. |
| 181893 | +** Return 0 if point X,Y is outside the polygon |
| 181894 | +*/ |
| 181895 | +static void geopolyContainsPointFunc( |
| 181896 | + sqlite3_context *context, |
| 181897 | + int argc, |
| 181898 | + sqlite3_value **argv |
| 181899 | +){ |
| 181900 | + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); |
| 181901 | + double x0 = sqlite3_value_double(argv[1]); |
| 181902 | + double y0 = sqlite3_value_double(argv[2]); |
| 181903 | + int v = 0; |
| 181904 | + int cnt = 0; |
| 181905 | + int ii; |
| 181906 | + if( p1==0 ) return; |
| 181907 | + for(ii=0; ii<p1->nVertex-1; ii++){ |
| 181908 | + v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], |
| 181909 | + p1->a[ii*2+2],p1->a[ii*2+3]); |
| 181910 | + if( v==2 ) break; |
| 181911 | + cnt += v; |
| 181912 | + } |
| 181913 | + if( v!=2 ){ |
| 181914 | + v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], |
| 181915 | + p1->a[0],p1->a[1]); |
| 181916 | + } |
| 181917 | + if( v==2 ){ |
| 181918 | + sqlite3_result_int(context, 1); |
| 181919 | + }else if( ((v+cnt)&1)==0 ){ |
| 181920 | + sqlite3_result_int(context, 0); |
| 181921 | + }else{ |
| 181922 | + sqlite3_result_int(context, 2); |
| 181923 | + } |
| 181924 | + sqlite3_free(p1); |
| 181925 | +} |
| 181926 | + |
| 181927 | +/* Forward declaration */ |
| 181928 | +static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2); |
| 181929 | + |
| 181930 | +/* |
| 181931 | +** SQL function: geopoly_within(P1,P2) |
| 181932 | +** |
| 181933 | +** Return +2 if P1 and P2 are the same polygon |
| 181934 | +** Return +1 if P2 is contained within P1 |
| 181935 | +** Return 0 if any part of P2 is on the outside of P1 |
| 181936 | +** |
| 181937 | +*/ |
| 181938 | +static void geopolyWithinFunc( |
| 181939 | + sqlite3_context *context, |
| 181940 | + int argc, |
| 181941 | + sqlite3_value **argv |
| 181942 | +){ |
| 181943 | + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); |
| 181944 | + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); |
| 181945 | + if( p1 && p2 ){ |
| 181946 | + int x = geopolyOverlap(p1, p2); |
| 181947 | + if( x<0 ){ |
| 181948 | + sqlite3_result_error_nomem(context); |
| 181949 | + }else{ |
| 181950 | + sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); |
| 181951 | + } |
| 181952 | + } |
| 181953 | + sqlite3_free(p1); |
| 181954 | + sqlite3_free(p2); |
| 181955 | +} |
| 181956 | + |
| 181957 | +/* Objects used by the overlap algorihm. */ |
| 181958 | +typedef struct GeoEvent GeoEvent; |
| 181959 | +typedef struct GeoSegment GeoSegment; |
| 181960 | +typedef struct GeoOverlap GeoOverlap; |
| 181961 | +struct GeoEvent { |
| 181962 | + double x; /* X coordinate at which event occurs */ |
| 181963 | + int eType; /* 0 for ADD, 1 for REMOVE */ |
| 181964 | + GeoSegment *pSeg; /* The segment to be added or removed */ |
| 181965 | + GeoEvent *pNext; /* Next event in the sorted list */ |
| 181966 | +}; |
| 181967 | +struct GeoSegment { |
| 181968 | + double C, B; /* y = C*x + B */ |
| 181969 | + double y; /* Current y value */ |
| 181970 | + float y0; /* Initial y value */ |
| 181971 | + unsigned char side; /* 1 for p1, 2 for p2 */ |
| 181972 | + unsigned int idx; /* Which segment within the side */ |
| 181973 | + GeoSegment *pNext; /* Next segment in a list sorted by y */ |
| 181974 | +}; |
| 181975 | +struct GeoOverlap { |
| 181976 | + GeoEvent *aEvent; /* Array of all events */ |
| 181977 | + GeoSegment *aSegment; /* Array of all segments */ |
| 181978 | + int nEvent; /* Number of events */ |
| 181979 | + int nSegment; /* Number of segments */ |
| 181980 | +}; |
| 181981 | + |
| 181982 | +/* |
| 181983 | +** Add a single segment and its associated events. |
| 181984 | +*/ |
| 181985 | +static void geopolyAddOneSegment( |
| 181986 | + GeoOverlap *p, |
| 181987 | + GeoCoord x0, |
| 181988 | + GeoCoord y0, |
| 181989 | + GeoCoord x1, |
| 181990 | + GeoCoord y1, |
| 181991 | + unsigned char side, |
| 181992 | + unsigned int idx |
| 181993 | +){ |
| 181994 | + GeoSegment *pSeg; |
| 181995 | + GeoEvent *pEvent; |
| 181996 | + if( x0==x1 ) return; /* Ignore vertical segments */ |
| 181997 | + if( x0>x1 ){ |
| 181998 | + GeoCoord t = x0; |
| 181999 | + x0 = x1; |
| 182000 | + x1 = t; |
| 182001 | + t = y0; |
| 182002 | + y0 = y1; |
| 182003 | + y1 = t; |
| 182004 | + } |
| 182005 | + pSeg = p->aSegment + p->nSegment; |
| 182006 | + p->nSegment++; |
| 182007 | + pSeg->C = (y1-y0)/(x1-x0); |
| 182008 | + pSeg->B = y1 - x1*pSeg->C; |
| 182009 | + pSeg->y0 = y0; |
| 182010 | + pSeg->side = side; |
| 182011 | + pSeg->idx = idx; |
| 182012 | + pEvent = p->aEvent + p->nEvent; |
| 182013 | + p->nEvent++; |
| 182014 | + pEvent->x = x0; |
| 182015 | + pEvent->eType = 0; |
| 182016 | + pEvent->pSeg = pSeg; |
| 182017 | + pEvent = p->aEvent + p->nEvent; |
| 182018 | + p->nEvent++; |
| 182019 | + pEvent->x = x1; |
| 182020 | + pEvent->eType = 1; |
| 182021 | + pEvent->pSeg = pSeg; |
| 182022 | +} |
| 182023 | + |
| 182024 | + |
| 182025 | + |
| 182026 | +/* |
| 182027 | +** Insert all segments and events for polygon pPoly. |
| 182028 | +*/ |
| 182029 | +static void geopolyAddSegments( |
| 182030 | + GeoOverlap *p, /* Add segments to this Overlap object */ |
| 182031 | + GeoPoly *pPoly, /* Take all segments from this polygon */ |
| 182032 | + unsigned char side /* The side of pPoly */ |
| 182033 | +){ |
| 182034 | + unsigned int i; |
| 182035 | + GeoCoord *x; |
| 182036 | + for(i=0; i<(unsigned)pPoly->nVertex-1; i++){ |
| 182037 | + x = pPoly->a + (i*2); |
| 182038 | + geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i); |
| 182039 | + } |
| 182040 | + x = pPoly->a + (i*2); |
| 182041 | + geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i); |
| 182042 | +} |
| 182043 | + |
| 182044 | +/* |
| 182045 | +** Merge two lists of sorted events by X coordinate |
| 182046 | +*/ |
| 182047 | +static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){ |
| 182048 | + GeoEvent head, *pLast; |
| 182049 | + head.pNext = 0; |
| 182050 | + pLast = &head; |
| 182051 | + while( pRight && pLeft ){ |
| 182052 | + if( pRight->x <= pLeft->x ){ |
| 182053 | + pLast->pNext = pRight; |
| 182054 | + pLast = pRight; |
| 182055 | + pRight = pRight->pNext; |
| 182056 | + }else{ |
| 182057 | + pLast->pNext = pLeft; |
| 182058 | + pLast = pLeft; |
| 182059 | + pLeft = pLeft->pNext; |
| 182060 | + } |
| 182061 | + } |
| 182062 | + pLast->pNext = pRight ? pRight : pLeft; |
| 182063 | + return head.pNext; |
| 182064 | +} |
| 182065 | + |
| 182066 | +/* |
| 182067 | +** Sort an array of nEvent event objects into a list. |
| 182068 | +*/ |
| 182069 | +static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){ |
| 182070 | + int mx = 0; |
| 182071 | + int i, j; |
| 182072 | + GeoEvent *p; |
| 182073 | + GeoEvent *a[50]; |
| 182074 | + for(i=0; i<nEvent; i++){ |
| 182075 | + p = &aEvent[i]; |
| 182076 | + p->pNext = 0; |
| 182077 | + for(j=0; j<mx && a[j]; j++){ |
| 182078 | + p = geopolyEventMerge(a[j], p); |
| 182079 | + a[j] = 0; |
| 182080 | + } |
| 182081 | + a[j] = p; |
| 182082 | + if( j>=mx ) mx = j+1; |
| 182083 | + } |
| 182084 | + p = 0; |
| 182085 | + for(i=0; i<mx; i++){ |
| 182086 | + p = geopolyEventMerge(a[i], p); |
| 182087 | + } |
| 182088 | + return p; |
| 182089 | +} |
| 182090 | + |
| 182091 | +/* |
| 182092 | +** Merge two lists of sorted segments by Y, and then by C. |
| 182093 | +*/ |
| 182094 | +static GeoSegment *geopolySegmentMerge(GeoSegment *pLeft, GeoSegment *pRight){ |
| 182095 | + GeoSegment head, *pLast; |
| 182096 | + head.pNext = 0; |
| 182097 | + pLast = &head; |
| 182098 | + while( pRight && pLeft ){ |
| 182099 | + double r = pRight->y - pLeft->y; |
| 182100 | + if( r==0.0 ) r = pRight->C - pLeft->C; |
| 182101 | + if( r<0.0 ){ |
| 182102 | + pLast->pNext = pRight; |
| 182103 | + pLast = pRight; |
| 182104 | + pRight = pRight->pNext; |
| 182105 | + }else{ |
| 182106 | + pLast->pNext = pLeft; |
| 182107 | + pLast = pLeft; |
| 182108 | + pLeft = pLeft->pNext; |
| 182109 | + } |
| 182110 | + } |
| 182111 | + pLast->pNext = pRight ? pRight : pLeft; |
| 182112 | + return head.pNext; |
| 182113 | +} |
| 182114 | + |
| 182115 | +/* |
| 182116 | +** Sort a list of GeoSegments in order of increasing Y and in the event of |
| 182117 | +** a tie, increasing C (slope). |
| 182118 | +*/ |
| 182119 | +static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){ |
| 182120 | + int mx = 0; |
| 182121 | + int i; |
| 182122 | + GeoSegment *p; |
| 182123 | + GeoSegment *a[50]; |
| 182124 | + while( pList ){ |
| 182125 | + p = pList; |
| 182126 | + pList = pList->pNext; |
| 182127 | + p->pNext = 0; |
| 182128 | + for(i=0; i<mx && a[i]; i++){ |
| 182129 | + p = geopolySegmentMerge(a[i], p); |
| 182130 | + a[i] = 0; |
| 182131 | + } |
| 182132 | + a[i] = p; |
| 182133 | + if( i>=mx ) mx = i+1; |
| 182134 | + } |
| 182135 | + p = 0; |
| 182136 | + for(i=0; i<mx; i++){ |
| 182137 | + p = geopolySegmentMerge(a[i], p); |
| 182138 | + } |
| 182139 | + return p; |
| 182140 | +} |
| 182141 | + |
| 182142 | +/* |
| 182143 | +** Determine the overlap between two polygons |
| 182144 | +*/ |
| 182145 | +static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ |
| 182146 | + int nVertex = p1->nVertex + p2->nVertex + 2; |
| 182147 | + GeoOverlap *p; |
| 182148 | + int nByte; |
| 182149 | + GeoEvent *pThisEvent; |
| 182150 | + double rX; |
| 182151 | + int rc = 0; |
| 182152 | + int needSort = 0; |
| 182153 | + GeoSegment *pActive = 0; |
| 182154 | + GeoSegment *pSeg; |
| 182155 | + unsigned char aOverlap[4]; |
| 182156 | + |
| 182157 | + nByte = sizeof(GeoEvent)*nVertex*2 |
| 182158 | + + sizeof(GeoSegment)*nVertex |
| 182159 | + + sizeof(GeoOverlap); |
| 182160 | + p = sqlite3_malloc( nByte ); |
| 182161 | + if( p==0 ) return -1; |
| 182162 | + p->aEvent = (GeoEvent*)&p[1]; |
| 182163 | + p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2]; |
| 182164 | + p->nEvent = p->nSegment = 0; |
| 182165 | + geopolyAddSegments(p, p1, 1); |
| 182166 | + geopolyAddSegments(p, p2, 2); |
| 182167 | + pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); |
| 182168 | + rX = pThisEvent->x==0.0 ? -1.0 : 0.0; |
| 182169 | + memset(aOverlap, 0, sizeof(aOverlap)); |
| 182170 | + while( pThisEvent ){ |
| 182171 | + if( pThisEvent->x!=rX ){ |
| 182172 | + GeoSegment *pPrev = 0; |
| 182173 | + int iMask = 0; |
| 182174 | + GEODEBUG(("Distinct X: %g\n", pThisEvent->x)); |
| 182175 | + rX = pThisEvent->x; |
| 182176 | + if( needSort ){ |
| 182177 | + GEODEBUG(("SORT\n")); |
| 182178 | + pActive = geopolySortSegmentsByYAndC(pActive); |
| 182179 | + needSort = 0; |
| 182180 | + } |
| 182181 | + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ |
| 182182 | + if( pPrev ){ |
| 182183 | + if( pPrev->y!=pSeg->y ){ |
| 182184 | + GEODEBUG(("MASK: %d\n", iMask)); |
| 182185 | + aOverlap[iMask] = 1; |
| 182186 | + } |
| 182187 | + } |
| 182188 | + iMask ^= pSeg->side; |
| 182189 | + pPrev = pSeg; |
| 182190 | + } |
| 182191 | + pPrev = 0; |
| 182192 | + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ |
| 182193 | + double y = pSeg->C*rX + pSeg->B; |
| 182194 | + GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y)); |
| 182195 | + pSeg->y = y; |
| 182196 | + if( pPrev ){ |
| 182197 | + if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){ |
| 182198 | + rc = 1; |
| 182199 | + GEODEBUG(("Crossing: %d.%d and %d.%d\n", |
| 182200 | + pPrev->side, pPrev->idx, |
| 182201 | + pSeg->side, pSeg->idx)); |
| 182202 | + goto geopolyOverlapDone; |
| 182203 | + }else if( pPrev->y!=pSeg->y ){ |
| 182204 | + GEODEBUG(("MASK: %d\n", iMask)); |
| 182205 | + aOverlap[iMask] = 1; |
| 182206 | + } |
| 182207 | + } |
| 182208 | + iMask ^= pSeg->side; |
| 182209 | + pPrev = pSeg; |
| 182210 | + } |
| 182211 | + } |
| 182212 | + GEODEBUG(("%s %d.%d C=%g B=%g\n", |
| 182213 | + pThisEvent->eType ? "RM " : "ADD", |
| 182214 | + pThisEvent->pSeg->side, pThisEvent->pSeg->idx, |
| 182215 | + pThisEvent->pSeg->C, |
| 182216 | + pThisEvent->pSeg->B)); |
| 182217 | + if( pThisEvent->eType==0 ){ |
| 182218 | + /* Add a segment */ |
| 182219 | + pSeg = pThisEvent->pSeg; |
| 182220 | + pSeg->y = pSeg->y0; |
| 182221 | + pSeg->pNext = pActive; |
| 182222 | + pActive = pSeg; |
| 182223 | + needSort = 1; |
| 182224 | + }else{ |
| 182225 | + /* Remove a segment */ |
| 182226 | + if( pActive==pThisEvent->pSeg ){ |
| 182227 | + pActive = pActive->pNext; |
| 182228 | + }else{ |
| 182229 | + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ |
| 182230 | + if( pSeg->pNext==pThisEvent->pSeg ){ |
| 182231 | + pSeg->pNext = pSeg->pNext->pNext; |
| 182232 | + break; |
| 182233 | + } |
| 182234 | + } |
| 182235 | + } |
| 182236 | + } |
| 182237 | + pThisEvent = pThisEvent->pNext; |
| 182238 | + } |
| 182239 | + if( aOverlap[3]==0 ){ |
| 182240 | + rc = 0; |
| 182241 | + }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){ |
| 182242 | + rc = 3; |
| 182243 | + }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){ |
| 182244 | + rc = 2; |
| 182245 | + }else if( aOverlap[1]==0 && aOverlap[2]==0 ){ |
| 182246 | + rc = 4; |
| 182247 | + }else{ |
| 182248 | + rc = 1; |
| 182249 | + } |
| 182250 | + |
| 182251 | +geopolyOverlapDone: |
| 182252 | + sqlite3_free(p); |
| 182253 | + return rc; |
| 182254 | +} |
| 182255 | + |
| 182256 | +/* |
| 182257 | +** SQL function: geopoly_overlap(P1,P2) |
| 182258 | +** |
| 182259 | +** Determine whether or not P1 and P2 overlap. Return value: |
| 182260 | +** |
| 182261 | +** 0 The two polygons are disjoint |
| 182262 | +** 1 They overlap |
| 182263 | +** 2 P1 is completely contained within P2 |
| 182264 | +** 3 P2 is completely contained within P1 |
| 182265 | +** 4 P1 and P2 are the same polygon |
| 182266 | +** NULL Either P1 or P2 or both are not valid polygons |
| 182267 | +*/ |
| 182268 | +static void geopolyOverlapFunc( |
| 182269 | + sqlite3_context *context, |
| 182270 | + int argc, |
| 182271 | + sqlite3_value **argv |
| 182272 | +){ |
| 182273 | + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); |
| 182274 | + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); |
| 182275 | + if( p1 && p2 ){ |
| 182276 | + int x = geopolyOverlap(p1, p2); |
| 182277 | + if( x<0 ){ |
| 182278 | + sqlite3_result_error_nomem(context); |
| 182279 | + }else{ |
| 182280 | + sqlite3_result_int(context, x); |
| 182281 | + } |
| 182282 | + } |
| 182283 | + sqlite3_free(p1); |
| 182284 | + sqlite3_free(p2); |
| 182285 | +} |
| 182286 | + |
| 182287 | +/* |
| 182288 | +** Enable or disable debugging output |
| 182289 | +*/ |
| 182290 | +static void geopolyDebugFunc( |
| 182291 | + sqlite3_context *context, |
| 182292 | + int argc, |
| 182293 | + sqlite3_value **argv |
| 182294 | +){ |
| 182295 | +#ifdef GEOPOLY_ENABLE_DEBUG |
| 182296 | + geo_debug = sqlite3_value_int(argv[0]); |
| 182297 | +#endif |
| 182298 | +} |
| 182299 | + |
| 182300 | +/* |
| 182301 | +** This function is the implementation of both the xConnect and xCreate |
| 182302 | +** methods of the geopoly virtual table. |
| 182303 | +** |
| 182304 | +** argv[0] -> module name |
| 182305 | +** argv[1] -> database name |
| 182306 | +** argv[2] -> table name |
| 182307 | +** argv[...] -> column names... |
| 182308 | +*/ |
| 182309 | +static int geopolyInit( |
| 182310 | + sqlite3 *db, /* Database connection */ |
| 182311 | + void *pAux, /* One of the RTREE_COORD_* constants */ |
| 182312 | + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ |
| 182313 | + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ |
| 182314 | + char **pzErr, /* OUT: Error message, if any */ |
| 182315 | + int isCreate /* True for xCreate, false for xConnect */ |
| 182316 | +){ |
| 182317 | + int rc = SQLITE_OK; |
| 182318 | + Rtree *pRtree; |
| 182319 | + int nDb; /* Length of string argv[1] */ |
| 182320 | + int nName; /* Length of string argv[2] */ |
| 182321 | + sqlite3_str *pSql; |
| 182322 | + char *zSql; |
| 182323 | + int ii; |
| 182324 | + |
| 182325 | + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); |
| 182326 | + |
| 182327 | + /* Allocate the sqlite3_vtab structure */ |
| 182328 | + nDb = (int)strlen(argv[1]); |
| 182329 | + nName = (int)strlen(argv[2]); |
| 182330 | + pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); |
| 182331 | + if( !pRtree ){ |
| 182332 | + return SQLITE_NOMEM; |
| 182333 | + } |
| 182334 | + memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); |
| 182335 | + pRtree->nBusy = 1; |
| 182336 | + pRtree->base.pModule = &rtreeModule; |
| 182337 | + pRtree->zDb = (char *)&pRtree[1]; |
| 182338 | + pRtree->zName = &pRtree->zDb[nDb+1]; |
| 182339 | + pRtree->eCoordType = RTREE_COORD_REAL32; |
| 182340 | + pRtree->nDim = 2; |
| 182341 | + pRtree->nDim2 = 4; |
| 182342 | + memcpy(pRtree->zDb, argv[1], nDb); |
| 182343 | + memcpy(pRtree->zName, argv[2], nName); |
| 182344 | + |
| 182345 | + |
| 182346 | + /* Create/Connect to the underlying relational database schema. If |
| 182347 | + ** that is successful, call sqlite3_declare_vtab() to configure |
| 182348 | + ** the r-tree table schema. |
| 182349 | + */ |
| 182350 | + pSql = sqlite3_str_new(db); |
| 182351 | + sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); |
| 182352 | + pRtree->nAux = 1; /* Add one for _shape */ |
| 182353 | + pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ |
| 182354 | + for(ii=3; ii<argc; ii++){ |
| 182355 | + pRtree->nAux++; |
| 182356 | + sqlite3_str_appendf(pSql, ",%s", argv[ii]); |
| 182357 | + } |
| 182358 | + sqlite3_str_appendf(pSql, ");"); |
| 182359 | + zSql = sqlite3_str_finish(pSql); |
| 182360 | + if( !zSql ){ |
| 182361 | + rc = SQLITE_NOMEM; |
| 182362 | + }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ |
| 182363 | + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |
| 182364 | + } |
| 182365 | + sqlite3_free(zSql); |
| 182366 | + if( rc ) goto geopolyInit_fail; |
| 182367 | + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; |
| 182368 | + |
| 182369 | + /* Figure out the node size to use. */ |
| 182370 | + rc = getNodeSize(db, pRtree, isCreate, pzErr); |
| 182371 | + if( rc ) goto geopolyInit_fail; |
| 182372 | + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); |
| 182373 | + if( rc ){ |
| 182374 | + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |
| 182375 | + goto geopolyInit_fail; |
| 182376 | + } |
| 182377 | + |
| 182378 | + *ppVtab = (sqlite3_vtab *)pRtree; |
| 182379 | + return SQLITE_OK; |
| 182380 | + |
| 182381 | +geopolyInit_fail: |
| 182382 | + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; |
| 182383 | + assert( *ppVtab==0 ); |
| 182384 | + assert( pRtree->nBusy==1 ); |
| 182385 | + rtreeRelease(pRtree); |
| 182386 | + return rc; |
| 182387 | +} |
| 182388 | + |
| 182389 | + |
| 182390 | +/* |
| 182391 | +** GEOPOLY virtual table module xCreate method. |
| 182392 | +*/ |
| 182393 | +static int geopolyCreate( |
| 182394 | + sqlite3 *db, |
| 182395 | + void *pAux, |
| 182396 | + int argc, const char *const*argv, |
| 182397 | + sqlite3_vtab **ppVtab, |
| 182398 | + char **pzErr |
| 182399 | +){ |
| 182400 | + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1); |
| 182401 | +} |
| 182402 | + |
| 182403 | +/* |
| 182404 | +** GEOPOLY virtual table module xConnect method. |
| 182405 | +*/ |
| 182406 | +static int geopolyConnect( |
| 182407 | + sqlite3 *db, |
| 182408 | + void *pAux, |
| 182409 | + int argc, const char *const*argv, |
| 182410 | + sqlite3_vtab **ppVtab, |
| 182411 | + char **pzErr |
| 182412 | +){ |
| 182413 | + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0); |
| 182414 | +} |
| 182415 | + |
| 182416 | + |
| 182417 | +/* |
| 182418 | +** GEOPOLY virtual table module xFilter method. |
| 182419 | +** |
| 182420 | +** Query plans: |
| 182421 | +** |
| 182422 | +** 1 rowid lookup |
| 182423 | +** 2 search for objects overlapping the same bounding box |
| 182424 | +** that contains polygon argv[0] |
| 182425 | +** 3 search for objects overlapping the same bounding box |
| 182426 | +** that contains polygon argv[0] |
| 182427 | +** 4 full table scan |
| 182428 | +*/ |
| 182429 | +static int geopolyFilter( |
| 182430 | + sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ |
| 182431 | + int idxNum, /* Query plan */ |
| 182432 | + const char *idxStr, /* Not Used */ |
| 182433 | + int argc, sqlite3_value **argv /* Parameters to the query plan */ |
| 182434 | +){ |
| 182435 | + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; |
| 182436 | + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; |
| 182437 | + RtreeNode *pRoot = 0; |
| 182438 | + int rc = SQLITE_OK; |
| 182439 | + int iCell = 0; |
| 182440 | + sqlite3_stmt *pStmt; |
| 182441 | + |
| 182442 | + rtreeReference(pRtree); |
| 182443 | + |
| 182444 | + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ |
| 182445 | + freeCursorConstraints(pCsr); |
| 182446 | + sqlite3_free(pCsr->aPoint); |
| 182447 | + pStmt = pCsr->pReadAux; |
| 182448 | + memset(pCsr, 0, sizeof(RtreeCursor)); |
| 182449 | + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; |
| 182450 | + pCsr->pReadAux = pStmt; |
| 182451 | + |
| 182452 | + pCsr->iStrategy = idxNum; |
| 182453 | + if( idxNum==1 ){ |
| 182454 | + /* Special case - lookup by rowid. */ |
| 182455 | + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ |
| 182456 | + RtreeSearchPoint *p; /* Search point for the leaf */ |
| 182457 | + i64 iRowid = sqlite3_value_int64(argv[0]); |
| 182458 | + i64 iNode = 0; |
| 182459 | + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); |
| 182460 | + if( rc==SQLITE_OK && pLeaf!=0 ){ |
| 182461 | + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); |
| 182462 | + assert( p!=0 ); /* Always returns pCsr->sPoint */ |
| 182463 | + pCsr->aNode[0] = pLeaf; |
| 182464 | + p->id = iNode; |
| 182465 | + p->eWithin = PARTLY_WITHIN; |
| 182466 | + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); |
| 182467 | + p->iCell = (u8)iCell; |
| 182468 | + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); |
| 182469 | + }else{ |
| 182470 | + pCsr->atEOF = 1; |
| 182471 | + } |
| 182472 | + }else{ |
| 182473 | + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array |
| 182474 | + ** with the configured constraints. |
| 182475 | + */ |
| 182476 | + rc = nodeAcquire(pRtree, 1, 0, &pRoot); |
| 182477 | + if( rc==SQLITE_OK && idxNum<=3 ){ |
| 182478 | + RtreeCoord bbox[4]; |
| 182479 | + RtreeConstraint *p; |
| 182480 | + assert( argc==1 ); |
| 182481 | + geopolyBBox(0, argv[0], bbox, &rc); |
| 182482 | + if( rc ){ |
| 182483 | + goto geopoly_filter_end; |
| 182484 | + } |
| 182485 | + pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); |
| 182486 | + pCsr->nConstraint = 4; |
| 182487 | + if( p==0 ){ |
| 182488 | + rc = SQLITE_NOMEM; |
| 182489 | + }else{ |
| 182490 | + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4); |
| 182491 | + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); |
| 182492 | + if( idxNum==2 ){ |
| 182493 | + /* Overlap query */ |
| 182494 | + p->op = 'B'; |
| 182495 | + p->iCoord = 0; |
| 182496 | + p->u.rValue = bbox[1].f; |
| 182497 | + p++; |
| 182498 | + p->op = 'D'; |
| 182499 | + p->iCoord = 1; |
| 182500 | + p->u.rValue = bbox[0].f; |
| 182501 | + p++; |
| 182502 | + p->op = 'B'; |
| 182503 | + p->iCoord = 2; |
| 182504 | + p->u.rValue = bbox[3].f; |
| 182505 | + p++; |
| 182506 | + p->op = 'D'; |
| 182507 | + p->iCoord = 3; |
| 182508 | + p->u.rValue = bbox[2].f; |
| 182509 | + }else{ |
| 182510 | + /* Within query */ |
| 182511 | + p->op = 'D'; |
| 182512 | + p->iCoord = 0; |
| 182513 | + p->u.rValue = bbox[0].f; |
| 182514 | + p++; |
| 182515 | + p->op = 'B'; |
| 182516 | + p->iCoord = 1; |
| 182517 | + p->u.rValue = bbox[1].f; |
| 182518 | + p++; |
| 182519 | + p->op = 'D'; |
| 182520 | + p->iCoord = 2; |
| 182521 | + p->u.rValue = bbox[2].f; |
| 182522 | + p++; |
| 182523 | + p->op = 'B'; |
| 182524 | + p->iCoord = 3; |
| 182525 | + p->u.rValue = bbox[3].f; |
| 182526 | + } |
| 182527 | + } |
| 182528 | + } |
| 182529 | + if( rc==SQLITE_OK ){ |
| 182530 | + RtreeSearchPoint *pNew; |
| 182531 | + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); |
| 182532 | + if( pNew==0 ){ |
| 182533 | + rc = SQLITE_NOMEM; |
| 182534 | + goto geopoly_filter_end; |
| 182535 | + } |
| 182536 | + pNew->id = 1; |
| 182537 | + pNew->iCell = 0; |
| 182538 | + pNew->eWithin = PARTLY_WITHIN; |
| 182539 | + assert( pCsr->bPoint==1 ); |
| 182540 | + pCsr->aNode[0] = pRoot; |
| 182541 | + pRoot = 0; |
| 182542 | + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); |
| 182543 | + rc = rtreeStepToLeaf(pCsr); |
| 182544 | + } |
| 182545 | + } |
| 182546 | + |
| 182547 | +geopoly_filter_end: |
| 182548 | + nodeRelease(pRtree, pRoot); |
| 182549 | + rtreeRelease(pRtree); |
| 182550 | + return rc; |
| 182551 | +} |
| 182552 | + |
| 182553 | +/* |
| 182554 | +** Rtree virtual table module xBestIndex method. There are three |
| 182555 | +** table scan strategies to choose from (in order from most to |
| 182556 | +** least desirable): |
| 182557 | +** |
| 182558 | +** idxNum idxStr Strategy |
| 182559 | +** ------------------------------------------------ |
| 182560 | +** 1 "rowid" Direct lookup by rowid. |
| 182561 | +** 2 "rtree" R-tree overlap query using geopoly_overlap() |
| 182562 | +** 3 "rtree" R-tree within query using geopoly_within() |
| 182563 | +** 4 "fullscan" full-table scan. |
| 182564 | +** ------------------------------------------------ |
| 182565 | +*/ |
| 182566 | +static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
| 182567 | + int ii; |
| 182568 | + int iRowidTerm = -1; |
| 182569 | + int iFuncTerm = -1; |
| 182570 | + int idxNum = 0; |
| 182571 | + |
| 182572 | + for(ii=0; ii<pIdxInfo->nConstraint; ii++){ |
| 182573 | + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; |
| 182574 | + if( !p->usable ) continue; |
| 182575 | + if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
| 182576 | + iRowidTerm = ii; |
| 182577 | + break; |
| 182578 | + } |
| 182579 | + if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ |
| 182580 | + /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap() |
| 182581 | + ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within(). |
| 182582 | + ** See geopolyFindFunction() */ |
| 182583 | + iFuncTerm = ii; |
| 182584 | + idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2; |
| 182585 | + } |
| 182586 | + } |
| 182587 | + |
| 182588 | + if( iRowidTerm>=0 ){ |
| 182589 | + pIdxInfo->idxNum = 1; |
| 182590 | + pIdxInfo->idxStr = "rowid"; |
| 182591 | + pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; |
| 182592 | + pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; |
| 182593 | + pIdxInfo->estimatedCost = 30.0; |
| 182594 | + pIdxInfo->estimatedRows = 1; |
| 182595 | + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; |
| 182596 | + return SQLITE_OK; |
| 182597 | + } |
| 182598 | + if( iFuncTerm>=0 ){ |
| 182599 | + pIdxInfo->idxNum = idxNum; |
| 182600 | + pIdxInfo->idxStr = "rtree"; |
| 182601 | + pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1; |
| 182602 | + pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0; |
| 182603 | + pIdxInfo->estimatedCost = 300.0; |
| 182604 | + pIdxInfo->estimatedRows = 10; |
| 182605 | + return SQLITE_OK; |
| 182606 | + } |
| 182607 | + pIdxInfo->idxNum = 4; |
| 182608 | + pIdxInfo->idxStr = "fullscan"; |
| 182609 | + pIdxInfo->estimatedCost = 3000000.0; |
| 182610 | + pIdxInfo->estimatedRows = 100000; |
| 182611 | + return SQLITE_OK; |
| 182612 | +} |
| 182613 | + |
| 182614 | + |
| 182615 | +/* |
| 182616 | +** GEOPOLY virtual table module xColumn method. |
| 182617 | +*/ |
| 182618 | +static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |
| 182619 | + Rtree *pRtree = (Rtree *)cur->pVtab; |
| 182620 | + RtreeCursor *pCsr = (RtreeCursor *)cur; |
| 182621 | + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); |
| 182622 | + int rc = SQLITE_OK; |
| 182623 | + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); |
| 182624 | + |
| 182625 | + if( rc ) return rc; |
| 182626 | + if( p==0 ) return SQLITE_OK; |
| 182627 | + if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; |
| 182628 | + if( i<=pRtree->nAux ){ |
| 182629 | + if( !pCsr->bAuxValid ){ |
| 182630 | + if( pCsr->pReadAux==0 ){ |
| 182631 | + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, |
| 182632 | + &pCsr->pReadAux, 0); |
| 182633 | + if( rc ) return rc; |
| 182634 | + } |
| 182635 | + sqlite3_bind_int64(pCsr->pReadAux, 1, |
| 182636 | + nodeGetRowid(pRtree, pNode, p->iCell)); |
| 182637 | + rc = sqlite3_step(pCsr->pReadAux); |
| 182638 | + if( rc==SQLITE_ROW ){ |
| 182639 | + pCsr->bAuxValid = 1; |
| 182640 | + }else{ |
| 182641 | + sqlite3_reset(pCsr->pReadAux); |
| 182642 | + if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 182643 | + return rc; |
| 182644 | + } |
| 182645 | + } |
| 182646 | + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2)); |
| 182647 | + } |
| 182648 | + return SQLITE_OK; |
| 182649 | +} |
| 182650 | + |
| 182651 | + |
| 182652 | +/* |
| 182653 | +** The xUpdate method for GEOPOLY module virtual tables. |
| 182654 | +** |
| 182655 | +** For DELETE: |
| 182656 | +** |
| 182657 | +** argv[0] = the rowid to be deleted |
| 182658 | +** |
| 182659 | +** For INSERT: |
| 182660 | +** |
| 182661 | +** argv[0] = SQL NULL |
| 182662 | +** argv[1] = rowid to insert, or an SQL NULL to select automatically |
| 182663 | +** argv[2] = _shape column |
| 182664 | +** argv[3] = first application-defined column.... |
| 182665 | +** |
| 182666 | +** For UPDATE: |
| 182667 | +** |
| 182668 | +** argv[0] = rowid to modify. Never NULL |
| 182669 | +** argv[1] = rowid after the change. Never NULL |
| 182670 | +** argv[2] = new value for _shape |
| 182671 | +** argv[3] = new value for first application-defined column.... |
| 182672 | +*/ |
| 182673 | +static int geopolyUpdate( |
| 182674 | + sqlite3_vtab *pVtab, |
| 182675 | + int nData, |
| 182676 | + sqlite3_value **aData, |
| 182677 | + sqlite_int64 *pRowid |
| 182678 | +){ |
| 182679 | + Rtree *pRtree = (Rtree *)pVtab; |
| 182680 | + int rc = SQLITE_OK; |
| 182681 | + RtreeCell cell; /* New cell to insert if nData>1 */ |
| 182682 | + i64 oldRowid; /* The old rowid */ |
| 182683 | + int oldRowidValid; /* True if oldRowid is valid */ |
| 182684 | + i64 newRowid; /* The new rowid */ |
| 182685 | + int newRowidValid; /* True if newRowid is valid */ |
| 182686 | + int coordChange = 0; /* Change in coordinates */ |
| 182687 | + |
| 182688 | + if( pRtree->nNodeRef ){ |
| 182689 | + /* Unable to write to the btree while another cursor is reading from it, |
| 182690 | + ** since the write might do a rebalance which would disrupt the read |
| 182691 | + ** cursor. */ |
| 182692 | + return SQLITE_LOCKED_VTAB; |
| 182693 | + } |
| 182694 | + rtreeReference(pRtree); |
| 182695 | + assert(nData>=1); |
| 182696 | + |
| 182697 | + oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; |
| 182698 | + oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; |
| 182699 | + newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; |
| 182700 | + newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; |
| 182701 | + cell.iRowid = newRowid; |
| 182702 | + |
| 182703 | + if( nData>1 /* not a DELETE */ |
| 182704 | + && (!oldRowidValid /* INSERT */ |
| 182705 | + || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ |
| 182706 | + || oldRowid!=newRowid) /* Rowid change */ |
| 182707 | + ){ |
| 182708 | + geopolyBBox(0, aData[2], cell.aCoord, &rc); |
| 182709 | + if( rc ){ |
| 182710 | + if( rc==SQLITE_ERROR ){ |
| 182711 | + pVtab->zErrMsg = |
| 182712 | + sqlite3_mprintf("_shape does not contain a valid polygon"); |
| 182713 | + } |
| 182714 | + goto geopoly_update_end; |
| 182715 | + } |
| 182716 | + coordChange = 1; |
| 182717 | + |
| 182718 | + /* If a rowid value was supplied, check if it is already present in |
| 182719 | + ** the table. If so, the constraint has failed. */ |
| 182720 | + if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ |
| 182721 | + int steprc; |
| 182722 | + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); |
| 182723 | + steprc = sqlite3_step(pRtree->pReadRowid); |
| 182724 | + rc = sqlite3_reset(pRtree->pReadRowid); |
| 182725 | + if( SQLITE_ROW==steprc ){ |
| 182726 | + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ |
| 182727 | + rc = rtreeDeleteRowid(pRtree, cell.iRowid); |
| 182728 | + }else{ |
| 182729 | + rc = rtreeConstraintError(pRtree, 0); |
| 182730 | + } |
| 182731 | + } |
| 182732 | + } |
| 182733 | + } |
| 182734 | + |
| 182735 | + /* If aData[0] is not an SQL NULL value, it is the rowid of a |
| 182736 | + ** record to delete from the r-tree table. The following block does |
| 182737 | + ** just that. |
| 182738 | + */ |
| 182739 | + if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){ |
| 182740 | + rc = rtreeDeleteRowid(pRtree, oldRowid); |
| 182741 | + } |
| 182742 | + |
| 182743 | + /* If the aData[] array contains more than one element, elements |
| 182744 | + ** (aData[2]..aData[argc-1]) contain a new record to insert into |
| 182745 | + ** the r-tree structure. |
| 182746 | + */ |
| 182747 | + if( rc==SQLITE_OK && nData>1 && coordChange ){ |
| 182748 | + /* Insert the new record into the r-tree */ |
| 182749 | + RtreeNode *pLeaf = 0; |
| 182750 | + if( !newRowidValid ){ |
| 182751 | + rc = rtreeNewRowid(pRtree, &cell.iRowid); |
| 182752 | + } |
| 182753 | + *pRowid = cell.iRowid; |
| 182754 | + if( rc==SQLITE_OK ){ |
| 182755 | + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); |
| 182756 | + } |
| 182757 | + if( rc==SQLITE_OK ){ |
| 182758 | + int rc2; |
| 182759 | + pRtree->iReinsertHeight = -1; |
| 182760 | + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); |
| 182761 | + rc2 = nodeRelease(pRtree, pLeaf); |
| 182762 | + if( rc==SQLITE_OK ){ |
| 182763 | + rc = rc2; |
| 182764 | + } |
| 182765 | + } |
| 182766 | + } |
| 182767 | + |
| 182768 | + /* Change the data */ |
| 182769 | + if( rc==SQLITE_OK ){ |
| 182770 | + sqlite3_stmt *pUp = pRtree->pWriteAux; |
| 182771 | + int jj; |
| 182772 | + int nChange = 0; |
| 182773 | + sqlite3_bind_int64(pUp, 1, cell.iRowid); |
| 182774 | + assert( pRtree->nAux>=1 ); |
| 182775 | + if( sqlite3_value_nochange(aData[2]) ){ |
| 182776 | + sqlite3_bind_null(pUp, 2); |
| 182777 | + }else{ |
| 182778 | + sqlite3_bind_value(pUp, 2, aData[2]); |
| 182779 | + nChange = 1; |
| 182780 | + } |
| 182781 | + for(jj=1; jj<pRtree->nAux; jj++){ |
| 182782 | + nChange++; |
| 182783 | + sqlite3_bind_value(pUp, jj+2, aData[jj+2]); |
| 182784 | + } |
| 182785 | + if( nChange ){ |
| 182786 | + sqlite3_step(pUp); |
| 182787 | + rc = sqlite3_reset(pUp); |
| 182788 | + } |
| 182789 | + } |
| 182790 | + |
| 182791 | +geopoly_update_end: |
| 182792 | + rtreeRelease(pRtree); |
| 182793 | + return rc; |
| 182794 | +} |
| 182795 | + |
| 182796 | +/* |
| 182797 | +** Report that geopoly_overlap() is an overloaded function suitable |
| 182798 | +** for use in xBestIndex. |
| 182799 | +*/ |
| 182800 | +static int geopolyFindFunction( |
| 182801 | + sqlite3_vtab *pVtab, |
| 182802 | + int nArg, |
| 182803 | + const char *zName, |
| 182804 | + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), |
| 182805 | + void **ppArg |
| 182806 | +){ |
| 182807 | + if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ |
| 182808 | + *pxFunc = geopolyOverlapFunc; |
| 182809 | + *ppArg = 0; |
| 182810 | + return SQLITE_INDEX_CONSTRAINT_FUNCTION; |
| 182811 | + } |
| 182812 | + if( sqlite3_stricmp(zName, "geopoly_within")==0 ){ |
| 182813 | + *pxFunc = geopolyWithinFunc; |
| 182814 | + *ppArg = 0; |
| 182815 | + return SQLITE_INDEX_CONSTRAINT_FUNCTION+1; |
| 182816 | + } |
| 182817 | + return 0; |
| 182818 | +} |
| 182819 | + |
| 182820 | + |
| 182821 | +static sqlite3_module geopolyModule = { |
| 182822 | + 2, /* iVersion */ |
| 182823 | + geopolyCreate, /* xCreate - create a table */ |
| 182824 | + geopolyConnect, /* xConnect - connect to an existing table */ |
| 182825 | + geopolyBestIndex, /* xBestIndex - Determine search strategy */ |
| 182826 | + rtreeDisconnect, /* xDisconnect - Disconnect from a table */ |
| 182827 | + rtreeDestroy, /* xDestroy - Drop a table */ |
| 182828 | + rtreeOpen, /* xOpen - open a cursor */ |
| 182829 | + rtreeClose, /* xClose - close a cursor */ |
| 182830 | + geopolyFilter, /* xFilter - configure scan constraints */ |
| 182831 | + rtreeNext, /* xNext - advance a cursor */ |
| 182832 | + rtreeEof, /* xEof */ |
| 182833 | + geopolyColumn, /* xColumn - read data */ |
| 182834 | + rtreeRowid, /* xRowid - read data */ |
| 182835 | + geopolyUpdate, /* xUpdate - write data */ |
| 182836 | + rtreeBeginTransaction, /* xBegin - begin transaction */ |
| 182837 | + rtreeEndTransaction, /* xSync - sync transaction */ |
| 182838 | + rtreeEndTransaction, /* xCommit - commit transaction */ |
| 182839 | + rtreeEndTransaction, /* xRollback - rollback transaction */ |
| 182840 | + geopolyFindFunction, /* xFindFunction - function overloading */ |
| 182841 | + rtreeRename, /* xRename - rename the table */ |
| 182842 | + rtreeSavepoint, /* xSavepoint */ |
| 182843 | + 0, /* xRelease */ |
| 182844 | + 0, /* xRollbackTo */ |
| 182845 | +}; |
| 182846 | + |
| 182847 | +static int sqlite3_geopoly_init(sqlite3 *db){ |
| 182848 | + int rc = SQLITE_OK; |
| 182849 | + static const struct { |
| 182850 | + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); |
| 182851 | + int nArg; |
| 182852 | + const char *zName; |
| 182853 | + } aFunc[] = { |
| 182854 | + { geopolyAreaFunc, 1, "geopoly_area" }, |
| 182855 | + { geopolyBlobFunc, 1, "geopoly_blob" }, |
| 182856 | + { geopolyJsonFunc, 1, "geopoly_json" }, |
| 182857 | + { geopolySvgFunc, -1, "geopoly_svg" }, |
| 182858 | + { geopolyWithinFunc, 2, "geopoly_within" }, |
| 182859 | + { geopolyContainsPointFunc, 3, "geopoly_contains_point" }, |
| 182860 | + { geopolyOverlapFunc, 2, "geopoly_overlap" }, |
| 182861 | + { geopolyDebugFunc, 1, "geopoly_debug" }, |
| 182862 | + { geopolyBBoxFunc, 1, "geopoly_bbox" }, |
| 182863 | + { geopolyXformFunc, 7, "geopoly_xform" }, |
| 182864 | + }; |
| 182865 | + static const struct { |
| 182866 | + void (*xStep)(sqlite3_context*,int,sqlite3_value**); |
| 182867 | + void (*xFinal)(sqlite3_context*); |
| 182868 | + const char *zName; |
| 182869 | + } aAgg[] = { |
| 182870 | + { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, |
| 182871 | + }; |
| 182872 | + int i; |
| 182873 | + for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ |
| 182874 | + rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, |
| 182875 | + SQLITE_UTF8, 0, |
| 182876 | + aFunc[i].xFunc, 0, 0); |
| 182877 | + } |
| 182878 | + for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ |
| 182879 | + rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0, |
| 182880 | + 0, aAgg[i].xStep, aAgg[i].xFinal); |
| 182881 | + } |
| 182882 | + if( rc==SQLITE_OK ){ |
| 182883 | + rc = sqlite3_create_module_v2(db, "geopoly", &geopolyModule, 0, 0); |
| 182884 | + } |
| 182885 | + return rc; |
| 182886 | +} |
| 182887 | + |
| 182888 | +/************** End of geopoly.c *********************************************/ |
| 182889 | +/************** Continuing where we left off in rtree.c **********************/ |
| 182890 | +#endif |
| 178593 | 182891 | |
| 178594 | 182892 | /* |
| 178595 | 182893 | ** Register the r-tree module with database handle db. This creates the |
| 178596 | 182894 | ** virtual table module "rtree" and the debugging/analysis scalar |
| 178597 | 182895 | ** function "rtreenode". |
| | @@ -178617,10 +182915,15 @@ |
| 178617 | 182915 | } |
| 178618 | 182916 | if( rc==SQLITE_OK ){ |
| 178619 | 182917 | void *c = (void *)RTREE_COORD_INT32; |
| 178620 | 182918 | rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); |
| 178621 | 182919 | } |
| 182920 | +#ifdef SQLITE_ENABLE_GEOPOLY |
| 182921 | + if( rc==SQLITE_OK ){ |
| 182922 | + rc = sqlite3_geopoly_init(db); |
| 182923 | + } |
| 182924 | +#endif |
| 178622 | 182925 | |
| 178623 | 182926 | return rc; |
| 178624 | 182927 | } |
| 178625 | 182928 | |
| 178626 | 182929 | /* |
| | @@ -191579,2506 +195882,10 @@ |
| 191579 | 195882 | } |
| 191580 | 195883 | |
| 191581 | 195884 | #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ |
| 191582 | 195885 | |
| 191583 | 195886 | /************** End of sqlite3session.c **************************************/ |
| 191584 | | -/************** Begin file json1.c *******************************************/ |
| 191585 | | -/* |
| 191586 | | -** 2015-08-12 |
| 191587 | | -** |
| 191588 | | -** The author disclaims copyright to this source code. In place of |
| 191589 | | -** a legal notice, here is a blessing: |
| 191590 | | -** |
| 191591 | | -** May you do good and not evil. |
| 191592 | | -** May you find forgiveness for yourself and forgive others. |
| 191593 | | -** May you share freely, never taking more than you give. |
| 191594 | | -** |
| 191595 | | -****************************************************************************** |
| 191596 | | -** |
| 191597 | | -** This SQLite extension implements JSON functions. The interface is |
| 191598 | | -** modeled after MySQL JSON functions: |
| 191599 | | -** |
| 191600 | | -** https://dev.mysql.com/doc/refman/5.7/en/json.html |
| 191601 | | -** |
| 191602 | | -** For the time being, all JSON is stored as pure text. (We might add |
| 191603 | | -** a JSONB type in the future which stores a binary encoding of JSON in |
| 191604 | | -** a BLOB, but there is no support for JSONB in the current implementation. |
| 191605 | | -** This implementation parses JSON text at 250 MB/s, so it is hard to see |
| 191606 | | -** how JSONB might improve on that.) |
| 191607 | | -*/ |
| 191608 | | -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) |
| 191609 | | -#if !defined(SQLITEINT_H) |
| 191610 | | -/* #include "sqlite3ext.h" */ |
| 191611 | | -#endif |
| 191612 | | -SQLITE_EXTENSION_INIT1 |
| 191613 | | -/* #include <assert.h> */ |
| 191614 | | -/* #include <string.h> */ |
| 191615 | | -/* #include <stdlib.h> */ |
| 191616 | | -/* #include <stdarg.h> */ |
| 191617 | | - |
| 191618 | | -/* Mark a function parameter as unused, to suppress nuisance compiler |
| 191619 | | -** warnings. */ |
| 191620 | | -#ifndef UNUSED_PARAM |
| 191621 | | -# define UNUSED_PARAM(X) (void)(X) |
| 191622 | | -#endif |
| 191623 | | - |
| 191624 | | -#ifndef LARGEST_INT64 |
| 191625 | | -# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) |
| 191626 | | -# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) |
| 191627 | | -#endif |
| 191628 | | - |
| 191629 | | -/* |
| 191630 | | -** Versions of isspace(), isalnum() and isdigit() to which it is safe |
| 191631 | | -** to pass signed char values. |
| 191632 | | -*/ |
| 191633 | | -#ifdef sqlite3Isdigit |
| 191634 | | - /* Use the SQLite core versions if this routine is part of the |
| 191635 | | - ** SQLite amalgamation */ |
| 191636 | | -# define safe_isdigit(x) sqlite3Isdigit(x) |
| 191637 | | -# define safe_isalnum(x) sqlite3Isalnum(x) |
| 191638 | | -# define safe_isxdigit(x) sqlite3Isxdigit(x) |
| 191639 | | -#else |
| 191640 | | - /* Use the standard library for separate compilation */ |
| 191641 | | -#include <ctype.h> /* amalgamator: keep */ |
| 191642 | | -# define safe_isdigit(x) isdigit((unsigned char)(x)) |
| 191643 | | -# define safe_isalnum(x) isalnum((unsigned char)(x)) |
| 191644 | | -# define safe_isxdigit(x) isxdigit((unsigned char)(x)) |
| 191645 | | -#endif |
| 191646 | | - |
| 191647 | | -/* |
| 191648 | | -** Growing our own isspace() routine this way is twice as fast as |
| 191649 | | -** the library isspace() function, resulting in a 7% overall performance |
| 191650 | | -** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). |
| 191651 | | -*/ |
| 191652 | | -static const char jsonIsSpace[] = { |
| 191653 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, |
| 191654 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191655 | | - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191656 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191657 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191658 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191659 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191660 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191661 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191662 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191663 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191664 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191665 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191666 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191667 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191668 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 191669 | | -}; |
| 191670 | | -#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) |
| 191671 | | - |
| 191672 | | -#ifndef SQLITE_AMALGAMATION |
| 191673 | | - /* Unsigned integer types. These are already defined in the sqliteInt.h, |
| 191674 | | - ** but the definitions need to be repeated for separate compilation. */ |
| 191675 | | - typedef sqlite3_uint64 u64; |
| 191676 | | - typedef unsigned int u32; |
| 191677 | | - typedef unsigned short int u16; |
| 191678 | | - typedef unsigned char u8; |
| 191679 | | -#endif |
| 191680 | | - |
| 191681 | | -/* Objects */ |
| 191682 | | -typedef struct JsonString JsonString; |
| 191683 | | -typedef struct JsonNode JsonNode; |
| 191684 | | -typedef struct JsonParse JsonParse; |
| 191685 | | - |
| 191686 | | -/* An instance of this object represents a JSON string |
| 191687 | | -** under construction. Really, this is a generic string accumulator |
| 191688 | | -** that can be and is used to create strings other than JSON. |
| 191689 | | -*/ |
| 191690 | | -struct JsonString { |
| 191691 | | - sqlite3_context *pCtx; /* Function context - put error messages here */ |
| 191692 | | - char *zBuf; /* Append JSON content here */ |
| 191693 | | - u64 nAlloc; /* Bytes of storage available in zBuf[] */ |
| 191694 | | - u64 nUsed; /* Bytes of zBuf[] currently used */ |
| 191695 | | - u8 bStatic; /* True if zBuf is static space */ |
| 191696 | | - u8 bErr; /* True if an error has been encountered */ |
| 191697 | | - char zSpace[100]; /* Initial static space */ |
| 191698 | | -}; |
| 191699 | | - |
| 191700 | | -/* JSON type values |
| 191701 | | -*/ |
| 191702 | | -#define JSON_NULL 0 |
| 191703 | | -#define JSON_TRUE 1 |
| 191704 | | -#define JSON_FALSE 2 |
| 191705 | | -#define JSON_INT 3 |
| 191706 | | -#define JSON_REAL 4 |
| 191707 | | -#define JSON_STRING 5 |
| 191708 | | -#define JSON_ARRAY 6 |
| 191709 | | -#define JSON_OBJECT 7 |
| 191710 | | - |
| 191711 | | -/* The "subtype" set for JSON values */ |
| 191712 | | -#define JSON_SUBTYPE 74 /* Ascii for "J" */ |
| 191713 | | - |
| 191714 | | -/* |
| 191715 | | -** Names of the various JSON types: |
| 191716 | | -*/ |
| 191717 | | -static const char * const jsonType[] = { |
| 191718 | | - "null", "true", "false", "integer", "real", "text", "array", "object" |
| 191719 | | -}; |
| 191720 | | - |
| 191721 | | -/* Bit values for the JsonNode.jnFlag field |
| 191722 | | -*/ |
| 191723 | | -#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ |
| 191724 | | -#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ |
| 191725 | | -#define JNODE_REMOVE 0x04 /* Do not output */ |
| 191726 | | -#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ |
| 191727 | | -#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ |
| 191728 | | -#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ |
| 191729 | | -#define JNODE_LABEL 0x40 /* Is a label of an object */ |
| 191730 | | - |
| 191731 | | - |
| 191732 | | -/* A single node of parsed JSON |
| 191733 | | -*/ |
| 191734 | | -struct JsonNode { |
| 191735 | | - u8 eType; /* One of the JSON_ type values */ |
| 191736 | | - u8 jnFlags; /* JNODE flags */ |
| 191737 | | - u32 n; /* Bytes of content, or number of sub-nodes */ |
| 191738 | | - union { |
| 191739 | | - const char *zJContent; /* Content for INT, REAL, and STRING */ |
| 191740 | | - u32 iAppend; /* More terms for ARRAY and OBJECT */ |
| 191741 | | - u32 iKey; /* Key for ARRAY objects in json_tree() */ |
| 191742 | | - u32 iReplace; /* Replacement content for JNODE_REPLACE */ |
| 191743 | | - JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ |
| 191744 | | - } u; |
| 191745 | | -}; |
| 191746 | | - |
| 191747 | | -/* A completely parsed JSON string |
| 191748 | | -*/ |
| 191749 | | -struct JsonParse { |
| 191750 | | - u32 nNode; /* Number of slots of aNode[] used */ |
| 191751 | | - u32 nAlloc; /* Number of slots of aNode[] allocated */ |
| 191752 | | - JsonNode *aNode; /* Array of nodes containing the parse */ |
| 191753 | | - const char *zJson; /* Original JSON string */ |
| 191754 | | - u32 *aUp; /* Index of parent of each node */ |
| 191755 | | - u8 oom; /* Set to true if out of memory */ |
| 191756 | | - u8 nErr; /* Number of errors seen */ |
| 191757 | | - u16 iDepth; /* Nesting depth */ |
| 191758 | | - int nJson; /* Length of the zJson string in bytes */ |
| 191759 | | -}; |
| 191760 | | - |
| 191761 | | -/* |
| 191762 | | -** Maximum nesting depth of JSON for this implementation. |
| 191763 | | -** |
| 191764 | | -** This limit is needed to avoid a stack overflow in the recursive |
| 191765 | | -** descent parser. A depth of 2000 is far deeper than any sane JSON |
| 191766 | | -** should go. |
| 191767 | | -*/ |
| 191768 | | -#define JSON_MAX_DEPTH 2000 |
| 191769 | | - |
| 191770 | | -/************************************************************************** |
| 191771 | | -** Utility routines for dealing with JsonString objects |
| 191772 | | -**************************************************************************/ |
| 191773 | | - |
| 191774 | | -/* Set the JsonString object to an empty string |
| 191775 | | -*/ |
| 191776 | | -static void jsonZero(JsonString *p){ |
| 191777 | | - p->zBuf = p->zSpace; |
| 191778 | | - p->nAlloc = sizeof(p->zSpace); |
| 191779 | | - p->nUsed = 0; |
| 191780 | | - p->bStatic = 1; |
| 191781 | | -} |
| 191782 | | - |
| 191783 | | -/* Initialize the JsonString object |
| 191784 | | -*/ |
| 191785 | | -static void jsonInit(JsonString *p, sqlite3_context *pCtx){ |
| 191786 | | - p->pCtx = pCtx; |
| 191787 | | - p->bErr = 0; |
| 191788 | | - jsonZero(p); |
| 191789 | | -} |
| 191790 | | - |
| 191791 | | - |
| 191792 | | -/* Free all allocated memory and reset the JsonString object back to its |
| 191793 | | -** initial state. |
| 191794 | | -*/ |
| 191795 | | -static void jsonReset(JsonString *p){ |
| 191796 | | - if( !p->bStatic ) sqlite3_free(p->zBuf); |
| 191797 | | - jsonZero(p); |
| 191798 | | -} |
| 191799 | | - |
| 191800 | | - |
| 191801 | | -/* Report an out-of-memory (OOM) condition |
| 191802 | | -*/ |
| 191803 | | -static void jsonOom(JsonString *p){ |
| 191804 | | - p->bErr = 1; |
| 191805 | | - sqlite3_result_error_nomem(p->pCtx); |
| 191806 | | - jsonReset(p); |
| 191807 | | -} |
| 191808 | | - |
| 191809 | | -/* Enlarge pJson->zBuf so that it can hold at least N more bytes. |
| 191810 | | -** Return zero on success. Return non-zero on an OOM error |
| 191811 | | -*/ |
| 191812 | | -static int jsonGrow(JsonString *p, u32 N){ |
| 191813 | | - u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10; |
| 191814 | | - char *zNew; |
| 191815 | | - if( p->bStatic ){ |
| 191816 | | - if( p->bErr ) return 1; |
| 191817 | | - zNew = sqlite3_malloc64(nTotal); |
| 191818 | | - if( zNew==0 ){ |
| 191819 | | - jsonOom(p); |
| 191820 | | - return SQLITE_NOMEM; |
| 191821 | | - } |
| 191822 | | - memcpy(zNew, p->zBuf, (size_t)p->nUsed); |
| 191823 | | - p->zBuf = zNew; |
| 191824 | | - p->bStatic = 0; |
| 191825 | | - }else{ |
| 191826 | | - zNew = sqlite3_realloc64(p->zBuf, nTotal); |
| 191827 | | - if( zNew==0 ){ |
| 191828 | | - jsonOom(p); |
| 191829 | | - return SQLITE_NOMEM; |
| 191830 | | - } |
| 191831 | | - p->zBuf = zNew; |
| 191832 | | - } |
| 191833 | | - p->nAlloc = nTotal; |
| 191834 | | - return SQLITE_OK; |
| 191835 | | -} |
| 191836 | | - |
| 191837 | | -/* Append N bytes from zIn onto the end of the JsonString string. |
| 191838 | | -*/ |
| 191839 | | -static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ |
| 191840 | | - if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; |
| 191841 | | - memcpy(p->zBuf+p->nUsed, zIn, N); |
| 191842 | | - p->nUsed += N; |
| 191843 | | -} |
| 191844 | | - |
| 191845 | | -/* Append formatted text (not to exceed N bytes) to the JsonString. |
| 191846 | | -*/ |
| 191847 | | -static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ |
| 191848 | | - va_list ap; |
| 191849 | | - if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; |
| 191850 | | - va_start(ap, zFormat); |
| 191851 | | - sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); |
| 191852 | | - va_end(ap); |
| 191853 | | - p->nUsed += (int)strlen(p->zBuf+p->nUsed); |
| 191854 | | -} |
| 191855 | | - |
| 191856 | | -/* Append a single character |
| 191857 | | -*/ |
| 191858 | | -static void jsonAppendChar(JsonString *p, char c){ |
| 191859 | | - if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; |
| 191860 | | - p->zBuf[p->nUsed++] = c; |
| 191861 | | -} |
| 191862 | | - |
| 191863 | | -/* Append a comma separator to the output buffer, if the previous |
| 191864 | | -** character is not '[' or '{'. |
| 191865 | | -*/ |
| 191866 | | -static void jsonAppendSeparator(JsonString *p){ |
| 191867 | | - char c; |
| 191868 | | - if( p->nUsed==0 ) return; |
| 191869 | | - c = p->zBuf[p->nUsed-1]; |
| 191870 | | - if( c!='[' && c!='{' ) jsonAppendChar(p, ','); |
| 191871 | | -} |
| 191872 | | - |
| 191873 | | -/* Append the N-byte string in zIn to the end of the JsonString string |
| 191874 | | -** under construction. Enclose the string in "..." and escape |
| 191875 | | -** any double-quotes or backslash characters contained within the |
| 191876 | | -** string. |
| 191877 | | -*/ |
| 191878 | | -static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ |
| 191879 | | - u32 i; |
| 191880 | | - if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; |
| 191881 | | - p->zBuf[p->nUsed++] = '"'; |
| 191882 | | - for(i=0; i<N; i++){ |
| 191883 | | - unsigned char c = ((unsigned const char*)zIn)[i]; |
| 191884 | | - if( c=='"' || c=='\\' ){ |
| 191885 | | - json_simple_escape: |
| 191886 | | - if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; |
| 191887 | | - p->zBuf[p->nUsed++] = '\\'; |
| 191888 | | - }else if( c<=0x1f ){ |
| 191889 | | - static const char aSpecial[] = { |
| 191890 | | - 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, |
| 191891 | | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 191892 | | - }; |
| 191893 | | - assert( sizeof(aSpecial)==32 ); |
| 191894 | | - assert( aSpecial['\b']=='b' ); |
| 191895 | | - assert( aSpecial['\f']=='f' ); |
| 191896 | | - assert( aSpecial['\n']=='n' ); |
| 191897 | | - assert( aSpecial['\r']=='r' ); |
| 191898 | | - assert( aSpecial['\t']=='t' ); |
| 191899 | | - if( aSpecial[c] ){ |
| 191900 | | - c = aSpecial[c]; |
| 191901 | | - goto json_simple_escape; |
| 191902 | | - } |
| 191903 | | - if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; |
| 191904 | | - p->zBuf[p->nUsed++] = '\\'; |
| 191905 | | - p->zBuf[p->nUsed++] = 'u'; |
| 191906 | | - p->zBuf[p->nUsed++] = '0'; |
| 191907 | | - p->zBuf[p->nUsed++] = '0'; |
| 191908 | | - p->zBuf[p->nUsed++] = '0' + (c>>4); |
| 191909 | | - c = "0123456789abcdef"[c&0xf]; |
| 191910 | | - } |
| 191911 | | - p->zBuf[p->nUsed++] = c; |
| 191912 | | - } |
| 191913 | | - p->zBuf[p->nUsed++] = '"'; |
| 191914 | | - assert( p->nUsed<p->nAlloc ); |
| 191915 | | -} |
| 191916 | | - |
| 191917 | | -/* |
| 191918 | | -** Append a function parameter value to the JSON string under |
| 191919 | | -** construction. |
| 191920 | | -*/ |
| 191921 | | -static void jsonAppendValue( |
| 191922 | | - JsonString *p, /* Append to this JSON string */ |
| 191923 | | - sqlite3_value *pValue /* Value to append */ |
| 191924 | | -){ |
| 191925 | | - switch( sqlite3_value_type(pValue) ){ |
| 191926 | | - case SQLITE_NULL: { |
| 191927 | | - jsonAppendRaw(p, "null", 4); |
| 191928 | | - break; |
| 191929 | | - } |
| 191930 | | - case SQLITE_INTEGER: |
| 191931 | | - case SQLITE_FLOAT: { |
| 191932 | | - const char *z = (const char*)sqlite3_value_text(pValue); |
| 191933 | | - u32 n = (u32)sqlite3_value_bytes(pValue); |
| 191934 | | - jsonAppendRaw(p, z, n); |
| 191935 | | - break; |
| 191936 | | - } |
| 191937 | | - case SQLITE_TEXT: { |
| 191938 | | - const char *z = (const char*)sqlite3_value_text(pValue); |
| 191939 | | - u32 n = (u32)sqlite3_value_bytes(pValue); |
| 191940 | | - if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ |
| 191941 | | - jsonAppendRaw(p, z, n); |
| 191942 | | - }else{ |
| 191943 | | - jsonAppendString(p, z, n); |
| 191944 | | - } |
| 191945 | | - break; |
| 191946 | | - } |
| 191947 | | - default: { |
| 191948 | | - if( p->bErr==0 ){ |
| 191949 | | - sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); |
| 191950 | | - p->bErr = 2; |
| 191951 | | - jsonReset(p); |
| 191952 | | - } |
| 191953 | | - break; |
| 191954 | | - } |
| 191955 | | - } |
| 191956 | | -} |
| 191957 | | - |
| 191958 | | - |
| 191959 | | -/* Make the JSON in p the result of the SQL function. |
| 191960 | | -*/ |
| 191961 | | -static void jsonResult(JsonString *p){ |
| 191962 | | - if( p->bErr==0 ){ |
| 191963 | | - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, |
| 191964 | | - p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, |
| 191965 | | - SQLITE_UTF8); |
| 191966 | | - jsonZero(p); |
| 191967 | | - } |
| 191968 | | - assert( p->bStatic ); |
| 191969 | | -} |
| 191970 | | - |
| 191971 | | -/************************************************************************** |
| 191972 | | -** Utility routines for dealing with JsonNode and JsonParse objects |
| 191973 | | -**************************************************************************/ |
| 191974 | | - |
| 191975 | | -/* |
| 191976 | | -** Return the number of consecutive JsonNode slots need to represent |
| 191977 | | -** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and |
| 191978 | | -** OBJECT types, the number might be larger. |
| 191979 | | -** |
| 191980 | | -** Appended elements are not counted. The value returned is the number |
| 191981 | | -** by which the JsonNode counter should increment in order to go to the |
| 191982 | | -** next peer value. |
| 191983 | | -*/ |
| 191984 | | -static u32 jsonNodeSize(JsonNode *pNode){ |
| 191985 | | - return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; |
| 191986 | | -} |
| 191987 | | - |
| 191988 | | -/* |
| 191989 | | -** Reclaim all memory allocated by a JsonParse object. But do not |
| 191990 | | -** delete the JsonParse object itself. |
| 191991 | | -*/ |
| 191992 | | -static void jsonParseReset(JsonParse *pParse){ |
| 191993 | | - sqlite3_free(pParse->aNode); |
| 191994 | | - pParse->aNode = 0; |
| 191995 | | - pParse->nNode = 0; |
| 191996 | | - pParse->nAlloc = 0; |
| 191997 | | - sqlite3_free(pParse->aUp); |
| 191998 | | - pParse->aUp = 0; |
| 191999 | | -} |
| 192000 | | - |
| 192001 | | -/* |
| 192002 | | -** Free a JsonParse object that was obtained from sqlite3_malloc(). |
| 192003 | | -*/ |
| 192004 | | -static void jsonParseFree(JsonParse *pParse){ |
| 192005 | | - jsonParseReset(pParse); |
| 192006 | | - sqlite3_free(pParse); |
| 192007 | | -} |
| 192008 | | - |
| 192009 | | -/* |
| 192010 | | -** Convert the JsonNode pNode into a pure JSON string and |
| 192011 | | -** append to pOut. Subsubstructure is also included. Return |
| 192012 | | -** the number of JsonNode objects that are encoded. |
| 192013 | | -*/ |
| 192014 | | -static void jsonRenderNode( |
| 192015 | | - JsonNode *pNode, /* The node to render */ |
| 192016 | | - JsonString *pOut, /* Write JSON here */ |
| 192017 | | - sqlite3_value **aReplace /* Replacement values */ |
| 192018 | | -){ |
| 192019 | | - if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ |
| 192020 | | - if( pNode->jnFlags & JNODE_REPLACE ){ |
| 192021 | | - jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); |
| 192022 | | - return; |
| 192023 | | - } |
| 192024 | | - pNode = pNode->u.pPatch; |
| 192025 | | - } |
| 192026 | | - switch( pNode->eType ){ |
| 192027 | | - default: { |
| 192028 | | - assert( pNode->eType==JSON_NULL ); |
| 192029 | | - jsonAppendRaw(pOut, "null", 4); |
| 192030 | | - break; |
| 192031 | | - } |
| 192032 | | - case JSON_TRUE: { |
| 192033 | | - jsonAppendRaw(pOut, "true", 4); |
| 192034 | | - break; |
| 192035 | | - } |
| 192036 | | - case JSON_FALSE: { |
| 192037 | | - jsonAppendRaw(pOut, "false", 5); |
| 192038 | | - break; |
| 192039 | | - } |
| 192040 | | - case JSON_STRING: { |
| 192041 | | - if( pNode->jnFlags & JNODE_RAW ){ |
| 192042 | | - jsonAppendString(pOut, pNode->u.zJContent, pNode->n); |
| 192043 | | - break; |
| 192044 | | - } |
| 192045 | | - /* Fall through into the next case */ |
| 192046 | | - } |
| 192047 | | - case JSON_REAL: |
| 192048 | | - case JSON_INT: { |
| 192049 | | - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); |
| 192050 | | - break; |
| 192051 | | - } |
| 192052 | | - case JSON_ARRAY: { |
| 192053 | | - u32 j = 1; |
| 192054 | | - jsonAppendChar(pOut, '['); |
| 192055 | | - for(;;){ |
| 192056 | | - while( j<=pNode->n ){ |
| 192057 | | - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ |
| 192058 | | - jsonAppendSeparator(pOut); |
| 192059 | | - jsonRenderNode(&pNode[j], pOut, aReplace); |
| 192060 | | - } |
| 192061 | | - j += jsonNodeSize(&pNode[j]); |
| 192062 | | - } |
| 192063 | | - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; |
| 192064 | | - pNode = &pNode[pNode->u.iAppend]; |
| 192065 | | - j = 1; |
| 192066 | | - } |
| 192067 | | - jsonAppendChar(pOut, ']'); |
| 192068 | | - break; |
| 192069 | | - } |
| 192070 | | - case JSON_OBJECT: { |
| 192071 | | - u32 j = 1; |
| 192072 | | - jsonAppendChar(pOut, '{'); |
| 192073 | | - for(;;){ |
| 192074 | | - while( j<=pNode->n ){ |
| 192075 | | - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ |
| 192076 | | - jsonAppendSeparator(pOut); |
| 192077 | | - jsonRenderNode(&pNode[j], pOut, aReplace); |
| 192078 | | - jsonAppendChar(pOut, ':'); |
| 192079 | | - jsonRenderNode(&pNode[j+1], pOut, aReplace); |
| 192080 | | - } |
| 192081 | | - j += 1 + jsonNodeSize(&pNode[j+1]); |
| 192082 | | - } |
| 192083 | | - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; |
| 192084 | | - pNode = &pNode[pNode->u.iAppend]; |
| 192085 | | - j = 1; |
| 192086 | | - } |
| 192087 | | - jsonAppendChar(pOut, '}'); |
| 192088 | | - break; |
| 192089 | | - } |
| 192090 | | - } |
| 192091 | | -} |
| 192092 | | - |
| 192093 | | -/* |
| 192094 | | -** Return a JsonNode and all its descendents as a JSON string. |
| 192095 | | -*/ |
| 192096 | | -static void jsonReturnJson( |
| 192097 | | - JsonNode *pNode, /* Node to return */ |
| 192098 | | - sqlite3_context *pCtx, /* Return value for this function */ |
| 192099 | | - sqlite3_value **aReplace /* Array of replacement values */ |
| 192100 | | -){ |
| 192101 | | - JsonString s; |
| 192102 | | - jsonInit(&s, pCtx); |
| 192103 | | - jsonRenderNode(pNode, &s, aReplace); |
| 192104 | | - jsonResult(&s); |
| 192105 | | - sqlite3_result_subtype(pCtx, JSON_SUBTYPE); |
| 192106 | | -} |
| 192107 | | - |
| 192108 | | -/* |
| 192109 | | -** Make the JsonNode the return value of the function. |
| 192110 | | -*/ |
| 192111 | | -static void jsonReturn( |
| 192112 | | - JsonNode *pNode, /* Node to return */ |
| 192113 | | - sqlite3_context *pCtx, /* Return value for this function */ |
| 192114 | | - sqlite3_value **aReplace /* Array of replacement values */ |
| 192115 | | -){ |
| 192116 | | - switch( pNode->eType ){ |
| 192117 | | - default: { |
| 192118 | | - assert( pNode->eType==JSON_NULL ); |
| 192119 | | - sqlite3_result_null(pCtx); |
| 192120 | | - break; |
| 192121 | | - } |
| 192122 | | - case JSON_TRUE: { |
| 192123 | | - sqlite3_result_int(pCtx, 1); |
| 192124 | | - break; |
| 192125 | | - } |
| 192126 | | - case JSON_FALSE: { |
| 192127 | | - sqlite3_result_int(pCtx, 0); |
| 192128 | | - break; |
| 192129 | | - } |
| 192130 | | - case JSON_INT: { |
| 192131 | | - sqlite3_int64 i = 0; |
| 192132 | | - const char *z = pNode->u.zJContent; |
| 192133 | | - if( z[0]=='-' ){ z++; } |
| 192134 | | - while( z[0]>='0' && z[0]<='9' ){ |
| 192135 | | - unsigned v = *(z++) - '0'; |
| 192136 | | - if( i>=LARGEST_INT64/10 ){ |
| 192137 | | - if( i>LARGEST_INT64/10 ) goto int_as_real; |
| 192138 | | - if( z[0]>='0' && z[0]<='9' ) goto int_as_real; |
| 192139 | | - if( v==9 ) goto int_as_real; |
| 192140 | | - if( v==8 ){ |
| 192141 | | - if( pNode->u.zJContent[0]=='-' ){ |
| 192142 | | - sqlite3_result_int64(pCtx, SMALLEST_INT64); |
| 192143 | | - goto int_done; |
| 192144 | | - }else{ |
| 192145 | | - goto int_as_real; |
| 192146 | | - } |
| 192147 | | - } |
| 192148 | | - } |
| 192149 | | - i = i*10 + v; |
| 192150 | | - } |
| 192151 | | - if( pNode->u.zJContent[0]=='-' ){ i = -i; } |
| 192152 | | - sqlite3_result_int64(pCtx, i); |
| 192153 | | - int_done: |
| 192154 | | - break; |
| 192155 | | - int_as_real: /* fall through to real */; |
| 192156 | | - } |
| 192157 | | - case JSON_REAL: { |
| 192158 | | - double r; |
| 192159 | | -#ifdef SQLITE_AMALGAMATION |
| 192160 | | - const char *z = pNode->u.zJContent; |
| 192161 | | - sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); |
| 192162 | | -#else |
| 192163 | | - r = strtod(pNode->u.zJContent, 0); |
| 192164 | | -#endif |
| 192165 | | - sqlite3_result_double(pCtx, r); |
| 192166 | | - break; |
| 192167 | | - } |
| 192168 | | - case JSON_STRING: { |
| 192169 | | -#if 0 /* Never happens because JNODE_RAW is only set by json_set(), |
| 192170 | | - ** json_insert() and json_replace() and those routines do not |
| 192171 | | - ** call jsonReturn() */ |
| 192172 | | - if( pNode->jnFlags & JNODE_RAW ){ |
| 192173 | | - sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, |
| 192174 | | - SQLITE_TRANSIENT); |
| 192175 | | - }else |
| 192176 | | -#endif |
| 192177 | | - assert( (pNode->jnFlags & JNODE_RAW)==0 ); |
| 192178 | | - if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ |
| 192179 | | - /* JSON formatted without any backslash-escapes */ |
| 192180 | | - sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, |
| 192181 | | - SQLITE_TRANSIENT); |
| 192182 | | - }else{ |
| 192183 | | - /* Translate JSON formatted string into raw text */ |
| 192184 | | - u32 i; |
| 192185 | | - u32 n = pNode->n; |
| 192186 | | - const char *z = pNode->u.zJContent; |
| 192187 | | - char *zOut; |
| 192188 | | - u32 j; |
| 192189 | | - zOut = sqlite3_malloc( n+1 ); |
| 192190 | | - if( zOut==0 ){ |
| 192191 | | - sqlite3_result_error_nomem(pCtx); |
| 192192 | | - break; |
| 192193 | | - } |
| 192194 | | - for(i=1, j=0; i<n-1; i++){ |
| 192195 | | - char c = z[i]; |
| 192196 | | - if( c!='\\' ){ |
| 192197 | | - zOut[j++] = c; |
| 192198 | | - }else{ |
| 192199 | | - c = z[++i]; |
| 192200 | | - if( c=='u' ){ |
| 192201 | | - u32 v = 0, k; |
| 192202 | | - for(k=0; k<4; i++, k++){ |
| 192203 | | - assert( i<n-2 ); |
| 192204 | | - c = z[i+1]; |
| 192205 | | - assert( safe_isxdigit(c) ); |
| 192206 | | - if( c<='9' ) v = v*16 + c - '0'; |
| 192207 | | - else if( c<='F' ) v = v*16 + c - 'A' + 10; |
| 192208 | | - else v = v*16 + c - 'a' + 10; |
| 192209 | | - } |
| 192210 | | - if( v==0 ) break; |
| 192211 | | - if( v<=0x7f ){ |
| 192212 | | - zOut[j++] = (char)v; |
| 192213 | | - }else if( v<=0x7ff ){ |
| 192214 | | - zOut[j++] = (char)(0xc0 | (v>>6)); |
| 192215 | | - zOut[j++] = 0x80 | (v&0x3f); |
| 192216 | | - }else{ |
| 192217 | | - zOut[j++] = (char)(0xe0 | (v>>12)); |
| 192218 | | - zOut[j++] = 0x80 | ((v>>6)&0x3f); |
| 192219 | | - zOut[j++] = 0x80 | (v&0x3f); |
| 192220 | | - } |
| 192221 | | - }else{ |
| 192222 | | - if( c=='b' ){ |
| 192223 | | - c = '\b'; |
| 192224 | | - }else if( c=='f' ){ |
| 192225 | | - c = '\f'; |
| 192226 | | - }else if( c=='n' ){ |
| 192227 | | - c = '\n'; |
| 192228 | | - }else if( c=='r' ){ |
| 192229 | | - c = '\r'; |
| 192230 | | - }else if( c=='t' ){ |
| 192231 | | - c = '\t'; |
| 192232 | | - } |
| 192233 | | - zOut[j++] = c; |
| 192234 | | - } |
| 192235 | | - } |
| 192236 | | - } |
| 192237 | | - zOut[j] = 0; |
| 192238 | | - sqlite3_result_text(pCtx, zOut, j, sqlite3_free); |
| 192239 | | - } |
| 192240 | | - break; |
| 192241 | | - } |
| 192242 | | - case JSON_ARRAY: |
| 192243 | | - case JSON_OBJECT: { |
| 192244 | | - jsonReturnJson(pNode, pCtx, aReplace); |
| 192245 | | - break; |
| 192246 | | - } |
| 192247 | | - } |
| 192248 | | -} |
| 192249 | | - |
| 192250 | | -/* Forward reference */ |
| 192251 | | -static int jsonParseAddNode(JsonParse*,u32,u32,const char*); |
| 192252 | | - |
| 192253 | | -/* |
| 192254 | | -** A macro to hint to the compiler that a function should not be |
| 192255 | | -** inlined. |
| 192256 | | -*/ |
| 192257 | | -#if defined(__GNUC__) |
| 192258 | | -# define JSON_NOINLINE __attribute__((noinline)) |
| 192259 | | -#elif defined(_MSC_VER) && _MSC_VER>=1310 |
| 192260 | | -# define JSON_NOINLINE __declspec(noinline) |
| 192261 | | -#else |
| 192262 | | -# define JSON_NOINLINE |
| 192263 | | -#endif |
| 192264 | | - |
| 192265 | | - |
| 192266 | | -static JSON_NOINLINE int jsonParseAddNodeExpand( |
| 192267 | | - JsonParse *pParse, /* Append the node to this object */ |
| 192268 | | - u32 eType, /* Node type */ |
| 192269 | | - u32 n, /* Content size or sub-node count */ |
| 192270 | | - const char *zContent /* Content */ |
| 192271 | | -){ |
| 192272 | | - u32 nNew; |
| 192273 | | - JsonNode *pNew; |
| 192274 | | - assert( pParse->nNode>=pParse->nAlloc ); |
| 192275 | | - if( pParse->oom ) return -1; |
| 192276 | | - nNew = pParse->nAlloc*2 + 10; |
| 192277 | | - pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew); |
| 192278 | | - if( pNew==0 ){ |
| 192279 | | - pParse->oom = 1; |
| 192280 | | - return -1; |
| 192281 | | - } |
| 192282 | | - pParse->nAlloc = nNew; |
| 192283 | | - pParse->aNode = pNew; |
| 192284 | | - assert( pParse->nNode<pParse->nAlloc ); |
| 192285 | | - return jsonParseAddNode(pParse, eType, n, zContent); |
| 192286 | | -} |
| 192287 | | - |
| 192288 | | -/* |
| 192289 | | -** Create a new JsonNode instance based on the arguments and append that |
| 192290 | | -** instance to the JsonParse. Return the index in pParse->aNode[] of the |
| 192291 | | -** new node, or -1 if a memory allocation fails. |
| 192292 | | -*/ |
| 192293 | | -static int jsonParseAddNode( |
| 192294 | | - JsonParse *pParse, /* Append the node to this object */ |
| 192295 | | - u32 eType, /* Node type */ |
| 192296 | | - u32 n, /* Content size or sub-node count */ |
| 192297 | | - const char *zContent /* Content */ |
| 192298 | | -){ |
| 192299 | | - JsonNode *p; |
| 192300 | | - if( pParse->nNode>=pParse->nAlloc ){ |
| 192301 | | - return jsonParseAddNodeExpand(pParse, eType, n, zContent); |
| 192302 | | - } |
| 192303 | | - p = &pParse->aNode[pParse->nNode]; |
| 192304 | | - p->eType = (u8)eType; |
| 192305 | | - p->jnFlags = 0; |
| 192306 | | - p->n = n; |
| 192307 | | - p->u.zJContent = zContent; |
| 192308 | | - return pParse->nNode++; |
| 192309 | | -} |
| 192310 | | - |
| 192311 | | -/* |
| 192312 | | -** Return true if z[] begins with 4 (or more) hexadecimal digits |
| 192313 | | -*/ |
| 192314 | | -static int jsonIs4Hex(const char *z){ |
| 192315 | | - int i; |
| 192316 | | - for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; |
| 192317 | | - return 1; |
| 192318 | | -} |
| 192319 | | - |
| 192320 | | -/* |
| 192321 | | -** Parse a single JSON value which begins at pParse->zJson[i]. Return the |
| 192322 | | -** index of the first character past the end of the value parsed. |
| 192323 | | -** |
| 192324 | | -** Return negative for a syntax error. Special cases: return -2 if the |
| 192325 | | -** first non-whitespace character is '}' and return -3 if the first |
| 192326 | | -** non-whitespace character is ']'. |
| 192327 | | -*/ |
| 192328 | | -static int jsonParseValue(JsonParse *pParse, u32 i){ |
| 192329 | | - char c; |
| 192330 | | - u32 j; |
| 192331 | | - int iThis; |
| 192332 | | - int x; |
| 192333 | | - JsonNode *pNode; |
| 192334 | | - const char *z = pParse->zJson; |
| 192335 | | - while( safe_isspace(z[i]) ){ i++; } |
| 192336 | | - if( (c = z[i])=='{' ){ |
| 192337 | | - /* Parse object */ |
| 192338 | | - iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); |
| 192339 | | - if( iThis<0 ) return -1; |
| 192340 | | - for(j=i+1;;j++){ |
| 192341 | | - while( safe_isspace(z[j]) ){ j++; } |
| 192342 | | - if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; |
| 192343 | | - x = jsonParseValue(pParse, j); |
| 192344 | | - if( x<0 ){ |
| 192345 | | - pParse->iDepth--; |
| 192346 | | - if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; |
| 192347 | | - return -1; |
| 192348 | | - } |
| 192349 | | - if( pParse->oom ) return -1; |
| 192350 | | - pNode = &pParse->aNode[pParse->nNode-1]; |
| 192351 | | - if( pNode->eType!=JSON_STRING ) return -1; |
| 192352 | | - pNode->jnFlags |= JNODE_LABEL; |
| 192353 | | - j = x; |
| 192354 | | - while( safe_isspace(z[j]) ){ j++; } |
| 192355 | | - if( z[j]!=':' ) return -1; |
| 192356 | | - j++; |
| 192357 | | - x = jsonParseValue(pParse, j); |
| 192358 | | - pParse->iDepth--; |
| 192359 | | - if( x<0 ) return -1; |
| 192360 | | - j = x; |
| 192361 | | - while( safe_isspace(z[j]) ){ j++; } |
| 192362 | | - c = z[j]; |
| 192363 | | - if( c==',' ) continue; |
| 192364 | | - if( c!='}' ) return -1; |
| 192365 | | - break; |
| 192366 | | - } |
| 192367 | | - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; |
| 192368 | | - return j+1; |
| 192369 | | - }else if( c=='[' ){ |
| 192370 | | - /* Parse array */ |
| 192371 | | - iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); |
| 192372 | | - if( iThis<0 ) return -1; |
| 192373 | | - for(j=i+1;;j++){ |
| 192374 | | - while( safe_isspace(z[j]) ){ j++; } |
| 192375 | | - if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; |
| 192376 | | - x = jsonParseValue(pParse, j); |
| 192377 | | - pParse->iDepth--; |
| 192378 | | - if( x<0 ){ |
| 192379 | | - if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; |
| 192380 | | - return -1; |
| 192381 | | - } |
| 192382 | | - j = x; |
| 192383 | | - while( safe_isspace(z[j]) ){ j++; } |
| 192384 | | - c = z[j]; |
| 192385 | | - if( c==',' ) continue; |
| 192386 | | - if( c!=']' ) return -1; |
| 192387 | | - break; |
| 192388 | | - } |
| 192389 | | - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; |
| 192390 | | - return j+1; |
| 192391 | | - }else if( c=='"' ){ |
| 192392 | | - /* Parse string */ |
| 192393 | | - u8 jnFlags = 0; |
| 192394 | | - j = i+1; |
| 192395 | | - for(;;){ |
| 192396 | | - c = z[j]; |
| 192397 | | - if( (c & ~0x1f)==0 ){ |
| 192398 | | - /* Control characters are not allowed in strings */ |
| 192399 | | - return -1; |
| 192400 | | - } |
| 192401 | | - if( c=='\\' ){ |
| 192402 | | - c = z[++j]; |
| 192403 | | - if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' |
| 192404 | | - || c=='n' || c=='r' || c=='t' |
| 192405 | | - || (c=='u' && jsonIs4Hex(z+j+1)) ){ |
| 192406 | | - jnFlags = JNODE_ESCAPE; |
| 192407 | | - }else{ |
| 192408 | | - return -1; |
| 192409 | | - } |
| 192410 | | - }else if( c=='"' ){ |
| 192411 | | - break; |
| 192412 | | - } |
| 192413 | | - j++; |
| 192414 | | - } |
| 192415 | | - jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); |
| 192416 | | - if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; |
| 192417 | | - return j+1; |
| 192418 | | - }else if( c=='n' |
| 192419 | | - && strncmp(z+i,"null",4)==0 |
| 192420 | | - && !safe_isalnum(z[i+4]) ){ |
| 192421 | | - jsonParseAddNode(pParse, JSON_NULL, 0, 0); |
| 192422 | | - return i+4; |
| 192423 | | - }else if( c=='t' |
| 192424 | | - && strncmp(z+i,"true",4)==0 |
| 192425 | | - && !safe_isalnum(z[i+4]) ){ |
| 192426 | | - jsonParseAddNode(pParse, JSON_TRUE, 0, 0); |
| 192427 | | - return i+4; |
| 192428 | | - }else if( c=='f' |
| 192429 | | - && strncmp(z+i,"false",5)==0 |
| 192430 | | - && !safe_isalnum(z[i+5]) ){ |
| 192431 | | - jsonParseAddNode(pParse, JSON_FALSE, 0, 0); |
| 192432 | | - return i+5; |
| 192433 | | - }else if( c=='-' || (c>='0' && c<='9') ){ |
| 192434 | | - /* Parse number */ |
| 192435 | | - u8 seenDP = 0; |
| 192436 | | - u8 seenE = 0; |
| 192437 | | - assert( '-' < '0' ); |
| 192438 | | - if( c<='0' ){ |
| 192439 | | - j = c=='-' ? i+1 : i; |
| 192440 | | - if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; |
| 192441 | | - } |
| 192442 | | - j = i+1; |
| 192443 | | - for(;; j++){ |
| 192444 | | - c = z[j]; |
| 192445 | | - if( c>='0' && c<='9' ) continue; |
| 192446 | | - if( c=='.' ){ |
| 192447 | | - if( z[j-1]=='-' ) return -1; |
| 192448 | | - if( seenDP ) return -1; |
| 192449 | | - seenDP = 1; |
| 192450 | | - continue; |
| 192451 | | - } |
| 192452 | | - if( c=='e' || c=='E' ){ |
| 192453 | | - if( z[j-1]<'0' ) return -1; |
| 192454 | | - if( seenE ) return -1; |
| 192455 | | - seenDP = seenE = 1; |
| 192456 | | - c = z[j+1]; |
| 192457 | | - if( c=='+' || c=='-' ){ |
| 192458 | | - j++; |
| 192459 | | - c = z[j+1]; |
| 192460 | | - } |
| 192461 | | - if( c<'0' || c>'9' ) return -1; |
| 192462 | | - continue; |
| 192463 | | - } |
| 192464 | | - break; |
| 192465 | | - } |
| 192466 | | - if( z[j-1]<'0' ) return -1; |
| 192467 | | - jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, |
| 192468 | | - j - i, &z[i]); |
| 192469 | | - return j; |
| 192470 | | - }else if( c=='}' ){ |
| 192471 | | - return -2; /* End of {...} */ |
| 192472 | | - }else if( c==']' ){ |
| 192473 | | - return -3; /* End of [...] */ |
| 192474 | | - }else if( c==0 ){ |
| 192475 | | - return 0; /* End of file */ |
| 192476 | | - }else{ |
| 192477 | | - return -1; /* Syntax error */ |
| 192478 | | - } |
| 192479 | | -} |
| 192480 | | - |
| 192481 | | -/* |
| 192482 | | -** Parse a complete JSON string. Return 0 on success or non-zero if there |
| 192483 | | -** are any errors. If an error occurs, free all memory associated with |
| 192484 | | -** pParse. |
| 192485 | | -** |
| 192486 | | -** pParse is uninitialized when this routine is called. |
| 192487 | | -*/ |
| 192488 | | -static int jsonParse( |
| 192489 | | - JsonParse *pParse, /* Initialize and fill this JsonParse object */ |
| 192490 | | - sqlite3_context *pCtx, /* Report errors here */ |
| 192491 | | - const char *zJson /* Input JSON text to be parsed */ |
| 192492 | | -){ |
| 192493 | | - int i; |
| 192494 | | - memset(pParse, 0, sizeof(*pParse)); |
| 192495 | | - if( zJson==0 ) return 1; |
| 192496 | | - pParse->zJson = zJson; |
| 192497 | | - i = jsonParseValue(pParse, 0); |
| 192498 | | - if( pParse->oom ) i = -1; |
| 192499 | | - if( i>0 ){ |
| 192500 | | - assert( pParse->iDepth==0 ); |
| 192501 | | - while( safe_isspace(zJson[i]) ) i++; |
| 192502 | | - if( zJson[i] ) i = -1; |
| 192503 | | - } |
| 192504 | | - if( i<=0 ){ |
| 192505 | | - if( pCtx!=0 ){ |
| 192506 | | - if( pParse->oom ){ |
| 192507 | | - sqlite3_result_error_nomem(pCtx); |
| 192508 | | - }else{ |
| 192509 | | - sqlite3_result_error(pCtx, "malformed JSON", -1); |
| 192510 | | - } |
| 192511 | | - } |
| 192512 | | - jsonParseReset(pParse); |
| 192513 | | - return 1; |
| 192514 | | - } |
| 192515 | | - return 0; |
| 192516 | | -} |
| 192517 | | - |
| 192518 | | -/* Mark node i of pParse as being a child of iParent. Call recursively |
| 192519 | | -** to fill in all the descendants of node i. |
| 192520 | | -*/ |
| 192521 | | -static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ |
| 192522 | | - JsonNode *pNode = &pParse->aNode[i]; |
| 192523 | | - u32 j; |
| 192524 | | - pParse->aUp[i] = iParent; |
| 192525 | | - switch( pNode->eType ){ |
| 192526 | | - case JSON_ARRAY: { |
| 192527 | | - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ |
| 192528 | | - jsonParseFillInParentage(pParse, i+j, i); |
| 192529 | | - } |
| 192530 | | - break; |
| 192531 | | - } |
| 192532 | | - case JSON_OBJECT: { |
| 192533 | | - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ |
| 192534 | | - pParse->aUp[i+j] = i; |
| 192535 | | - jsonParseFillInParentage(pParse, i+j+1, i); |
| 192536 | | - } |
| 192537 | | - break; |
| 192538 | | - } |
| 192539 | | - default: { |
| 192540 | | - break; |
| 192541 | | - } |
| 192542 | | - } |
| 192543 | | -} |
| 192544 | | - |
| 192545 | | -/* |
| 192546 | | -** Compute the parentage of all nodes in a completed parse. |
| 192547 | | -*/ |
| 192548 | | -static int jsonParseFindParents(JsonParse *pParse){ |
| 192549 | | - u32 *aUp; |
| 192550 | | - assert( pParse->aUp==0 ); |
| 192551 | | - aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode ); |
| 192552 | | - if( aUp==0 ){ |
| 192553 | | - pParse->oom = 1; |
| 192554 | | - return SQLITE_NOMEM; |
| 192555 | | - } |
| 192556 | | - jsonParseFillInParentage(pParse, 0, 0); |
| 192557 | | - return SQLITE_OK; |
| 192558 | | -} |
| 192559 | | - |
| 192560 | | -/* |
| 192561 | | -** Magic number used for the JSON parse cache in sqlite3_get_auxdata() |
| 192562 | | -*/ |
| 192563 | | -#define JSON_CACHE_ID (-429938) |
| 192564 | | - |
| 192565 | | -/* |
| 192566 | | -** Obtain a complete parse of the JSON found in the first argument |
| 192567 | | -** of the argv array. Use the sqlite3_get_auxdata() cache for this |
| 192568 | | -** parse if it is available. If the cache is not available or if it |
| 192569 | | -** is no longer valid, parse the JSON again and return the new parse, |
| 192570 | | -** and also register the new parse so that it will be available for |
| 192571 | | -** future sqlite3_get_auxdata() calls. |
| 192572 | | -*/ |
| 192573 | | -static JsonParse *jsonParseCached( |
| 192574 | | - sqlite3_context *pCtx, |
| 192575 | | - sqlite3_value **argv |
| 192576 | | -){ |
| 192577 | | - const char *zJson = (const char*)sqlite3_value_text(argv[0]); |
| 192578 | | - int nJson = sqlite3_value_bytes(argv[0]); |
| 192579 | | - JsonParse *p; |
| 192580 | | - if( zJson==0 ) return 0; |
| 192581 | | - p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); |
| 192582 | | - if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){ |
| 192583 | | - p->nErr = 0; |
| 192584 | | - return p; /* The cached entry matches, so return it */ |
| 192585 | | - } |
| 192586 | | - p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); |
| 192587 | | - if( p==0 ){ |
| 192588 | | - sqlite3_result_error_nomem(pCtx); |
| 192589 | | - return 0; |
| 192590 | | - } |
| 192591 | | - memset(p, 0, sizeof(*p)); |
| 192592 | | - p->zJson = (char*)&p[1]; |
| 192593 | | - memcpy((char*)p->zJson, zJson, nJson+1); |
| 192594 | | - if( jsonParse(p, pCtx, p->zJson) ){ |
| 192595 | | - sqlite3_free(p); |
| 192596 | | - return 0; |
| 192597 | | - } |
| 192598 | | - p->nJson = nJson; |
| 192599 | | - sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree); |
| 192600 | | - return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); |
| 192601 | | -} |
| 192602 | | - |
| 192603 | | -/* |
| 192604 | | -** Compare the OBJECT label at pNode against zKey,nKey. Return true on |
| 192605 | | -** a match. |
| 192606 | | -*/ |
| 192607 | | -static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ |
| 192608 | | - if( pNode->jnFlags & JNODE_RAW ){ |
| 192609 | | - if( pNode->n!=nKey ) return 0; |
| 192610 | | - return strncmp(pNode->u.zJContent, zKey, nKey)==0; |
| 192611 | | - }else{ |
| 192612 | | - if( pNode->n!=nKey+2 ) return 0; |
| 192613 | | - return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; |
| 192614 | | - } |
| 192615 | | -} |
| 192616 | | - |
| 192617 | | -/* forward declaration */ |
| 192618 | | -static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); |
| 192619 | | - |
| 192620 | | -/* |
| 192621 | | -** Search along zPath to find the node specified. Return a pointer |
| 192622 | | -** to that node, or NULL if zPath is malformed or if there is no such |
| 192623 | | -** node. |
| 192624 | | -** |
| 192625 | | -** If pApnd!=0, then try to append new nodes to complete zPath if it is |
| 192626 | | -** possible to do so and if no existing node corresponds to zPath. If |
| 192627 | | -** new nodes are appended *pApnd is set to 1. |
| 192628 | | -*/ |
| 192629 | | -static JsonNode *jsonLookupStep( |
| 192630 | | - JsonParse *pParse, /* The JSON to search */ |
| 192631 | | - u32 iRoot, /* Begin the search at this node */ |
| 192632 | | - const char *zPath, /* The path to search */ |
| 192633 | | - int *pApnd, /* Append nodes to complete path if not NULL */ |
| 192634 | | - const char **pzErr /* Make *pzErr point to any syntax error in zPath */ |
| 192635 | | -){ |
| 192636 | | - u32 i, j, nKey; |
| 192637 | | - const char *zKey; |
| 192638 | | - JsonNode *pRoot = &pParse->aNode[iRoot]; |
| 192639 | | - if( zPath[0]==0 ) return pRoot; |
| 192640 | | - if( zPath[0]=='.' ){ |
| 192641 | | - if( pRoot->eType!=JSON_OBJECT ) return 0; |
| 192642 | | - zPath++; |
| 192643 | | - if( zPath[0]=='"' ){ |
| 192644 | | - zKey = zPath + 1; |
| 192645 | | - for(i=1; zPath[i] && zPath[i]!='"'; i++){} |
| 192646 | | - nKey = i-1; |
| 192647 | | - if( zPath[i] ){ |
| 192648 | | - i++; |
| 192649 | | - }else{ |
| 192650 | | - *pzErr = zPath; |
| 192651 | | - return 0; |
| 192652 | | - } |
| 192653 | | - }else{ |
| 192654 | | - zKey = zPath; |
| 192655 | | - for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} |
| 192656 | | - nKey = i; |
| 192657 | | - } |
| 192658 | | - if( nKey==0 ){ |
| 192659 | | - *pzErr = zPath; |
| 192660 | | - return 0; |
| 192661 | | - } |
| 192662 | | - j = 1; |
| 192663 | | - for(;;){ |
| 192664 | | - while( j<=pRoot->n ){ |
| 192665 | | - if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ |
| 192666 | | - return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); |
| 192667 | | - } |
| 192668 | | - j++; |
| 192669 | | - j += jsonNodeSize(&pRoot[j]); |
| 192670 | | - } |
| 192671 | | - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; |
| 192672 | | - iRoot += pRoot->u.iAppend; |
| 192673 | | - pRoot = &pParse->aNode[iRoot]; |
| 192674 | | - j = 1; |
| 192675 | | - } |
| 192676 | | - if( pApnd ){ |
| 192677 | | - u32 iStart, iLabel; |
| 192678 | | - JsonNode *pNode; |
| 192679 | | - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); |
| 192680 | | - iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath); |
| 192681 | | - zPath += i; |
| 192682 | | - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); |
| 192683 | | - if( pParse->oom ) return 0; |
| 192684 | | - if( pNode ){ |
| 192685 | | - pRoot = &pParse->aNode[iRoot]; |
| 192686 | | - pRoot->u.iAppend = iStart - iRoot; |
| 192687 | | - pRoot->jnFlags |= JNODE_APPEND; |
| 192688 | | - pParse->aNode[iLabel].jnFlags |= JNODE_RAW; |
| 192689 | | - } |
| 192690 | | - return pNode; |
| 192691 | | - } |
| 192692 | | - }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ |
| 192693 | | - if( pRoot->eType!=JSON_ARRAY ) return 0; |
| 192694 | | - i = 0; |
| 192695 | | - j = 1; |
| 192696 | | - while( safe_isdigit(zPath[j]) ){ |
| 192697 | | - i = i*10 + zPath[j] - '0'; |
| 192698 | | - j++; |
| 192699 | | - } |
| 192700 | | - if( zPath[j]!=']' ){ |
| 192701 | | - *pzErr = zPath; |
| 192702 | | - return 0; |
| 192703 | | - } |
| 192704 | | - zPath += j + 1; |
| 192705 | | - j = 1; |
| 192706 | | - for(;;){ |
| 192707 | | - while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ |
| 192708 | | - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; |
| 192709 | | - j += jsonNodeSize(&pRoot[j]); |
| 192710 | | - } |
| 192711 | | - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; |
| 192712 | | - iRoot += pRoot->u.iAppend; |
| 192713 | | - pRoot = &pParse->aNode[iRoot]; |
| 192714 | | - j = 1; |
| 192715 | | - } |
| 192716 | | - if( j<=pRoot->n ){ |
| 192717 | | - return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); |
| 192718 | | - } |
| 192719 | | - if( i==0 && pApnd ){ |
| 192720 | | - u32 iStart; |
| 192721 | | - JsonNode *pNode; |
| 192722 | | - iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); |
| 192723 | | - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); |
| 192724 | | - if( pParse->oom ) return 0; |
| 192725 | | - if( pNode ){ |
| 192726 | | - pRoot = &pParse->aNode[iRoot]; |
| 192727 | | - pRoot->u.iAppend = iStart - iRoot; |
| 192728 | | - pRoot->jnFlags |= JNODE_APPEND; |
| 192729 | | - } |
| 192730 | | - return pNode; |
| 192731 | | - } |
| 192732 | | - }else{ |
| 192733 | | - *pzErr = zPath; |
| 192734 | | - } |
| 192735 | | - return 0; |
| 192736 | | -} |
| 192737 | | - |
| 192738 | | -/* |
| 192739 | | -** Append content to pParse that will complete zPath. Return a pointer |
| 192740 | | -** to the inserted node, or return NULL if the append fails. |
| 192741 | | -*/ |
| 192742 | | -static JsonNode *jsonLookupAppend( |
| 192743 | | - JsonParse *pParse, /* Append content to the JSON parse */ |
| 192744 | | - const char *zPath, /* Description of content to append */ |
| 192745 | | - int *pApnd, /* Set this flag to 1 */ |
| 192746 | | - const char **pzErr /* Make this point to any syntax error */ |
| 192747 | | -){ |
| 192748 | | - *pApnd = 1; |
| 192749 | | - if( zPath[0]==0 ){ |
| 192750 | | - jsonParseAddNode(pParse, JSON_NULL, 0, 0); |
| 192751 | | - return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; |
| 192752 | | - } |
| 192753 | | - if( zPath[0]=='.' ){ |
| 192754 | | - jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); |
| 192755 | | - }else if( strncmp(zPath,"[0]",3)==0 ){ |
| 192756 | | - jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); |
| 192757 | | - }else{ |
| 192758 | | - return 0; |
| 192759 | | - } |
| 192760 | | - if( pParse->oom ) return 0; |
| 192761 | | - return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); |
| 192762 | | -} |
| 192763 | | - |
| 192764 | | -/* |
| 192765 | | -** Return the text of a syntax error message on a JSON path. Space is |
| 192766 | | -** obtained from sqlite3_malloc(). |
| 192767 | | -*/ |
| 192768 | | -static char *jsonPathSyntaxError(const char *zErr){ |
| 192769 | | - return sqlite3_mprintf("JSON path error near '%q'", zErr); |
| 192770 | | -} |
| 192771 | | - |
| 192772 | | -/* |
| 192773 | | -** Do a node lookup using zPath. Return a pointer to the node on success. |
| 192774 | | -** Return NULL if not found or if there is an error. |
| 192775 | | -** |
| 192776 | | -** On an error, write an error message into pCtx and increment the |
| 192777 | | -** pParse->nErr counter. |
| 192778 | | -** |
| 192779 | | -** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if |
| 192780 | | -** nodes are appended. |
| 192781 | | -*/ |
| 192782 | | -static JsonNode *jsonLookup( |
| 192783 | | - JsonParse *pParse, /* The JSON to search */ |
| 192784 | | - const char *zPath, /* The path to search */ |
| 192785 | | - int *pApnd, /* Append nodes to complete path if not NULL */ |
| 192786 | | - sqlite3_context *pCtx /* Report errors here, if not NULL */ |
| 192787 | | -){ |
| 192788 | | - const char *zErr = 0; |
| 192789 | | - JsonNode *pNode = 0; |
| 192790 | | - char *zMsg; |
| 192791 | | - |
| 192792 | | - if( zPath==0 ) return 0; |
| 192793 | | - if( zPath[0]!='$' ){ |
| 192794 | | - zErr = zPath; |
| 192795 | | - goto lookup_err; |
| 192796 | | - } |
| 192797 | | - zPath++; |
| 192798 | | - pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); |
| 192799 | | - if( zErr==0 ) return pNode; |
| 192800 | | - |
| 192801 | | -lookup_err: |
| 192802 | | - pParse->nErr++; |
| 192803 | | - assert( zErr!=0 && pCtx!=0 ); |
| 192804 | | - zMsg = jsonPathSyntaxError(zErr); |
| 192805 | | - if( zMsg ){ |
| 192806 | | - sqlite3_result_error(pCtx, zMsg, -1); |
| 192807 | | - sqlite3_free(zMsg); |
| 192808 | | - }else{ |
| 192809 | | - sqlite3_result_error_nomem(pCtx); |
| 192810 | | - } |
| 192811 | | - return 0; |
| 192812 | | -} |
| 192813 | | - |
| 192814 | | - |
| 192815 | | -/* |
| 192816 | | -** Report the wrong number of arguments for json_insert(), json_replace() |
| 192817 | | -** or json_set(). |
| 192818 | | -*/ |
| 192819 | | -static void jsonWrongNumArgs( |
| 192820 | | - sqlite3_context *pCtx, |
| 192821 | | - const char *zFuncName |
| 192822 | | -){ |
| 192823 | | - char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", |
| 192824 | | - zFuncName); |
| 192825 | | - sqlite3_result_error(pCtx, zMsg, -1); |
| 192826 | | - sqlite3_free(zMsg); |
| 192827 | | -} |
| 192828 | | - |
| 192829 | | -/* |
| 192830 | | -** Mark all NULL entries in the Object passed in as JNODE_REMOVE. |
| 192831 | | -*/ |
| 192832 | | -static void jsonRemoveAllNulls(JsonNode *pNode){ |
| 192833 | | - int i, n; |
| 192834 | | - assert( pNode->eType==JSON_OBJECT ); |
| 192835 | | - n = pNode->n; |
| 192836 | | - for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ |
| 192837 | | - switch( pNode[i].eType ){ |
| 192838 | | - case JSON_NULL: |
| 192839 | | - pNode[i].jnFlags |= JNODE_REMOVE; |
| 192840 | | - break; |
| 192841 | | - case JSON_OBJECT: |
| 192842 | | - jsonRemoveAllNulls(&pNode[i]); |
| 192843 | | - break; |
| 192844 | | - } |
| 192845 | | - } |
| 192846 | | -} |
| 192847 | | - |
| 192848 | | - |
| 192849 | | -/**************************************************************************** |
| 192850 | | -** SQL functions used for testing and debugging |
| 192851 | | -****************************************************************************/ |
| 192852 | | - |
| 192853 | | -#ifdef SQLITE_DEBUG |
| 192854 | | -/* |
| 192855 | | -** The json_parse(JSON) function returns a string which describes |
| 192856 | | -** a parse of the JSON provided. Or it returns NULL if JSON is not |
| 192857 | | -** well-formed. |
| 192858 | | -*/ |
| 192859 | | -static void jsonParseFunc( |
| 192860 | | - sqlite3_context *ctx, |
| 192861 | | - int argc, |
| 192862 | | - sqlite3_value **argv |
| 192863 | | -){ |
| 192864 | | - JsonString s; /* Output string - not real JSON */ |
| 192865 | | - JsonParse x; /* The parse */ |
| 192866 | | - u32 i; |
| 192867 | | - |
| 192868 | | - assert( argc==1 ); |
| 192869 | | - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 192870 | | - jsonParseFindParents(&x); |
| 192871 | | - jsonInit(&s, ctx); |
| 192872 | | - for(i=0; i<x.nNode; i++){ |
| 192873 | | - const char *zType; |
| 192874 | | - if( x.aNode[i].jnFlags & JNODE_LABEL ){ |
| 192875 | | - assert( x.aNode[i].eType==JSON_STRING ); |
| 192876 | | - zType = "label"; |
| 192877 | | - }else{ |
| 192878 | | - zType = jsonType[x.aNode[i].eType]; |
| 192879 | | - } |
| 192880 | | - jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d", |
| 192881 | | - i, zType, x.aNode[i].n, x.aUp[i]); |
| 192882 | | - if( x.aNode[i].u.zJContent!=0 ){ |
| 192883 | | - jsonAppendRaw(&s, " ", 1); |
| 192884 | | - jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n); |
| 192885 | | - } |
| 192886 | | - jsonAppendRaw(&s, "\n", 1); |
| 192887 | | - } |
| 192888 | | - jsonParseReset(&x); |
| 192889 | | - jsonResult(&s); |
| 192890 | | -} |
| 192891 | | - |
| 192892 | | -/* |
| 192893 | | -** The json_test1(JSON) function return true (1) if the input is JSON |
| 192894 | | -** text generated by another json function. It returns (0) if the input |
| 192895 | | -** is not known to be JSON. |
| 192896 | | -*/ |
| 192897 | | -static void jsonTest1Func( |
| 192898 | | - sqlite3_context *ctx, |
| 192899 | | - int argc, |
| 192900 | | - sqlite3_value **argv |
| 192901 | | -){ |
| 192902 | | - UNUSED_PARAM(argc); |
| 192903 | | - sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); |
| 192904 | | -} |
| 192905 | | -#endif /* SQLITE_DEBUG */ |
| 192906 | | - |
| 192907 | | -/**************************************************************************** |
| 192908 | | -** Scalar SQL function implementations |
| 192909 | | -****************************************************************************/ |
| 192910 | | - |
| 192911 | | -/* |
| 192912 | | -** Implementation of the json_QUOTE(VALUE) function. Return a JSON value |
| 192913 | | -** corresponding to the SQL value input. Mostly this means putting |
| 192914 | | -** double-quotes around strings and returning the unquoted string "null" |
| 192915 | | -** when given a NULL input. |
| 192916 | | -*/ |
| 192917 | | -static void jsonQuoteFunc( |
| 192918 | | - sqlite3_context *ctx, |
| 192919 | | - int argc, |
| 192920 | | - sqlite3_value **argv |
| 192921 | | -){ |
| 192922 | | - JsonString jx; |
| 192923 | | - UNUSED_PARAM(argc); |
| 192924 | | - |
| 192925 | | - jsonInit(&jx, ctx); |
| 192926 | | - jsonAppendValue(&jx, argv[0]); |
| 192927 | | - jsonResult(&jx); |
| 192928 | | - sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 192929 | | -} |
| 192930 | | - |
| 192931 | | -/* |
| 192932 | | -** Implementation of the json_array(VALUE,...) function. Return a JSON |
| 192933 | | -** array that contains all values given in arguments. Or if any argument |
| 192934 | | -** is a BLOB, throw an error. |
| 192935 | | -*/ |
| 192936 | | -static void jsonArrayFunc( |
| 192937 | | - sqlite3_context *ctx, |
| 192938 | | - int argc, |
| 192939 | | - sqlite3_value **argv |
| 192940 | | -){ |
| 192941 | | - int i; |
| 192942 | | - JsonString jx; |
| 192943 | | - |
| 192944 | | - jsonInit(&jx, ctx); |
| 192945 | | - jsonAppendChar(&jx, '['); |
| 192946 | | - for(i=0; i<argc; i++){ |
| 192947 | | - jsonAppendSeparator(&jx); |
| 192948 | | - jsonAppendValue(&jx, argv[i]); |
| 192949 | | - } |
| 192950 | | - jsonAppendChar(&jx, ']'); |
| 192951 | | - jsonResult(&jx); |
| 192952 | | - sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 192953 | | -} |
| 192954 | | - |
| 192955 | | - |
| 192956 | | -/* |
| 192957 | | -** json_array_length(JSON) |
| 192958 | | -** json_array_length(JSON, PATH) |
| 192959 | | -** |
| 192960 | | -** Return the number of elements in the top-level JSON array. |
| 192961 | | -** Return 0 if the input is not a well-formed JSON array. |
| 192962 | | -*/ |
| 192963 | | -static void jsonArrayLengthFunc( |
| 192964 | | - sqlite3_context *ctx, |
| 192965 | | - int argc, |
| 192966 | | - sqlite3_value **argv |
| 192967 | | -){ |
| 192968 | | - JsonParse *p; /* The parse */ |
| 192969 | | - sqlite3_int64 n = 0; |
| 192970 | | - u32 i; |
| 192971 | | - JsonNode *pNode; |
| 192972 | | - |
| 192973 | | - p = jsonParseCached(ctx, argv); |
| 192974 | | - if( p==0 ) return; |
| 192975 | | - assert( p->nNode ); |
| 192976 | | - if( argc==2 ){ |
| 192977 | | - const char *zPath = (const char*)sqlite3_value_text(argv[1]); |
| 192978 | | - pNode = jsonLookup(p, zPath, 0, ctx); |
| 192979 | | - }else{ |
| 192980 | | - pNode = p->aNode; |
| 192981 | | - } |
| 192982 | | - if( pNode==0 ){ |
| 192983 | | - return; |
| 192984 | | - } |
| 192985 | | - if( pNode->eType==JSON_ARRAY ){ |
| 192986 | | - assert( (pNode->jnFlags & JNODE_APPEND)==0 ); |
| 192987 | | - for(i=1; i<=pNode->n; n++){ |
| 192988 | | - i += jsonNodeSize(&pNode[i]); |
| 192989 | | - } |
| 192990 | | - } |
| 192991 | | - sqlite3_result_int64(ctx, n); |
| 192992 | | -} |
| 192993 | | - |
| 192994 | | -/* |
| 192995 | | -** json_extract(JSON, PATH, ...) |
| 192996 | | -** |
| 192997 | | -** Return the element described by PATH. Return NULL if there is no |
| 192998 | | -** PATH element. If there are multiple PATHs, then return a JSON array |
| 192999 | | -** with the result from each path. Throw an error if the JSON or any PATH |
| 193000 | | -** is malformed. |
| 193001 | | -*/ |
| 193002 | | -static void jsonExtractFunc( |
| 193003 | | - sqlite3_context *ctx, |
| 193004 | | - int argc, |
| 193005 | | - sqlite3_value **argv |
| 193006 | | -){ |
| 193007 | | - JsonParse *p; /* The parse */ |
| 193008 | | - JsonNode *pNode; |
| 193009 | | - const char *zPath; |
| 193010 | | - JsonString jx; |
| 193011 | | - int i; |
| 193012 | | - |
| 193013 | | - if( argc<2 ) return; |
| 193014 | | - p = jsonParseCached(ctx, argv); |
| 193015 | | - if( p==0 ) return; |
| 193016 | | - jsonInit(&jx, ctx); |
| 193017 | | - jsonAppendChar(&jx, '['); |
| 193018 | | - for(i=1; i<argc; i++){ |
| 193019 | | - zPath = (const char*)sqlite3_value_text(argv[i]); |
| 193020 | | - pNode = jsonLookup(p, zPath, 0, ctx); |
| 193021 | | - if( p->nErr ) break; |
| 193022 | | - if( argc>2 ){ |
| 193023 | | - jsonAppendSeparator(&jx); |
| 193024 | | - if( pNode ){ |
| 193025 | | - jsonRenderNode(pNode, &jx, 0); |
| 193026 | | - }else{ |
| 193027 | | - jsonAppendRaw(&jx, "null", 4); |
| 193028 | | - } |
| 193029 | | - }else if( pNode ){ |
| 193030 | | - jsonReturn(pNode, ctx, 0); |
| 193031 | | - } |
| 193032 | | - } |
| 193033 | | - if( argc>2 && i==argc ){ |
| 193034 | | - jsonAppendChar(&jx, ']'); |
| 193035 | | - jsonResult(&jx); |
| 193036 | | - sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 193037 | | - } |
| 193038 | | - jsonReset(&jx); |
| 193039 | | -} |
| 193040 | | - |
| 193041 | | -/* This is the RFC 7396 MergePatch algorithm. |
| 193042 | | -*/ |
| 193043 | | -static JsonNode *jsonMergePatch( |
| 193044 | | - JsonParse *pParse, /* The JSON parser that contains the TARGET */ |
| 193045 | | - u32 iTarget, /* Node of the TARGET in pParse */ |
| 193046 | | - JsonNode *pPatch /* The PATCH */ |
| 193047 | | -){ |
| 193048 | | - u32 i, j; |
| 193049 | | - u32 iRoot; |
| 193050 | | - JsonNode *pTarget; |
| 193051 | | - if( pPatch->eType!=JSON_OBJECT ){ |
| 193052 | | - return pPatch; |
| 193053 | | - } |
| 193054 | | - assert( iTarget>=0 && iTarget<pParse->nNode ); |
| 193055 | | - pTarget = &pParse->aNode[iTarget]; |
| 193056 | | - assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); |
| 193057 | | - if( pTarget->eType!=JSON_OBJECT ){ |
| 193058 | | - jsonRemoveAllNulls(pPatch); |
| 193059 | | - return pPatch; |
| 193060 | | - } |
| 193061 | | - iRoot = iTarget; |
| 193062 | | - for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){ |
| 193063 | | - u32 nKey; |
| 193064 | | - const char *zKey; |
| 193065 | | - assert( pPatch[i].eType==JSON_STRING ); |
| 193066 | | - assert( pPatch[i].jnFlags & JNODE_LABEL ); |
| 193067 | | - nKey = pPatch[i].n; |
| 193068 | | - zKey = pPatch[i].u.zJContent; |
| 193069 | | - assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); |
| 193070 | | - for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ |
| 193071 | | - assert( pTarget[j].eType==JSON_STRING ); |
| 193072 | | - assert( pTarget[j].jnFlags & JNODE_LABEL ); |
| 193073 | | - assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); |
| 193074 | | - if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ |
| 193075 | | - if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; |
| 193076 | | - if( pPatch[i+1].eType==JSON_NULL ){ |
| 193077 | | - pTarget[j+1].jnFlags |= JNODE_REMOVE; |
| 193078 | | - }else{ |
| 193079 | | - JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); |
| 193080 | | - if( pNew==0 ) return 0; |
| 193081 | | - pTarget = &pParse->aNode[iTarget]; |
| 193082 | | - if( pNew!=&pTarget[j+1] ){ |
| 193083 | | - pTarget[j+1].u.pPatch = pNew; |
| 193084 | | - pTarget[j+1].jnFlags |= JNODE_PATCH; |
| 193085 | | - } |
| 193086 | | - } |
| 193087 | | - break; |
| 193088 | | - } |
| 193089 | | - } |
| 193090 | | - if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ |
| 193091 | | - int iStart, iPatch; |
| 193092 | | - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); |
| 193093 | | - jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); |
| 193094 | | - iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); |
| 193095 | | - if( pParse->oom ) return 0; |
| 193096 | | - jsonRemoveAllNulls(pPatch); |
| 193097 | | - pTarget = &pParse->aNode[iTarget]; |
| 193098 | | - pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; |
| 193099 | | - pParse->aNode[iRoot].u.iAppend = iStart - iRoot; |
| 193100 | | - iRoot = iStart; |
| 193101 | | - pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; |
| 193102 | | - pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; |
| 193103 | | - } |
| 193104 | | - } |
| 193105 | | - return pTarget; |
| 193106 | | -} |
| 193107 | | - |
| 193108 | | -/* |
| 193109 | | -** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON |
| 193110 | | -** object that is the result of running the RFC 7396 MergePatch() algorithm |
| 193111 | | -** on the two arguments. |
| 193112 | | -*/ |
| 193113 | | -static void jsonPatchFunc( |
| 193114 | | - sqlite3_context *ctx, |
| 193115 | | - int argc, |
| 193116 | | - sqlite3_value **argv |
| 193117 | | -){ |
| 193118 | | - JsonParse x; /* The JSON that is being patched */ |
| 193119 | | - JsonParse y; /* The patch */ |
| 193120 | | - JsonNode *pResult; /* The result of the merge */ |
| 193121 | | - |
| 193122 | | - UNUSED_PARAM(argc); |
| 193123 | | - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 193124 | | - if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ |
| 193125 | | - jsonParseReset(&x); |
| 193126 | | - return; |
| 193127 | | - } |
| 193128 | | - pResult = jsonMergePatch(&x, 0, y.aNode); |
| 193129 | | - assert( pResult!=0 || x.oom ); |
| 193130 | | - if( pResult ){ |
| 193131 | | - jsonReturnJson(pResult, ctx, 0); |
| 193132 | | - }else{ |
| 193133 | | - sqlite3_result_error_nomem(ctx); |
| 193134 | | - } |
| 193135 | | - jsonParseReset(&x); |
| 193136 | | - jsonParseReset(&y); |
| 193137 | | -} |
| 193138 | | - |
| 193139 | | - |
| 193140 | | -/* |
| 193141 | | -** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON |
| 193142 | | -** object that contains all name/value given in arguments. Or if any name |
| 193143 | | -** is not a string or if any value is a BLOB, throw an error. |
| 193144 | | -*/ |
| 193145 | | -static void jsonObjectFunc( |
| 193146 | | - sqlite3_context *ctx, |
| 193147 | | - int argc, |
| 193148 | | - sqlite3_value **argv |
| 193149 | | -){ |
| 193150 | | - int i; |
| 193151 | | - JsonString jx; |
| 193152 | | - const char *z; |
| 193153 | | - u32 n; |
| 193154 | | - |
| 193155 | | - if( argc&1 ){ |
| 193156 | | - sqlite3_result_error(ctx, "json_object() requires an even number " |
| 193157 | | - "of arguments", -1); |
| 193158 | | - return; |
| 193159 | | - } |
| 193160 | | - jsonInit(&jx, ctx); |
| 193161 | | - jsonAppendChar(&jx, '{'); |
| 193162 | | - for(i=0; i<argc; i+=2){ |
| 193163 | | - if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){ |
| 193164 | | - sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1); |
| 193165 | | - jsonReset(&jx); |
| 193166 | | - return; |
| 193167 | | - } |
| 193168 | | - jsonAppendSeparator(&jx); |
| 193169 | | - z = (const char*)sqlite3_value_text(argv[i]); |
| 193170 | | - n = (u32)sqlite3_value_bytes(argv[i]); |
| 193171 | | - jsonAppendString(&jx, z, n); |
| 193172 | | - jsonAppendChar(&jx, ':'); |
| 193173 | | - jsonAppendValue(&jx, argv[i+1]); |
| 193174 | | - } |
| 193175 | | - jsonAppendChar(&jx, '}'); |
| 193176 | | - jsonResult(&jx); |
| 193177 | | - sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 193178 | | -} |
| 193179 | | - |
| 193180 | | - |
| 193181 | | -/* |
| 193182 | | -** json_remove(JSON, PATH, ...) |
| 193183 | | -** |
| 193184 | | -** Remove the named elements from JSON and return the result. malformed |
| 193185 | | -** JSON or PATH arguments result in an error. |
| 193186 | | -*/ |
| 193187 | | -static void jsonRemoveFunc( |
| 193188 | | - sqlite3_context *ctx, |
| 193189 | | - int argc, |
| 193190 | | - sqlite3_value **argv |
| 193191 | | -){ |
| 193192 | | - JsonParse x; /* The parse */ |
| 193193 | | - JsonNode *pNode; |
| 193194 | | - const char *zPath; |
| 193195 | | - u32 i; |
| 193196 | | - |
| 193197 | | - if( argc<1 ) return; |
| 193198 | | - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 193199 | | - assert( x.nNode ); |
| 193200 | | - for(i=1; i<(u32)argc; i++){ |
| 193201 | | - zPath = (const char*)sqlite3_value_text(argv[i]); |
| 193202 | | - if( zPath==0 ) goto remove_done; |
| 193203 | | - pNode = jsonLookup(&x, zPath, 0, ctx); |
| 193204 | | - if( x.nErr ) goto remove_done; |
| 193205 | | - if( pNode ) pNode->jnFlags |= JNODE_REMOVE; |
| 193206 | | - } |
| 193207 | | - if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ |
| 193208 | | - jsonReturnJson(x.aNode, ctx, 0); |
| 193209 | | - } |
| 193210 | | -remove_done: |
| 193211 | | - jsonParseReset(&x); |
| 193212 | | -} |
| 193213 | | - |
| 193214 | | -/* |
| 193215 | | -** json_replace(JSON, PATH, VALUE, ...) |
| 193216 | | -** |
| 193217 | | -** Replace the value at PATH with VALUE. If PATH does not already exist, |
| 193218 | | -** this routine is a no-op. If JSON or PATH is malformed, throw an error. |
| 193219 | | -*/ |
| 193220 | | -static void jsonReplaceFunc( |
| 193221 | | - sqlite3_context *ctx, |
| 193222 | | - int argc, |
| 193223 | | - sqlite3_value **argv |
| 193224 | | -){ |
| 193225 | | - JsonParse x; /* The parse */ |
| 193226 | | - JsonNode *pNode; |
| 193227 | | - const char *zPath; |
| 193228 | | - u32 i; |
| 193229 | | - |
| 193230 | | - if( argc<1 ) return; |
| 193231 | | - if( (argc&1)==0 ) { |
| 193232 | | - jsonWrongNumArgs(ctx, "replace"); |
| 193233 | | - return; |
| 193234 | | - } |
| 193235 | | - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 193236 | | - assert( x.nNode ); |
| 193237 | | - for(i=1; i<(u32)argc; i+=2){ |
| 193238 | | - zPath = (const char*)sqlite3_value_text(argv[i]); |
| 193239 | | - pNode = jsonLookup(&x, zPath, 0, ctx); |
| 193240 | | - if( x.nErr ) goto replace_err; |
| 193241 | | - if( pNode ){ |
| 193242 | | - pNode->jnFlags |= (u8)JNODE_REPLACE; |
| 193243 | | - pNode->u.iReplace = i + 1; |
| 193244 | | - } |
| 193245 | | - } |
| 193246 | | - if( x.aNode[0].jnFlags & JNODE_REPLACE ){ |
| 193247 | | - sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); |
| 193248 | | - }else{ |
| 193249 | | - jsonReturnJson(x.aNode, ctx, argv); |
| 193250 | | - } |
| 193251 | | -replace_err: |
| 193252 | | - jsonParseReset(&x); |
| 193253 | | -} |
| 193254 | | - |
| 193255 | | -/* |
| 193256 | | -** json_set(JSON, PATH, VALUE, ...) |
| 193257 | | -** |
| 193258 | | -** Set the value at PATH to VALUE. Create the PATH if it does not already |
| 193259 | | -** exist. Overwrite existing values that do exist. |
| 193260 | | -** If JSON or PATH is malformed, throw an error. |
| 193261 | | -** |
| 193262 | | -** json_insert(JSON, PATH, VALUE, ...) |
| 193263 | | -** |
| 193264 | | -** Create PATH and initialize it to VALUE. If PATH already exists, this |
| 193265 | | -** routine is a no-op. If JSON or PATH is malformed, throw an error. |
| 193266 | | -*/ |
| 193267 | | -static void jsonSetFunc( |
| 193268 | | - sqlite3_context *ctx, |
| 193269 | | - int argc, |
| 193270 | | - sqlite3_value **argv |
| 193271 | | -){ |
| 193272 | | - JsonParse x; /* The parse */ |
| 193273 | | - JsonNode *pNode; |
| 193274 | | - const char *zPath; |
| 193275 | | - u32 i; |
| 193276 | | - int bApnd; |
| 193277 | | - int bIsSet = *(int*)sqlite3_user_data(ctx); |
| 193278 | | - |
| 193279 | | - if( argc<1 ) return; |
| 193280 | | - if( (argc&1)==0 ) { |
| 193281 | | - jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); |
| 193282 | | - return; |
| 193283 | | - } |
| 193284 | | - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 193285 | | - assert( x.nNode ); |
| 193286 | | - for(i=1; i<(u32)argc; i+=2){ |
| 193287 | | - zPath = (const char*)sqlite3_value_text(argv[i]); |
| 193288 | | - bApnd = 0; |
| 193289 | | - pNode = jsonLookup(&x, zPath, &bApnd, ctx); |
| 193290 | | - if( x.oom ){ |
| 193291 | | - sqlite3_result_error_nomem(ctx); |
| 193292 | | - goto jsonSetDone; |
| 193293 | | - }else if( x.nErr ){ |
| 193294 | | - goto jsonSetDone; |
| 193295 | | - }else if( pNode && (bApnd || bIsSet) ){ |
| 193296 | | - pNode->jnFlags |= (u8)JNODE_REPLACE; |
| 193297 | | - pNode->u.iReplace = i + 1; |
| 193298 | | - } |
| 193299 | | - } |
| 193300 | | - if( x.aNode[0].jnFlags & JNODE_REPLACE ){ |
| 193301 | | - sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); |
| 193302 | | - }else{ |
| 193303 | | - jsonReturnJson(x.aNode, ctx, argv); |
| 193304 | | - } |
| 193305 | | -jsonSetDone: |
| 193306 | | - jsonParseReset(&x); |
| 193307 | | -} |
| 193308 | | - |
| 193309 | | -/* |
| 193310 | | -** json_type(JSON) |
| 193311 | | -** json_type(JSON, PATH) |
| 193312 | | -** |
| 193313 | | -** Return the top-level "type" of a JSON string. Throw an error if |
| 193314 | | -** either the JSON or PATH inputs are not well-formed. |
| 193315 | | -*/ |
| 193316 | | -static void jsonTypeFunc( |
| 193317 | | - sqlite3_context *ctx, |
| 193318 | | - int argc, |
| 193319 | | - sqlite3_value **argv |
| 193320 | | -){ |
| 193321 | | - JsonParse x; /* The parse */ |
| 193322 | | - const char *zPath; |
| 193323 | | - JsonNode *pNode; |
| 193324 | | - |
| 193325 | | - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; |
| 193326 | | - assert( x.nNode ); |
| 193327 | | - if( argc==2 ){ |
| 193328 | | - zPath = (const char*)sqlite3_value_text(argv[1]); |
| 193329 | | - pNode = jsonLookup(&x, zPath, 0, ctx); |
| 193330 | | - }else{ |
| 193331 | | - pNode = x.aNode; |
| 193332 | | - } |
| 193333 | | - if( pNode ){ |
| 193334 | | - sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); |
| 193335 | | - } |
| 193336 | | - jsonParseReset(&x); |
| 193337 | | -} |
| 193338 | | - |
| 193339 | | -/* |
| 193340 | | -** json_valid(JSON) |
| 193341 | | -** |
| 193342 | | -** Return 1 if JSON is a well-formed JSON string according to RFC-7159. |
| 193343 | | -** Return 0 otherwise. |
| 193344 | | -*/ |
| 193345 | | -static void jsonValidFunc( |
| 193346 | | - sqlite3_context *ctx, |
| 193347 | | - int argc, |
| 193348 | | - sqlite3_value **argv |
| 193349 | | -){ |
| 193350 | | - JsonParse x; /* The parse */ |
| 193351 | | - int rc = 0; |
| 193352 | | - |
| 193353 | | - UNUSED_PARAM(argc); |
| 193354 | | - if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){ |
| 193355 | | - rc = 1; |
| 193356 | | - } |
| 193357 | | - jsonParseReset(&x); |
| 193358 | | - sqlite3_result_int(ctx, rc); |
| 193359 | | -} |
| 193360 | | - |
| 193361 | | - |
| 193362 | | -/**************************************************************************** |
| 193363 | | -** Aggregate SQL function implementations |
| 193364 | | -****************************************************************************/ |
| 193365 | | -/* |
| 193366 | | -** json_group_array(VALUE) |
| 193367 | | -** |
| 193368 | | -** Return a JSON array composed of all values in the aggregate. |
| 193369 | | -*/ |
| 193370 | | -static void jsonArrayStep( |
| 193371 | | - sqlite3_context *ctx, |
| 193372 | | - int argc, |
| 193373 | | - sqlite3_value **argv |
| 193374 | | -){ |
| 193375 | | - JsonString *pStr; |
| 193376 | | - UNUSED_PARAM(argc); |
| 193377 | | - pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 193378 | | - if( pStr ){ |
| 193379 | | - if( pStr->zBuf==0 ){ |
| 193380 | | - jsonInit(pStr, ctx); |
| 193381 | | - jsonAppendChar(pStr, '['); |
| 193382 | | - }else{ |
| 193383 | | - jsonAppendChar(pStr, ','); |
| 193384 | | - pStr->pCtx = ctx; |
| 193385 | | - } |
| 193386 | | - jsonAppendValue(pStr, argv[0]); |
| 193387 | | - } |
| 193388 | | -} |
| 193389 | | -static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ |
| 193390 | | - JsonString *pStr; |
| 193391 | | - pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 193392 | | - if( pStr ){ |
| 193393 | | - pStr->pCtx = ctx; |
| 193394 | | - jsonAppendChar(pStr, ']'); |
| 193395 | | - if( pStr->bErr ){ |
| 193396 | | - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); |
| 193397 | | - assert( pStr->bStatic ); |
| 193398 | | - }else if( isFinal ){ |
| 193399 | | - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, |
| 193400 | | - pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); |
| 193401 | | - pStr->bStatic = 1; |
| 193402 | | - }else{ |
| 193403 | | - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, SQLITE_TRANSIENT); |
| 193404 | | - pStr->nUsed--; |
| 193405 | | - } |
| 193406 | | - }else{ |
| 193407 | | - sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); |
| 193408 | | - } |
| 193409 | | - sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 193410 | | -} |
| 193411 | | -static void jsonArrayValue(sqlite3_context *ctx){ |
| 193412 | | - jsonArrayCompute(ctx, 0); |
| 193413 | | -} |
| 193414 | | -static void jsonArrayFinal(sqlite3_context *ctx){ |
| 193415 | | - jsonArrayCompute(ctx, 1); |
| 193416 | | -} |
| 193417 | | - |
| 193418 | | -#ifndef SQLITE_OMIT_WINDOWFUNC |
| 193419 | | -/* |
| 193420 | | -** This method works for both json_group_array() and json_group_object(). |
| 193421 | | -** It works by removing the first element of the group by searching forward |
| 193422 | | -** to the first comma (",") that is not within a string and deleting all |
| 193423 | | -** text through that comma. |
| 193424 | | -*/ |
| 193425 | | -static void jsonGroupInverse( |
| 193426 | | - sqlite3_context *ctx, |
| 193427 | | - int argc, |
| 193428 | | - sqlite3_value **argv |
| 193429 | | -){ |
| 193430 | | - int i; |
| 193431 | | - int inStr = 0; |
| 193432 | | - char *z; |
| 193433 | | - JsonString *pStr; |
| 193434 | | - UNUSED_PARAM(argc); |
| 193435 | | - UNUSED_PARAM(argv); |
| 193436 | | - pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 193437 | | -#ifdef NEVER |
| 193438 | | - /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will |
| 193439 | | - ** always have been called to initalize it */ |
| 193440 | | - if( NEVER(!pStr) ) return; |
| 193441 | | -#endif |
| 193442 | | - z = pStr->zBuf; |
| 193443 | | - for(i=1; z[i]!=',' || inStr; i++){ |
| 193444 | | - assert( i<pStr->nUsed ); |
| 193445 | | - if( z[i]=='"' ){ |
| 193446 | | - inStr = !inStr; |
| 193447 | | - }else if( z[i]=='\\' ){ |
| 193448 | | - i++; |
| 193449 | | - } |
| 193450 | | - } |
| 193451 | | - pStr->nUsed -= i; |
| 193452 | | - memmove(&z[1], &z[i+1], pStr->nUsed-1); |
| 193453 | | -} |
| 193454 | | -#else |
| 193455 | | -# define jsonGroupInverse 0 |
| 193456 | | -#endif |
| 193457 | | - |
| 193458 | | - |
| 193459 | | -/* |
| 193460 | | -** json_group_obj(NAME,VALUE) |
| 193461 | | -** |
| 193462 | | -** Return a JSON object composed of all names and values in the aggregate. |
| 193463 | | -*/ |
| 193464 | | -static void jsonObjectStep( |
| 193465 | | - sqlite3_context *ctx, |
| 193466 | | - int argc, |
| 193467 | | - sqlite3_value **argv |
| 193468 | | -){ |
| 193469 | | - JsonString *pStr; |
| 193470 | | - const char *z; |
| 193471 | | - u32 n; |
| 193472 | | - UNUSED_PARAM(argc); |
| 193473 | | - pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 193474 | | - if( pStr ){ |
| 193475 | | - if( pStr->zBuf==0 ){ |
| 193476 | | - jsonInit(pStr, ctx); |
| 193477 | | - jsonAppendChar(pStr, '{'); |
| 193478 | | - }else{ |
| 193479 | | - jsonAppendChar(pStr, ','); |
| 193480 | | - pStr->pCtx = ctx; |
| 193481 | | - } |
| 193482 | | - z = (const char*)sqlite3_value_text(argv[0]); |
| 193483 | | - n = (u32)sqlite3_value_bytes(argv[0]); |
| 193484 | | - jsonAppendString(pStr, z, n); |
| 193485 | | - jsonAppendChar(pStr, ':'); |
| 193486 | | - jsonAppendValue(pStr, argv[1]); |
| 193487 | | - } |
| 193488 | | -} |
| 193489 | | -static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 193490 | | - JsonString *pStr; |
| 193491 | | - pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 193492 | | - if( pStr ){ |
| 193493 | | - jsonAppendChar(pStr, '}'); |
| 193494 | | - if( pStr->bErr ){ |
| 193495 | | - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); |
| 193496 | | - assert( pStr->bStatic ); |
| 193497 | | - }else if( isFinal ){ |
| 193498 | | - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, |
| 193499 | | - pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); |
| 193500 | | - pStr->bStatic = 1; |
| 193501 | | - }else{ |
| 193502 | | - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, SQLITE_TRANSIENT); |
| 193503 | | - pStr->nUsed--; |
| 193504 | | - } |
| 193505 | | - }else{ |
| 193506 | | - sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); |
| 193507 | | - } |
| 193508 | | - sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 193509 | | -} |
| 193510 | | -static void jsonObjectValue(sqlite3_context *ctx){ |
| 193511 | | - jsonObjectCompute(ctx, 0); |
| 193512 | | -} |
| 193513 | | -static void jsonObjectFinal(sqlite3_context *ctx){ |
| 193514 | | - jsonObjectCompute(ctx, 1); |
| 193515 | | -} |
| 193516 | | - |
| 193517 | | - |
| 193518 | | - |
| 193519 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 193520 | | -/**************************************************************************** |
| 193521 | | -** The json_each virtual table |
| 193522 | | -****************************************************************************/ |
| 193523 | | -typedef struct JsonEachCursor JsonEachCursor; |
| 193524 | | -struct JsonEachCursor { |
| 193525 | | - sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 193526 | | - u32 iRowid; /* The rowid */ |
| 193527 | | - u32 iBegin; /* The first node of the scan */ |
| 193528 | | - u32 i; /* Index in sParse.aNode[] of current row */ |
| 193529 | | - u32 iEnd; /* EOF when i equals or exceeds this value */ |
| 193530 | | - u8 eType; /* Type of top-level element */ |
| 193531 | | - u8 bRecursive; /* True for json_tree(). False for json_each() */ |
| 193532 | | - char *zJson; /* Input JSON */ |
| 193533 | | - char *zRoot; /* Path by which to filter zJson */ |
| 193534 | | - JsonParse sParse; /* Parse of the input JSON */ |
| 193535 | | -}; |
| 193536 | | - |
| 193537 | | -/* Constructor for the json_each virtual table */ |
| 193538 | | -static int jsonEachConnect( |
| 193539 | | - sqlite3 *db, |
| 193540 | | - void *pAux, |
| 193541 | | - int argc, const char *const*argv, |
| 193542 | | - sqlite3_vtab **ppVtab, |
| 193543 | | - char **pzErr |
| 193544 | | -){ |
| 193545 | | - sqlite3_vtab *pNew; |
| 193546 | | - int rc; |
| 193547 | | - |
| 193548 | | -/* Column numbers */ |
| 193549 | | -#define JEACH_KEY 0 |
| 193550 | | -#define JEACH_VALUE 1 |
| 193551 | | -#define JEACH_TYPE 2 |
| 193552 | | -#define JEACH_ATOM 3 |
| 193553 | | -#define JEACH_ID 4 |
| 193554 | | -#define JEACH_PARENT 5 |
| 193555 | | -#define JEACH_FULLKEY 6 |
| 193556 | | -#define JEACH_PATH 7 |
| 193557 | | -#define JEACH_JSON 8 |
| 193558 | | -#define JEACH_ROOT 9 |
| 193559 | | - |
| 193560 | | - UNUSED_PARAM(pzErr); |
| 193561 | | - UNUSED_PARAM(argv); |
| 193562 | | - UNUSED_PARAM(argc); |
| 193563 | | - UNUSED_PARAM(pAux); |
| 193564 | | - rc = sqlite3_declare_vtab(db, |
| 193565 | | - "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," |
| 193566 | | - "json HIDDEN,root HIDDEN)"); |
| 193567 | | - if( rc==SQLITE_OK ){ |
| 193568 | | - pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); |
| 193569 | | - if( pNew==0 ) return SQLITE_NOMEM; |
| 193570 | | - memset(pNew, 0, sizeof(*pNew)); |
| 193571 | | - } |
| 193572 | | - return rc; |
| 193573 | | -} |
| 193574 | | - |
| 193575 | | -/* destructor for json_each virtual table */ |
| 193576 | | -static int jsonEachDisconnect(sqlite3_vtab *pVtab){ |
| 193577 | | - sqlite3_free(pVtab); |
| 193578 | | - return SQLITE_OK; |
| 193579 | | -} |
| 193580 | | - |
| 193581 | | -/* constructor for a JsonEachCursor object for json_each(). */ |
| 193582 | | -static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
| 193583 | | - JsonEachCursor *pCur; |
| 193584 | | - |
| 193585 | | - UNUSED_PARAM(p); |
| 193586 | | - pCur = sqlite3_malloc( sizeof(*pCur) ); |
| 193587 | | - if( pCur==0 ) return SQLITE_NOMEM; |
| 193588 | | - memset(pCur, 0, sizeof(*pCur)); |
| 193589 | | - *ppCursor = &pCur->base; |
| 193590 | | - return SQLITE_OK; |
| 193591 | | -} |
| 193592 | | - |
| 193593 | | -/* constructor for a JsonEachCursor object for json_tree(). */ |
| 193594 | | -static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
| 193595 | | - int rc = jsonEachOpenEach(p, ppCursor); |
| 193596 | | - if( rc==SQLITE_OK ){ |
| 193597 | | - JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; |
| 193598 | | - pCur->bRecursive = 1; |
| 193599 | | - } |
| 193600 | | - return rc; |
| 193601 | | -} |
| 193602 | | - |
| 193603 | | -/* Reset a JsonEachCursor back to its original state. Free any memory |
| 193604 | | -** held. */ |
| 193605 | | -static void jsonEachCursorReset(JsonEachCursor *p){ |
| 193606 | | - sqlite3_free(p->zJson); |
| 193607 | | - sqlite3_free(p->zRoot); |
| 193608 | | - jsonParseReset(&p->sParse); |
| 193609 | | - p->iRowid = 0; |
| 193610 | | - p->i = 0; |
| 193611 | | - p->iEnd = 0; |
| 193612 | | - p->eType = 0; |
| 193613 | | - p->zJson = 0; |
| 193614 | | - p->zRoot = 0; |
| 193615 | | -} |
| 193616 | | - |
| 193617 | | -/* Destructor for a jsonEachCursor object */ |
| 193618 | | -static int jsonEachClose(sqlite3_vtab_cursor *cur){ |
| 193619 | | - JsonEachCursor *p = (JsonEachCursor*)cur; |
| 193620 | | - jsonEachCursorReset(p); |
| 193621 | | - sqlite3_free(cur); |
| 193622 | | - return SQLITE_OK; |
| 193623 | | -} |
| 193624 | | - |
| 193625 | | -/* Return TRUE if the jsonEachCursor object has been advanced off the end |
| 193626 | | -** of the JSON object */ |
| 193627 | | -static int jsonEachEof(sqlite3_vtab_cursor *cur){ |
| 193628 | | - JsonEachCursor *p = (JsonEachCursor*)cur; |
| 193629 | | - return p->i >= p->iEnd; |
| 193630 | | -} |
| 193631 | | - |
| 193632 | | -/* Advance the cursor to the next element for json_tree() */ |
| 193633 | | -static int jsonEachNext(sqlite3_vtab_cursor *cur){ |
| 193634 | | - JsonEachCursor *p = (JsonEachCursor*)cur; |
| 193635 | | - if( p->bRecursive ){ |
| 193636 | | - if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; |
| 193637 | | - p->i++; |
| 193638 | | - p->iRowid++; |
| 193639 | | - if( p->i<p->iEnd ){ |
| 193640 | | - u32 iUp = p->sParse.aUp[p->i]; |
| 193641 | | - JsonNode *pUp = &p->sParse.aNode[iUp]; |
| 193642 | | - p->eType = pUp->eType; |
| 193643 | | - if( pUp->eType==JSON_ARRAY ){ |
| 193644 | | - if( iUp==p->i-1 ){ |
| 193645 | | - pUp->u.iKey = 0; |
| 193646 | | - }else{ |
| 193647 | | - pUp->u.iKey++; |
| 193648 | | - } |
| 193649 | | - } |
| 193650 | | - } |
| 193651 | | - }else{ |
| 193652 | | - switch( p->eType ){ |
| 193653 | | - case JSON_ARRAY: { |
| 193654 | | - p->i += jsonNodeSize(&p->sParse.aNode[p->i]); |
| 193655 | | - p->iRowid++; |
| 193656 | | - break; |
| 193657 | | - } |
| 193658 | | - case JSON_OBJECT: { |
| 193659 | | - p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); |
| 193660 | | - p->iRowid++; |
| 193661 | | - break; |
| 193662 | | - } |
| 193663 | | - default: { |
| 193664 | | - p->i = p->iEnd; |
| 193665 | | - break; |
| 193666 | | - } |
| 193667 | | - } |
| 193668 | | - } |
| 193669 | | - return SQLITE_OK; |
| 193670 | | -} |
| 193671 | | - |
| 193672 | | -/* Append the name of the path for element i to pStr |
| 193673 | | -*/ |
| 193674 | | -static void jsonEachComputePath( |
| 193675 | | - JsonEachCursor *p, /* The cursor */ |
| 193676 | | - JsonString *pStr, /* Write the path here */ |
| 193677 | | - u32 i /* Path to this element */ |
| 193678 | | -){ |
| 193679 | | - JsonNode *pNode, *pUp; |
| 193680 | | - u32 iUp; |
| 193681 | | - if( i==0 ){ |
| 193682 | | - jsonAppendChar(pStr, '$'); |
| 193683 | | - return; |
| 193684 | | - } |
| 193685 | | - iUp = p->sParse.aUp[i]; |
| 193686 | | - jsonEachComputePath(p, pStr, iUp); |
| 193687 | | - pNode = &p->sParse.aNode[i]; |
| 193688 | | - pUp = &p->sParse.aNode[iUp]; |
| 193689 | | - if( pUp->eType==JSON_ARRAY ){ |
| 193690 | | - jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); |
| 193691 | | - }else{ |
| 193692 | | - assert( pUp->eType==JSON_OBJECT ); |
| 193693 | | - if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; |
| 193694 | | - assert( pNode->eType==JSON_STRING ); |
| 193695 | | - assert( pNode->jnFlags & JNODE_LABEL ); |
| 193696 | | - jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); |
| 193697 | | - } |
| 193698 | | -} |
| 193699 | | - |
| 193700 | | -/* Return the value of a column */ |
| 193701 | | -static int jsonEachColumn( |
| 193702 | | - sqlite3_vtab_cursor *cur, /* The cursor */ |
| 193703 | | - sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
| 193704 | | - int i /* Which column to return */ |
| 193705 | | -){ |
| 193706 | | - JsonEachCursor *p = (JsonEachCursor*)cur; |
| 193707 | | - JsonNode *pThis = &p->sParse.aNode[p->i]; |
| 193708 | | - switch( i ){ |
| 193709 | | - case JEACH_KEY: { |
| 193710 | | - if( p->i==0 ) break; |
| 193711 | | - if( p->eType==JSON_OBJECT ){ |
| 193712 | | - jsonReturn(pThis, ctx, 0); |
| 193713 | | - }else if( p->eType==JSON_ARRAY ){ |
| 193714 | | - u32 iKey; |
| 193715 | | - if( p->bRecursive ){ |
| 193716 | | - if( p->iRowid==0 ) break; |
| 193717 | | - iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; |
| 193718 | | - }else{ |
| 193719 | | - iKey = p->iRowid; |
| 193720 | | - } |
| 193721 | | - sqlite3_result_int64(ctx, (sqlite3_int64)iKey); |
| 193722 | | - } |
| 193723 | | - break; |
| 193724 | | - } |
| 193725 | | - case JEACH_VALUE: { |
| 193726 | | - if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 193727 | | - jsonReturn(pThis, ctx, 0); |
| 193728 | | - break; |
| 193729 | | - } |
| 193730 | | - case JEACH_TYPE: { |
| 193731 | | - if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 193732 | | - sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); |
| 193733 | | - break; |
| 193734 | | - } |
| 193735 | | - case JEACH_ATOM: { |
| 193736 | | - if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 193737 | | - if( pThis->eType>=JSON_ARRAY ) break; |
| 193738 | | - jsonReturn(pThis, ctx, 0); |
| 193739 | | - break; |
| 193740 | | - } |
| 193741 | | - case JEACH_ID: { |
| 193742 | | - sqlite3_result_int64(ctx, |
| 193743 | | - (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); |
| 193744 | | - break; |
| 193745 | | - } |
| 193746 | | - case JEACH_PARENT: { |
| 193747 | | - if( p->i>p->iBegin && p->bRecursive ){ |
| 193748 | | - sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); |
| 193749 | | - } |
| 193750 | | - break; |
| 193751 | | - } |
| 193752 | | - case JEACH_FULLKEY: { |
| 193753 | | - JsonString x; |
| 193754 | | - jsonInit(&x, ctx); |
| 193755 | | - if( p->bRecursive ){ |
| 193756 | | - jsonEachComputePath(p, &x, p->i); |
| 193757 | | - }else{ |
| 193758 | | - if( p->zRoot ){ |
| 193759 | | - jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); |
| 193760 | | - }else{ |
| 193761 | | - jsonAppendChar(&x, '$'); |
| 193762 | | - } |
| 193763 | | - if( p->eType==JSON_ARRAY ){ |
| 193764 | | - jsonPrintf(30, &x, "[%d]", p->iRowid); |
| 193765 | | - }else if( p->eType==JSON_OBJECT ){ |
| 193766 | | - jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); |
| 193767 | | - } |
| 193768 | | - } |
| 193769 | | - jsonResult(&x); |
| 193770 | | - break; |
| 193771 | | - } |
| 193772 | | - case JEACH_PATH: { |
| 193773 | | - if( p->bRecursive ){ |
| 193774 | | - JsonString x; |
| 193775 | | - jsonInit(&x, ctx); |
| 193776 | | - jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); |
| 193777 | | - jsonResult(&x); |
| 193778 | | - break; |
| 193779 | | - } |
| 193780 | | - /* For json_each() path and root are the same so fall through |
| 193781 | | - ** into the root case */ |
| 193782 | | - } |
| 193783 | | - default: { |
| 193784 | | - const char *zRoot = p->zRoot; |
| 193785 | | - if( zRoot==0 ) zRoot = "$"; |
| 193786 | | - sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); |
| 193787 | | - break; |
| 193788 | | - } |
| 193789 | | - case JEACH_JSON: { |
| 193790 | | - assert( i==JEACH_JSON ); |
| 193791 | | - sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); |
| 193792 | | - break; |
| 193793 | | - } |
| 193794 | | - } |
| 193795 | | - return SQLITE_OK; |
| 193796 | | -} |
| 193797 | | - |
| 193798 | | -/* Return the current rowid value */ |
| 193799 | | -static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 193800 | | - JsonEachCursor *p = (JsonEachCursor*)cur; |
| 193801 | | - *pRowid = p->iRowid; |
| 193802 | | - return SQLITE_OK; |
| 193803 | | -} |
| 193804 | | - |
| 193805 | | -/* The query strategy is to look for an equality constraint on the json |
| 193806 | | -** column. Without such a constraint, the table cannot operate. idxNum is |
| 193807 | | -** 1 if the constraint is found, 3 if the constraint and zRoot are found, |
| 193808 | | -** and 0 otherwise. |
| 193809 | | -*/ |
| 193810 | | -static int jsonEachBestIndex( |
| 193811 | | - sqlite3_vtab *tab, |
| 193812 | | - sqlite3_index_info *pIdxInfo |
| 193813 | | -){ |
| 193814 | | - int i; |
| 193815 | | - int jsonIdx = -1; |
| 193816 | | - int rootIdx = -1; |
| 193817 | | - const struct sqlite3_index_constraint *pConstraint; |
| 193818 | | - |
| 193819 | | - UNUSED_PARAM(tab); |
| 193820 | | - pConstraint = pIdxInfo->aConstraint; |
| 193821 | | - for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 193822 | | - if( pConstraint->usable==0 ) continue; |
| 193823 | | - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
| 193824 | | - switch( pConstraint->iColumn ){ |
| 193825 | | - case JEACH_JSON: jsonIdx = i; break; |
| 193826 | | - case JEACH_ROOT: rootIdx = i; break; |
| 193827 | | - default: /* no-op */ break; |
| 193828 | | - } |
| 193829 | | - } |
| 193830 | | - if( jsonIdx<0 ){ |
| 193831 | | - pIdxInfo->idxNum = 0; |
| 193832 | | - pIdxInfo->estimatedCost = 1e99; |
| 193833 | | - }else{ |
| 193834 | | - pIdxInfo->estimatedCost = 1.0; |
| 193835 | | - pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1; |
| 193836 | | - pIdxInfo->aConstraintUsage[jsonIdx].omit = 1; |
| 193837 | | - if( rootIdx<0 ){ |
| 193838 | | - pIdxInfo->idxNum = 1; |
| 193839 | | - }else{ |
| 193840 | | - pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2; |
| 193841 | | - pIdxInfo->aConstraintUsage[rootIdx].omit = 1; |
| 193842 | | - pIdxInfo->idxNum = 3; |
| 193843 | | - } |
| 193844 | | - } |
| 193845 | | - return SQLITE_OK; |
| 193846 | | -} |
| 193847 | | - |
| 193848 | | -/* Start a search on a new JSON string */ |
| 193849 | | -static int jsonEachFilter( |
| 193850 | | - sqlite3_vtab_cursor *cur, |
| 193851 | | - int idxNum, const char *idxStr, |
| 193852 | | - int argc, sqlite3_value **argv |
| 193853 | | -){ |
| 193854 | | - JsonEachCursor *p = (JsonEachCursor*)cur; |
| 193855 | | - const char *z; |
| 193856 | | - const char *zRoot = 0; |
| 193857 | | - sqlite3_int64 n; |
| 193858 | | - |
| 193859 | | - UNUSED_PARAM(idxStr); |
| 193860 | | - UNUSED_PARAM(argc); |
| 193861 | | - jsonEachCursorReset(p); |
| 193862 | | - if( idxNum==0 ) return SQLITE_OK; |
| 193863 | | - z = (const char*)sqlite3_value_text(argv[0]); |
| 193864 | | - if( z==0 ) return SQLITE_OK; |
| 193865 | | - n = sqlite3_value_bytes(argv[0]); |
| 193866 | | - p->zJson = sqlite3_malloc64( n+1 ); |
| 193867 | | - if( p->zJson==0 ) return SQLITE_NOMEM; |
| 193868 | | - memcpy(p->zJson, z, (size_t)n+1); |
| 193869 | | - if( jsonParse(&p->sParse, 0, p->zJson) ){ |
| 193870 | | - int rc = SQLITE_NOMEM; |
| 193871 | | - if( p->sParse.oom==0 ){ |
| 193872 | | - sqlite3_free(cur->pVtab->zErrMsg); |
| 193873 | | - cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); |
| 193874 | | - if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; |
| 193875 | | - } |
| 193876 | | - jsonEachCursorReset(p); |
| 193877 | | - return rc; |
| 193878 | | - }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ |
| 193879 | | - jsonEachCursorReset(p); |
| 193880 | | - return SQLITE_NOMEM; |
| 193881 | | - }else{ |
| 193882 | | - JsonNode *pNode = 0; |
| 193883 | | - if( idxNum==3 ){ |
| 193884 | | - const char *zErr = 0; |
| 193885 | | - zRoot = (const char*)sqlite3_value_text(argv[1]); |
| 193886 | | - if( zRoot==0 ) return SQLITE_OK; |
| 193887 | | - n = sqlite3_value_bytes(argv[1]); |
| 193888 | | - p->zRoot = sqlite3_malloc64( n+1 ); |
| 193889 | | - if( p->zRoot==0 ) return SQLITE_NOMEM; |
| 193890 | | - memcpy(p->zRoot, zRoot, (size_t)n+1); |
| 193891 | | - if( zRoot[0]!='$' ){ |
| 193892 | | - zErr = zRoot; |
| 193893 | | - }else{ |
| 193894 | | - pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); |
| 193895 | | - } |
| 193896 | | - if( zErr ){ |
| 193897 | | - sqlite3_free(cur->pVtab->zErrMsg); |
| 193898 | | - cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); |
| 193899 | | - jsonEachCursorReset(p); |
| 193900 | | - return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; |
| 193901 | | - }else if( pNode==0 ){ |
| 193902 | | - return SQLITE_OK; |
| 193903 | | - } |
| 193904 | | - }else{ |
| 193905 | | - pNode = p->sParse.aNode; |
| 193906 | | - } |
| 193907 | | - p->iBegin = p->i = (int)(pNode - p->sParse.aNode); |
| 193908 | | - p->eType = pNode->eType; |
| 193909 | | - if( p->eType>=JSON_ARRAY ){ |
| 193910 | | - pNode->u.iKey = 0; |
| 193911 | | - p->iEnd = p->i + pNode->n + 1; |
| 193912 | | - if( p->bRecursive ){ |
| 193913 | | - p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; |
| 193914 | | - if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ |
| 193915 | | - p->i--; |
| 193916 | | - } |
| 193917 | | - }else{ |
| 193918 | | - p->i++; |
| 193919 | | - } |
| 193920 | | - }else{ |
| 193921 | | - p->iEnd = p->i+1; |
| 193922 | | - } |
| 193923 | | - } |
| 193924 | | - return SQLITE_OK; |
| 193925 | | -} |
| 193926 | | - |
| 193927 | | -/* The methods of the json_each virtual table */ |
| 193928 | | -static sqlite3_module jsonEachModule = { |
| 193929 | | - 0, /* iVersion */ |
| 193930 | | - 0, /* xCreate */ |
| 193931 | | - jsonEachConnect, /* xConnect */ |
| 193932 | | - jsonEachBestIndex, /* xBestIndex */ |
| 193933 | | - jsonEachDisconnect, /* xDisconnect */ |
| 193934 | | - 0, /* xDestroy */ |
| 193935 | | - jsonEachOpenEach, /* xOpen - open a cursor */ |
| 193936 | | - jsonEachClose, /* xClose - close a cursor */ |
| 193937 | | - jsonEachFilter, /* xFilter - configure scan constraints */ |
| 193938 | | - jsonEachNext, /* xNext - advance a cursor */ |
| 193939 | | - jsonEachEof, /* xEof - check for end of scan */ |
| 193940 | | - jsonEachColumn, /* xColumn - read data */ |
| 193941 | | - jsonEachRowid, /* xRowid - read data */ |
| 193942 | | - 0, /* xUpdate */ |
| 193943 | | - 0, /* xBegin */ |
| 193944 | | - 0, /* xSync */ |
| 193945 | | - 0, /* xCommit */ |
| 193946 | | - 0, /* xRollback */ |
| 193947 | | - 0, /* xFindMethod */ |
| 193948 | | - 0, /* xRename */ |
| 193949 | | - 0, /* xSavepoint */ |
| 193950 | | - 0, /* xRelease */ |
| 193951 | | - 0 /* xRollbackTo */ |
| 193952 | | -}; |
| 193953 | | - |
| 193954 | | -/* The methods of the json_tree virtual table. */ |
| 193955 | | -static sqlite3_module jsonTreeModule = { |
| 193956 | | - 0, /* iVersion */ |
| 193957 | | - 0, /* xCreate */ |
| 193958 | | - jsonEachConnect, /* xConnect */ |
| 193959 | | - jsonEachBestIndex, /* xBestIndex */ |
| 193960 | | - jsonEachDisconnect, /* xDisconnect */ |
| 193961 | | - 0, /* xDestroy */ |
| 193962 | | - jsonEachOpenTree, /* xOpen - open a cursor */ |
| 193963 | | - jsonEachClose, /* xClose - close a cursor */ |
| 193964 | | - jsonEachFilter, /* xFilter - configure scan constraints */ |
| 193965 | | - jsonEachNext, /* xNext - advance a cursor */ |
| 193966 | | - jsonEachEof, /* xEof - check for end of scan */ |
| 193967 | | - jsonEachColumn, /* xColumn - read data */ |
| 193968 | | - jsonEachRowid, /* xRowid - read data */ |
| 193969 | | - 0, /* xUpdate */ |
| 193970 | | - 0, /* xBegin */ |
| 193971 | | - 0, /* xSync */ |
| 193972 | | - 0, /* xCommit */ |
| 193973 | | - 0, /* xRollback */ |
| 193974 | | - 0, /* xFindMethod */ |
| 193975 | | - 0, /* xRename */ |
| 193976 | | - 0, /* xSavepoint */ |
| 193977 | | - 0, /* xRelease */ |
| 193978 | | - 0 /* xRollbackTo */ |
| 193979 | | -}; |
| 193980 | | -#endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 193981 | | - |
| 193982 | | -/**************************************************************************** |
| 193983 | | -** The following routines are the only publically visible identifiers in this |
| 193984 | | -** file. Call the following routines in order to register the various SQL |
| 193985 | | -** functions and the virtual table implemented by this file. |
| 193986 | | -****************************************************************************/ |
| 193987 | | - |
| 193988 | | -SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ |
| 193989 | | - int rc = SQLITE_OK; |
| 193990 | | - unsigned int i; |
| 193991 | | - static const struct { |
| 193992 | | - const char *zName; |
| 193993 | | - int nArg; |
| 193994 | | - int flag; |
| 193995 | | - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); |
| 193996 | | - } aFunc[] = { |
| 193997 | | - { "json", 1, 0, jsonRemoveFunc }, |
| 193998 | | - { "json_array", -1, 0, jsonArrayFunc }, |
| 193999 | | - { "json_array_length", 1, 0, jsonArrayLengthFunc }, |
| 194000 | | - { "json_array_length", 2, 0, jsonArrayLengthFunc }, |
| 194001 | | - { "json_extract", -1, 0, jsonExtractFunc }, |
| 194002 | | - { "json_insert", -1, 0, jsonSetFunc }, |
| 194003 | | - { "json_object", -1, 0, jsonObjectFunc }, |
| 194004 | | - { "json_patch", 2, 0, jsonPatchFunc }, |
| 194005 | | - { "json_quote", 1, 0, jsonQuoteFunc }, |
| 194006 | | - { "json_remove", -1, 0, jsonRemoveFunc }, |
| 194007 | | - { "json_replace", -1, 0, jsonReplaceFunc }, |
| 194008 | | - { "json_set", -1, 1, jsonSetFunc }, |
| 194009 | | - { "json_type", 1, 0, jsonTypeFunc }, |
| 194010 | | - { "json_type", 2, 0, jsonTypeFunc }, |
| 194011 | | - { "json_valid", 1, 0, jsonValidFunc }, |
| 194012 | | - |
| 194013 | | -#if SQLITE_DEBUG |
| 194014 | | - /* DEBUG and TESTING functions */ |
| 194015 | | - { "json_parse", 1, 0, jsonParseFunc }, |
| 194016 | | - { "json_test1", 1, 0, jsonTest1Func }, |
| 194017 | | -#endif |
| 194018 | | - }; |
| 194019 | | - static const struct { |
| 194020 | | - const char *zName; |
| 194021 | | - int nArg; |
| 194022 | | - void (*xStep)(sqlite3_context*,int,sqlite3_value**); |
| 194023 | | - void (*xFinal)(sqlite3_context*); |
| 194024 | | - void (*xValue)(sqlite3_context*); |
| 194025 | | - } aAgg[] = { |
| 194026 | | - { "json_group_array", 1, |
| 194027 | | - jsonArrayStep, jsonArrayFinal, jsonArrayValue }, |
| 194028 | | - { "json_group_object", 2, |
| 194029 | | - jsonObjectStep, jsonObjectFinal, jsonObjectValue }, |
| 194030 | | - }; |
| 194031 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 194032 | | - static const struct { |
| 194033 | | - const char *zName; |
| 194034 | | - sqlite3_module *pModule; |
| 194035 | | - } aMod[] = { |
| 194036 | | - { "json_each", &jsonEachModule }, |
| 194037 | | - { "json_tree", &jsonTreeModule }, |
| 194038 | | - }; |
| 194039 | | -#endif |
| 194040 | | - for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ |
| 194041 | | - rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, |
| 194042 | | - SQLITE_UTF8 | SQLITE_DETERMINISTIC, |
| 194043 | | - (void*)&aFunc[i].flag, |
| 194044 | | - aFunc[i].xFunc, 0, 0); |
| 194045 | | - } |
| 194046 | | -#ifndef SQLITE_OMIT_WINDOWFUNC |
| 194047 | | - for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ |
| 194048 | | - rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg, |
| 194049 | | - SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, |
| 194050 | | - aAgg[i].xStep, aAgg[i].xFinal, |
| 194051 | | - aAgg[i].xValue, jsonGroupInverse, 0); |
| 194052 | | - } |
| 194053 | | -#endif |
| 194054 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 194055 | | - for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){ |
| 194056 | | - rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0); |
| 194057 | | - } |
| 194058 | | -#endif |
| 194059 | | - return rc; |
| 194060 | | -} |
| 194061 | | - |
| 194062 | | - |
| 194063 | | -#ifndef SQLITE_CORE |
| 194064 | | -#ifdef _WIN32 |
| 194065 | | -__declspec(dllexport) |
| 194066 | | -#endif |
| 194067 | | -SQLITE_API int sqlite3_json_init( |
| 194068 | | - sqlite3 *db, |
| 194069 | | - char **pzErrMsg, |
| 194070 | | - const sqlite3_api_routines *pApi |
| 194071 | | -){ |
| 194072 | | - SQLITE_EXTENSION_INIT2(pApi); |
| 194073 | | - (void)pzErrMsg; /* Unused parameter */ |
| 194074 | | - return sqlite3Json1Init(db); |
| 194075 | | -} |
| 194076 | | -#endif |
| 194077 | | -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */ |
| 194078 | | - |
| 194079 | | -/************** End of json1.c ***********************************************/ |
| 194080 | 195887 | /************** Begin file fts5.c ********************************************/ |
| 194081 | 195888 | |
| 194082 | 195889 | |
| 194083 | 195890 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) |
| 194084 | 195891 | |
| | @@ -211528,11 +213335,11 @@ |
| 211528 | 213335 | int nArg, /* Number of args */ |
| 211529 | 213336 | sqlite3_value **apUnused /* Function arguments */ |
| 211530 | 213337 | ){ |
| 211531 | 213338 | assert( nArg==0 ); |
| 211532 | 213339 | UNUSED_PARAM2(nArg, apUnused); |
| 211533 | | - sqlite3_result_text(pCtx, "fts5: 2018-08-16 15:29:40 60045fbf52162f15f2e18a4e392e80fab19bdbce242728b5e62b0894eac49dfd", -1, SQLITE_TRANSIENT); |
| 213340 | + sqlite3_result_text(pCtx, "fts5: 2018-08-30 01:52:10 58078c0d2647a194279fa80e032670441b296ffc3acee692901faa5beca460b7", -1, SQLITE_TRANSIENT); |
| 211534 | 213341 | } |
| 211535 | 213342 | |
| 211536 | 213343 | static int fts5Init(sqlite3 *db){ |
| 211537 | 213344 | static const sqlite3_module fts5Mod = { |
| 211538 | 213345 | /* iVersion */ 2, |
| | @@ -216238,12 +218045,12 @@ |
| 216238 | 218045 | } |
| 216239 | 218046 | #endif /* SQLITE_CORE */ |
| 216240 | 218047 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ |
| 216241 | 218048 | |
| 216242 | 218049 | /************** End of stmt.c ************************************************/ |
| 216243 | | -#if __LINE__!=216243 |
| 218050 | +#if __LINE__!=218050 |
| 216244 | 218051 | #undef SQLITE_SOURCE_ID |
| 216245 | | -#define SQLITE_SOURCE_ID "2018-08-16 16:24:24 456842924bb33c0af8af29402f06e5f25b6791f698a0d12a080258b20b0calt2" |
| 218052 | +#define SQLITE_SOURCE_ID "2018-08-30 01:52:10 58078c0d2647a194279fa80e032670441b296ffc3acee692901faa5beca4alt2" |
| 216246 | 218053 | #endif |
| 216247 | 218054 | /* Return the source-id for this library */ |
| 216248 | 218055 | SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } |
| 216249 | 218056 | /************************** End of sqlite3.c ******************************/ |
| 216250 | 218057 | |