SQLite

Check-in [9041ee4a6f]
Login

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

Overview
Comment:Fixes for problems following OOM errors.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1: 9041ee4a6f0e8389297f887f1431ab5cfe783390
User & Date: drh 2016-08-20 18:06:14.286
Context
2016-08-20
21:02
Clarification of code comments in expr.c. Clean up the implementations of sqlite3ExprIsVector() and sqlite3ExprVectorSize() slightly. (check-in: 4fb66d6592 user: drh tags: rowvalue)
18:06
Fixes for problems following OOM errors. (check-in: 9041ee4a6f user: drh tags: rowvalue)
17:00
Do not duplicate the Expr.pLeft subtree of a TK_SELECT_COLUMN node. (check-in: 8384c77ebb user: drh tags: rowvalue)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/expr.c.
402
403
404
405
406
407
408
409

410


411
412
413
414
415
416
417
    ** sqlite3ExprDelete() specifically skips the recursive delete of
    ** pLeft on TK_SELECT_COLUMN nodes.  But pRight is followed, so pVector
    ** can be attached to pRight to cause this node to take ownership of
    ** pVector.  Typically there will be multiple TK_SELECT_COLUMN nodes
    ** with the same pLeft pointer to the pVector, but only one of them
    ** will own the pVector.
    */
    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0);

    if( pRet ) pRet->iColumn = iField;


    assert( pRet==0 || pRet->iTable==0 );
  }else{
    if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
    pRet = sqlite3ExprDup(pParse->db, pVector, 0);
  }
  return pRet;
}







|
>
|
>
>







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    ** sqlite3ExprDelete() specifically skips the recursive delete of
    ** pLeft on TK_SELECT_COLUMN nodes.  But pRight is followed, so pVector
    ** can be attached to pRight to cause this node to take ownership of
    ** pVector.  Typically there will be multiple TK_SELECT_COLUMN nodes
    ** with the same pLeft pointer to the pVector, but only one of them
    ** will own the pVector.
    */
    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0, 0);
    if( pRet ){
      pRet->iColumn = iField;
      pRet->pLeft = pVector;
    }
    assert( pRet==0 || pRet->iTable==0 );
  }else{
    if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
    pRet = sqlite3ExprDup(pParse->db, pVector, 0);
  }
  return pRet;
}
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
  Expr *pVector,                  /* Vector to extract element from */
  int iField,                     /* Field to extract from pVector */
  int regSelect,                  /* First in array of registers */
  Expr **ppExpr,                  /* OUT: Expression element */
  int *pRegFree                   /* OUT: Temp register to free */
){
  assert( pVector->op==TK_VECTOR || pVector->op==TK_SELECT );

  assert( pParse->nErr || (pVector->op==TK_VECTOR)==(regSelect==0) );
  if( pVector->op==TK_SELECT ){
    *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
     return regSelect+iField;
  }
  *ppExpr = pVector->x.pList->a[iField].pExpr;
  return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
}







>
|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
  Expr *pVector,                  /* Vector to extract element from */
  int iField,                     /* Field to extract from pVector */
  int regSelect,                  /* First in array of registers */
  Expr **ppExpr,                  /* OUT: Expression element */
  int *pRegFree                   /* OUT: Temp register to free */
){
  assert( pVector->op==TK_VECTOR || pVector->op==TK_SELECT );
  assert( pParse->nErr || pParse->db->mallocFailed
          || (pVector->op==TK_VECTOR)==(regSelect==0) );
  if( pVector->op==TK_SELECT ){
    *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
     return regSelect+iField;
  }
  *ppExpr = pVector->x.pList->a[iField].pExpr;
  return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
}
Changes to src/parse.y.
948
949
950
951
952
953
954
955

956
957
958
959


960
961
962
963
964
965
966
  static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
    if( doNot ){
      pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0);
    }
  }
}

expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). { 

  A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0);
  if( A.pExpr ){
    A.pExpr->x.pList = sqlite3ExprListAppend(pParse, X, Y.pExpr);
    spanSet(&A, &L, &R);


  }
}

expr(A) ::= expr(A) AND(OP) expr(Y).    {spanBinaryExpr(pParse,@OP,&A,&Y);}
expr(A) ::= expr(A) OR(OP) expr(Y).     {spanBinaryExpr(pParse,@OP,&A,&Y);}
expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
                                        {spanBinaryExpr(pParse,@OP,&A,&Y);}







|
>


|

>
>







948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
  static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
    if( doNot ){
      pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0);
    }
  }
}

expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). {
  ExprList *pList = sqlite3ExprListAppend(pParse, X, Y.pExpr);
  A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0);
  if( A.pExpr ){
    A.pExpr->x.pList = pList;
    spanSet(&A, &L, &R);
  }else{
    sqlite3ExprListDelete(pParse->db, pList);
  }
}

expr(A) ::= expr(A) AND(OP) expr(Y).    {spanBinaryExpr(pParse,@OP,&A,&Y);}
expr(A) ::= expr(A) OR(OP) expr(Y).     {spanBinaryExpr(pParse,@OP,&A,&Y);}
expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
                                        {spanBinaryExpr(pParse,@OP,&A,&Y);}