Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Optimizations on the SELECT code generator. (CVS 1926) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9c411c3c8dde2061c98513a413ef58c5 |
User & Date: | drh 2004-09-01 03:06:35.000 |
Context
2004-09-01
| ||
16:12 | Work around a bug in the Borland C++ compiler. Ticket #881. (CVS 1927) (check-in: 18af6ba580 user: drh tags: trunk) | |
03:06 | Optimizations on the SELECT code generator. (CVS 1926) (check-in: 9c411c3c8d user: drh tags: trunk) | |
2004-08-31
| ||
23:41 | Changes to support compiling under windows. (CVS 1925) (check-in: 68a712f372 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.159 2004/09/01 03:06:35 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> char const *sqlite3AffinityString(char affinity){ switch( affinity ){ case SQLITE_AFF_INTEGER: return "i"; |
︙ | ︙ | |||
214 215 216 217 218 219 220 221 222 223 224 225 226 227 | sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span); }else{ pNew->span = pNew->token; } } return pNew; } /* ** Set the Expr.span field of the given expression to span all ** text between the two given tokens. */ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ assert( pRight!=0 ); | > > > > > > > > > > > > > > | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span); }else{ pNew->span = pNew->token; } } return pNew; } /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. */ Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){ if( pLeft==0 ){ return pRight; }else if( pRight==0 ){ return pLeft; }else{ return sqlite3Expr(TK_AND, pLeft, pRight, 0); } } /* ** Set the Expr.span field of the given expression to span all ** text between the two given tokens. */ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ assert( pRight!=0 ); |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.206 2004/09/01 03:06:35 drh Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. |
︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | static int columnIndex(Table *pTab, const char *zCol){ int i; for(i=0; i<pTab->nCol; i++){ if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; } return -1; } /* ** Add a term to the WHERE expression in *ppExpr that requires the ** zCol column to be equal in the two tables pTab1 and pTab2. */ static void addWhereTerm( const char *zCol, /* Name of the column */ const Table *pTab1, /* First table */ const Table *pTab2, /* Second table */ Expr **ppExpr /* Add the equality term to this expression */ ){ Token dummy; Expr *pE1a, *pE1b, *pE1c; Expr *pE2a, *pE2b, *pE2c; Expr *pE; | > > > > > > > > > > < < | | < | < < | < < < | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | static int columnIndex(Table *pTab, const char *zCol){ int i; for(i=0; i<pTab->nCol; i++){ if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; } return -1; } /* ** Set the value of a token to a '\000'-terminated string. */ static void setToken(Token *p, const char *z){ p->z = z; p->n = strlen(z); p->dyn = 0; } /* ** Add a term to the WHERE expression in *ppExpr that requires the ** zCol column to be equal in the two tables pTab1 and pTab2. */ static void addWhereTerm( const char *zCol, /* Name of the column */ const Table *pTab1, /* First table */ const Table *pTab2, /* Second table */ Expr **ppExpr /* Add the equality term to this expression */ ){ Token dummy; Expr *pE1a, *pE1b, *pE1c; Expr *pE2a, *pE2b, *pE2c; Expr *pE; setToken(&dummy, zCol); pE1a = sqlite3Expr(TK_ID, 0, 0, &dummy); pE2a = sqlite3Expr(TK_ID, 0, 0, &dummy); setToken(&dummy, pTab1->zName); pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy); setToken(&dummy, pTab2->zName); pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy); pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0); pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0); pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0); ExprSetProperty(pE, EP_FromJoin); *ppExpr = sqlite3ExprAnd(*ppExpr, pE); } /* ** Set the EP_FromJoin property on all terms of the given expression. ** ** The EP_FromJoin property is used on terms of an expression to tell ** the LEFT OUTER JOIN processing logic that this term is part of the |
︙ | ︙ | |||
199 200 201 202 203 204 205 206 207 208 209 | } } /* ** This routine processes the join information for a SELECT statement. ** ON and USING clauses are converted into extra terms of the WHERE clause. ** NATURAL joins also create extra WHERE clause terms. ** ** This routine returns the number of errors encountered. */ static int sqliteProcessJoin(Parse *pParse, Select *p){ | > > > > > > > | | > > > > > | < < > > | | < | < | | > | | | | | < | < < < | | | < < < | | | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | } } /* ** This routine processes the join information for a SELECT statement. ** ON and USING clauses are converted into extra terms of the WHERE clause. ** NATURAL joins also create extra WHERE clause terms. ** ** The terms of a FROM clause are contained in the Select.pSrc structure. ** The left most table is the first entry in Select.pSrc. The right-most ** table is the last entry. The join operator is held in the entry to ** the left. Thus entry 0 contains the join operator for the join between ** entries 0 and 1. Any ON or USING clauses associated with the join are ** also attached to the left entry. ** ** This routine returns the number of errors encountered. */ static int sqliteProcessJoin(Parse *pParse, Select *p){ SrcList *pSrc; /* All tables in the FROM clause */ int i, j; /* Loop counters */ struct SrcList_item *pLeft; /* Left table being joined */ struct SrcList_item *pRight; /* Right table being joined */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ Table *pLeftTab = pLeft->pTab; Table *pRightTab = pRight->pTab; if( pLeftTab==0 || pRightTab==0 ) continue; /* When the NATURAL keyword is present, add WHERE clause terms for ** every column that the two tables have in common. */ if( pLeft->jointype & JT_NATURAL ){ if( pLeft->pOn || pLeft->pUsing ){ sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); return 1; } for(j=0; j<pLeftTab->nCol; j++){ char *zName = pLeftTab->aCol[j].zName; if( columnIndex(pRightTab, zName)>=0 ){ addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere); } } } /* Disallow both ON and USING clauses in the same join */ if( pLeft->pOn && pLeft->pUsing ){ sqlite3ErrorMsg(pParse, "cannot have both ON and USING " "clauses in the same join"); return 1; } /* Add the ON clause to the end of the WHERE clause, connected by ** an AND operator. */ if( pLeft->pOn ){ setJoinExpr(pLeft->pOn); p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn); pLeft->pOn = 0; } /* Create extra terms on the WHERE clause for each column named ** in the USING clause. Example: If the two tables to be joined are ** A and B and the USING clause names X, Y, and Z, then add this ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z ** Report an error if any column mentioned in the USING clause is ** not contained in both tables to be joined. */ if( pLeft->pUsing ){ IdList *pList = pLeft->pUsing; for(j=0; j<pList->nId; j++){ char *zName = pList->a[j].zName; if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); return 1; } addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere); } } } return 0; } /* |
︙ | ︙ | |||
817 818 819 820 821 822 823 824 825 | pEList = pSelect->pEList; pTab->nCol = pEList->nExpr; assert( pTab->nCol>0 ); pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){ Expr *pR; char *zType; Expr *p = pEList->a[i].pExpr; assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); | > | | | | < < < | | | < | < | > | 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 | pEList = pSelect->pEList; pTab->nCol = pEList->nExpr; assert( pTab->nCol>0 ); pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){ Expr *pR; char *zType; char *zName; Expr *p = pEList->a[i].pExpr; assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); if( (zName = pEList->a[i].zName)!=0 ){ zName = sqliteStrDup(zName); }else if( p->op==TK_DOT && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ int cnt; zName = sqlite3MPrintf("%T", &pR->token); for(j=cnt=0; j<i; j++){ if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){ sqliteFree(zName); zName = sqlite3MPrintf("%T_%d", &pR->token, ++cnt); j = -1; } } }else if( p->span.z && p->span.z[0] ){ zName = sqlite3MPrintf("%T", &p->span); }else{ zName = sqlite3MPrintf("column%d", i+1); } sqlite3Dequote(zName); pCol->zName = zName; zType = sqliteStrDup(columnType(pParse, pSelect->pSrc ,p)); pCol->zType = zType; pCol->affinity = SQLITE_AFF_NUMERIC; if( zType ){ pCol->affinity = sqlite3AffinityType(zType, strlen(zType)); } |
︙ | ︙ | |||
903 904 905 906 907 908 909 | /* This routine has run before! No need to continue */ return 0; } if( pFrom->zName==0 ){ /* A sub-query in the FROM clause of a SELECT */ assert( pFrom->pSelect!=0 ); if( pFrom->zAlias==0 ){ | | | < | 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 | /* This routine has run before! No need to continue */ return 0; } if( pFrom->zName==0 ){ /* A sub-query in the FROM clause of a SELECT */ assert( pFrom->pSelect!=0 ); if( pFrom->zAlias==0 ){ pFrom->zAlias = sqlite3MPrintf("sqlite_subquery_%p_", (void*)pFrom->pSelect); } pFrom->pTab = pTab = sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect); if( pTab==0 ){ return 1; } /* The isTransient flag indicates that the Table structure has been |
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 | continue; } tableSeen = 1; for(j=0; j<pTab->nCol; j++){ Expr *pExpr, *pLeft, *pRight; char *zName = pTab->aCol[j].zName; | > > | | | | | | | | | | | > < < | < < | < | | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | continue; } tableSeen = 1; for(j=0; j<pTab->nCol; j++){ Expr *pExpr, *pLeft, *pRight; char *zName = pTab->aCol[j].zName; if( i>0 ){ struct SrcList_item *pLeft = &pTabList->a[i-1]; if( (pLeft->jointype & JT_NATURAL)!=0 && columnIndex(pLeft->pTab, zName)>=0 ){ /* In a NATURAL join, omit the join columns from the ** table on the right */ continue; } if( sqlite3IdListIndex(pLeft->pUsing, zName)>=0 ){ /* In a join with a USING clause, omit columns in the ** using clause from the table on the right. */ continue; } } pRight = sqlite3Expr(TK_ID, 0, 0, 0); if( pRight==0 ) break; setToken(&pRight->token, zName); if( zTabName && pTabList->nSrc>1 ){ pLeft = sqlite3Expr(TK_ID, 0, 0, 0); pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0); if( pExpr==0 ) break; setToken(&pLeft->token, zTabName); setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName)); pExpr->span.dyn = 1; pExpr->token.z = 0; pExpr->token.n = 0; pExpr->token.dyn = 0; }else{ pExpr = pRight; pExpr->span = pExpr->token; |
︙ | ︙ | |||
1074 1075 1076 1077 1078 1079 1080 1081 1082 | ** If the bindings are not removed, then the Select.pSrc->a[].pTab field ** will be left pointing to a deallocated Table structure after the ** DROP and a coredump will occur the next time the VIEW is used. */ void sqlite3SelectUnbind(Select *p){ int i; SrcList *pSrc = p->pSrc; Table *pTab; if( p==0 ) return; | > | | | | | | 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 | ** If the bindings are not removed, then the Select.pSrc->a[].pTab field ** will be left pointing to a deallocated Table structure after the ** DROP and a coredump will occur the next time the VIEW is used. */ void sqlite3SelectUnbind(Select *p){ int i; SrcList *pSrc = p->pSrc; struct SrcList_item *pItem; Table *pTab; if( p==0 ) return; for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){ if( (pTab = pItem->pTab)!=0 ){ if( pTab->isTransient ){ sqlite3DeleteTable(0, pTab); } pItem->pTab = 0; if( pItem->pSelect ){ sqlite3SelectUnbind(pItem->pSelect); } } } } /* ** This routine associates entries in an ORDER BY expression list with |
︙ | ︙ | |||
1259 1260 1261 1262 1263 1264 1265 | if( fillInColumnList(pParse, p) ){ return 0; } nColumn = p->pEList->nExpr; pKeyInfo = sqliteMalloc( sizeof(*pKeyInfo)+nColumn*sizeof(CollSeq*) ); if( pKeyInfo==0 ) return 0; | | | 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 | if( fillInColumnList(pParse, p) ){ return 0; } nColumn = p->pEList->nExpr; pKeyInfo = sqliteMalloc( sizeof(*pKeyInfo)+nColumn*sizeof(CollSeq*) ); if( pKeyInfo==0 ) return 0; pKeyInfo->enc = db->enc; pKeyInfo->nField = nColumn; for(i=0; i<nColumn; i++){ pKeyInfo->aColl[i] = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr); if( !pKeyInfo->aColl[i] ){ pKeyInfo->aColl[i] = db->pDfltColl; } } |
︙ | ︙ | |||
1832 1833 1834 1835 1836 1837 1838 | int subqueryIsAgg /* True if the subquery uses aggregate functions */ ){ Select *pSub; /* The inner query or "subquery" */ SrcList *pSrc; /* The FROM clause of the outer query */ SrcList *pSubSrc; /* The FROM clause of the subquery */ ExprList *pList; /* The result set of the outer query */ int iParent; /* VDBE cursor number of the pSub result set temp table */ | | | > | > | 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 | int subqueryIsAgg /* True if the subquery uses aggregate functions */ ){ Select *pSub; /* The inner query or "subquery" */ SrcList *pSrc; /* The FROM clause of the outer query */ SrcList *pSubSrc; /* The FROM clause of the subquery */ ExprList *pList; /* The result set of the outer query */ int iParent; /* VDBE cursor number of the pSub result set temp table */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ struct SrcList_item *pSubitem; /* The subquery */ /* Check to see if flattening is permitted. Return 0 if not. */ if( p==0 ) return 0; pSrc = p->pSrc; assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); pSubitem = &pSrc->a[iFrom]; pSub = pSubitem->pSelect; assert( pSub!=0 ); if( isAgg && subqueryIsAgg ) return 0; if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; pSubSrc = pSub->pSrc; assert( pSubSrc ); if( pSubSrc->nSrc==0 ) return 0; if( (pSub->isDistinct || pSub->nLimit>=0) && (pSrc->nSrc>1 || isAgg) ){ |
︙ | ︙ | |||
1899 1900 1901 1902 1903 1904 1905 | ** the FROM clause of the outer query. Before doing this, remember ** the cursor number for the original outer query FROM element in ** iParent. The iParent cursor will never be used. Subsequent code ** will scan expressions looking for iParent references and replace ** those references with expressions that resolve to the subquery FROM ** elements we are now copying in. */ | | | > | | | | | | 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 | ** the FROM clause of the outer query. Before doing this, remember ** the cursor number for the original outer query FROM element in ** iParent. The iParent cursor will never be used. Subsequent code ** will scan expressions looking for iParent references and replace ** those references with expressions that resolve to the subquery FROM ** elements we are now copying in. */ iParent = pSubitem->iCursor; { int nSubSrc = pSubSrc->nSrc; int jointype = pSubitem->jointype; Table *pTab = pSubitem->pTab; if( pTab && pTab->isTransient ){ sqlite3DeleteTable(0, pSubitem->pTab); } sqliteFree(pSubitem->zDatabase); sqliteFree(pSubitem->zName); sqliteFree(pSubitem->zAlias); if( nSubSrc>1 ){ int extra = nSubSrc - 1; for(i=1; i<nSubSrc; i++){ pSrc = sqlite3SrcListAppend(pSrc, 0, 0); } p->pSrc = pSrc; for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){ |
︙ | ︙ | |||
1968 1969 1970 1971 1972 1973 1974 | pWhere = 0; } if( subqueryIsAgg ){ assert( p->pHaving==0 ); p->pHaving = p->pWhere; p->pWhere = pWhere; substExpr(p->pHaving, iParent, pSub->pEList); | < < < < < | < < < < < | < | 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 | pWhere = 0; } if( subqueryIsAgg ){ assert( p->pHaving==0 ); p->pHaving = p->pWhere; p->pWhere = pWhere; substExpr(p->pHaving, iParent, pSub->pEList); p->pHaving = sqlite3ExprAnd(p->pHaving, sqlite3ExprDup(pSub->pHaving)); assert( p->pGroupBy==0 ); p->pGroupBy = sqlite3ExprListDup(pSub->pGroupBy); }else{ substExpr(p->pWhere, iParent, pSub->pEList); p->pWhere = sqlite3ExprAnd(p->pWhere, pWhere); } /* The flattened query is distinct if either the inner or the ** outer query is distinct. */ p->isDistinct = p->isDistinct || pSub->isDistinct; |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.318 2004/09/01 03:06:35 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "config.h" #include "sqlite3.h" #include "hash.h" |
︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 | void sqlite3SetNString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3Dequote(char*); int sqlite3KeywordCode(const char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); Expr *sqlite3Expr(int, Expr*, Expr*, Token*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(ExprList*, Token*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*); void sqlite3ExprListDelete(ExprList*); int sqlite3Init(sqlite*, char**); int sqlite3InitCallback(void*, int, char**, char**); | > | 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 | void sqlite3SetNString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3Dequote(char*); int sqlite3KeywordCode(const char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); Expr *sqlite3Expr(int, Expr*, Expr*, Token*); Expr *sqlite3ExprAnd(Expr*, Expr*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(ExprList*, Token*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*); void sqlite3ExprListDelete(ExprList*); int sqlite3Init(sqlite*, char**); int sqlite3InitCallback(void*, int, char**, char**); |
︙ | ︙ |