Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Refinements to the name resolution logic. Change the name of the keywordhash.c file to keywordhash.h. (CVS 2229) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0142ae6f0004bf18a1c2d8e49c09d2a9 |
User & Date: | drh 2005-01-18 04:00:43.000 |
Context
2005-01-18
| ||
14:45 | Continue refactoring name resolution. Fix for ticket #1047. (CVS 2230) (check-in: 88d4834fec user: drh tags: trunk) | |
04:00 | Refinements to the name resolution logic. Change the name of the keywordhash.c file to keywordhash.h. (CVS 2229) (check-in: 0142ae6f00 user: drh tags: trunk) | |
2005-01-17
| ||
22:08 | Infrastructure changes to handle name resolution differently. This is needed to fix various long-standing problems with column names in joins. It will also make the implementation of correlated subqueries easier. (CVS 2228) (check-in: 4a7534396a user: drh tags: trunk) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
239 240 241 242 243 244 245 | # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # | | | | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # target_source: $(SRC) parse.c opcodes.c keywordhash.h $(VDBEHDR) rm -rf tsrc mkdir -p tsrc cp $(SRC) $(VDBEHDR) tsrc rm tsrc/sqlite.h.in tsrc/parse.y cp parse.c opcodes.c keywordhash.h tsrc cp $(TOP)/sqlite3.def tsrc # Rules to build the LEMON compiler generator # lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o lemon $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . |
︙ | ︙ | |||
359 360 361 362 363 364 365 | table.lo: $(TOP)/src/table.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/table.c tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/tclsqlite.c | | | | | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | table.lo: $(TOP)/src/table.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/table.c tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/tclsqlite.c tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR) $(LTCOMPILE) -c $(TOP)/src/tokenize.c keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash$(BEXE) $(OPTS) $(TOP)/tool/mkkeywordhash.c ./mkkeywordhash$(BEXE) >keywordhash.h trigger.lo: $(TOP)/src/trigger.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/trigger.c update.lo: $(TOP)/src/update.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/update.c |
︙ | ︙ | |||
617 618 619 620 621 622 623 | tclsh $(TOP)/tclinstaller.tcl $(VERSION) clean: rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la rm -f sqlite3.h opcodes.* rm -rf .libs .deps rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz | | | 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | tclsh $(TOP)/tclinstaller.tcl $(VERSION) clean: rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la rm -f sqlite3.h opcodes.* rm -rf .libs .deps rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz rm -f mkkeywordhash$(BEXE) keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -f testfixture$(TEXE) test.db rm -rf doc rm -f common.tcl rm -f sqlite3.dll sqlite3.lib |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
176 177 178 179 180 181 182 | # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # target_source: $(SRC) $(VDBEHDR) opcodes.c keywordhash.h rm -rf tsrc mkdir tsrc cp $(SRC) $(VDBEHDR) tsrc rm tsrc/sqlite.h.in tsrc/parse.y cp parse.c opcodes.c keywordhash.h tsrc cp $(TOP)/sqlite3.def tsrc # Rules to build the LEMON compiler generator # lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o lemon $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . |
︙ | ︙ | |||
297 298 299 300 301 302 303 | table.o: $(TOP)/src/table.c $(HDR) $(TCCX) -c $(TOP)/src/table.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c | | | | | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | table.o: $(TOP)/src/table.c $(HDR) $(TCCX) -c $(TOP)/src/table.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) $(TCCX) -c $(TOP)/src/tokenize.c keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c ./mkkeywordhash >keywordhash.h trigger.o: $(TOP)/src/trigger.c $(HDR) $(TCCX) -c $(TOP)/src/trigger.c update.o: $(TOP)/src/update.c $(HDR) $(TCCX) -c $(TOP)/src/update.c |
︙ | ︙ | |||
538 539 540 541 542 543 544 | install: sqlite3 libsqlite3.a sqlite3.h mv sqlite3 /usr/bin mv libsqlite3.a /usr/lib mv sqlite3.h /usr/include clean: rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* | | | 538 539 540 541 542 543 544 545 546 547 548 | install: sqlite3 libsqlite3.a sqlite3.h mv sqlite3 /usr/bin mv libsqlite3.a /usr/lib mv sqlite3.h /usr/include clean: rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -rf tsrc |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.293 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
880 881 882 883 884 885 886 | pCol = &(p->aCol[p->nCol-1]); if( !sqlite3ExprIsConstant(pExpr) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); }else{ sqlite3ExprDelete(pCol->pDflt); pCol->pDflt = sqlite3ExprDup(pExpr); | | | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 | pCol = &(p->aCol[p->nCol-1]); if( !sqlite3ExprIsConstant(pExpr) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); }else{ sqlite3ExprDelete(pCol->pDflt); pCol->pDflt = sqlite3ExprDup(pExpr); sqlite3ExprResolveNames(pParse,0,0,pExpr,0,0); } sqlite3ExprDelete(pExpr); } /* ** Designate the PRIMARY KEY for the table. pList is a list of names ** of columns that form the primary key. If pList is NULL, then the |
︙ | ︙ |
Changes to src/delete.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 ** in order to generate code for DELETE FROM statements. ** | | | 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 ** in order to generate code for DELETE FROM statements. ** ** $Id: delete.c,v 1.97 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
146 147 148 149 150 151 152 | oldIdx = pParse->nTab++; } /* Resolve the column names in all the expressions. */ assert( pTabList->nSrc==1 ); iCur = pTabList->a[0].iCursor = pParse->nTab++; | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | oldIdx = pParse->nTab++; } /* Resolve the column names in all the expressions. */ assert( pTabList->nSrc==1 ); iCur = pTabList->a[0].iCursor = pParse->nTab++; if( sqlite3ExprResolveNames(pParse, pTabList, 0, pWhere, 0, 1) ){ goto delete_from_cleanup; } /* Start the view context */ if( isView ){ sqlite3AuthContextPush(pParse, &sContext, pTab->zName); |
︙ | ︙ |
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.180 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
558 559 560 561 562 563 564 565 566 567 568 569 570 571 | } sqliteFree(pList->a); sqliteFree(pList); } /* ** Walk an expression tree. Call xFunc for each node visited. ** The return value from xFunc determines whether the tree walk continues. ** 0 means continue walking the tree. 1 means do not walk children ** of the current node but continue with siblings. 2 means abandon ** the tree walk completely. ** ** The return value from this routine is 1 to abandon the tree walk ** and 0 to continue. | > | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 | } sqliteFree(pList->a); sqliteFree(pList); } /* ** Walk an expression tree. Call xFunc for each node visited. ** ** The return value from xFunc determines whether the tree walk continues. ** 0 means continue walking the tree. 1 means do not walk children ** of the current node but continue with siblings. 2 means abandon ** the tree walk completely. ** ** The return value from this routine is 1 to abandon the tree walk ** and 0 to continue. |
︙ | ︙ | |||
590 591 592 593 594 595 596 | return rc>1; } /* ** This routine is designed as an xFunc for walkExprTree(). ** ** pArg is really a pointer to an integer. If we can tell by looking | | | | | > > > > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | return rc>1; } /* ** This routine is designed as an xFunc for walkExprTree(). ** ** pArg is really a pointer to an integer. If we can tell by looking ** at pExpr that the expression that contains pExpr is not a constant ** expression, then set *pArg to 0 and return 2 to abandon the tree walk. ** If pExpr does does not disqualify the expression from being a constant ** then do nothing. ** ** After walking the whole tree, if no nodes are found that disqualify ** the expression as constant, then we assume the whole expression ** is constant. See sqlite3ExprIsConstant() for additional information. */ static int exprNodeIsConstant(void *pArg, Expr *pExpr){ switch( pExpr->op ){ case TK_ID: case TK_COLUMN: case TK_DOT: case TK_AGG_FUNCTION: |
︙ | ︙ | |||
624 625 626 627 628 629 630 | int sqlite3ExprIsConstant(Expr *p){ int isConst = 1; walkExprTree(p, exprNodeIsConstant, &isConst); return isConst; } /* | | | 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 | int sqlite3ExprIsConstant(Expr *p){ int isConst = 1; walkExprTree(p, exprNodeIsConstant, &isConst); return isConst; } /* ** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. */ int sqlite3ExprIsInteger(Expr *p, int *pValue){ switch( p->op ){ case TK_INTEGER: { |
︙ | ︙ | |||
705 706 707 708 709 710 711 712 713 714 715 716 717 718 | char *zCol = 0; /* Name of the column. The "Z" */ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); if( sqlite3_malloc_failed ){ return 1; /* Leak memory (zDb and zTab) if malloc fails */ | > | 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | char *zCol = 0; /* Name of the column. The "Z" */ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); if( sqlite3_malloc_failed ){ return 1; /* Leak memory (zDb and zTab) if malloc fails */ |
︙ | ︙ | |||
868 869 870 871 872 873 874 875 876 877 878 879 880 881 | }else if( zTab ){ sqlite3SetString(&z, zTab, ".", zCol, 0); }else{ z = sqliteStrDup(zCol); } sqlite3ErrorMsg(pParse, zErr, z); sqliteFree(z); } /* If a column from a table in pSrcList is referenced, then record ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the ** column number is greater than the number of bits in the bitmask ** then set the high-order bit of the bitmask. | > | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 | }else if( zTab ){ sqlite3SetString(&z, zTab, ".", zCol, 0); }else{ z = sqliteStrDup(zCol); } sqlite3ErrorMsg(pParse, zErr, z); sqliteFree(z); pTopNC->nErr++; } /* If a column from a table in pSrcList is referenced, then record ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the ** column number is greater than the number of bits in the bitmask ** then set the high-order bit of the bitmask. |
︙ | ︙ | |||
953 954 955 956 957 958 959 | } } } /* ** This routine is designed as an xFunc for walkExprTree(). ** | | | > > > > | 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 | } } } /* ** This routine is designed as an xFunc for walkExprTree(). ** ** Resolve symbolic names into TK_COLUMN operators for the current ** node in the expression tree. Return 0 to continue the search down ** the tree or 2 to abort the tree walk. ** ** This routine also does error checking and name resolution for ** function names. The operator for aggregate functions is changed ** to TK_AGG_FUNCTION. */ static int nameResolverStep(void *pArg, Expr *pExpr){ NameContext *pNC = (NameContext*)pArg; SrcList *pSrcList; Parse *pParse; int i; |
︙ | ︙ | |||
1035 1036 1037 1038 1039 1040 1041 | int n = pList ? pList->nExpr : 0; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ int i; int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ | | | < | 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 | int n = pList ? pList->nExpr : 0; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ int i; int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ int enc = pParse->db->enc; /* The database encoding */ getFunctionName(pExpr, &zId, &nId); pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); if( pDef==0 ){ pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); if( pDef==0 ){ no_such_func = 1; |
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 | nId, zId); pNC->nErr++; } if( is_agg ){ pExpr->op = TK_AGG_FUNCTION; pNC->hasAgg = 1; } | < | | < < | | 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 | nId, zId); pNC->nErr++; } if( is_agg ){ pExpr->op = TK_AGG_FUNCTION; pNC->hasAgg = 1; } if( is_agg ) pNC->allowAgg = 0; for(i=0; pNC->nErr==0 && i<n; i++){ walkExprTree(pList->a[i].pExpr, nameResolverStep, pNC); } if( is_agg ) pNC->allowAgg = 1; /* FIX ME: Compute pExpr->affinity based on the expected return ** type of the function */ return is_agg; } } return 0; |
︙ | ︙ | |||
1102 1103 1104 1105 1106 1107 1108 | ** alias for ROWID. ** ** Also resolve function names and check the functions for proper ** usage. Make sure all function names are recognized and all functions ** have the correct number of arguments. Leave an error message ** in pParse->zErrMsg if anything is amiss. Return the number of errors. ** | | | < > | > > | > | > | | > > > > | 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 | ** alias for ROWID. ** ** Also resolve function names and check the functions for proper ** usage. Make sure all function names are recognized and all functions ** have the correct number of arguments. Leave an error message ** in pParse->zErrMsg if anything is amiss. Return the number of errors. ** ** If the expression contains aggregate functions then set the EP_Agg ** property on the expression. */ int sqlite3ExprResolveNames( Parse *pParse, /* The parser context */ SrcList *pSrcList, /* List of tables used to resolve column names */ ExprList *pEList, /* List of expressions used to resolve "AS" */ Expr *pExpr, /* The expression to be analyzed. */ int allowAgg, /* True to allow aggregate expressions */ int codeSubquery /* If true, then generate code for subqueries too */ ){ NameContext sNC; if( pExpr==0 ) return 0; memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSrcList; sNC.pParse = pParse; sNC.pEList = pEList; sNC.allowAgg = allowAgg; walkExprTree(pExpr, nameResolverStep, &sNC); if( sNC.hasAgg ){ ExprSetProperty(pExpr, EP_Agg); } if( sNC.nErr>0 ){ ExprSetProperty(pExpr, EP_Error); }else if( codeSubquery && sqlite3ExprCodeSubquery(pParse, pExpr) ){ return 1; } return ExprHasProperty(pExpr, EP_Error); } /* ** Generate code for subqueries and IN operators. ** ** IN operators comes in two forms: ** ** expr IN (exprlist) ** and ** expr IN (SELECT ...) ** ** The first form is handled by creating a set holding the list ** of allowed values. The second form causes the SELECT to generate ** a temporary table. ** ** This routine also looks for scalar SELECTs that are part of an expression. ** If it finds any, it generates code to write the value of that select ** into a memory cell. ** ** This routine is a callback for wallExprTree() used to implement ** sqlite3ExprCodeSubquery(). See comments on those routines for ** additional information. */ static int codeSubqueryStep(void *pArg, Expr *pExpr){ Parse *pParse = (Parse*)pArg; switch( pExpr->op ){ case TK_IN: { char affinity; |
︙ | ︙ | |||
1218 1219 1220 1221 1222 1223 1224 | /* Check that the expression is constant and valid. */ if( !sqlite3ExprIsConstant(pE2) ){ sqlite3ErrorMsg(pParse, "right-hand side of IN operator must be constant"); return 2; } | | | 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | /* Check that the expression is constant and valid. */ if( !sqlite3ExprIsConstant(pE2) ){ sqlite3ErrorMsg(pParse, "right-hand side of IN operator must be constant"); return 2; } if( sqlite3ExprResolveNames(pParse, 0, 0, pE2, 0, 0) ){ return 2; } /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2); sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); sqlite3VdbeAddOp(v, OP_String8, 0, 0); |
︙ | ︙ | |||
1247 1248 1249 1250 1251 1252 1253 | return 1; } } return 0; } /* | | > | 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 | return 1; } } return 0; } /* ** Generate code to evaluate subqueries and IN operators contained ** in expression pExpr. */ int sqlite3ExprCodeSubquery(Parse *pParse, Expr *pExpr){ walkExprTree(pExpr, codeSubqueryStep, pParse); return 0; } /* |
︙ | ︙ | |||
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 | if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0; } return 1; } /* ** Add a new element to the pParse->aAgg[] array and return its index. */ static int appendAggInfo(Parse *pParse){ if( (pParse->nAgg & 0x7)==0 ){ int amt = pParse->nAgg + 8; AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0])); if( aAgg==0 ){ return -1; | > > | 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 | if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0; } return 1; } /* ** Add a new element to the pParse->aAgg[] array and return its index. ** The new element is initialized to zero. The calling function is ** expected to fill it in. */ static int appendAggInfo(Parse *pParse){ if( (pParse->nAgg & 0x7)==0 ){ int amt = pParse->nAgg + 8; AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0])); if( aAgg==0 ){ return -1; |
︙ | ︙ |
Changes to src/insert.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 INSERT 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 INSERT statements in SQLite. ** ** $Id: insert.c,v 1.132 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
376 377 378 379 380 381 382 | assert( pList!=0 ); srcTab = -1; useTempTable = 0; assert( pList ); nColumn = pList->nExpr; dummy.nSrc = 0; for(i=0; i<nColumn; i++){ | | | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | assert( pList!=0 ); srcTab = -1; useTempTable = 0; assert( pList ); nColumn = pList->nExpr; dummy.nSrc = 0; for(i=0; i<nColumn; i++){ if( sqlite3ExprResolveNames(pParse,&dummy,0,pList->a[i].pExpr,0,1) ){ goto insert_cleanup; } } } /* Make sure the number of columns in the source data matches the number ** of columns to be inserted into the table. |
︙ | ︙ |
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.224 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. |
︙ | ︙ | |||
2182 2183 2184 2185 2186 2187 2188 | for(i=0; i<pOrderBy->nExpr; i++){ int iCol; Expr *pE = pOrderBy->a[i].pExpr; if( sqlite3ExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){ sqlite3ExprDelete(pE); pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); } | | | 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 | for(i=0; i<pOrderBy->nExpr; i++){ int iCol; Expr *pE = pOrderBy->a[i].pExpr; if( sqlite3ExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){ sqlite3ExprDelete(pE); pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); } if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pE, isAgg, 1) ){ return 1; } if( sqlite3ExprIsConstant(pE) ){ if( sqlite3ExprIsInteger(pE, &iCol)==0 ){ sqlite3ErrorMsg(pParse, "%s BY terms must not be non-integer constants", zType); return 1; |
︙ | ︙ | |||
2351 2352 2353 2354 2355 2356 2357 | /* At this point, we should have allocated all the cursors that we ** need to handle subquerys and temporary tables. ** ** Resolve the column names and do a semantics check on all the expressions. */ for(i=0; i<pEList->nExpr; i++){ | > | < > | | > | 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 | /* At this point, we should have allocated all the cursors that we ** need to handle subquerys and temporary tables. ** ** Resolve the column names and do a semantics check on all the expressions. */ for(i=0; i<pEList->nExpr; i++){ Expr *pX = pEList->a[i].pExpr; if( sqlite3ExprResolveNames(pParse, pTabList, 0, pX, 1, 1) ){ goto select_end; } if( ExprHasProperty(pX, EP_Agg) ) isAgg = 1; } if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pWhere, 0, 1) ){ goto select_end; } if( pHaving ){ if( pGroupBy==0 ){ sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); goto select_end; } if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pHaving, 1, 1) ){ goto select_end; } if( ExprHasProperty(pHaving, EP_Agg) ) isAgg = 1; } if( pGroupBy && !isAgg ){ sqlite3ErrorMsg(pParse, "GROUP BY may only be used on aggregate queries"); goto select_end; } if( processOrderGroupBy(pParse, pOrderBy, pTabList, pEList, isAgg, "ORDER") || processOrderGroupBy(pParse, pGroupBy, pTabList, pEList, isAgg, "GROUP") |
︙ | ︙ |
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.355 2005/01/18 04:00:44 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** These #defines should enable >2GB file support on Posix if the ** underlying operating system supports it. If the OS lacks |
︙ | ︙ | |||
813 814 815 816 817 818 819 820 821 822 823 824 825 826 | /* ** The following are the meanings of bits in the Expr.flags field. */ #define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ #define EP_Agg 0x0002 /* Contains one or more aggregate functions */ #define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */ /* ** These macros can be used to test, set, or clear bits in the ** Expr.flags field. */ #define ExprHasProperty(E,P) (((E)->flags&(P))==(P)) #define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0) | > | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 | /* ** The following are the meanings of bits in the Expr.flags field. */ #define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ #define EP_Agg 0x0002 /* Contains one or more aggregate functions */ #define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */ #define EP_Error 0x0008 /* Expression contains one or more errors */ /* ** These macros can be used to test, set, or clear bits in the ** Expr.flags field. */ #define ExprHasProperty(E,P) (((E)->flags&(P))==(P)) #define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0) |
︙ | ︙ | |||
1419 1420 1421 1422 1423 1424 1425 | void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); void sqlite3Vacuum(Parse*, Token*); int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(Token*); int sqlite3ExprCheck(Parse*, Expr*, int, int*); int sqlite3ExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); | | | 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 | void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); void sqlite3Vacuum(Parse*, Token*); int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(Token*); int sqlite3ExprCheck(Parse*, Expr*, int, int*); int sqlite3ExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqlite3ExprResolveNames(Parse*, SrcList*, ExprList*, Expr*, int, int); int sqlite3ExprCodeSubquery(Parse*, Expr*); int sqlite3ExprAnalyzeAggregates(Parse*, Expr*); Vdbe *sqlite3GetVdbe(Parse*); void sqlite3Randomness(int, void*); void sqlite3RollbackAll(sqlite3*); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3BeginTransaction(Parse*, int); |
︙ | ︙ |
Changes to src/tokenize.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** | | | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.99 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* ** The sqlite3KeywordCode function looks up an identifier to determine if ** it is a keyword. If it is a keyword, the token code of that keyword is ** returned. If the input is not a keyword, TK_ID is returned. ** ** The implementation of this routine was generated by a program, ** mkkeywordhash.h, located in the tool subdirectory of the distribution. ** The output of the mkkeywordhash.c program is written into a file ** named keywordhash.h and then included into this source file by ** the #include below. */ #include "keywordhash.h" /* ** If X is a character that can be used in an identifier and ** X&0x80==0 then isIdChar[X] will be 1. If X&0x80==0x80 then ** X is always an identifier character. (Hence all UTF-8 ** characters can be part of an identifier). isIdChar[X] will |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
762 763 764 765 766 767 768 | trigStackEntry.ignoreJump = ignoreJump; pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, pTrigger->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(pTrigger->pWhen); | | | 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 | trigStackEntry.ignoreJump = ignoreJump; pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, pTrigger->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(pTrigger->pWhen); if( sqlite3ExprResolveNames(pParse, &dummyTablist, 0, whenExpr, 0, 1) ){ pParse->trigStack = trigStackEntry.pNext; sqlite3ExprDelete(whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); sqlite3ExprDelete(whenExpr); |
︙ | ︙ |
Changes to src/update.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 UPDATE statements. ** | | | 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 UPDATE statements. ** ** $Id: update.c,v 1.102 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. ** ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; |
︙ | ︙ | |||
118 119 120 121 122 123 124 | ** for each column to be updated in the pChanges array. For each ** column to be updated, make sure we have authorization to change ** that column. */ chngRecno = 0; for(i=0; i<pChanges->nExpr; i++){ if( sqlite3ExprResolveNames(pParse, pTabList, 0, | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | ** for each column to be updated in the pChanges array. For each ** column to be updated, make sure we have authorization to change ** that column. */ chngRecno = 0; for(i=0; i<pChanges->nExpr; i++){ if( sqlite3ExprResolveNames(pParse, pTabList, 0, pChanges->a[i].pExpr, 0, 1) ){ goto update_cleanup; } for(j=0; j<pTab->nCol; j++){ if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){ if( j==pTab->iPKey ){ chngRecno = 1; pRecnoExpr = pChanges->a[i].pExpr; |
︙ | ︙ | |||
194 195 196 197 198 199 200 | aIdxUsed[j] = 0; } } /* Resolve the column names in all the expressions in the ** WHERE clause. */ | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | aIdxUsed[j] = 0; } } /* Resolve the column names in all the expressions in the ** WHERE clause. */ if( sqlite3ExprResolveNames(pParse, pTabList, 0, pWhere, 0, 1) ){ goto update_cleanup; } /* Start the view context */ if( isView ){ sqlite3AuthContextPush(pParse, &sContext, pTab->zName); |
︙ | ︙ |