1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-18 10:21:03 +03:00

Query optimizer enhancement: In "FROM a,b,c left join d" allow the C table

to be reordered with A and B.  This used to be the case but the capability
was removed by (3203) and (3052) in response to ticket #1652.  This change
restores the capability. (CVS 3529)

FossilOrigin-Name: 7393c81b8cb9d4344ae744de9eabcb3af64f1db8
This commit is contained in:
drh
2006-12-16 16:25:15 +00:00
parent f0fa1c1b9f
commit 61dfc31d80
9 changed files with 212 additions and 86 deletions

View File

@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
** $Id: build.c,v 1.411 2006/09/11 23:45:49 drh Exp $
** $Id: build.c,v 1.412 2006/12/16 16:25:15 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -2940,15 +2940,6 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
}
}
/*
** Add an alias to the last identifier on the given identifier list.
*/
void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){
if( pList && pList->nSrc>0 ){
pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken);
}
}
/*
** Delete an entire SrcList including all its substructure.
*/
@@ -2968,6 +2959,74 @@ void sqlite3SrcListDelete(SrcList *pList){
sqliteFree(pList);
}
/*
** This routine is called by the parser to add a new term to the
** end of a growing FROM clause. The "p" parameter is the part of
** the FROM clause that has already been constructed. "p" is NULL
** if this is the first term of the FROM clause. pTable and pDatabase
** are the name of the table and database named in the FROM clause term.
** pDatabase is NULL if the database name qualifier is missing - the
** usual case. If the term has a alias, then pAlias points to the
** alias token. If the term is a subquery, then pSubquery is the
** SELECT statement that the subquery encodes. The pTable and
** pDatabase parameters are NULL for subqueries. The pOn and pUsing
** parameters are the content of the ON and USING clauses.
**
** Return a new SrcList which encodes is the FROM with the new
** term added.
*/
SrcList *sqlite3SrcListAppendFromTerm(
SrcList *p, /* The left part of the FROM clause already seen */
Token *pTable, /* Name of the table to add to the FROM clause */
Token *pDatabase, /* Name of the database containing pTable */
Token *pAlias, /* The right-hand side of the AS subexpression */
Select *pSubquery, /* A subquery used in place of a table name */
Expr *pOn, /* The ON clause of a join */
IdList *pUsing /* The USING clause of a join */
){
struct SrcList_item *pItem;
p = sqlite3SrcListAppend(p, pTable, pDatabase);
if( p==0 || p->nSrc==0 ){
sqlite3ExprDelete(pOn);
sqlite3IdListDelete(pUsing);
sqlite3SelectDelete(pSubquery);
return p;
}
pItem = &p->a[p->nSrc-1];
if( pAlias && pAlias->n ){
pItem->zAlias = sqlite3NameFromToken(pAlias);
}
pItem->pSelect = pSubquery;
pItem->pOn = pOn;
pItem->pUsing = pUsing;
return p;
}
/*
** When building up a FROM clause in the parser, the join operator
** is initially attached to the left operand. But the code generator
** expects the join operator to be on the right operand. This routine
** Shifts all join operators from left to right for an entire FROM
** clause.
**
** Example: Suppose the join is like this:
**
** A natural cross join B
**
** The operator is "natural cross join". The A and B operands are stored
** in p->a[0] and p->a[1], respectively. The parser initially stores the
** operator with A. This routine shifts that operator over to B.
*/
void sqlite3SrcListShiftJoinType(SrcList *p){
if( p && p->a ){
int i;
for(i=p->nSrc-1; i>0; i--){
p->a[i].jointype = p->a[i-1].jointype;
}
p->a[0].jointype = 0;
}
}
/*
** Begin a transaction
*/