⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 select.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  int iParm = pDest->iParm;  int regRow;  int regRowid;  iTab = pOrderBy->iECursor;  if( eDest==SRT_Output || eDest==SRT_Coroutine ){    pseudoTab = pParse->nTab++;    sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nColumn);    sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Output);  }  addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, brk);  codeOffset(v, p, cont);  regRow = sqlite3GetTempReg(pParse);  regRowid = sqlite3GetTempReg(pParse);  sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow);  switch( eDest ){    case SRT_Table:    case SRT_EphemTab: {      sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);      sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);      sqlite3VdbeChangeP5(v, OPFLAG_APPEND);      break;    }#ifndef SQLITE_OMIT_SUBQUERY    case SRT_Set: {      assert( nColumn==1 );      sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);      sqlite3ExprCacheAffinityChange(pParse, regRow, 1);      sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);      break;    }    case SRT_Mem: {      assert( nColumn==1 );      sqlite3ExprCodeMove(pParse, regRow, iParm, 1);      /* The LIMIT clause will terminate the loop for us */      break;    }#endif    case SRT_Output:    case SRT_Coroutine: {      int i;      sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid);      sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid);      for(i=0; i<nColumn; i++){        assert( regRow!=pDest->iMem+i );        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);      }      if( eDest==SRT_Output ){        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);        sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);      }else{        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);      }      break;    }    default: {      /* Do nothing */      break;    }  }  sqlite3ReleaseTempReg(pParse, regRow);  sqlite3ReleaseTempReg(pParse, regRowid);  /* LIMIT has been implemented by the pushOntoSorter() routine.  */  assert( p->iLimit==0 );  /* The bottom of the loop  */  sqlite3VdbeResolveLabel(v, cont);  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);  sqlite3VdbeResolveLabel(v, brk);  if( eDest==SRT_Output || eDest==SRT_Coroutine ){    sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);  }}/*** Return a pointer to a string containing the 'declaration type' of the** expression pExpr. The string may be treated as static by the caller.**** The declaration type is the exact datatype definition extracted from the** original CREATE TABLE statement if the expression is a column. The** declaration type for a ROWID field is INTEGER. Exactly when an expression** is considered a column can be complex in the presence of subqueries. The** result-set expression in all of the following SELECT statements is ** considered a column by this function.****   SELECT col FROM tbl;**   SELECT (SELECT col FROM tbl;**   SELECT (SELECT col FROM tbl);**   SELECT abc FROM (SELECT col AS abc FROM tbl);** ** The declaration type for any expression other than a column is NULL.*/static const char *columnType(  NameContext *pNC,   Expr *pExpr,  const char **pzOriginDb,  const char **pzOriginTab,  const char **pzOriginCol){  char const *zType = 0;  char const *zOriginDb = 0;  char const *zOriginTab = 0;  char const *zOriginCol = 0;  int j;  if( pExpr==0 || pNC->pSrcList==0 ) return 0;  switch( pExpr->op ){    case TK_AGG_COLUMN:    case TK_COLUMN: {      /* The expression is a column. Locate the table the column is being      ** extracted from in NameContext.pSrcList. This table may be real      ** database table or a subquery.      */      Table *pTab = 0;            /* Table structure column is extracted from */      Select *pS = 0;             /* Select the column is extracted from */      int iCol = pExpr->iColumn;  /* Index of column in pTab */      while( pNC && !pTab ){        SrcList *pTabList = pNC->pSrcList;        for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);        if( j<pTabList->nSrc ){          pTab = pTabList->a[j].pTab;          pS = pTabList->a[j].pSelect;        }else{          pNC = pNC->pNext;        }      }      if( pTab==0 ){        /* FIX ME:        ** This can occurs if you have something like "SELECT new.x;" inside        ** a trigger.  In other words, if you reference the special "new"        ** table in the result set of a select.  We do not have a good way        ** to find the actual table type, so call it "TEXT".  This is really        ** something of a bug, but I do not know how to fix it.        **        ** This code does not produce the correct answer - it just prevents        ** a segfault.  See ticket #1229.        */        zType = "TEXT";        break;      }      assert( pTab );      if( pS ){        /* The "table" is actually a sub-select or a view in the FROM clause        ** of the SELECT statement. Return the declaration type and origin        ** data for the result-set column of the sub-select.        */        if( iCol>=0 && iCol<pS->pEList->nExpr ){          /* If iCol is less than zero, then the expression requests the          ** rowid of the sub-select or view. This expression is legal (see           ** test case misc2.2.2) - it always evaluates to NULL.          */          NameContext sNC;          Expr *p = pS->pEList->a[iCol].pExpr;          sNC.pSrcList = pS->pSrc;          sNC.pNext = 0;          sNC.pParse = pNC->pParse;          zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);         }      }else if( pTab->pSchema ){        /* A real table */        assert( !pS );        if( iCol<0 ) iCol = pTab->iPKey;        assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );        if( iCol<0 ){          zType = "INTEGER";          zOriginCol = "rowid";        }else{          zType = pTab->aCol[iCol].zType;          zOriginCol = pTab->aCol[iCol].zName;        }        zOriginTab = pTab->zName;        if( pNC->pParse ){          int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);          zOriginDb = pNC->pParse->db->aDb[iDb].zName;        }      }      break;    }#ifndef SQLITE_OMIT_SUBQUERY    case TK_SELECT: {      /* The expression is a sub-select. Return the declaration type and      ** origin info for the single column in the result set of the SELECT      ** statement.      */      NameContext sNC;      Select *pS = pExpr->pSelect;      Expr *p = pS->pEList->a[0].pExpr;      sNC.pSrcList = pS->pSrc;      sNC.pNext = pNC;      sNC.pParse = pNC->pParse;      zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);       break;    }#endif  }    if( pzOriginDb ){    assert( pzOriginTab && pzOriginCol );    *pzOriginDb = zOriginDb;    *pzOriginTab = zOriginTab;    *pzOriginCol = zOriginCol;  }  return zType;}/*** Generate code that will tell the VDBE the declaration types of columns** in the result set.*/static void generateColumnTypes(  Parse *pParse,      /* Parser context */  SrcList *pTabList,  /* List of tables */  ExprList *pEList    /* Expressions defining the result set */){#ifndef SQLITE_OMIT_DECLTYPE  Vdbe *v = pParse->pVdbe;  int i;  NameContext sNC;  sNC.pSrcList = pTabList;  sNC.pParse = pParse;  for(i=0; i<pEList->nExpr; i++){    Expr *p = pEList->a[i].pExpr;    const char *zType;#ifdef SQLITE_ENABLE_COLUMN_METADATA    const char *zOrigDb = 0;    const char *zOrigTab = 0;    const char *zOrigCol = 0;    zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);    /* The vdbe must make its own copy of the column-type and other     ** column specific strings, in case the schema is reset before this    ** virtual machine is deleted.    */    sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P4_TRANSIENT);    sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P4_TRANSIENT);    sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P4_TRANSIENT);#else    zType = columnType(&sNC, p, 0, 0, 0);#endif    sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P4_TRANSIENT);  }#endif /* SQLITE_OMIT_DECLTYPE */}/*** Generate code that will tell the VDBE the names of columns** in the result set.  This information is used to provide the** azCol[] values in the callback.*/static void generateColumnNames(  Parse *pParse,      /* Parser context */  SrcList *pTabList,  /* List of tables */  ExprList *pEList    /* Expressions defining the result set */){  Vdbe *v = pParse->pVdbe;  int i, j;  sqlite3 *db = pParse->db;  int fullNames, shortNames;#ifndef SQLITE_OMIT_EXPLAIN  /* If this is an EXPLAIN, skip this step */  if( pParse->explain ){    return;  }#endif  assert( v!=0 );  if( pParse->colNamesSet || v==0 || db->mallocFailed ) return;  pParse->colNamesSet = 1;  fullNames = (db->flags & SQLITE_FullColNames)!=0;  shortNames = (db->flags & SQLITE_ShortColNames)!=0;  sqlite3VdbeSetNumCols(v, pEList->nExpr);  for(i=0; i<pEList->nExpr; i++){    Expr *p;    p = pEList->a[i].pExpr;    if( p==0 ) continue;    if( pEList->a[i].zName ){      char *zName = pEList->a[i].zName;      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));    }else if( p->op==TK_COLUMN && pTabList ){      Table *pTab;      char *zCol;      int iCol = p->iColumn;      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}      assert( j<pTabList->nSrc );      pTab = pTabList->a[j].pTab;      if( iCol<0 ) iCol = pTab->iPKey;      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );      if( iCol<0 ){        zCol = "rowid";      }else{        zCol = pTab->aCol[iCol].zName;      }      if( !shortNames && !fullNames ){        sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){        char *zName = 0;        char *zTab;         zTab = pTabList->a[j].zAlias;        if( fullNames || zTab==0 ) zTab = pTab->zName;        zName = sqlite3MPrintf(db, "%s.%s", zTab, zCol);        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P4_DYNAMIC);      }else{        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));      }    }else{      sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);    }  }  generateColumnTypes(pParse, pTabList, pEList);}#ifndef SQLITE_OMIT_COMPOUND_SELECT/*** Name of the connection operator, used for error messages.*/static const char *selectOpName(int id){  char *z;  switch( id ){    case TK_ALL:       z = "UNION ALL";   break;    case TK_INTERSECT: z = "INTERSECT";   break;    case TK_EXCEPT:    z = "EXCEPT";      break;    default:           z = "UNION";       break;  }  return z;}#endif /* SQLITE_OMIT_COMPOUND_SELECT *//*** Given a an expression list (which is really the list of expressions** that form the result set of a SELECT statement) compute appropriate** column names for a table that would hold the expression list.**** All column names will be unique.**** Only the column names are computed.  Column.zType, Column.zColl,** and other fields of Column are zeroed.**** Return SQLITE_OK on success.  If a memory allocation error occurs,** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.*/static int selectColumnsFromExprList(  Parse *pParse,          /* Parsing context */  ExprList *pEList,       /* Expr list from which to derive column names */  int *pnCol,             /* Write the number of columns here */  Column **paCol          /* Write the new column list here */){  sqlite3 *db = pParse->db;  int i, j, cnt;  Column *aCol, *pCol;  int nCol;  Expr *p;  char *zName;  int nName;  *pnCol = nCol = pEList->nExpr;  aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);  if( aCol==0 ) return SQLITE_NOMEM;  for(i=0, pCol=aCol; i<nCol; i++, pCol++){    /* Get an appropriate name for the column    */    p = pEList->a[i].pExpr;    assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );    if( (zName = pEList->a[i].zName)!=0 ){      /* If the column contains an "AS <name>" phrase, use <name> as the name */      zName = sqlite3DbStrDup(db, zName);    }else{      Expr *pCol = p;      Table *pTab;      while( pCol->op==TK_DOT ) pCol = pCol->pRight;      if( pCol->op==TK_COLUMN && (pTab = pCol->pTab)!=0 ){        /* For columns use the column name name */        int iCol = pCol->iColumn;        if( iCol<0 ) iCol = pTab->iPKey;        zName = sqlite3MPrintf(db, "%s",                 iCol>=0 ? pTab->aCol[iCol].zName : "rowid");      }else{        /* Use the original text of the column expression as its name */        zName = sqlite3MPrintf(db, "%T", &pCol->span);      }    }    if( db->mallocFailed ){      sqlite3DbFree(db, zName);      break;    }    sqlite3Dequote(zName);    /* Make sure the column name is unique.  If the name is not unique,    ** append a integer to the name so that it becomes unique.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -