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 |