/ Check-in [85cca7cd]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:First cut at adding the COLLATE operator. Regression tests pass (or at least the quick set does) and a few new tests have been added. But many more tests are needed. Rules for combining collations need to be worked out. (CVS 3624)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:85cca7cd252d46ba71d302a89bc67c56146ec552
User & Date: drh 2007-02-01 23:02:45
Context
2007-02-02
12:33
Fix typos in the pragma documentation. Ticket #2210. (CVS 3625) check-in: f0c66ad8 user: drh tags: trunk
2007-02-01
23:02
First cut at adding the COLLATE operator. Regression tests pass (or at least the quick set does) and a few new tests have been added. But many more tests are needed. Rules for combining collations need to be worked out. (CVS 3624) check-in: 85cca7cd user: drh tags: trunk
01:53
Fix a bug in the copy method of the TCL interface. Ticket #2201. (CVS 3623) check-in: 93626396 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
44
45
46
47
48
49
50















51
52
53
54
55
56
57
...
886
887
888
889
890
891
892

893

894
895
896
897
898
899
900
...
942
943
944
945
946
947
948

949

950
951
952
953
954
955
956
**    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.272 2007/02/01 01:40:44 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
#ifndef SQLITE_OMIT_CAST
  if( op==TK_CAST ){
    return sqlite3AffinityType(&pExpr->token);
  }
#endif
  return pExpr->affinity;
}
















/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  CollSeq *pColl = 0;
................................................................................
            cnt++;
            pExpr->iTable = pItem->iCursor;
            pMatch = pItem;
            pExpr->pSchema = pTab->pSchema;
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;

            pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);

            if( i<pSrcList->nSrc-1 ){
              if( pItem[1].jointype & JT_NATURAL ){
                /* If this match occurred in the left table of a natural join,
                ** then skip the right table to avoid a duplicate match */
                pItem++;
                i++;
              }else if( (pUsing = pItem[1].pUsing)!=0 ){
................................................................................
        cntTab++;
        for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            const char *zColl = pTab->aCol[iCol].zColl;
            cnt++;
            pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
            pExpr->affinity = pTab->aCol[iCol].affinity;

            pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);

            pExpr->pTab = pTab;
            break;
          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
|
>







 







>
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
...
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
**    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.273 2007/02/01 23:02:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
#ifndef SQLITE_OMIT_CAST
  if( op==TK_CAST ){
    return sqlite3AffinityType(&pExpr->token);
  }
#endif
  return pExpr->affinity;
}

/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken.   Return a pointer to the revised expression.
*/
Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
  CollSeq *pColl;
  if( pExpr==0 ) return 0;
  pColl = sqlite3LocateCollSeq(pParse, (char*)pName->z, pName->n);
  if( pColl ){
    pExpr->pColl = pColl;
    pExpr->flags |= EP_ExpCollate;
  }
  return pExpr;
}

