/ Check-in [41335d88]
Login

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

Overview
Comment:An alternative method of encoding the wildcard in "SELECT *". This is an experiment.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | select-wildcard
Files: files | file ages | folders
SHA1:41335d8800eaf36c8d3e96ac855c9aef11d49460
User & Date: drh 2016-03-17 18:41:38
Context
2016-03-17
18:41
An alternative method of encoding the wildcard in "SELECT *". This is an experiment. Closed-Leaf check-in: 41335d88 user: drh tags: select-wildcard
2016-03-16
21:29
The prepared statements for some pragmas can now be reused without invoking an automatic reprepare. check-in: 97b0e88c user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  1279   1279   */
  1280   1280   u32 sqlite3ExprListFlags(const ExprList *pList){
  1281   1281     int i;
  1282   1282     u32 m = 0;
  1283   1283     if( pList ){
  1284   1284       for(i=0; i<pList->nExpr; i++){
  1285   1285          Expr *pExpr = pList->a[i].pExpr;
  1286         -       if( ALWAYS(pExpr) ) m |= pExpr->flags;
         1286  +       assert( pExpr!=0 );
         1287  +       m |= pExpr->flags;
  1287   1288       }
  1288   1289     }
  1289   1290     return m;
  1290   1291   }
  1291   1292   
  1292   1293   /*
  1293   1294   ** These routines are Walker callbacks used to check expressions to

Changes to src/parse.y.

   546    546   sclp(A) ::= .                                {A = 0;}
   547    547   selcollist(A) ::= sclp(A) expr(X) as(Y).     {
   548    548      A = sqlite3ExprListAppend(pParse, A, X.pExpr);
   549    549      if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1);
   550    550      sqlite3ExprListSetSpan(pParse,A,&X);
   551    551   }
   552    552   selcollist(A) ::= sclp(A) STAR. {
   553         -  Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
   554         -  A = sqlite3ExprListAppend(pParse, A, p);
          553  +  A = sqlite3WildcardResultSet(pParse,A);
   555    554   }
   556    555   selcollist(A) ::= sclp(A) nm(X) DOT STAR(Y). {
   557    556     Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &Y);
   558    557     Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
   559    558     Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
          559  +  if( pDot ) ExprSetProperty(pDot, EP_Wildcard);
   560    560     A = sqlite3ExprListAppend(pParse,A, pDot);
   561    561   }
   562    562   
   563    563   // An option "AS <id>" phrase that can follow one of the expressions that
   564    564   // define the result set, or one of the tables in the FROM clause.
   565    565   //
   566    566   %type as {Token}

Changes to src/select.c.

    88     88     pDest->eDest = (u8)eDest;
    89     89     pDest->iSDParm = iParm;
    90     90     pDest->affSdst = 0;
    91     91     pDest->iSdst = 0;
    92     92     pDest->nSdst = 0;
    93     93   }
    94     94   
           95  +/*
           96  +** Return an expression list that represents the wildcard result set
           97  +** of a SELECT.
           98  +*/
           99  +ExprList *sqlite3WildcardResultSet(Parse *pParse, ExprList *pPrior){
          100  +  Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
          101  +  if( p ) ExprSetProperty(p, EP_Wildcard);
          102  +  return sqlite3ExprListAppend(pParse, pPrior, p);
          103  +}
          104  +
    95    105   
    96    106   /*
    97    107   ** Allocate a new Select structure and return a pointer to that
    98    108   ** structure.
    99    109   */
   100    110   Select *sqlite3SelectNew(
   101    111     Parse *pParse,        /* Parsing context */
................................................................................
   113    123     Select standin;
   114    124     sqlite3 *db = pParse->db;
   115    125     pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
   116    126     if( pNew==0 ){
   117    127       assert( db->mallocFailed );
   118    128       pNew = &standin;
   119    129     }
   120         -  if( pEList==0 ){
   121         -    pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
   122         -  }
          130  +  if( pEList==0 ) pEList = sqlite3WildcardResultSet(pParse,0);
   123    131     pNew->pEList = pEList;
   124    132     pNew->op = TK_SELECT;
   125    133     pNew->selFlags = selFlags;
   126    134     pNew->iLimit = 0;
   127    135     pNew->iOffset = 0;
   128    136   #if SELECTTRACE_ENABLED
   129    137     pNew->zSelName[0] = 0;
................................................................................
  3948   3956     pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
  3949   3957     if( pNew==0 ) return WRC_Abort;
  3950   3958     memset(&dummy, 0, sizeof(dummy));
  3951   3959     pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0);
  3952   3960     if( pNewSrc==0 ) return WRC_Abort;
  3953   3961     *pNew = *p;
  3954   3962     p->pSrc = pNewSrc;
  3955         -  p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
         3963  +  p->pEList = sqlite3WildcardResultSet(pParse,0);
  3956   3964     p->op = TK_SELECT;
  3957   3965     p->pWhere = 0;
  3958   3966     pNew->pGroupBy = 0;
  3959   3967     pNew->pHaving = 0;
  3960   3968     pNew->pOrderBy = 0;
  3961   3969     p->pPrior = 0;
  3962   3970     p->pNext = 0;
