| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2008 Nov 28 | 2 ** 2008 Nov 28 |
| 3 ** | 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
| 6 ** | 6 ** |
| 7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
| 10 ** | 10 ** |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ | 786 static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ |
| 787 int rc = SQLITE_OK; /* Return code */ | 787 int rc = SQLITE_OK; /* Return code */ |
| 788 Fts3Expr *pRoot = *pp; /* Initial root node */ | 788 Fts3Expr *pRoot = *pp; /* Initial root node */ |
| 789 Fts3Expr *pFree = 0; /* List of free nodes. Linked by pParent. */ | 789 Fts3Expr *pFree = 0; /* List of free nodes. Linked by pParent. */ |
| 790 int eType = pRoot->eType; /* Type of node in this tree */ | 790 int eType = pRoot->eType; /* Type of node in this tree */ |
| 791 | 791 |
| 792 if( nMaxDepth==0 ){ | 792 if( nMaxDepth==0 ){ |
| 793 rc = SQLITE_ERROR; | 793 rc = SQLITE_ERROR; |
| 794 } | 794 } |
| 795 | 795 |
| 796 if( rc==SQLITE_OK && (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ | 796 if( rc==SQLITE_OK ){ |
| 797 Fts3Expr **apLeaf; | 797 if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ |
| 798 apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth); | 798 Fts3Expr **apLeaf; |
| 799 if( 0==apLeaf ){ | 799 apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth); |
| 800 rc = SQLITE_NOMEM; | 800 if( 0==apLeaf ){ |
| 801 }else{ | 801 rc = SQLITE_NOMEM; |
| 802 memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth); | 802 }else{ |
| 803 } | 803 memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth); |
| 804 | |
| 805 if( rc==SQLITE_OK ){ | |
| 806 int i; | |
| 807 Fts3Expr *p; | |
| 808 | |
| 809 /* Set $p to point to the left-most leaf in the tree of eType nodes. */ | |
| 810 for(p=pRoot; p->eType==eType; p=p->pLeft){ | |
| 811 assert( p->pParent==0 || p->pParent->pLeft==p ); | |
| 812 assert( p->pLeft && p->pRight ); | |
| 813 } | |
| 814 | |
| 815 /* This loop runs once for each leaf in the tree of eType nodes. */ | |
| 816 while( 1 ){ | |
| 817 int iLvl; | |
| 818 Fts3Expr *pParent = p->pParent; /* Current parent of p */ | |
| 819 | |
| 820 assert( pParent==0 || pParent->pLeft==p ); | |
| 821 p->pParent = 0; | |
| 822 if( pParent ){ | |
| 823 pParent->pLeft = 0; | |
| 824 }else{ | |
| 825 pRoot = 0; | |
| 826 } | |
| 827 rc = fts3ExprBalance(&p, nMaxDepth-1); | |
| 828 if( rc!=SQLITE_OK ) break; | |
| 829 | |
| 830 for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){ | |
| 831 if( apLeaf[iLvl]==0 ){ | |
| 832 apLeaf[iLvl] = p; | |
| 833 p = 0; | |
| 834 }else{ | |
| 835 assert( pFree ); | |
| 836 pFree->pLeft = apLeaf[iLvl]; | |
| 837 pFree->pRight = p; | |
| 838 pFree->pLeft->pParent = pFree; | |
| 839 pFree->pRight->pParent = pFree; | |
| 840 | |
| 841 p = pFree; | |
| 842 pFree = pFree->pParent; | |
| 843 p->pParent = 0; | |
| 844 apLeaf[iLvl] = 0; | |
| 845 } | |
| 846 } | |
| 847 if( p ){ | |
| 848 sqlite3Fts3ExprFree(p); | |
| 849 rc = SQLITE_TOOBIG; | |
| 850 break; | |
| 851 } | |
| 852 | |
| 853 /* If that was the last leaf node, break out of the loop */ | |
| 854 if( pParent==0 ) break; | |
| 855 | |
| 856 /* Set $p to point to the next leaf in the tree of eType nodes */ | |
| 857 for(p=pParent->pRight; p->eType==eType; p=p->pLeft); | |
| 858 | |
| 859 /* Remove pParent from the original tree. */ | |
| 860 assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent ); | |
| 861 pParent->pRight->pParent = pParent->pParent; | |
| 862 if( pParent->pParent ){ | |
| 863 pParent->pParent->pLeft = pParent->pRight; | |
| 864 }else{ | |
| 865 assert( pParent==pRoot ); | |
| 866 pRoot = pParent->pRight; | |
| 867 } | |
| 868 | |
| 869 /* Link pParent into the free node list. It will be used as an | |
| 870 ** internal node of the new tree. */ | |
| 871 pParent->pParent = pFree; | |
| 872 pFree = pParent; | |
| 873 } | 804 } |
| 874 | 805 |
| 875 if( rc==SQLITE_OK ){ | 806 if( rc==SQLITE_OK ){ |
| 876 p = 0; | 807 int i; |
| 877 for(i=0; i<nMaxDepth; i++){ | 808 Fts3Expr *p; |
| 878 if( apLeaf[i] ){ | 809 |
| 879 if( p==0 ){ | 810 /* Set $p to point to the left-most leaf in the tree of eType nodes. */ |
| 880 p = apLeaf[i]; | 811 for(p=pRoot; p->eType==eType; p=p->pLeft){ |
| 881 p->pParent = 0; | 812 assert( p->pParent==0 || p->pParent->pLeft==p ); |
| 813 assert( p->pLeft && p->pRight ); |
| 814 } |
| 815 |
| 816 /* This loop runs once for each leaf in the tree of eType nodes. */ |
| 817 while( 1 ){ |
| 818 int iLvl; |
| 819 Fts3Expr *pParent = p->pParent; /* Current parent of p */ |
| 820 |
| 821 assert( pParent==0 || pParent->pLeft==p ); |
| 822 p->pParent = 0; |
| 823 if( pParent ){ |
| 824 pParent->pLeft = 0; |
| 825 }else{ |
| 826 pRoot = 0; |
| 827 } |
| 828 rc = fts3ExprBalance(&p, nMaxDepth-1); |
| 829 if( rc!=SQLITE_OK ) break; |
| 830 |
| 831 for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){ |
| 832 if( apLeaf[iLvl]==0 ){ |
| 833 apLeaf[iLvl] = p; |
| 834 p = 0; |
| 882 }else{ | 835 }else{ |
| 883 assert( pFree!=0 ); | 836 assert( pFree ); |
| 837 pFree->pLeft = apLeaf[iLvl]; |
| 884 pFree->pRight = p; | 838 pFree->pRight = p; |
| 885 pFree->pLeft = apLeaf[i]; | |
| 886 pFree->pLeft->pParent = pFree; | 839 pFree->pLeft->pParent = pFree; |
| 887 pFree->pRight->pParent = pFree; | 840 pFree->pRight->pParent = pFree; |
| 888 | 841 |
| 889 p = pFree; | 842 p = pFree; |
| 890 pFree = pFree->pParent; | 843 pFree = pFree->pParent; |
| 891 p->pParent = 0; | 844 p->pParent = 0; |
| 845 apLeaf[iLvl] = 0; |
| 892 } | 846 } |
| 893 } | 847 } |
| 848 if( p ){ |
| 849 sqlite3Fts3ExprFree(p); |
| 850 rc = SQLITE_TOOBIG; |
| 851 break; |
| 852 } |
| 853 |
| 854 /* If that was the last leaf node, break out of the loop */ |
| 855 if( pParent==0 ) break; |
| 856 |
| 857 /* Set $p to point to the next leaf in the tree of eType nodes */ |
| 858 for(p=pParent->pRight; p->eType==eType; p=p->pLeft); |
| 859 |
| 860 /* Remove pParent from the original tree. */ |
| 861 assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent ); |
| 862 pParent->pRight->pParent = pParent->pParent; |
| 863 if( pParent->pParent ){ |
| 864 pParent->pParent->pLeft = pParent->pRight; |
| 865 }else{ |
| 866 assert( pParent==pRoot ); |
| 867 pRoot = pParent->pRight; |
| 868 } |
| 869 |
| 870 /* Link pParent into the free node list. It will be used as an |
| 871 ** internal node of the new tree. */ |
| 872 pParent->pParent = pFree; |
| 873 pFree = pParent; |
| 894 } | 874 } |
| 895 pRoot = p; | 875 |
| 896 }else{ | 876 if( rc==SQLITE_OK ){ |
| 897 /* An error occurred. Delete the contents of the apLeaf[] array | 877 p = 0; |
| 898 ** and pFree list. Everything else is cleaned up by the call to | 878 for(i=0; i<nMaxDepth; i++){ |
| 899 ** sqlite3Fts3ExprFree(pRoot) below. */ | 879 if( apLeaf[i] ){ |
| 900 Fts3Expr *pDel; | 880 if( p==0 ){ |
| 901 for(i=0; i<nMaxDepth; i++){ | 881 p = apLeaf[i]; |
| 902 sqlite3Fts3ExprFree(apLeaf[i]); | 882 p->pParent = 0; |
| 883 }else{ |
| 884 assert( pFree!=0 ); |
| 885 pFree->pRight = p; |
| 886 pFree->pLeft = apLeaf[i]; |
| 887 pFree->pLeft->pParent = pFree; |
| 888 pFree->pRight->pParent = pFree; |
| 889 |
| 890 p = pFree; |
| 891 pFree = pFree->pParent; |
| 892 p->pParent = 0; |
| 893 } |
| 894 } |
| 895 } |
| 896 pRoot = p; |
| 897 }else{ |
| 898 /* An error occurred. Delete the contents of the apLeaf[] array |
| 899 ** and pFree list. Everything else is cleaned up by the call to |
| 900 ** sqlite3Fts3ExprFree(pRoot) below. */ |
| 901 Fts3Expr *pDel; |
| 902 for(i=0; i<nMaxDepth; i++){ |
| 903 sqlite3Fts3ExprFree(apLeaf[i]); |
| 904 } |
| 905 while( (pDel=pFree)!=0 ){ |
| 906 pFree = pDel->pParent; |
| 907 sqlite3_free(pDel); |
| 908 } |
| 903 } | 909 } |
| 904 while( (pDel=pFree)!=0 ){ | 910 |
| 905 pFree = pDel->pParent; | 911 assert( pFree==0 ); |
| 906 sqlite3_free(pDel); | 912 sqlite3_free( apLeaf ); |
| 907 } | 913 } |
| 914 }else if( eType==FTSQUERY_NOT ){ |
| 915 Fts3Expr *pLeft = pRoot->pLeft; |
| 916 Fts3Expr *pRight = pRoot->pRight; |
| 917 |
| 918 pRoot->pLeft = 0; |
| 919 pRoot->pRight = 0; |
| 920 pLeft->pParent = 0; |
| 921 pRight->pParent = 0; |
| 922 |
| 923 rc = fts3ExprBalance(&pLeft, nMaxDepth-1); |
| 924 if( rc==SQLITE_OK ){ |
| 925 rc = fts3ExprBalance(&pRight, nMaxDepth-1); |
| 908 } | 926 } |
| 909 | 927 |
| 910 assert( pFree==0 ); | 928 if( rc!=SQLITE_OK ){ |
| 911 sqlite3_free( apLeaf ); | 929 sqlite3Fts3ExprFree(pRight); |
| 930 sqlite3Fts3ExprFree(pLeft); |
| 931 }else{ |
| 932 assert( pLeft && pRight ); |
| 933 pRoot->pLeft = pLeft; |
| 934 pLeft->pParent = pRoot; |
| 935 pRoot->pRight = pRight; |
| 936 pRight->pParent = pRoot; |
| 937 } |
| 912 } | 938 } |
| 913 } | 939 } |
| 914 | 940 |
| 915 if( rc!=SQLITE_OK ){ | 941 if( rc!=SQLITE_OK ){ |
| 916 sqlite3Fts3ExprFree(pRoot); | 942 sqlite3Fts3ExprFree(pRoot); |
| 917 pRoot = 0; | 943 pRoot = 0; |
| 918 } | 944 } |
| 919 *pp = pRoot; | 945 *pp = pRoot; |
| 920 return rc; | 946 return rc; |
| 921 } | 947 } |
| 922 | 948 |
| 923 /* | 949 /* |
| 924 ** This function is similar to sqlite3Fts3ExprParse(), with the following | 950 ** This function is similar to sqlite3Fts3ExprParse(), with the following |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); | 1041 rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); |
| 1016 if( rc==SQLITE_OK ){ | 1042 if( rc==SQLITE_OK ){ |
| 1017 rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); | 1043 rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); |
| 1018 } | 1044 } |
| 1019 } | 1045 } |
| 1020 | 1046 |
| 1021 if( rc!=SQLITE_OK ){ | 1047 if( rc!=SQLITE_OK ){ |
| 1022 sqlite3Fts3ExprFree(*ppExpr); | 1048 sqlite3Fts3ExprFree(*ppExpr); |
| 1023 *ppExpr = 0; | 1049 *ppExpr = 0; |
| 1024 if( rc==SQLITE_TOOBIG ){ | 1050 if( rc==SQLITE_TOOBIG ){ |
| 1025 *pzErr = sqlite3_mprintf( | 1051 sqlite3Fts3ErrMsg(pzErr, |
| 1026 "FTS expression tree is too large (maximum depth %d)", | 1052 "FTS expression tree is too large (maximum depth %d)", |
| 1027 SQLITE_FTS3_MAX_EXPR_DEPTH | 1053 SQLITE_FTS3_MAX_EXPR_DEPTH |
| 1028 ); | 1054 ); |
| 1029 rc = SQLITE_ERROR; | 1055 rc = SQLITE_ERROR; |
| 1030 }else if( rc==SQLITE_ERROR ){ | 1056 }else if( rc==SQLITE_ERROR ){ |
| 1031 *pzErr = sqlite3_mprintf("malformed MATCH expression: [%s]", z); | 1057 sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); |
| 1032 } | 1058 } |
| 1033 } | 1059 } |
| 1034 | 1060 |
| 1035 return rc; | 1061 return rc; |
| 1036 } | 1062 } |
| 1037 | 1063 |
| 1038 /* | 1064 /* |
| 1039 ** Free a single node of an expression tree. | 1065 ** Free a single node of an expression tree. |
| 1040 */ | 1066 */ |
| 1041 static void fts3FreeExprNode(Fts3Expr *p){ | 1067 static void fts3FreeExprNode(Fts3Expr *p){ |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 if( rc==SQLITE_OK ){ | 1300 if( rc==SQLITE_OK ){ |
| 1275 rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", | 1301 rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", |
| 1276 -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0 | 1302 -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0 |
| 1277 ); | 1303 ); |
| 1278 } | 1304 } |
| 1279 return rc; | 1305 return rc; |
| 1280 } | 1306 } |
| 1281 | 1307 |
| 1282 #endif | 1308 #endif |
| 1283 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ | 1309 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| OLD | NEW |