/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  CollSeq *pColl = 0;
................................................................................
            cnt++;
            pExpr->iTable = pItem->iCursor;
            pMatch = pItem;
            pExpr->pSchema = pTab->pSchema;
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;
            if( (pExpr->flags & EP_ExpCollate)==0 ){
              pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
            }
            if( i<pSrcList->nSrc-1 ){
              if( pItem[1].jointype & JT_NATURAL ){
                /* If this match occurred in the left table of a natural join,
                ** then skip the right table to avoid a duplicate match */
                pItem++;
                i++;
              }else if( (pUsing = pItem[1].pUsing)!=0 ){
................................................................................
        cntTab++;
        for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            const char *zColl = pTab->aCol[iCol].zColl;
            cnt++;
            pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
            pExpr->affinity = pTab->aCol[iCol].affinity;
            if( (pExpr->flags & EP_ExpCollate)==0 ){
              pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
            }
            pExpr->pTab = pTab;
            break;
          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
...
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
...
638
639
640
641
642
643
644



645
646
647
648
649
650
651
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.213 2007/01/27 02:38:30 drh Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
................................................................................
%right NOT.
%left IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
%left GT LE LT GE.
%right ESCAPE.
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%left CONCAT.
%right UMINUS UPLUS BITNOT.

// And "ids" is an identifer-or-string.
//
%type ids {Token}
ids(A) ::= ID|STRING(X).   {A = X;}

................................................................................
%type sortlist {ExprList*}
%destructor sortlist {sqlite3ExprListDelete($$);}
%type sortitem {Expr*}
%destructor sortitem {sqlite3ExprDelete($$);}

orderby_opt(A) ::= .                          {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
  A = sqlite3ExprListAppend(X,Y,C.n>0?&C:0);
  if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
  A = sqlite3ExprListAppend(0,Y,C.n>0?&C:0);
  if( A && A->a ) A->a[0].sortOrder = Z;
}
sortitem(A) ::= expr(X).   {A = X;}

%type sortorder {int}
%type collate {Token}

................................................................................
term(A) ::= STRING(X).       {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= REGISTER(X).     {A = sqlite3RegisterExpr(pParse, &X);}
expr(A) ::= VARIABLE(X).     {
  Token *pToken = &X;
  Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
  sqlite3ExprAssignVarNumber(pParse, pExpr);
}



%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
  A = sqlite3Expr(TK_CAST, E, 0, &T);
  sqlite3ExprSpan(A,&X,&Y);
}
%endif  SQLITE_OMIT_CAST
expr(A) ::= ID(X) LP distinct(D) exprlist(Y) RP(E). {







|







 







|







 







|
|


|
|







 







>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
...
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
...
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.214 2007/02/01 23:02:45 drh Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
................................................................................
%right NOT.
%left IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
%left GT LE LT GE.
%right ESCAPE.
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%left CONCAT COLLATE.
%right UMINUS UPLUS BITNOT.

// And "ids" is an identifer-or-string.
//
%type ids {Token}
ids(A) ::= ID|STRING(X).   {A = X;}

................................................................................
%type sortlist {ExprList*}
%destructor sortlist {sqlite3ExprListDelete($$);}
%type sortitem {Expr*}
%destructor sortitem {sqlite3ExprDelete($$);}

orderby_opt(A) ::= .                          {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). {
  A = sqlite3ExprListAppend(X,Y,0);
  if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
sortlist(A) ::= sortitem(Y) sortorder(Z). {
  A = sqlite3ExprListAppend(0,Y,0);
  if( A && A->a ) A->a[0].sortOrder = Z;
}
sortitem(A) ::= expr(X).   {A = X;}

%type sortorder {int}
%type collate {Token}

................................................................................
term(A) ::= STRING(X).       {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= REGISTER(X).     {A = sqlite3RegisterExpr(pParse, &X);}
expr(A) ::= VARIABLE(X).     {
  Token *pToken = &X;
  Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
  sqlite3ExprAssignVarNumber(pParse, pExpr);
}
expr(A) ::= expr(E) COLLATE id(C). {
  A = sqlite3ExprSetColl(pParse, E, &C);
}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
  A = sqlite3Expr(TK_CAST, E, 0, &T);
  sqlite3ExprSpan(A,&X,&Y);
}
%endif  SQLITE_OMIT_CAST
expr(A) ::= ID(X) LP distinct(D) exprlist(Y) RP(E). {

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
....
2474
2475
2476
2477
2478
2479
2480


2481
2482




2483
2484
2485
2486
2487
2488
2489
....
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
**    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.325 2007/01/26 19:23:33 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................

      aCopy = &pKeyInfo->aColl[nOrderByExpr];
      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol];
      memcpy(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));
      apColl = pKeyInfo->aColl;
      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
        Expr *pExpr = pOTerm->pExpr;
        char *zName = pOTerm->zName;
        assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );
        if( zName ){
          *apColl = sqlite3LocateCollSeq(pParse, zName, -1);
        }else{
          *apColl = aCopy[pExpr->iColumn];
        }
        *pSortOrder = pOTerm->sortOrder;
      }
      assert( p->pRightmost==p );
      assert( p->addrOpenEphm[2]>=0 );
................................................................................

  if( pOrderBy==0 ) return 0;
  for(i=0; i<pOrderBy->nExpr; i++){
    int iCol;
    Expr *pE = pOrderBy->a[i].pExpr;
    if( sqlite3ExprIsInteger(pE, &iCol) ){
      if( iCol>0 && iCol<=pEList->nExpr ){


        sqlite3ExprDelete(pE);
        pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);




      }else{
        sqlite3ErrorMsg(pParse, 
           "%s BY column number %d out of range - should be "
           "between 1 and %d", zType, iCol, pEList->nExpr);
        return 1;
      }
    }
................................................................................
  if( pParent && pParentAgg &&
      flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){
    if( isAgg ) *pParentAgg = 1;
    goto select_end;
  }
#endif

  /* If there is an ORDER BY clause, resolve any collation sequences
  ** names that have been explicitly specified and create a sorting index.
  **
  ** This sorting index might end up being unused if the data can be 
  ** extracted in pre-sorted order.  If that is the case, then the
  ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
  ** we figure out that the sorting index is not needed.  The addrSortIndex
  ** variable is used to facilitate that change.
  */
  if( pOrderBy ){
    struct ExprList_item *pTerm;
    KeyInfo *pKeyInfo;
    for(i=0, pTerm=pOrderBy->a; i<pOrderBy->nExpr; i++, pTerm++){
      if( pTerm->zName ){
        pTerm->pExpr->pColl = sqlite3LocateCollSeq(pParse, pTerm->zName, -1);
      }
    }
    if( pParse->nErr ){
      goto select_end;
    }
    pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
    pOrderBy->iECursor = pParse->nTab++;
    p->addrOpenEphm[2] = addrSortIndex =
      sqlite3VdbeOp3(v, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+2,                     (char*)pKeyInfo, P3_KEYINFO_HANDOFF);







|







 







|
|
|
<







 







>
>


>
>
>
>







 







|
<
<
|






<

<
<
<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957

1958
1959
1960
1961
1962
1963
1964
....
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
....
2915
2916
2917
2918
2919
2920
2921
2922


2923
2924
2925
2926
2927
2928
2929

2930





2931
2932
2933
2934
2935
2936
2937
**    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.326 2007/02/01 23:02:45 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................

      aCopy = &pKeyInfo->aColl[nOrderByExpr];
      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol];
      memcpy(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));
      apColl = pKeyInfo->aColl;
      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
        Expr *pExpr = pOTerm->pExpr;
        if( (pExpr->flags & EP_ExpCollate) ){
          assert( pExpr->pColl!=0 );
          *apColl = pExpr->pColl;

        }else{
          *apColl = aCopy[pExpr->iColumn];
        }
        *pSortOrder = pOTerm->sortOrder;
      }
      assert( p->pRightmost==p );
      assert( p->addrOpenEphm[2]>=0 );
................................................................................

  if( pOrderBy==0 ) return 0;
  for(i=0; i<pOrderBy->nExpr; i++){
    int iCol;
    Expr *pE = pOrderBy->a[i].pExpr;
    if( sqlite3ExprIsInteger(pE, &iCol) ){
      if( iCol>0 && iCol<=pEList->nExpr ){
        CollSeq *pColl = pE->pColl;
        int flags = pE->flags & EP_ExpCollate;
        sqlite3ExprDelete(pE);
        pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
        if( pColl && flags ){
          pE->pColl = pColl;
          pE->flags |= flags;
        }
      }else{
        sqlite3ErrorMsg(pParse, 
           "%s BY column number %d out of range - should be "
           "between 1 and %d", zType, iCol, pEList->nExpr);
        return 1;
      }
    }
................................................................................
  if( pParent && pParentAgg &&
      flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){
    if( isAgg ) *pParentAgg = 1;
    goto select_end;
  }
#endif

  /* If there is an ORDER BY clause, then this sorting


  ** index might end up being unused if the data can be 
  ** extracted in pre-sorted order.  If that is the case, then the
  ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
  ** we figure out that the sorting index is not needed.  The addrSortIndex
  ** variable is used to facilitate that change.
  */
  if( pOrderBy ){

    KeyInfo *pKeyInfo;





    if( pParse->nErr ){
      goto select_end;
    }
    pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
    pOrderBy->iECursor = pParse->nTab++;
    p->addrOpenEphm[2] = addrSortIndex =
      sqlite3VdbeOp3(v, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+2,                     (char*)pKeyInfo, P3_KEYINFO_HANDOFF);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
....
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
**    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.534 2007/02/01 01:40:44 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
#define EP_Agg          0x02  /* Contains one or more aggregate functions */
#define EP_Resolved     0x04  /* IDs have been resolved to COLUMNs */
#define EP_Error        0x08  /* Expression contains one or more errors */
#define EP_Distinct     0x10  /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect    0x20  /* pSelect is correlated, not constant */
#define EP_Dequoted     0x40  /* True if the string has been dequoted */
#define EP_InfixFunc    0x80  /* True for an infix function: LIKE, GLOB, etc */


/*
** 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)
................................................................................
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrStr(int);
int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);

int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
void sqlite3utf16Substr(sqlite3_context *,int,sqlite3_value **);

const void *sqlite3ValueText(sqlite3_value*, u8);







|







 







>







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
....
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
**    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.535 2007/02/01 23:02:45 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
#define EP_Agg          0x02  /* Contains one or more aggregate functions */
#define EP_Resolved     0x04  /* IDs have been resolved to COLUMNs */
#define EP_Error        0x08  /* Expression contains one or more errors */
#define EP_Distinct     0x10  /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect    0x20  /* pSelect is correlated, not constant */
#define EP_Dequoted     0x40  /* True if the string has been dequoted */
#define EP_InfixFunc    0x80  /* True for an infix function: LIKE, GLOB, etc */
#define EP_ExpCollate  0x100  /* Collating sequence specified explicitly */

/*
** 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)
................................................................................
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrStr(int);
int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
void sqlite3utf16Substr(sqlite3_context *,int,sqlite3_value **);

const void *sqlite3ValueText(sqlite3_value*, u8);

Changes to test/collate1.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
86
87
88
89
90
91
92















93
94
95
96
97
98
99
...
129
130
131
132
133
134
135

























136



























137
138
139
140
141
142
143
...
175
176
177
178
179
180
181






182
183
184
185
186
187
188
...
216
217
218
219
220
221
222





223
224
225
226
227
228
229
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: collate1.test,v 1.4 2005/11/01 15:48:25 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#
# Tests are roughly organised as follows:
#
................................................................................
} {0x119 0x2D {}}
do_test collate1-1.4 {
  execsql {
   SELECT c2 FROM collate1t1 ORDER BY 1 COLLATE hex ASC;
  }
} {{} 0x2D 0x119}
do_test collate1-1.5 {















  execsql {
    DROP TABLE collate1t1;
  }
} {}

do_test collate1-2.0 {
  execsql {
................................................................................
} {7 0xA 5 0x11 5 0xA 11 0x101 11 0x11 {} {}}
do_test collate1-2.6 {
  execsql {
    SELECT c1, c2 FROM collate1t1 
        ORDER BY 1 COLLATE binary ASC, 2 COLLATE hex ASC;
  }
} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA}

























do_test collate1-2.7 {



























  execsql {
    DROP TABLE collate1t1;
  }
} {}

#
# These tests ensure that the default collation type for a column is used 
................................................................................
    SELECT a as c1, b as c2 FROM collate1t1 ORDER BY c1;
  }
} {{} {} 1 1 0x5 5 0x45 69}
do_test collate1-3.5 {
  execsql {
    SELECT a as c1, b as c2 FROM collate1t1 ORDER BY c1 COLLATE binary;
  }






} {{} {} 0x45 69 0x5 5 1 1}
do_test collate1-3.6 {
  execsql {
    DROP TABLE collate1t1;
  }
} {}

................................................................................
  }
} {{} 1 12 101}
do_test collate1-4.4 {
  execsql {
    SELECT c1||'' FROM collate1t1 ORDER BY 1;
  }
} {{} 1 101 12}





do_test collate1-4.5 {
  execsql {
    DROP TABLE collate1t1;
  }
} {}

finish_test







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>







 







>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: collate1.test,v 1.5 2007/02/01 23:02:46 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#
# Tests are roughly organised as follows:
#
................................................................................
} {0x119 0x2D {}}
do_test collate1-1.4 {
  execsql {
   SELECT c2 FROM collate1t1 ORDER BY 1 COLLATE hex ASC;
  }
} {{} 0x2D 0x119}
do_test collate1-1.5 {
  execsql {
    SELECT c2 COLLATE hex FROM collate1t1 ORDER BY 1
  }
} {{} 0x2D 0x119}
do_test collate1-1.6 {
  execsql {
    SELECT c2 COLLATE hex FROM collate1t1 ORDER BY 1 ASC
  }
} {{} 0x2D 0x119}
do_test collate1-1.7 {
  execsql {
    SELECT c2 COLLATE hex FROM collate1t1 ORDER BY 1 DESC
  }
} {0x119 0x2D {}}
do_test collate1-1.99 {
  execsql {
    DROP TABLE collate1t1;
  }
} {}

do_test collate1-2.0 {
  execsql {
................................................................................
} {7 0xA 5 0x11 5 0xA 11 0x101 11 0x11 {} {}}
do_test collate1-2.6 {
  execsql {
    SELECT c1, c2 FROM collate1t1 
        ORDER BY 1 COLLATE binary ASC, 2 COLLATE hex ASC;
  }
} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA}
do_test collate1-2.12.1 {
  execsql {
    SELECT c1 COLLATE numeric, c2 FROM collate1t1 
     ORDER BY 1, 2 COLLATE hex;
  }
} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
do_test collate1-2.12.2 {
  execsql {
    SELECT c1 COLLATE hex, c2 FROM collate1t1 
     ORDER BY 1 COLLATE numeric, 2 COLLATE hex;
  }
} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
do_test collate1-2.12.3 {
  execsql {
    SELECT c1, c2 COLLATE hex FROM collate1t1 
     ORDER BY 1 COLLATE numeric, 2;
  }
} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
do_test collate1-2.12.4 {
  execsql {
    SELECT c1 COLLATE numeric, c2 COLLATE hex
      FROM collate1t1 
     ORDER BY 1, 2;
  }
} {{} {} 5 0xA 5 0x11 7 0xA 11 0x11 11 0x101}
do_test collate1-2.13 {
  execsql {
    SELECT c1 COLLATE binary, c2 COLLATE hex
      FROM collate1t1
     ORDER BY 1, 2;
  }
} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA}
do_test collate1-2.14 {
  execsql {
    SELECT c1, c2
      FROM collate1t1 ORDER BY 1 COLLATE binary DESC, 2 COLLATE hex;
  }
} {7 0xA 5 0xA 5 0x11 11 0x11 11 0x101 {} {}}
do_test collate1-2.15 {
  execsql {
    SELECT c1 COLLATE binary, c2 COLLATE hex
      FROM collate1t1 
     ORDER BY 1 DESC, 2 DESC;
  }
} {7 0xA 5 0x11 5 0xA 11 0x101 11 0x11 {} {}}
do_test collate1-2.16 {
  execsql {
    SELECT c1 COLLATE hex, c2 COLLATE binary
      FROM collate1t1 
     ORDER BY 1 COLLATE binary ASC, 2 COLLATE hex ASC;
  }
} {{} {} 11 0x11 11 0x101 5 0xA 5 0x11 7 0xA}
do_test collate1-2.99 {
  execsql {
    DROP TABLE collate1t1;
  }
} {}

#
# These tests ensure that the default collation type for a column is used 
................................................................................
    SELECT a as c1, b as c2 FROM collate1t1 ORDER BY c1;
  }
} {{} {} 1 1 0x5 5 0x45 69}
do_test collate1-3.5 {
  execsql {
    SELECT a as c1, b as c2 FROM collate1t1 ORDER BY c1 COLLATE binary;
  }
} {{} {} 0x45 69 0x5 5 1 1}
do_test collate1-3.5.1 {
  execsql {
    SELECT a COLLATE binary as c1, b as c2
      FROM collate1t1 ORDER BY c1;
  }
} {{} {} 0x45 69 0x5 5 1 1}
do_test collate1-3.6 {
  execsql {
    DROP TABLE collate1t1;
  }
} {}

................................................................................
  }
} {{} 1 12 101}
do_test collate1-4.4 {
  execsql {
    SELECT c1||'' FROM collate1t1 ORDER BY 1;
  }
} {{} 1 101 12}
do_test collate1-4.4.1 {
  execsql {
    SELECT (c1||'') COLLATE numeric FROM collate1t1 ORDER BY 1;
  }
} {{} 1 12 101}
do_test collate1-4.5 {
  execsql {
    DROP TABLE collate1t1;
  }
} {}

finish_test

Changes to test/collate2.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
93
94
95
96
97
98
99
100















101
102
103


















104
105
106
107
108


















109
110
111
112
113
114
115
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: collate2.test,v 1.4 2005/01/21 03:12:16 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#
# Tests are organised as follows:
#
................................................................................
    }
  }
} {}
do_test collate2-1.1 {
  execsql {
    SELECT a FROM collate2t1 WHERE a > 'aa' ORDER BY 1;
  }
} {ab bA bB ba bb}















do_test collate2-1.2 {
  execsql {
    SELECT b FROM collate2t1 WHERE b > 'aa' ORDER BY 1, oid;


















  }
} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
do_test collate2-1.3 {
  execsql {
    SELECT c FROM collate2t1 WHERE c > 'aa' ORDER BY 1;


















  }
} {ba Ab Bb ab bb}
do_test collate2-1.4 {
  execsql {
    SELECT a FROM collate2t1 WHERE a < 'aa' ORDER BY 1;
  }
} {AA AB Aa Ab BA BB Ba Bb aA aB}







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: collate2.test,v 1.5 2007/02/01 23:02:46 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#
# Tests are organised as follows:
#
................................................................................
    }
  }
} {}
do_test collate2-1.1 {
  execsql {
    SELECT a FROM collate2t1 WHERE a > 'aa' ORDER BY 1;
  }
} {ab bA bB ba bb}
do_test collate2-1.1.1 {
  execsql {
    SELECT a FROM collate2t1 WHERE a COLLATE binary > 'aa' ORDER BY 1;
  }
} {ab bA bB ba bb}
do_test collate2-1.1.2 {
  execsql {
    SELECT a FROM collate2t1 WHERE b COLLATE binary > 'aa' ORDER BY 1;
  }
} {ab bA bB ba bb}
do_test collate2-1.1.3 {
  execsql {
    SELECT a FROM collate2t1 WHERE c COLLATE binary > 'aa' ORDER BY 1;
  }
} {ab bA bB ba bb}
do_test collate2-1.2 {
  execsql {
    SELECT b FROM collate2t1 WHERE b > 'aa' ORDER BY 1, oid;
  }
} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
do_test collate2-1.2.1 {
  execsql {
    SELECT b FROM collate2t1 WHERE a COLLATE nocase > 'aa'
     ORDER BY 1, oid;
  }
} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
do_test collate2-1.2.2 {
  execsql {
    SELECT b FROM collate2t1 WHERE b COLLATE nocase > 'aa'
     ORDER BY 1, oid;
  }
} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
do_test collate2-1.2.3 {
  execsql {
    SELECT b FROM collate2t1 WHERE c COLLATE nocase > 'aa'
     ORDER BY 1, oid;
  }
} {ab aB Ab AB ba bA Ba BA bb bB Bb BB}
do_test collate2-1.3 {
  execsql {
    SELECT c FROM collate2t1 WHERE c > 'aa' ORDER BY 1;
  }
} {ba Ab Bb ab bb}
do_test collate2-1.3.1 {
  execsql {
    SELECT c FROM collate2t1 WHERE a COLLATE backwards > 'aa'
    ORDER BY 1;
  }
} {ba Ab Bb ab bb}
do_test collate2-1.3.2 {
  execsql {
    SELECT c FROM collate2t1 WHERE b COLLATE backwards > 'aa'
    ORDER BY 1;
  }
} {ba Ab Bb ab bb}
do_test collate2-1.3.3 {
  execsql {
    SELECT c FROM collate2t1 WHERE c COLLATE backwards > 'aa'
    ORDER BY 1;
  }
} {ba Ab Bb ab bb}
do_test collate2-1.4 {
  execsql {
    SELECT a FROM collate2t1 WHERE a < 'aa' ORDER BY 1;
  }
} {AA AB Aa Ab BA BB Ba Bb aA aB}

Changes to www/lang.tcl.

1
2
3
4
5
6
7
8
9
10
11
....
1003
1004
1005
1006
1007
1008
1009
1010

1011
1012
1013
1014
1015
1016
1017
....
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039





1040
1041
1042
1043
1044
1045
1046
#
# Run this Tcl script to generate the lang-*.html files.
#
set rcsid {$Id: lang.tcl,v 1.120 2007/01/29 17:58:28 drh Exp $}
source common.tcl

if {[llength $argv]>0} {
  set outputdir [lindex $argv 0]
} else {
  set outputdir ""
}
................................................................................
<expr> NOTNULL |
<expr> [NOT] BETWEEN <expr> AND <expr> |
<expr> [NOT] IN ( <value-list> ) |
<expr> [NOT] IN ( <select-statement> ) |
<expr> [NOT] IN [<database-name> .] <table-name> |
[EXISTS] ( <select-statement> ) |
CASE [<expr>] LP WHEN <expr> THEN <expr> RPPLUS [ELSE <expr>] END |
CAST ( <expr> AS <type> )

} {like-op} {
LIKE | GLOB | REGEXP | MATCH
}

puts {
<p>This section is different from the others.  Most other sections of
this document talks about a particular SQL command.  This section does
................................................................................
&lt;&lt;   &gt;&gt;   &amp;    |
&lt;    &lt;=   &gt;    &gt;=
=    ==   !=   &lt;&gt;   </big>IN
AND   
OR</font>
</pre></blockquote>

<p>Supported unary operators are these:</p>

<blockquote><pre>
<font color="#2c2cf0"><big>-    +    !    ~    NOT</big></font>
</pre></blockquote>






<p>The unary operator [Operator +] is a no-op.  It can be applied
to strings, numbers, or blobs and it always gives as its result the
value of the operand.</p>

<p>Note that there are two variations of the equals and not equals
operators.  Equals can be either}



|







 







|
>







 







|




>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
....
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
....
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
#
# Run this Tcl script to generate the lang-*.html files.
#
set rcsid {$Id: lang.tcl,v 1.121 2007/02/01 23:02:46 drh Exp $}
source common.tcl

if {[llength $argv]>0} {
  set outputdir [lindex $argv 0]
} else {
  set outputdir ""
}
................................................................................
<expr> NOTNULL |
<expr> [NOT] BETWEEN <expr> AND <expr> |
<expr> [NOT] IN ( <value-list> ) |
<expr> [NOT] IN ( <select-statement> ) |
<expr> [NOT] IN [<database-name> .] <table-name> |
[EXISTS] ( <select-statement> ) |
CASE [<expr>] LP WHEN <expr> THEN <expr> RPPLUS [ELSE <expr>] END |
CAST ( <expr> AS <type> ) |
<expr> COLLATE <collation-name>
} {like-op} {
LIKE | GLOB | REGEXP | MATCH
}

puts {
<p>This section is different from the others.  Most other sections of
this document talks about a particular SQL command.  This section does
................................................................................
&lt;&lt;   &gt;&gt;   &amp;    |
&lt;    &lt;=   &gt;    &gt;=
=    ==   !=   &lt;&gt;   </big>IN
AND   
OR</font>
</pre></blockquote>

<p>Supported unary prefix operators are these:</p>

<blockquote><pre>
<font color="#2c2cf0"><big>-    +    !    ~    NOT</big></font>
</pre></blockquote>

<p>The COLLATE operator can be thought of as a unary postfix
operator.  The COLLATE operator has the highest precedence.
It always binds more tightly than any prefix unary operator or
any binary operator.</p>

<p>The unary operator [Operator +] is a no-op.  It can be applied
to strings, numbers, or blobs and it always gives as its result the
value of the operand.</p>

<p>Note that there are two variations of the equals and not equals
operators.  Equals can be either}