................................................................................
  4306   4314     /* For every "*" that occurs in the column list, insert the names of
  4307   4315     ** all columns in all tables.  And for every TABLE.* insert the names
  4308   4316     ** of all columns in TABLE.  The parser inserted a special expression
  4309   4317     ** with the TK_ASTERISK operator for each "*" that it found in the column
  4310   4318     ** list.  The following code just has to locate the TK_ASTERISK
  4311   4319     ** expressions and expand each one to the list of all columns in
  4312   4320     ** all tables.
  4313         -  **
  4314         -  ** The first loop just checks to see if there are any "*" operators
  4315         -  ** that need expanding.
  4316   4321     */
  4317         -  for(k=0; k<pEList->nExpr; k++){
  4318         -    pE = pEList->a[k].pExpr;
  4319         -    if( pE->op==TK_ASTERISK ) break;
  4320         -    assert( pE->op!=TK_DOT || pE->pRight!=0 );
  4321         -    assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
  4322         -    if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
  4323         -  }
  4324         -  if( k<pEList->nExpr ){
         4322  +  if( sqlite3ExprListFlags(pEList) & EP_Wildcard ){
  4325   4323       /*
  4326   4324       ** If we get here it means the result set contains one or more "*"
  4327   4325       ** operators that need to be expanded.  Loop through each expression
  4328   4326       ** in the result set and expand them one by one.
  4329   4327       */
  4330   4328       struct ExprList_item *a = pEList->a;
  4331   4329       ExprList *pNew = 0;
................................................................................
  4333   4331       int longNames = (flags & SQLITE_FullColNames)!=0
  4334   4332                         && (flags & SQLITE_ShortColNames)==0;
  4335   4333   
  4336   4334       for(k=0; k<pEList->nExpr; k++){
  4337   4335         pE = a[k].pExpr;
  4338   4336         pRight = pE->pRight;
  4339   4337         assert( pE->op!=TK_DOT || pRight!=0 );
  4340         -      if( pE->op!=TK_ASTERISK
  4341         -       && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
  4342         -      ){
         4338  +      if( !ExprHasProperty(pE, EP_Wildcard) ){
  4343   4339           /* This particular expression does not need to be expanded.
  4344   4340           */
  4345   4341           pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
  4346   4342           if( pNew ){
  4347   4343             pNew->a[pNew->nExpr-1].zName = a[k].zName;
  4348   4344             pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
  4349   4345             a[k].zName = 0;

Changes to src/sqliteInt.h.

  2253   2253   #define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
  2254   2254   #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
  2255   2255   #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
  2256   2256   #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
  2257   2257   #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
  2258   2258   #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
  2259   2259   #define EP_Alias     0x400000 /* Is an alias for a result set column */
         2260  +#define EP_Wildcard  0x800000 /* The "*" or "TABLE.*" of a SELECT result */
  2260   2261   
  2261   2262   /*
  2262   2263   ** Combinations of two or more EP_* flags
  2263   2264   */
  2264   2265   #define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
  2265   2266   
  2266   2267   /*
................................................................................
  3523   3524   void sqlite3SrcListAssignCursors(Parse*, SrcList*);
  3524   3525   void sqlite3IdListDelete(sqlite3*, IdList*);
  3525   3526   void sqlite3SrcListDelete(sqlite3*, SrcList*);
  3526   3527   Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
  3527   3528   Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
  3528   3529                             Expr*, int, int);
  3529   3530   void sqlite3DropIndex(Parse*, SrcList*, int);
         3531  +ExprList *sqlite3WildcardResultSet(Parse*,ExprList*);
  3530   3532   int sqlite3Select(Parse*, Select*, SelectDest*);
  3531   3533   Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
  3532   3534                            Expr*,ExprList*,u32,Expr*,Expr*);
  3533   3535   void sqlite3SelectDelete(sqlite3*, Select*);
  3534   3536   Table *sqlite3SrcListLookup(Parse*, SrcList*);
  3535   3537   int sqlite3IsReadOnly(Parse*, Table*, int);
  3536   3538   void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);