mirror of
				https://github.com/sqlite/sqlite.git
				synced 2025-11-03 16:53:36 +03:00 
			
		
		
		
	Save about 800 bytes of code space by aligning TK_ and OP_ constants so that
we do not have to translate between them. (CVS 1998) FossilOrigin-Name: 4c817e3f293a9c1365e632f7dc13ae440263332a
This commit is contained in:
		
							
								
								
									
										12
									
								
								Makefile.in
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Makefile.in
									
									
									
									
									
								
							@@ -286,18 +286,16 @@ pager.lo:	$(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
 | 
				
			|||||||
opcodes.lo:	opcodes.c
 | 
					opcodes.lo:	opcodes.c
 | 
				
			||||||
	$(LTCOMPILE) -c opcodes.c
 | 
						$(LTCOMPILE) -c opcodes.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
opcodes.c:	$(TOP)/src/vdbe.c
 | 
					opcodes.c:	opcodes.h
 | 
				
			||||||
	echo '/* Automatically generated file.  Do not edit */' >opcodes.c
 | 
						echo '/* Automatically generated file.  Do not edit */' >opcodes.c
 | 
				
			||||||
	echo 'char *sqlite3OpcodeNames[] = { "???", ' >>opcodes.c
 | 
						echo 'char *sqlite3OpcodeNames[] = { "???", ' >>opcodes.c
 | 
				
			||||||
	grep '^case OP_' $(TOP)/src/vdbe.c | \
 | 
						grep OP_ opcodes.h | sort -n +2 | \
 | 
				
			||||||
	  sed -e 's/^.*OP_/  "/' -e 's/:.*$$/", /' >>opcodes.c
 | 
						  sed -e 's/^.*OP_/  "/' -e 's/ [ 0-9]*$$/", /' >>opcodes.c
 | 
				
			||||||
	echo '};' >>opcodes.c
 | 
						echo '};' >>opcodes.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
opcodes.h:	$(TOP)/src/vdbe.h
 | 
					opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
 | 
				
			||||||
	echo '/* Automatically generated file.  Do not edit */' >opcodes.h
 | 
						echo '/* Automatically generated file.  Do not edit */' >opcodes.h
 | 
				
			||||||
	grep '^case OP_' $(TOP)/src/vdbe.c | \
 | 
						cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >>opcodes.h
 | 
				
			||||||
	  sed -e 's/://' | \
 | 
					 | 
				
			||||||
	  awk '{printf "#define %-30s %3d\n", $$2, ++cnt}' >>opcodes.h
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
os_mac.lo:	$(TOP)/src/os_mac.c $(HDR)
 | 
					os_mac.lo:	$(TOP)/src/os_mac.c $(HDR)
 | 
				
			||||||
	$(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_mac.c
 | 
						$(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_mac.c
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								main.mk
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								main.mk
									
									
									
									
									
								
							@@ -255,18 +255,16 @@ pager.o:	$(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
 | 
				
			|||||||
opcodes.o:	opcodes.c
 | 
					opcodes.o:	opcodes.c
 | 
				
			||||||
	$(TCCX) -c opcodes.c
 | 
						$(TCCX) -c opcodes.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
opcodes.c:	$(TOP)/src/vdbe.c
 | 
					opcodes.c:	opcodes.h
 | 
				
			||||||
	echo '/* Automatically generated file.  Do not edit */' >opcodes.c
 | 
						echo '/* Automatically generated file.  Do not edit */' >opcodes.c
 | 
				
			||||||
	echo 'char *sqlite3OpcodeNames[] = { "???", ' >>opcodes.c
 | 
						echo 'char *sqlite3OpcodeNames[] = { "???", ' >>opcodes.c
 | 
				
			||||||
	grep '^case OP_' $(TOP)/src/vdbe.c | \
 | 
						grep OP_ opcodes.h | sort -n +2 | \
 | 
				
			||||||
	  sed -e 's/^.*OP_/  "/' -e 's/:.*$$/", /' >>opcodes.c
 | 
						  sed -e 's/^.*OP_/  "/' -e 's/ [ 0-9]*$$/", /' >>opcodes.c
 | 
				
			||||||
	echo '};' >>opcodes.c
 | 
						echo '};' >>opcodes.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
opcodes.h:	$(TOP)/src/vdbe.h
 | 
					opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
 | 
				
			||||||
	echo '/* Automatically generated file.  Do not edit */' >opcodes.h
 | 
						echo '/* Automatically generated file.  Do not edit */' >opcodes.h
 | 
				
			||||||
	grep '^case OP_' $(TOP)/src/vdbe.c | \
 | 
						cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >>opcodes.h
 | 
				
			||||||
	  sed -e 's/://' | \
 | 
					 | 
				
			||||||
	  awk '{printf "#define %-30s %3d\n", $$2, ++cnt}' >>opcodes.h
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
os_mac.o:	$(TOP)/src/os_mac.c $(HDR)
 | 
					os_mac.o:	$(TOP)/src/os_mac.c $(HDR)
 | 
				
			||||||
	$(TCCX) -c $(TOP)/src/os_mac.c
 | 
						$(TCCX) -c $(TOP)/src/os_mac.c
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								manifest
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								manifest
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
C Fixes\sto\sthe\sOsUnlock()\sinterface.\s\sCorrectly\sleave\sa\sSHARED\slock\sbehind\nwhen\srequested.\s\sHonor\sthe\serror\scode\sthat\sOsUnlock()\sreturns.\nTicket\s#913\sand\s#938.\s(CVS\s1997)
 | 
					C Save\sabout\s800\sbytes\sof\scode\sspace\sby\saligning\sTK_\sand\sOP_\sconstants\sso\sthat\nwe\sdo\snot\shave\sto\stranslate\sbetween\sthem.\s(CVS\s1998)
 | 
				
			||||||
D 2004-10-02T20:38:28
 | 
					D 2004-10-04T13:19:24
 | 
				
			||||||
F Makefile.in abdeb5bd9d017822691884935c320037c33f6ee6
 | 
					F Makefile.in 78ddc9fca09ab6e3b75a79ecf8d490e34cd0519c
 | 
				
			||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 | 
					F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 | 
				
			||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
 | 
					F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
 | 
				
			||||||
F VERSION 0aeddfe96f008f6cbe2c7167a782f3133e118d8d
 | 
					F VERSION 0aeddfe96f008f6cbe2c7167a782f3133e118d8d
 | 
				
			||||||
@@ -17,8 +17,9 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
 | 
				
			|||||||
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 | 
					F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 | 
				
			||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 | 
					F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 | 
				
			||||||
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
 | 
					F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
 | 
				
			||||||
F main.mk fbe4b06ed4d32c529f1514595defe73a424a357e
 | 
					F main.mk cabfd4a3e786840e8924689b04751a8c48dc4a42
 | 
				
			||||||
F mkdll.sh 468d4f41d3ea98221371df4825cfbffbaac4d7e4
 | 
					F mkdll.sh 468d4f41d3ea98221371df4825cfbffbaac4d7e4
 | 
				
			||||||
 | 
					F mkopcodeh.awk a80e53c2f41cd89b1355c2e3d9389e3f6f8e017d
 | 
				
			||||||
F mkso.sh 7b67da1d63070875ba948e749aee9ef50ce36e3d
 | 
					F mkso.sh 7b67da1d63070875ba948e749aee9ef50ce36e3d
 | 
				
			||||||
F publish.sh 72bde067dda3fc2d33e92f20253b924e3b97da30
 | 
					F publish.sh 72bde067dda3fc2d33e92f20253b924e3b97da30
 | 
				
			||||||
F spec.template b2f6c4e488cbc3b993a57deba22cbc36203c4da3
 | 
					F spec.template b2f6c4e488cbc3b993a57deba22cbc36203c4da3
 | 
				
			||||||
@@ -33,7 +34,7 @@ F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
 | 
				
			|||||||
F src/build.c 2ed6d9c26ad736142012bc99898869db17337121
 | 
					F src/build.c 2ed6d9c26ad736142012bc99898869db17337121
 | 
				
			||||||
F src/date.c 93927e2d1ffbd833fc220644896cfdc8f8d4af34
 | 
					F src/date.c 93927e2d1ffbd833fc220644896cfdc8f8d4af34
 | 
				
			||||||
F src/delete.c d862b383a9abc0b79f4588783c2619fe52d74ea7
 | 
					F src/delete.c d862b383a9abc0b79f4588783c2619fe52d74ea7
 | 
				
			||||||
F src/expr.c f255c5c56c0371cb2955cbc2733621051e4f79f8
 | 
					F src/expr.c 2f492bf532d700bd2c38e16caa49048535e8ed27
 | 
				
			||||||
F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1
 | 
					F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1
 | 
				
			||||||
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
 | 
					F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
 | 
				
			||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
 | 
					F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
 | 
				
			||||||
@@ -53,14 +54,14 @@ F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
 | 
				
			|||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 | 
					F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 | 
				
			||||||
F src/pager.c d3688828d314135ef0cd87b4d892805136c4168f
 | 
					F src/pager.c d3688828d314135ef0cd87b4d892805136c4168f
 | 
				
			||||||
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
 | 
					F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
 | 
				
			||||||
F src/parse.y 968231351dd13ef6ee544336295db54708c22faf
 | 
					F src/parse.y eb4920f637b4e44e038220e67dac07854bfd6325
 | 
				
			||||||
F src/pragma.c 45978cc82fdf91f00d024a8e875c2b679fbce488
 | 
					F src/pragma.c 45978cc82fdf91f00d024a8e875c2b679fbce488
 | 
				
			||||||
F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1
 | 
					F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1
 | 
				
			||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 | 
					F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 | 
				
			||||||
F src/select.c 96b1489111abe9b584be2f2cce26ad6f2d425b4e
 | 
					F src/select.c 96b1489111abe9b584be2f2cce26ad6f2d425b4e
 | 
				
			||||||
F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
 | 
					F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
 | 
				
			||||||
F src/sqlite.h.in 9bb76ff9e79ee72e6d529ff6ab1c252d513c3864
 | 
					F src/sqlite.h.in 9bb76ff9e79ee72e6d529ff6ab1c252d513c3864
 | 
				
			||||||
F src/sqliteInt.h 5c406ebc830c5129748b77539283c0e20f978887
 | 
					F src/sqliteInt.h bfb12f1da75b2a8f5c88c9c3050343571def65b9
 | 
				
			||||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
 | 
					F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
 | 
				
			||||||
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
 | 
					F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
 | 
				
			||||||
F src/test1.c 3d78e5d827bf5d037f697c233c5934d45af46cb5
 | 
					F src/test1.c 3d78e5d827bf5d037f697c233c5934d45af46cb5
 | 
				
			||||||
@@ -74,7 +75,7 @@ F src/update.c 7157084216c4b02a23cdb23eb6d246aa9034fa4d
 | 
				
			|||||||
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
 | 
					F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
 | 
				
			||||||
F src/util.c f4ab796b9def353feed2191d7ce8e39a0f5059cd
 | 
					F src/util.c f4ab796b9def353feed2191d7ce8e39a0f5059cd
 | 
				
			||||||
F src/vacuum.c 257de36230cb988842f66eb08dc6c0250b8e05f3
 | 
					F src/vacuum.c 257de36230cb988842f66eb08dc6c0250b8e05f3
 | 
				
			||||||
F src/vdbe.c 0542852785220807feb02b9dee1150ac2e592c8d
 | 
					F src/vdbe.c 49d4bda66884b1017e11962c7fb7eaf15b436be8
 | 
				
			||||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
 | 
					F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
 | 
				
			||||||
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
 | 
					F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
 | 
				
			||||||
F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
 | 
					F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
 | 
				
			||||||
@@ -248,7 +249,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
 | 
				
			|||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 | 
					F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 | 
				
			||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 | 
					F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 | 
				
			||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
 | 
					F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
 | 
				
			||||||
P 4493e287809874fabeddf5ca9045065a30790f2f
 | 
					P c4697503d0ad080290b91e96dfc9a1a63f2df7e6
 | 
				
			||||||
R ebf4aac4c1a61ea57872e563bbdb1393
 | 
					R 7fe455a514dce92e3703ce1da8317d3a
 | 
				
			||||||
U drh
 | 
					U drh
 | 
				
			||||||
Z 44aded0ba9c92340348fe0ad36d9356d
 | 
					Z 28445a4252d9b9c0f55f4514219ea5c1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
c4697503d0ad080290b91e96dfc9a1a63f2df7e6
 | 
					4c817e3f293a9c1365e632f7dc13ae440263332a
 | 
				
			||||||
							
								
								
									
										45
									
								
								mkopcodeh.awk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								mkopcodeh.awk
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/awk -f
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This AWK script scans a concatenation of the parse.h output file from the
 | 
				
			||||||
 | 
					# parser and the vdbe.c source file in order to generate the opcodes numbers
 | 
				
			||||||
 | 
					# for all opcodes.  
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The lines of the vdbe.c that we are interested in are of the form:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#       case OP_aaaa:      /* same as TK_bbbbb */
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The TK_ comment is optional.  If it is present, then the value assigned to
 | 
				
			||||||
 | 
					# the OP_ is the same as the TK_ value.  If missing, the OP_ value is assigned
 | 
				
			||||||
 | 
					# a small integer that is different from every other OP_ value.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Remember the TK_ values from the parse.h file
 | 
				
			||||||
 | 
					/^#define TK_/ {
 | 
				
			||||||
 | 
					  tk[$2] = $3
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Scan for "case OP_aaaa:" lines in the vdbe.c file
 | 
				
			||||||
 | 
					/^case OP_/ {
 | 
				
			||||||
 | 
					  name = $2
 | 
				
			||||||
 | 
					  gsub(/:/,"",name)
 | 
				
			||||||
 | 
					  op[name] = -1
 | 
				
			||||||
 | 
					  for(i=3; i<NF-2; i++){
 | 
				
			||||||
 | 
					    if($i=="same" && $(i+1)=="as"){
 | 
				
			||||||
 | 
					      op[name] = tk[$(i+2)]
 | 
				
			||||||
 | 
					      used[op[name]] = 1
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Assign numbers to all opcodes and output the result.
 | 
				
			||||||
 | 
					END {
 | 
				
			||||||
 | 
					  cnt = 0
 | 
				
			||||||
 | 
					  for(name in op){
 | 
				
			||||||
 | 
					    if( op[name]<0 ){
 | 
				
			||||||
 | 
					      cnt++
 | 
				
			||||||
 | 
					      while( used[cnt] ) cnt++
 | 
				
			||||||
 | 
					      op[name] = cnt
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf "#define %-30s %d\n", name, op[name]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										137
									
								
								src/expr.c
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								src/expr.c
									
									
									
									
									
								
							@@ -12,7 +12,7 @@
 | 
				
			|||||||
** This file contains routines used for analyzing expressions and
 | 
					** This file contains routines used for analyzing expressions and
 | 
				
			||||||
** for generating VDBE code that evaluates expressions in SQLite.
 | 
					** for generating VDBE code that evaluates expressions in SQLite.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** $Id: expr.c,v 1.165 2004/09/25 13:12:15 drh Exp $
 | 
					** $Id: expr.c,v 1.166 2004/10/04 13:19:24 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "sqliteInt.h"
 | 
					#include "sqliteInt.h"
 | 
				
			||||||
#include <ctype.h>
 | 
					#include <ctype.h>
 | 
				
			||||||
@@ -1180,41 +1180,19 @@ static void codeInteger(Vdbe *v, const char *z, int n){
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
** Generate code into the current Vdbe to evaluate the given
 | 
					** Generate code into the current Vdbe to evaluate the given
 | 
				
			||||||
** expression and leave the result on the top of stack.
 | 
					** expression and leave the result on the top of stack.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** This code depends on the fact that certain token values (ex: TK_EQ)
 | 
				
			||||||
 | 
					** are the same as opcode values (ex: OP_Eq) that implement the corresponding
 | 
				
			||||||
 | 
					** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
 | 
				
			||||||
 | 
					** the make process cause these values to align.  Assert()s in the code
 | 
				
			||||||
 | 
					** below verify that the numbers are aligned correctly.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
 | 
					void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
 | 
				
			||||||
  Vdbe *v = pParse->pVdbe;
 | 
					  Vdbe *v = pParse->pVdbe;
 | 
				
			||||||
  int op;
 | 
					  int op;
 | 
				
			||||||
  if( v==0 || pExpr==0 ) return;
 | 
					  if( v==0 || pExpr==0 ) return;
 | 
				
			||||||
  switch( pExpr->op ){
 | 
					  op = pExpr->op;
 | 
				
			||||||
    case TK_PLUS:     op = OP_Add;      break;
 | 
					  switch( op ){
 | 
				
			||||||
    case TK_MINUS:    op = OP_Subtract; break;
 | 
					 | 
				
			||||||
    case TK_STAR:     op = OP_Multiply; break;
 | 
					 | 
				
			||||||
    case TK_SLASH:    op = OP_Divide;   break;
 | 
					 | 
				
			||||||
    case TK_AND:      op = OP_And;      break;
 | 
					 | 
				
			||||||
    case TK_OR:       op = OP_Or;       break;
 | 
					 | 
				
			||||||
    case TK_LT:       op = OP_Lt;       break;
 | 
					 | 
				
			||||||
    case TK_LE:       op = OP_Le;       break;
 | 
					 | 
				
			||||||
    case TK_GT:       op = OP_Gt;       break;
 | 
					 | 
				
			||||||
    case TK_GE:       op = OP_Ge;       break;
 | 
					 | 
				
			||||||
    case TK_NE:       op = OP_Ne;       break;
 | 
					 | 
				
			||||||
    case TK_EQ:       op = OP_Eq;       break;
 | 
					 | 
				
			||||||
    case TK_ISNULL:   op = OP_IsNull;   break;
 | 
					 | 
				
			||||||
    case TK_NOTNULL:  op = OP_NotNull;  break;
 | 
					 | 
				
			||||||
    case TK_NOT:      op = OP_Not;      break;
 | 
					 | 
				
			||||||
    case TK_UMINUS:   op = OP_Negative; break;
 | 
					 | 
				
			||||||
    case TK_BITAND:   op = OP_BitAnd;   break;
 | 
					 | 
				
			||||||
    case TK_BITOR:    op = OP_BitOr;    break;
 | 
					 | 
				
			||||||
    case TK_BITNOT:   op = OP_BitNot;   break;
 | 
					 | 
				
			||||||
    case TK_LSHIFT:   op = OP_ShiftLeft;  break;
 | 
					 | 
				
			||||||
    case TK_RSHIFT:   op = OP_ShiftRight; break;
 | 
					 | 
				
			||||||
    case TK_REM:      op = OP_Remainder;  break;
 | 
					 | 
				
			||||||
    case TK_FLOAT:    op = OP_Real;       break;
 | 
					 | 
				
			||||||
    case TK_STRING:   op = OP_String8;    break;
 | 
					 | 
				
			||||||
    case TK_BLOB:     op = OP_HexBlob;    break;
 | 
					 | 
				
			||||||
    case TK_CONCAT:   op = OP_Concat;     break;
 | 
					 | 
				
			||||||
    default: op = 0; break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  switch( pExpr->op ){
 | 
					 | 
				
			||||||
    case TK_COLUMN: {
 | 
					    case TK_COLUMN: {
 | 
				
			||||||
      if( pParse->useAgg ){
 | 
					      if( pParse->useAgg ){
 | 
				
			||||||
        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
 | 
					        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
 | 
				
			||||||
@@ -1236,11 +1214,14 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    case TK_FLOAT:
 | 
					    case TK_FLOAT:
 | 
				
			||||||
    case TK_STRING: {
 | 
					    case TK_STRING: {
 | 
				
			||||||
 | 
					      assert( TK_FLOAT==OP_Real );
 | 
				
			||||||
 | 
					      assert( TK_STRING==OP_String8 );
 | 
				
			||||||
      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
 | 
					      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
 | 
				
			||||||
      sqlite3VdbeDequoteP3(v, -1);
 | 
					      sqlite3VdbeDequoteP3(v, -1);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case TK_BLOB: {
 | 
					    case TK_BLOB: {
 | 
				
			||||||
 | 
					      assert( TK_BLOB==OP_HexBlob );
 | 
				
			||||||
      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1);
 | 
					      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1);
 | 
				
			||||||
      sqlite3VdbeDequoteP3(v, -1);
 | 
					      sqlite3VdbeDequoteP3(v, -1);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
@@ -1262,6 +1243,12 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
 | 
				
			|||||||
    case TK_GE:
 | 
					    case TK_GE:
 | 
				
			||||||
    case TK_NE:
 | 
					    case TK_NE:
 | 
				
			||||||
    case TK_EQ: {
 | 
					    case TK_EQ: {
 | 
				
			||||||
 | 
					      assert( TK_LT==OP_Lt );
 | 
				
			||||||
 | 
					      assert( TK_LE==OP_Le );
 | 
				
			||||||
 | 
					      assert( TK_GT==OP_Gt );
 | 
				
			||||||
 | 
					      assert( TK_GE==OP_Ge );
 | 
				
			||||||
 | 
					      assert( TK_EQ==OP_Eq );
 | 
				
			||||||
 | 
					      assert( TK_NE==OP_Ne );
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
					      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pRight);
 | 
					      sqlite3ExprCode(pParse, pExpr->pRight);
 | 
				
			||||||
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
 | 
					      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
 | 
				
			||||||
@@ -1279,6 +1266,17 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
 | 
				
			|||||||
    case TK_LSHIFT:
 | 
					    case TK_LSHIFT:
 | 
				
			||||||
    case TK_RSHIFT: 
 | 
					    case TK_RSHIFT: 
 | 
				
			||||||
    case TK_CONCAT: {
 | 
					    case TK_CONCAT: {
 | 
				
			||||||
 | 
					      assert( TK_AND==OP_And );
 | 
				
			||||||
 | 
					      assert( TK_OR==OP_Or );
 | 
				
			||||||
 | 
					      assert( TK_PLUS==OP_Add );
 | 
				
			||||||
 | 
					      assert( TK_MINUS==OP_Subtract );
 | 
				
			||||||
 | 
					      assert( TK_REM==OP_Remainder );
 | 
				
			||||||
 | 
					      assert( TK_BITAND==OP_BitAnd );
 | 
				
			||||||
 | 
					      assert( TK_BITOR==OP_BitOr );
 | 
				
			||||||
 | 
					      assert( TK_SLASH==OP_Divide );
 | 
				
			||||||
 | 
					      assert( TK_LSHIFT==OP_ShiftLeft );
 | 
				
			||||||
 | 
					      assert( TK_RSHIFT==OP_ShiftRight );
 | 
				
			||||||
 | 
					      assert( TK_CONCAT==OP_Concat );
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
					      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pRight);
 | 
					      sqlite3ExprCode(pParse, pExpr->pRight);
 | 
				
			||||||
      sqlite3VdbeAddOp(v, op, 0, 0);
 | 
					      sqlite3VdbeAddOp(v, op, 0, 0);
 | 
				
			||||||
@@ -1303,6 +1301,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    case TK_BITNOT:
 | 
					    case TK_BITNOT:
 | 
				
			||||||
    case TK_NOT: {
 | 
					    case TK_NOT: {
 | 
				
			||||||
 | 
					      assert( TK_BITNOT==OP_BitNot );
 | 
				
			||||||
 | 
					      assert( TK_NOT==OP_Not );
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
					      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
				
			||||||
      sqlite3VdbeAddOp(v, op, 0, 0);
 | 
					      sqlite3VdbeAddOp(v, op, 0, 0);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
@@ -1310,13 +1310,15 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
 | 
				
			|||||||
    case TK_ISNULL:
 | 
					    case TK_ISNULL:
 | 
				
			||||||
    case TK_NOTNULL: {
 | 
					    case TK_NOTNULL: {
 | 
				
			||||||
      int dest;
 | 
					      int dest;
 | 
				
			||||||
 | 
					      assert( TK_ISNULL==OP_IsNull );
 | 
				
			||||||
 | 
					      assert( TK_NOTNULL==OP_NotNull );
 | 
				
			||||||
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
 | 
					      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
					      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
				
			||||||
      dest = sqlite3VdbeCurrentAddr(v) + 2;
 | 
					      dest = sqlite3VdbeCurrentAddr(v) + 2;
 | 
				
			||||||
      sqlite3VdbeAddOp(v, op, 1, dest);
 | 
					      sqlite3VdbeAddOp(v, op, 1, dest);
 | 
				
			||||||
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
 | 
					      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    case TK_AGG_FUNCTION: {
 | 
					    case TK_AGG_FUNCTION: {
 | 
				
			||||||
      sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
 | 
					      sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
@@ -1503,23 +1505,19 @@ int sqlite3ExprCodeExprList(
 | 
				
			|||||||
**
 | 
					**
 | 
				
			||||||
** If the expression evaluates to NULL (neither true nor false), then
 | 
					** If the expression evaluates to NULL (neither true nor false), then
 | 
				
			||||||
** take the jump if the jumpIfNull flag is true.
 | 
					** take the jump if the jumpIfNull flag is true.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** This code depends on the fact that certain token values (ex: TK_EQ)
 | 
				
			||||||
 | 
					** are the same as opcode values (ex: OP_Eq) that implement the corresponding
 | 
				
			||||||
 | 
					** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
 | 
				
			||||||
 | 
					** the make process cause these values to align.  Assert()s in the code
 | 
				
			||||||
 | 
					** below verify that the numbers are aligned correctly.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
 | 
					void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
 | 
				
			||||||
  Vdbe *v = pParse->pVdbe;
 | 
					  Vdbe *v = pParse->pVdbe;
 | 
				
			||||||
  int op = 0;
 | 
					  int op = 0;
 | 
				
			||||||
  if( v==0 || pExpr==0 ) return;
 | 
					  if( v==0 || pExpr==0 ) return;
 | 
				
			||||||
  switch( pExpr->op ){
 | 
					  op = pExpr->op;
 | 
				
			||||||
    case TK_LT:       op = OP_Lt;       break;
 | 
					  switch( op ){
 | 
				
			||||||
    case TK_LE:       op = OP_Le;       break;
 | 
					 | 
				
			||||||
    case TK_GT:       op = OP_Gt;       break;
 | 
					 | 
				
			||||||
    case TK_GE:       op = OP_Ge;       break;
 | 
					 | 
				
			||||||
    case TK_NE:       op = OP_Ne;       break;
 | 
					 | 
				
			||||||
    case TK_EQ:       op = OP_Eq;       break;
 | 
					 | 
				
			||||||
    case TK_ISNULL:   op = OP_IsNull;   break;
 | 
					 | 
				
			||||||
    case TK_NOTNULL:  op = OP_NotNull;  break;
 | 
					 | 
				
			||||||
    default:  break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  switch( pExpr->op ){
 | 
					 | 
				
			||||||
    case TK_AND: {
 | 
					    case TK_AND: {
 | 
				
			||||||
      int d2 = sqlite3VdbeMakeLabel(v);
 | 
					      int d2 = sqlite3VdbeMakeLabel(v);
 | 
				
			||||||
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
 | 
					      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
 | 
				
			||||||
@@ -1542,6 +1540,12 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
 | 
				
			|||||||
    case TK_GE:
 | 
					    case TK_GE:
 | 
				
			||||||
    case TK_NE:
 | 
					    case TK_NE:
 | 
				
			||||||
    case TK_EQ: {
 | 
					    case TK_EQ: {
 | 
				
			||||||
 | 
					      assert( TK_LT==OP_Lt );
 | 
				
			||||||
 | 
					      assert( TK_LE==OP_Le );
 | 
				
			||||||
 | 
					      assert( TK_GT==OP_Gt );
 | 
				
			||||||
 | 
					      assert( TK_GE==OP_Ge );
 | 
				
			||||||
 | 
					      assert( TK_EQ==OP_Eq );
 | 
				
			||||||
 | 
					      assert( TK_NE==OP_Ne );
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
					      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pRight);
 | 
					      sqlite3ExprCode(pParse, pExpr->pRight);
 | 
				
			||||||
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
 | 
					      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
 | 
				
			||||||
@@ -1549,6 +1553,8 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    case TK_ISNULL:
 | 
					    case TK_ISNULL:
 | 
				
			||||||
    case TK_NOTNULL: {
 | 
					    case TK_NOTNULL: {
 | 
				
			||||||
 | 
					      assert( TK_ISNULL==OP_IsNull );
 | 
				
			||||||
 | 
					      assert( TK_NOTNULL==OP_NotNull );
 | 
				
			||||||
      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
					      sqlite3ExprCode(pParse, pExpr->pLeft);
 | 
				
			||||||
      sqlite3VdbeAddOp(v, op, 1, dest);
 | 
					      sqlite3VdbeAddOp(v, op, 1, dest);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
@@ -1597,17 +1603,38 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
 | 
				
			|||||||
  Vdbe *v = pParse->pVdbe;
 | 
					  Vdbe *v = pParse->pVdbe;
 | 
				
			||||||
  int op = 0;
 | 
					  int op = 0;
 | 
				
			||||||
  if( v==0 || pExpr==0 ) return;
 | 
					  if( v==0 || pExpr==0 ) return;
 | 
				
			||||||
  switch( pExpr->op ){
 | 
					
 | 
				
			||||||
    case TK_LT:       op = OP_Ge;       break;
 | 
					  /* The value of pExpr->op and op are related as follows:
 | 
				
			||||||
    case TK_LE:       op = OP_Gt;       break;
 | 
					  **
 | 
				
			||||||
    case TK_GT:       op = OP_Le;       break;
 | 
					  **       pExpr->op            op
 | 
				
			||||||
    case TK_GE:       op = OP_Lt;       break;
 | 
					  **       ---------          ----------
 | 
				
			||||||
    case TK_NE:       op = OP_Eq;       break;
 | 
					  **       TK_ISNULL          OP_NotNull
 | 
				
			||||||
    case TK_EQ:       op = OP_Ne;       break;
 | 
					  **       TK_NOTNULL         OP_IsNull
 | 
				
			||||||
    case TK_ISNULL:   op = OP_NotNull;  break;
 | 
					  **       TK_NE              OP_Eq
 | 
				
			||||||
    case TK_NOTNULL:  op = OP_IsNull;   break;
 | 
					  **       TK_EQ              OP_Ne
 | 
				
			||||||
    default:  break;
 | 
					  **       TK_GT              OP_Le
 | 
				
			||||||
  }
 | 
					  **       TK_LE              OP_Gt
 | 
				
			||||||
 | 
					  **       TK_GE              OP_Lt
 | 
				
			||||||
 | 
					  **       TK_LT              OP_Ge
 | 
				
			||||||
 | 
					  **
 | 
				
			||||||
 | 
					  ** For other values of pExpr->op, op is undefined and unused.
 | 
				
			||||||
 | 
					  ** The value of TK_ and OP_ constants are arranged such that we
 | 
				
			||||||
 | 
					  ** can compute the mapping above using the following expression.
 | 
				
			||||||
 | 
					  ** Assert()s verify that the computation is correct.
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Verify correct alignment of TK_ and OP_ constants
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_NE || op==OP_Eq );
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_EQ || op==OP_Ne );
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_LT || op==OP_Ge );
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_LE || op==OP_Gt );
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_GT || op==OP_Le );
 | 
				
			||||||
 | 
					  assert( pExpr->op!=TK_GE || op==OP_Lt );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch( pExpr->op ){
 | 
					  switch( pExpr->op ){
 | 
				
			||||||
    case TK_AND: {
 | 
					    case TK_AND: {
 | 
				
			||||||
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
 | 
					      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								src/parse.y
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/parse.y
									
									
									
									
									
								
							@@ -14,7 +14,7 @@
 | 
				
			|||||||
** the parser.  Lemon will also generate a header file containing
 | 
					** the parser.  Lemon will also generate a header file containing
 | 
				
			||||||
** numeric codes for all of the tokens.
 | 
					** numeric codes for all of the tokens.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** @(#) $Id: parse.y,v 1.139 2004/09/30 14:22:47 drh Exp $
 | 
					** @(#) $Id: parse.y,v 1.140 2004/10/04 13:19:24 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
%token_prefix TK_
 | 
					%token_prefix TK_
 | 
				
			||||||
%token_type {Token}
 | 
					%token_type {Token}
 | 
				
			||||||
@@ -137,11 +137,17 @@ id(A) ::= ID(X).         {A = X;}
 | 
				
			|||||||
// causes them to be assigned integer values that are close together,
 | 
					// causes them to be assigned integer values that are close together,
 | 
				
			||||||
// which keeps parser tables smaller.
 | 
					// which keeps parser tables smaller.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// The token values assigned to these symbols is determined by the order
 | 
				
			||||||
 | 
					// in which lemon first sees them.  It must be the case that ISNULL/NOTNULL,
 | 
				
			||||||
 | 
					// NE/EQ, GT/LE, and GE/LT are separated by only a single value.  See
 | 
				
			||||||
 | 
					// the sqlite3ExprIfFalse() routine for additional information on this
 | 
				
			||||||
 | 
					// constraint.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
%left OR.
 | 
					%left OR.
 | 
				
			||||||
%left AND.
 | 
					%left AND.
 | 
				
			||||||
%right NOT.
 | 
					%right NOT.
 | 
				
			||||||
%left ISNULL NOTNULL IS LIKE GLOB BETWEEN IN NE EQ.
 | 
					%left IS LIKE GLOB BETWEEN IN ISNULL NOTNULL NE EQ.
 | 
				
			||||||
%left GT GE LT LE.
 | 
					%left GT LE GE LT.
 | 
				
			||||||
%left BITAND BITOR LSHIFT RSHIFT.
 | 
					%left BITAND BITOR LSHIFT RSHIFT.
 | 
				
			||||||
%left PLUS MINUS.
 | 
					%left PLUS MINUS.
 | 
				
			||||||
%left STAR SLASH REM.
 | 
					%left STAR SLASH REM.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
*************************************************************************
 | 
					*************************************************************************
 | 
				
			||||||
** Internal interface definitions for SQLite.
 | 
					** Internal interface definitions for SQLite.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** @(#) $Id: sqliteInt.h,v 1.325 2004/10/01 02:00:31 drh Exp $
 | 
					** @(#) $Id: sqliteInt.h,v 1.326 2004/10/04 13:19:24 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#ifndef _SQLITEINT_H_
 | 
					#ifndef _SQLITEINT_H_
 | 
				
			||||||
#define _SQLITEINT_H_
 | 
					#define _SQLITEINT_H_
 | 
				
			||||||
@@ -767,9 +767,9 @@ struct Token {
 | 
				
			|||||||
struct Expr {
 | 
					struct Expr {
 | 
				
			||||||
  u8 op;                 /* Operation performed by this node */
 | 
					  u8 op;                 /* Operation performed by this node */
 | 
				
			||||||
  char affinity;         /* The affinity of the column or 0 if not a column */
 | 
					  char affinity;         /* The affinity of the column or 0 if not a column */
 | 
				
			||||||
  CollSeq *pColl;        /* The collation type of the column or 0 */
 | 
					 | 
				
			||||||
  u8 iDb;                /* Database referenced by this expression */
 | 
					  u8 iDb;                /* Database referenced by this expression */
 | 
				
			||||||
  u8 flags;              /* Various flags.  See below */
 | 
					  u8 flags;              /* Various flags.  See below */
 | 
				
			||||||
 | 
					  CollSeq *pColl;        /* The collation type of the column or 0 */
 | 
				
			||||||
  Expr *pLeft, *pRight;  /* Left and right subnodes */
 | 
					  Expr *pLeft, *pRight;  /* Left and right subnodes */
 | 
				
			||||||
  ExprList *pList;       /* A list of expressions used as function arguments
 | 
					  ExprList *pList;       /* A list of expressions used as function arguments
 | 
				
			||||||
                         ** or in "<expr> IN (<expr-list)" */
 | 
					                         ** or in "<expr> IN (<expr-list)" */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										90
									
								
								src/vdbe.c
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								src/vdbe.c
									
									
									
									
									
								
							@@ -43,7 +43,7 @@
 | 
				
			|||||||
** in this file for details.  If in doubt, do not deviate from existing
 | 
					** in this file for details.  If in doubt, do not deviate from existing
 | 
				
			||||||
** commenting and indentation practices when changing or adding code.
 | 
					** commenting and indentation practices when changing or adding code.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** $Id: vdbe.c,v 1.415 2004/09/19 00:50:21 drh Exp $
 | 
					** $Id: vdbe.c,v 1.416 2004/10/04 13:19:24 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "sqliteInt.h"
 | 
					#include "sqliteInt.h"
 | 
				
			||||||
#include "os.h"
 | 
					#include "os.h"
 | 
				
			||||||
@@ -183,32 +183,6 @@ static int AggInsert(Agg *p, char *zKey, int nKey){
 | 
				
			|||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
** Store a pointer to the AggElem currently in focus in *ppElem. Return
 | 
					 | 
				
			||||||
** SQLITE_OK if successful, otherwise an error-code.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
static int AggInFocus(Agg *p, AggElem **ppElem){
 | 
					 | 
				
			||||||
  int rc;
 | 
					 | 
				
			||||||
  int res;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if( p->pCurrent ){
 | 
					 | 
				
			||||||
    *ppElem = p->pCurrent;
 | 
					 | 
				
			||||||
    return SQLITE_OK;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  rc = sqlite3BtreeFirst(p->pCsr, &res);
 | 
					 | 
				
			||||||
  if( rc!=SQLITE_OK ){
 | 
					 | 
				
			||||||
    return rc;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if( res!=0 ){
 | 
					 | 
				
			||||||
    rc = AggInsert(p,"",1);
 | 
					 | 
				
			||||||
    *ppElem = p->pCurrent;
 | 
					 | 
				
			||||||
  }else{
 | 
					 | 
				
			||||||
    rc = sqlite3BtreeData(p->pCsr, 0, 4, (char *)ppElem);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return rc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
** Pop the stack N times.
 | 
					** Pop the stack N times.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
@@ -559,7 +533,9 @@ int sqlite3VdbeExec(
 | 
				
			|||||||
** file looking for lines that begin with "case OP_".  The opcodes.h files
 | 
					** file looking for lines that begin with "case OP_".  The opcodes.h files
 | 
				
			||||||
** will be filled with #defines that give unique integer values to each
 | 
					** will be filled with #defines that give unique integer values to each
 | 
				
			||||||
** opcode and the opcodes.c file is filled with an array of strings where
 | 
					** opcode and the opcodes.c file is filled with an array of strings where
 | 
				
			||||||
** each string is the symbolic name for the corresponding opcode.
 | 
					** each string is the symbolic name for the corresponding opcode.  If the
 | 
				
			||||||
 | 
					** case statement is followed by a comment of the form "/# same as ... #/"
 | 
				
			||||||
 | 
					** that comment is used to determine the particular value of the opcode.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** Documentation about VDBE opcodes is generated by scanning this file
 | 
					** Documentation about VDBE opcodes is generated by scanning this file
 | 
				
			||||||
** for lines of that contain "Opcode:".  That line and all subsequent
 | 
					** for lines of that contain "Opcode:".  That line and all subsequent
 | 
				
			||||||
@@ -677,7 +653,7 @@ case OP_Integer: {
 | 
				
			|||||||
**
 | 
					**
 | 
				
			||||||
** The string value P3 is converted to a real and pushed on to the stack.
 | 
					** The string value P3 is converted to a real and pushed on to the stack.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_Real: {
 | 
					case OP_Real: {            /* same as TK_FLOAT */
 | 
				
			||||||
  pTos++;
 | 
					  pTos++;
 | 
				
			||||||
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
 | 
					  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
 | 
				
			||||||
  pTos->z = pOp->p3;
 | 
					  pTos->z = pOp->p3;
 | 
				
			||||||
@@ -694,7 +670,7 @@ case OP_Real: {
 | 
				
			|||||||
** P3 points to a nul terminated UTF-8 string. This opcode is transformed
 | 
					** P3 points to a nul terminated UTF-8 string. This opcode is transformed
 | 
				
			||||||
** into an OP_String before it is executed for the first time.
 | 
					** into an OP_String before it is executed for the first time.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_String8: {
 | 
					case OP_String8: {         /* same as TK_STRING */
 | 
				
			||||||
  pOp->opcode = OP_String;
 | 
					  pOp->opcode = OP_String;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
 | 
					  if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
 | 
				
			||||||
@@ -745,7 +721,7 @@ case OP_String: {
 | 
				
			|||||||
** The first time this instruction executes, in transforms itself into a
 | 
					** The first time this instruction executes, in transforms itself into a
 | 
				
			||||||
** 'Blob' opcode with a binary blob as P3.
 | 
					** 'Blob' opcode with a binary blob as P3.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_HexBlob: {
 | 
					case OP_HexBlob: {            /* same as TK_BLOB */
 | 
				
			||||||
  pOp->opcode = OP_Blob;
 | 
					  pOp->opcode = OP_Blob;
 | 
				
			||||||
  pOp->p1 = strlen(pOp->p3)/2;
 | 
					  pOp->p1 = strlen(pOp->p3)/2;
 | 
				
			||||||
  if( pOp->p1 ){
 | 
					  if( pOp->p1 ){
 | 
				
			||||||
@@ -922,7 +898,7 @@ case OP_Callback: {
 | 
				
			|||||||
** When P1==1, this routine makes a copy of the top stack element
 | 
					** When P1==1, this routine makes a copy of the top stack element
 | 
				
			||||||
** into memory obtained from sqliteMalloc().
 | 
					** into memory obtained from sqliteMalloc().
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_Concat: {
 | 
					case OP_Concat: {           /* same as TK_CONCAT */
 | 
				
			||||||
  char *zNew;
 | 
					  char *zNew;
 | 
				
			||||||
  int nByte;
 | 
					  int nByte;
 | 
				
			||||||
  int nField;
 | 
					  int nField;
 | 
				
			||||||
@@ -1030,11 +1006,11 @@ case OP_Concat: {
 | 
				
			|||||||
** function before the division.  Division by zero returns NULL.
 | 
					** function before the division.  Division by zero returns NULL.
 | 
				
			||||||
** If either operand is NULL, the result is NULL.
 | 
					** If either operand is NULL, the result is NULL.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_Add:
 | 
					case OP_Add:                   /* same as TK_PLUS */
 | 
				
			||||||
case OP_Subtract:
 | 
					case OP_Subtract:              /* same as TK_MINUS */
 | 
				
			||||||
case OP_Multiply:
 | 
					case OP_Multiply:              /* same as TK_STAR */
 | 
				
			||||||
case OP_Divide:
 | 
					case OP_Divide:                /* same as TK_SLASH */
 | 
				
			||||||
case OP_Remainder: {
 | 
					case OP_Remainder: {           /* same as TK_REM */
 | 
				
			||||||
  Mem *pNos = &pTos[-1];
 | 
					  Mem *pNos = &pTos[-1];
 | 
				
			||||||
  assert( pNos>=p->aStack );
 | 
					  assert( pNos>=p->aStack );
 | 
				
			||||||
  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
 | 
					  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
 | 
				
			||||||
@@ -1233,10 +1209,10 @@ case OP_Function: {
 | 
				
			|||||||
** right by N bits where N is the top element on the stack.
 | 
					** right by N bits where N is the top element on the stack.
 | 
				
			||||||
** If either operand is NULL, the result is NULL.
 | 
					** If either operand is NULL, the result is NULL.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_BitAnd:
 | 
					case OP_BitAnd:                 /* same as TK_BITAND */
 | 
				
			||||||
case OP_BitOr:
 | 
					case OP_BitOr:                  /* same as TK_BITOR */
 | 
				
			||||||
case OP_ShiftLeft:
 | 
					case OP_ShiftLeft:              /* same as TK_LSHIFT */
 | 
				
			||||||
case OP_ShiftRight: {
 | 
					case OP_ShiftRight: {           /* same as TK_RSHIFT */
 | 
				
			||||||
  Mem *pNos = &pTos[-1];
 | 
					  Mem *pNos = &pTos[-1];
 | 
				
			||||||
  int a, b;
 | 
					  int a, b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1398,12 +1374,12 @@ case OP_MustBeInt: {
 | 
				
			|||||||
** the 2nd element down on the stack is greater than or equal to the
 | 
					** the 2nd element down on the stack is greater than or equal to the
 | 
				
			||||||
** top of the stack.  See the Eq opcode for additional information.
 | 
					** top of the stack.  See the Eq opcode for additional information.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_Eq:
 | 
					case OP_Eq:               /* same as TK_EQ */
 | 
				
			||||||
case OP_Ne:
 | 
					case OP_Ne:               /* same as TK_NE */
 | 
				
			||||||
case OP_Lt:
 | 
					case OP_Lt:               /* same as TK_LT */
 | 
				
			||||||
case OP_Le:
 | 
					case OP_Le:               /* same as TK_LE */
 | 
				
			||||||
case OP_Gt:
 | 
					case OP_Gt:               /* same as TK_GT */
 | 
				
			||||||
case OP_Ge: {
 | 
					case OP_Ge: {             /* same as TK_GE */
 | 
				
			||||||
  Mem *pNos;
 | 
					  Mem *pNos;
 | 
				
			||||||
  int flags;
 | 
					  int flags;
 | 
				
			||||||
  int res;
 | 
					  int res;
 | 
				
			||||||
@@ -1469,8 +1445,8 @@ case OP_Ge: {
 | 
				
			|||||||
** two values and push the resulting boolean value back onto the
 | 
					** two values and push the resulting boolean value back onto the
 | 
				
			||||||
** stack. 
 | 
					** stack. 
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_And:
 | 
					case OP_And:              /* same as TK_AND */
 | 
				
			||||||
case OP_Or: {
 | 
					case OP_Or: {             /* same as TK_OR */
 | 
				
			||||||
  Mem *pNos = &pTos[-1];
 | 
					  Mem *pNos = &pTos[-1];
 | 
				
			||||||
  int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */
 | 
					  int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1517,7 +1493,7 @@ case OP_Or: {
 | 
				
			|||||||
** with its absolute value. If the top of the stack is NULL
 | 
					** with its absolute value. If the top of the stack is NULL
 | 
				
			||||||
** its value is unchanged.
 | 
					** its value is unchanged.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_Negative:
 | 
					case OP_Negative:              /* same as TK_UMINUS */
 | 
				
			||||||
case OP_AbsValue: {
 | 
					case OP_AbsValue: {
 | 
				
			||||||
  assert( pTos>=p->aStack );
 | 
					  assert( pTos>=p->aStack );
 | 
				
			||||||
  if( pTos->flags & MEM_Real ){
 | 
					  if( pTos->flags & MEM_Real ){
 | 
				
			||||||
@@ -1550,7 +1526,7 @@ case OP_AbsValue: {
 | 
				
			|||||||
** with its complement.  If the top of the stack is NULL its value
 | 
					** with its complement.  If the top of the stack is NULL its value
 | 
				
			||||||
** is unchanged.
 | 
					** is unchanged.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_Not: {
 | 
					case OP_Not: {                /* same as TK_NOT */
 | 
				
			||||||
  assert( pTos>=p->aStack );
 | 
					  assert( pTos>=p->aStack );
 | 
				
			||||||
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
 | 
					  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
 | 
				
			||||||
  Integerify(pTos);
 | 
					  Integerify(pTos);
 | 
				
			||||||
@@ -1566,7 +1542,7 @@ case OP_Not: {
 | 
				
			|||||||
** with its ones-complement.  If the top of the stack is NULL its
 | 
					** with its ones-complement.  If the top of the stack is NULL its
 | 
				
			||||||
** value is unchanged.
 | 
					** value is unchanged.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_BitNot: {
 | 
					case OP_BitNot: {             /* same as TK_BITNOT */
 | 
				
			||||||
  assert( pTos>=p->aStack );
 | 
					  assert( pTos>=p->aStack );
 | 
				
			||||||
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
 | 
					  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
 | 
				
			||||||
  Integerify(pTos);
 | 
					  Integerify(pTos);
 | 
				
			||||||
@@ -1627,7 +1603,7 @@ case OP_IfNot: {
 | 
				
			|||||||
** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
 | 
					** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
 | 
				
			||||||
** unchanged.
 | 
					** unchanged.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_IsNull: {
 | 
					case OP_IsNull: {            /* same as TK_ISNULL */
 | 
				
			||||||
  int i, cnt;
 | 
					  int i, cnt;
 | 
				
			||||||
  Mem *pTerm;
 | 
					  Mem *pTerm;
 | 
				
			||||||
  cnt = pOp->p1;
 | 
					  cnt = pOp->p1;
 | 
				
			||||||
@@ -1650,7 +1626,7 @@ case OP_IsNull: {
 | 
				
			|||||||
** stack if P1 times if P1 is greater than zero.  If P1 is less than
 | 
					** stack if P1 times if P1 is greater than zero.  If P1 is less than
 | 
				
			||||||
** zero then leave the stack unchanged.
 | 
					** zero then leave the stack unchanged.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
case OP_NotNull: {
 | 
					case OP_NotNull: {            /* same as TK_NOTNULL */
 | 
				
			||||||
  int i, cnt;
 | 
					  int i, cnt;
 | 
				
			||||||
  cnt = pOp->p1;
 | 
					  cnt = pOp->p1;
 | 
				
			||||||
  if( cnt<0 ) cnt = -cnt;
 | 
					  if( cnt<0 ) cnt = -cnt;
 | 
				
			||||||
@@ -4241,8 +4217,7 @@ case OP_AggFocus: {
 | 
				
			|||||||
case OP_AggSet: {
 | 
					case OP_AggSet: {
 | 
				
			||||||
  AggElem *pFocus;
 | 
					  AggElem *pFocus;
 | 
				
			||||||
  int i = pOp->p2;
 | 
					  int i = pOp->p2;
 | 
				
			||||||
  rc = AggInFocus(&p->agg, &pFocus);
 | 
					  pFocus = p->agg.pCurrent;
 | 
				
			||||||
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
 | 
					 | 
				
			||||||
  assert( pTos>=p->aStack );
 | 
					  assert( pTos>=p->aStack );
 | 
				
			||||||
  if( pFocus==0 ) goto no_mem;
 | 
					  if( pFocus==0 ) goto no_mem;
 | 
				
			||||||
  assert( i>=0 && i<p->agg.nMem );
 | 
					  assert( i>=0 && i<p->agg.nMem );
 | 
				
			||||||
@@ -4260,8 +4235,7 @@ case OP_AggSet: {
 | 
				
			|||||||
case OP_AggGet: {
 | 
					case OP_AggGet: {
 | 
				
			||||||
  AggElem *pFocus;
 | 
					  AggElem *pFocus;
 | 
				
			||||||
  int i = pOp->p2;
 | 
					  int i = pOp->p2;
 | 
				
			||||||
  rc = AggInFocus(&p->agg, &pFocus);
 | 
					  pFocus = p->agg.pCurrent;
 | 
				
			||||||
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
 | 
					 | 
				
			||||||
  if( pFocus==0 ) goto no_mem;
 | 
					  if( pFocus==0 ) goto no_mem;
 | 
				
			||||||
  assert( i>=0 && i<p->agg.nMem );
 | 
					  assert( i>=0 && i<p->agg.nMem );
 | 
				
			||||||
  pTos++;
 | 
					  pTos++;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user