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:
79
src/build.c
79
src/build.c
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user