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

📄 expr.c

📁 SQLite 2.8.6 源代码,用来在Linux/Unix/Windows上编译安装.它是一个小型的数据库,但是非常好用,速度也快,一般的数据库查询之类的操作据统计比MySQL,PostgreSQL
💻 C
📖 第 1 页 / 共 4 页
字号:
int sqliteExprResolveIds(  Parse *pParse,     /* The parser context */  SrcList *pTabList, /* List of tables used to resolve column names */  ExprList *pEList,  /* List of expressions used to resolve "AS" */  Expr *pExpr        /* The expression to be analyzed. */){  int i;  if( pExpr==0 || pTabList==0 ) return 0;  for(i=0; i<pTabList->nSrc; i++){    assert( pTabList->a[i].iCursor>=0 && pTabList->a[i].iCursor<pParse->nTab );  }  switch( pExpr->op ){    /* Double-quoted strings (ex: "abc") are used as identifiers if    ** possible.  Otherwise they remain as strings.  Single-quoted    ** strings (ex: 'abc') are always string literals.    */    case TK_STRING: {      if( pExpr->token.z[0]=='\'' ) break;      /* Fall thru into the TK_ID case if this is a double-quoted string */    }    /* A lone identifier.  Try and match it as follows:    **    **     1.  To the name of a column of one of the tables in pTabList    **    **     2.  To the right side of an AS keyword in the column list of    **         a SELECT statement.  (For example, match against 'x' in    **         "SELECT a+b AS 'x' FROM t1".)    **    **     3.  One of the special names "ROWID", "OID", or "_ROWID_".    */    case TK_ID: {      int cnt = 0;      /* Number of matches */      char *z;      int iDb = -1;      assert( pExpr->token.z );      z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);      sqliteDequote(z);      if( z==0 ) return 1;      for(i=0; i<pTabList->nSrc; i++){        int j;        Table *pTab = pTabList->a[i].pTab;        if( pTab==0 ) continue;        iDb = pTab->iDb;        assert( pTab->nCol>0 );        for(j=0; j<pTab->nCol; j++){          if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){            cnt++;            pExpr->iTable = pTabList->a[i].iCursor;            pExpr->iDb = pTab->iDb;            if( j==pTab->iPKey ){              /* Substitute the record number for the INTEGER PRIMARY KEY */              pExpr->iColumn = -1;              pExpr->dataType = SQLITE_SO_NUM;            }else{              pExpr->iColumn = j;              pExpr->dataType = pTab->aCol[j].sortOrder & SQLITE_SO_TYPEMASK;            }            pExpr->op = TK_COLUMN;          }        }      }      if( cnt==0 && pEList!=0 ){        int j;        for(j=0; j<pEList->nExpr; j++){          char *zAs = pEList->a[j].zName;          if( zAs!=0 && sqliteStrICmp(zAs, z)==0 ){            cnt++;            assert( pExpr->pLeft==0 && pExpr->pRight==0 );            pExpr->op = TK_AS;            pExpr->iColumn = j;            pExpr->pLeft = sqliteExprDup(pEList->a[j].pExpr);          }        }       }      if( cnt==0 && iDb>=0 && sqliteIsRowid(z) ){        pExpr->iColumn = -1;        pExpr->iTable = pTabList->a[0].iCursor;        pExpr->iDb = iDb;        cnt = 1 + (pTabList->nSrc>1);        pExpr->op = TK_COLUMN;        pExpr->dataType = SQLITE_SO_NUM;      }      sqliteFree(z);      if( cnt==0 && pExpr->token.z[0]!='"' ){        sqliteErrorMsg(pParse, "no such column: %T", &pExpr->token);        return 1;      }else if( cnt>1 ){        sqliteErrorMsg(pParse, "ambiguous column name: %T", &pExpr->token);        return 1;      }      if( pExpr->op==TK_COLUMN ){        sqliteAuthRead(pParse, pExpr, pTabList);      }      break;     }      /* A table name and column name:     ID.ID    ** Or a database, table and column:  ID.ID.ID    */    case TK_DOT: {      int cnt = 0;             /* Number of matches */      int cntTab = 0;          /* Number of matching tables */      int i;                   /* Loop counter */      Expr *pLeft, *pRight;    /* Left and right subbranches of the expr */      char *zLeft, *zRight;    /* Text of an identifier */      char *zDb;               /* Name of database holding table */      sqlite *db = pParse->db;      pRight = pExpr->pRight;      if( pRight->op==TK_ID ){        pLeft = pExpr->pLeft;        zDb = 0;      }else{        Expr *pDb = pExpr->pLeft;        assert( pDb && pDb->op==TK_ID && pDb->token.z );        zDb = sqliteStrNDup(pDb->token.z, pDb->token.n);        pLeft = pRight->pLeft;        pRight = pRight->pRight;      }      assert( pLeft && pLeft->op==TK_ID && pLeft->token.z );      assert( pRight && pRight->op==TK_ID && pRight->token.z );      zLeft = sqliteStrNDup(pLeft->token.z, pLeft->token.n);      zRight = sqliteStrNDup(pRight->token.z, pRight->token.n);      if( zLeft==0 || zRight==0 ){        sqliteFree(zLeft);        sqliteFree(zRight);        sqliteFree(zDb);        return 1;      }      sqliteDequote(zDb);      sqliteDequote(zLeft);      sqliteDequote(zRight);      pExpr->iTable = -1;      for(i=0; i<pTabList->nSrc; i++){        int j;        char *zTab;        Table *pTab = pTabList->a[i].pTab;        if( pTab==0 ) continue;        assert( pTab->nCol>0 );        if( pTabList->a[i].zAlias ){          zTab = pTabList->a[i].zAlias;          if( sqliteStrICmp(zTab, zLeft)!=0 ) continue;        }else{          zTab = pTab->zName;          if( zTab==0 || sqliteStrICmp(zTab, zLeft)!=0 ) continue;          if( zDb!=0 && sqliteStrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){            continue;          }        }        if( 0==(cntTab++) ){          pExpr->iTable = pTabList->a[i].iCursor;          pExpr->iDb = pTab->iDb;        }        for(j=0; j<pTab->nCol; j++){          if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){            cnt++;            pExpr->iTable = pTabList->a[i].iCursor;            pExpr->iDb = pTab->iDb;            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */            pExpr->iColumn = j==pTab->iPKey ? -1 : j;            pExpr->dataType = pTab->aCol[j].sortOrder & SQLITE_SO_TYPEMASK;          }        }      }      /* If we have not already resolved this *.* expression, then maybe        * it is a new.* or old.* trigger argument reference */      if( cnt == 0 && pParse->trigStack != 0 ){        TriggerStack *pTriggerStack = pParse->trigStack;        int t = 0;        if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zLeft) == 0 ){          pExpr->iTable = pTriggerStack->newIdx;          assert( pTriggerStack->pTab );          pExpr->iDb = pTriggerStack->pTab->iDb;          cntTab++;          t = 1;        }        if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zLeft) == 0 ){          pExpr->iTable = pTriggerStack->oldIdx;          assert( pTriggerStack->pTab );          pExpr->iDb = pTriggerStack->pTab->iDb;          cntTab++;          t = 1;        }        if( t ){ 	  int j;          Table *pTab = pTriggerStack->pTab;          for(j=0; j < pTab->nCol; j++) {            if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){              cnt++;              pExpr->iColumn = j==pTab->iPKey ? -1 : j;              pExpr->dataType = pTab->aCol[j].sortOrder & SQLITE_SO_TYPEMASK;            }          }	}      }      if( cnt==0 && cntTab==1 && sqliteIsRowid(zRight) ){        cnt = 1;        pExpr->iColumn = -1;        pExpr->dataType = SQLITE_SO_NUM;      }      sqliteFree(zDb);      sqliteFree(zLeft);      sqliteFree(zRight);      if( cnt==0 ){        sqliteErrorMsg(pParse, "no such column: %T.%T",               &pLeft->token, &pRight->token);        return 1;      }else if( cnt>1 ){        sqliteErrorMsg(pParse, "ambiguous column name: %T.%T",          &pLeft->token, &pRight->token);        return 1;      }      sqliteExprDelete(pExpr->pLeft);      pExpr->pLeft = 0;      sqliteExprDelete(pExpr->pRight);      pExpr->pRight = 0;      pExpr->op = TK_COLUMN;      sqliteAuthRead(pParse, pExpr, pTabList);      break;    }    case TK_IN: {      Vdbe *v = sqliteGetVdbe(pParse);      if( v==0 ) return 1;      if( sqliteExprResolveIds(pParse, pTabList, pEList, pExpr->pLeft) ){        return 1;      }      if( pExpr->pSelect ){        /* Case 1:     expr IN (SELECT ...)        **        ** Generate code to write the results of the select into a temporary        ** table.  The cursor number of the temporary table has already        ** been put in iTable by sqliteExprResolveInSelect().        */        pExpr->iTable = pParse->nTab++;        sqliteVdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 1);        sqliteSelect(pParse, pExpr->pSelect, SRT_Set, pExpr->iTable, 0,0,0);      }else if( pExpr->pList ){        /* Case 2:     expr IN (exprlist)        **        ** Create a set to put the exprlist values in.  The Set id is stored        ** in iTable.        */        int i, iSet;        for(i=0; i<pExpr->pList->nExpr; i++){          Expr *pE2 = pExpr->pList->a[i].pExpr;          if( !sqliteExprIsConstant(pE2) ){            sqliteErrorMsg(pParse,              "right-hand side of IN operator must be constant");            return 1;          }          if( sqliteExprCheck(pParse, pE2, 0, 0) ){            return 1;          }        }        iSet = pExpr->iTable = pParse->nSet++;        for(i=0; i<pExpr->pList->nExpr; i++){          Expr *pE2 = pExpr->pList->a[i].pExpr;          switch( pE2->op ){            case TK_FLOAT:            case TK_INTEGER:            case TK_STRING: {              int addr = sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);              assert( pE2->token.z );              sqliteVdbeChangeP3(v, addr, pE2->token.z, pE2->token.n);              sqliteVdbeDequoteP3(v, addr);              break;            }            default: {              sqliteExprCode(pParse, pE2);              sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);              break;            }          }        }      }      break;    }    case TK_SELECT: {      /* This has to be a scalar SELECT.  Generate code to put the      ** value of this select in a memory cell and record the number      ** of the memory cell in iColumn.      */      pExpr->iColumn = pParse->nMem++;      if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iColumn,0,0,0) ){        return 1;      }      break;    }    /* For all else, just recursively walk the tree */    default: {      if( pExpr->pLeft      && sqliteExprResolveIds(pParse, pTabList, pEList, pExpr->pLeft) ){        return 1;      }      if( pExpr->pRight       && sqliteExprResolveIds(pParse, pTabList, pEList, pExpr->pRight) ){        return 1;      }      if( pExpr->pList ){        int i;        ExprList *pList = pExpr->pList;        for(i=0; i<pList->nExpr; i++){          Expr *pArg = pList->a[i].pExpr;          if( sqliteExprResolveIds(pParse, pTabList, pEList, pArg) ){            return 1;          }        }      }    }  }  return 0;}/*** pExpr is a node that defines a function of some kind.  It might** be a syntactic function like "count(x)" or it might be a function** that implements an operator, like "a LIKE b".  **** This routine makes *pzName point to the name of the function and ** *pnName hold the number of characters in the function name.*/static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){  switch( pExpr->op ){    case TK_FUNCTION: {      *pzName = pExpr->token.z;      *pnName = pExpr->token.n;      break;    }    case TK_LIKE: {      *pzName = "like";      *pnName = 4;      break;    }    case TK_GLOB: {      *pzName = "glob";      *pnName = 4;      break;    }    default: {      *pzName = "can't happen";      *pnName = 12;      break;    }  }}/*** Error check the functions in an expression.  Make sure all** function names are recognized and all functions have the correct** number of arguments.  Leave an error message in pParse->zErrMsg** if anything is amiss.  Return the number of errors.**** if pIsAgg is not null and this expression is an aggregate function** (like count(*) or max(value)) then write a 1 into *pIsAgg.*/int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){  int nErr = 0;  if( pExpr==0 ) return 0;  switch( pExpr->op ){    case TK_GLOB:    case TK_LIKE:    case TK_FUNCTION: {      int n = pExpr->pList ? pExpr->pList->nExpr : 0;  /* Number of arguments */      int no_such_func = 0;       /* True if no such function exists */      int is_type_of = 0;         /* True if is the special TypeOf() function */      int wrong_num_args = 0;     /* True if wrong number of arguments */      int is_agg = 0;             /* True if is an aggregate function */      int i;      int nId;                    /* Number of characters in function name */      const char *zId;            /* The function name. */      FuncDef *pDef;      getFunctionName(pExpr, &zId, &nId);      pDef = sqliteFindFunction(pParse->db, zId, nId, n, 0);      if( pDef==0 ){        pDef = sqliteFindFunction(pParse->db, zId, nId, -1, 0);        if( pDef==0 ){          if( n==1 && nId==6 && sqliteStrNICmp(zId, "typeof", 6)==0 ){            is_type_of = 1;          }else {            no_such_func = 1;          }        }else{          wrong_num_args = 1;        }      }else{        is_agg = pDef->xFunc==0;      }      if( is_agg && !allowAgg ){        sqliteSetNString(&pParse->zErrMsg, "misuse of aggregate function ", -1,           zId, nId, "()", 2, 0);        pParse->nErr++;        nErr++;        is_agg = 0;      }else if( no_such_func ){        sqliteSetNString(&pParse->zErrMsg, "no such function: ", -1, zId,nId,0);        pParse->nErr++;        nErr++;      }else if( wrong_num_args ){

⌨️ 快捷键说明

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