blob: 52e4d30d8da249f4c679d278554bdd94ef8d6ece [file] [log] [blame]
drhcce7d172000-05-31 15:34:51 +00001/*
2** Copyright (c) 1999, 2000 D. Richard Hipp
3**
4** This program is free software; you can redistribute it and/or
5** modify it under the terms of the GNU General Public
6** License as published by the Free Software Foundation; either
7** version 2 of the License, or (at your option) any later version.
8**
9** This program is distributed in the hope that it will be useful,
10** but WITHOUT ANY WARRANTY; without even the implied warranty of
11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12** General Public License for more details.
13**
14** You should have received a copy of the GNU General Public
15** License along with this library; if not, write to the
16** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17** Boston, MA 02111-1307, USA.
18**
19** Author contact information:
20** drh@hwaci.com
21** http://www.hwaci.com/drh/
22**
23*************************************************************************
24** This file contains C code routines that are called by the parser
25** to handle SELECT statements.
26**
drhefb72512000-05-31 20:00:52 +000027** $Id: select.c,v 1.3 2000/05/31 20:00:52 drh Exp $
drhcce7d172000-05-31 15:34:51 +000028*/
29#include "sqliteInt.h"
30
31
32/*
33** Process a SELECT statement.
34*/
35void sqliteSelect(
36 Parse *pParse, /* The parser context */
37 ExprList *pEList, /* List of fields to extract. NULL means "*" */
38 IdList *pTabList, /* List of tables to select from */
39 Expr *pWhere, /* The WHERE clause. May be NULL */
drhefb72512000-05-31 20:00:52 +000040 ExprList *pOrderBy, /* The ORDER BY clause. May be NULL */
41 int distinct /* If true, only output distinct results */
drhcce7d172000-05-31 15:34:51 +000042){
43 int i, j;
44 WhereInfo *pWInfo;
45 Vdbe *v;
46 int isAgg = 0; /* True for select lists like "count(*)" */
47
48 if( pParse->nErr>0 ) goto select_cleanup;
49
50 /* Look up every table in the table list.
51 */
52 for(i=0; i<pTabList->nId; i++){
53 pTabList->a[i].pTab = sqliteFindTable(pParse->db, pTabList->a[i].zName);
54 if( pTabList->a[i].pTab==0 ){
55 sqliteSetString(&pParse->zErrMsg, "no such table: ",
56 pTabList->a[i].zName, 0);
57 pParse->nErr++;
58 goto select_cleanup;
59 }
60 }
61
62 /* If the list of fields to retrieve is "*" then replace it with
63 ** a list of all fields from all tables.
64 */
65 if( pEList==0 ){
66 for(i=0; i<pTabList->nId; i++){
67 Table *pTab = pTabList->a[i].pTab;
68 for(j=0; j<pTab->nCol; j++){
69 Expr *pExpr = sqliteExpr(TK_FIELD, 0, 0, 0);
70 pExpr->iTable = i;
71 pExpr->iField = j;
72 pEList = sqliteExprListAppend(pEList, pExpr, 0);
73 }
74 }
75 }
76
77 /* Resolve the field names and do a semantics check on all the expressions.
78 */
79 for(i=0; i<pEList->nExpr; i++){
80 if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
81 goto select_cleanup;
82 }
83 if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &pEList->a[i].isAgg) ){
84 goto select_cleanup;
85 }
86 }
87 if( pEList->nExpr>0 ){
88 isAgg = pEList->a[0].isAgg;
89 for(i=1; i<pEList->nExpr; i++){
90 if( pEList->a[i].isAgg!=isAgg ){
91 sqliteSetString(&pParse->zErrMsg, "some selected items are aggregates "
92 "and others are not", 0);
93 pParse->nErr++;
94 goto select_cleanup;
95 }
96 }
97 }
98 if( pWhere ){
99 if( sqliteExprResolveIds(pParse, pTabList, pWhere) ){
100 goto select_cleanup;
101 }
102 if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
103 goto select_cleanup;
104 }
105 }
106 if( pOrderBy ){
107 for(i=0; i<pOrderBy->nExpr; i++){
108 if( sqliteExprResolveIds(pParse, pTabList, pOrderBy->a[i].pExpr) ){
109 goto select_cleanup;
110 }
111 if( sqliteExprCheck(pParse, pOrderBy->a[i].pExpr, 0, 0) ){
112 goto select_cleanup;
113 }
114 }
115 }
116
117 /* ORDER BY is ignored if this is an aggregate query like count(*)
118 ** since only one row will be returned.
119 */
120 if( isAgg && pOrderBy ){
121 sqliteExprListDelete(pOrderBy);
122 pOrderBy = 0;
123 }
124
drhefb72512000-05-31 20:00:52 +0000125 /* Turn off distinct if this is an aggregate
126 */
127 if( isAgg ){
128 distinct = 0;
129 }
130
drhcce7d172000-05-31 15:34:51 +0000131 /* Begin generating code.
132 */
133 v = pParse->pVdbe;
134 if( v==0 ){
135 v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
136 }
137 if( v==0 ) goto select_cleanup;
138 if( pOrderBy ){
139 sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
140 }
141
142 /* Identify column names
143 */
144 sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0, 0, 0);
145 for(i=0; i<pEList->nExpr; i++){
146 Expr *p;
147 if( pEList->a[i].zName ){
148 char *zName = pEList->a[i].zName;
149 int addr = sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
150 if( zName[0]=='\'' || zName[0]=='"' ){
151 sqliteVdbeDequoteP3(v, addr);
152 }
153 continue;
154 }
155 p = pEList->a[i].pExpr;
156 if( p->op!=TK_FIELD ){
157 char zName[30];
158 sprintf(zName, "field%d", i+1);
159 sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
160 }else{
161 if( pTabList->nId>1 ){
162 char *zName = 0;
163 Table *pTab = pTabList->a[p->iTable].pTab;
drhda9d6c42000-05-31 18:20:14 +0000164 char *zTab;
165
166 zTab = pTabList->a[p->iTable].zAlias;
167 if( zTab==0 ) zTab = pTab->zName;
168 sqliteSetString(&zName, zTab, ".", pTab->azCol[p->iField], 0);
drhcce7d172000-05-31 15:34:51 +0000169 sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
170 sqliteFree(zName);
171 }else{
172 Table *pTab = pTabList->a[0].pTab;
173 sqliteVdbeAddOp(v, OP_ColumnName, i, 0, pTab->azCol[p->iField], 0);
174 }
175 }
176 }
177
178 /* Initialize the stack to contain aggregate seed values
179 */
180 if( isAgg ){
181 for(i=0; i<pEList->nExpr; i++){
182 Expr *p = pEList->a[i].pExpr;
183 switch( sqliteFuncId(&p->token) ){
184 case FN_Min:
185 case FN_Max: {
186 sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
187 break;
188 }
189 default: {
190 sqliteVdbeAddOp(v, OP_Integer, 0, 0, 0, 0);
191 break;
192 }
193 }
194 }
195 }
196
197 /* Begin the database scan
drhefb72512000-05-31 20:00:52 +0000198 */
199 if( distinct ){
200 distinct = pTabList->nId*2+1;
201 sqliteVdbeAddOp(v, OP_Open, distinct, 0, 0, 0);
202 }
drhcce7d172000-05-31 15:34:51 +0000203 pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0);
204 if( pWInfo==0 ) goto select_cleanup;
205
206 /* Pull the requested fields.
207 */
drhda9d6c42000-05-31 18:20:14 +0000208 if( !isAgg ){
209 for(i=0; i<pEList->nExpr; i++){
210 sqliteExprCode(pParse, pEList->a[i].pExpr);
211 }
drhcce7d172000-05-31 15:34:51 +0000212 }
drhefb72512000-05-31 20:00:52 +0000213
214 /* If the current result is not distinct, script the remainder
215 ** of this processing.
216 */
217 if( distinct ){
218 int isDistinct = sqliteVdbeMakeLabel(v);
219 sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1, 0, 0);
220 sqliteVdbeAddOp(v, OP_Distinct, distinct, isDistinct, 0, 0);
221 sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0, 0, 0);
222 sqliteVdbeAddOp(v, OP_Goto, 0, pWInfo->iContinue, 0, 0);
223 sqliteVdbeAddOp(v, OP_String, 0, 0, "", isDistinct);
224 sqliteVdbeAddOp(v, OP_Put, distinct, 0, 0, 0);
225 }
drhcce7d172000-05-31 15:34:51 +0000226
227 /* If there is no ORDER BY clause, then we can invoke the callback
228 ** right away. If there is an ORDER BY, then we need to put the
229 ** data into an appropriate sorter record.
230 */
231 if( pOrderBy ){
232 char *zSortOrder;
233 sqliteVdbeAddOp(v, OP_SortMakeRec, pEList->nExpr, 0, 0, 0);
234 zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
235 if( zSortOrder==0 ) goto select_cleanup;
236 for(i=0; i<pOrderBy->nExpr; i++){
237 zSortOrder[i] = pOrderBy->a[i].idx ? '-' : '+';
238 sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
239 }
240 zSortOrder[pOrderBy->nExpr] = 0;
241 sqliteVdbeAddOp(v, OP_SortMakeKey, pOrderBy->nExpr, 0, zSortOrder, 0);
242 sqliteVdbeAddOp(v, OP_SortPut, 0, 0, 0, 0);
243 }else if( isAgg ){
244 int n = pEList->nExpr;
245 for(i=0; i<n; i++){
246 Expr *p = pEList->a[i].pExpr;
247 int id = sqliteFuncId(&p->token);
248 int op, p1;
249 if( n>1 ){
250 sqliteVdbeAddOp(v, OP_Pull, n-1, 0, 0, 0);
251 }
252 if( id!=FN_Count && p->pList && p->pList->nExpr>=1 ){
253 sqliteExprCode(pParse, p->pList->a[0].pExpr);
254 }
255 switch( sqliteFuncId(&p->token) ){
256 case FN_Count: op = OP_AddImm; p1 = 1; break;
257 case FN_Sum: op = OP_Add; p1 = 0; break;
258 case FN_Min: op = OP_Min; p1 = 1; break;
259 case FN_Max: op = OP_Max; p1 = 0; break;
260 }
261 sqliteVdbeAddOp(v, op, p1, 0, 0, 0);
262 }
263 }else{
264 sqliteVdbeAddOp(v, OP_Callback, pEList->nExpr, 0, 0, 0);
265 }
266
267 /* End the database scan loop.
268 */
269 sqliteWhereEnd(pWInfo);
270
271 /* If there is an ORDER BY clause, then we need to sort the results
272 ** and send them to the callback one by one.
273 */
274 if( pOrderBy ){
275 int end = sqliteVdbeMakeLabel(v);
276 int addr;
277 sqliteVdbeAddOp(v, OP_Sort, 0, 0, 0, 0);
278 addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end, 0, 0);
279 sqliteVdbeAddOp(v, OP_SortCallback, pEList->nExpr, 0, 0, 0);
280 sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
281 sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
282 }
283
284 /* If this is an aggregate, then we need to invoke the callback
285 ** exactly once.
286 */
287 if( isAgg ){
288 sqliteVdbeAddOp(v, OP_Callback, pEList->nExpr, 0, 0, 0);
289 }
290
291 /* Always execute the following code before exiting, in order to
292 ** release resources.
293 */
294select_cleanup:
295 sqliteExprListDelete(pEList);
296 sqliteIdListDelete(pTabList);
297 sqliteExprDelete(pWhere);
298 sqliteExprListDelete(pOrderBy);
299 return;
300}