/ Check-in [8fb6bd9b]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:The valueFromFunction() routine is better able to handle OOM errors. Omit unreachable branches.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | stat4-function
Files: files | file ages | folders
SHA1: 8fb6bd9be59d6b04e922d7b246aaefd4851539b6
User & Date: drh 2015-03-12 06:46:52
Context
2015-03-12
18:38
If an error occurs in the compile-time evaluation of an application-defined function, then propagate back out the exact error code, not just the generic SQLITE_ERROR. check-in: 93f42586 user: drh tags: stat4-function
06:46
The valueFromFunction() routine is better able to handle OOM errors. Omit unreachable branches. check-in: 8fb6bd9b user: drh tags: stat4-function
2015-03-11
20:59
Allow the default value for columns added using ALTER TABLE ADD COLUMN to be a function in existing schemas loaded from disk. But prevent this version of SQLite from being used to create such a column. check-in: ff868e22 user: dan tags: stat4-function
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

18
19
20
21
22
23
24


25
26
27
28
29
30
31
32
#include <assert.h>
#include "vdbeInt.h"

/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){


  VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
  assert( pOp->opcode==OP_CollSeq );
  assert( pOp->p4type==P4_COLLSEQ );
  return pOp->p4.pColl;
}

/*
** Indicate that the accumulator load should be skipped on this







>
>
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <assert.h>
#include "vdbeInt.h"

/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
  VdbeOp *pOp;
  assert( context->pVdbe!=0 );
  pOp = &context->pVdbe->aOp[context->iOp-1];
  assert( pOp->opcode==OP_CollSeq );
  assert( pOp->p4type==P4_COLLSEQ );
  return pOp->p4.pColl;
}

/*
** Indicate that the accumulator load should be skipped on this

Changes to src/vdbeapi.c.

629
630
631
632
633
634
635
636




637
638
639
640
641
642









643
644
645

646
647
648
649
650
651
652
653
...
709
710
711
712
713
714
715

716



717
718
719
720
721
722
723
...
733
734
735
736
737
738
739

740



741
742
743
744
745
746
747
*/
sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
  assert( p && p->pFunc );
  return p->pOut->db;
}

/*
** Return the current time for a statement




*/
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
  Vdbe *v = p->pVdbe;
  sqlite3_int64 iTime = 0;
  int rc;
  if( v && v->iCurrentTime ) return v->iCurrentTime;









  rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &iTime);
  if( rc ) return 0;
  if( v ) v->iCurrentTime = iTime;

  return iTime;
}

/*
** The following is the implementation of an SQL function that always
** fails with an error message stating that the function is used in the
** wrong context.  The sqlite3_overload_function() API might construct
** SQL function that use this routine so that the functions will exist
................................................................................
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  AuxData *pAuxData;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );

  if( pCtx->pVdbe==0 ) return 0;



  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
  }

  return (pAuxData ? pAuxData->pAux : 0);
}

................................................................................
  void (*xDelete)(void*)
){
  AuxData *pAuxData;
  Vdbe *pVdbe = pCtx->pVdbe;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  if( iArg<0 ) goto failed;

  if( pVdbe==0 ) goto failed;




  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
  }
  if( pAuxData==0 ){
    pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
    if( !pAuxData ) goto failed;







|
>
>
>
>


<
<

<
>
>
>
>
>
>
>
>
>
|
|
<
>
|







 







>

>
>
>







 







>

>
>
>







629
630
631
632
633
634
635
636
637
638
639
640
641
642


643

644
645
646
647
648
649
650
651
652
653
654

655
656
657
658
659
660
661
662
663
...
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
...
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
*/
sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
  assert( p && p->pFunc );
  return p->pOut->db;
}

/*
** Return the current time for a statement.  If the current time
** is requested more than once within the same run of a single prepared
** statement, the exact same time is returned for each invocation regardless
** of the amount of time that elapses between invocations.  In other words,
** the time returned is always the time of the first call.
*/
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){


  int rc;

  sqlite3_int64 iTime = 0;
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
  sqlite3_int64 *piTime = &iTime;
  assert( p->pVdbe!=0 );
#else
  sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
  if( *piTime==0 )
#endif
  {
    rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime);
    if( rc ) *piTime = 0;

  }
  return *piTime;
}

/*
** The following is the implementation of an SQL function that always
** fails with an error message stating that the function is used in the
** wrong context.  The sqlite3_overload_function() API might construct
** SQL function that use this routine so that the functions will exist
................................................................................
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  AuxData *pAuxData;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#if SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx->pVdbe==0 ) return 0;
#else
  assert( pCtx->pVdbe!=0 );
#endif
  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
  }

  return (pAuxData ? pAuxData->pAux : 0);
}

................................................................................
  void (*xDelete)(void*)
){
  AuxData *pAuxData;
  Vdbe *pVdbe = pCtx->pVdbe;

  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  if( iArg<0 ) goto failed;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pVdbe==0 ) goto failed;
#else
  assert( pVdbe!=0 );
#endif

  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
  }
  if( pAuxData==0 ){
    pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
    if( !pAuxData ) goto failed;

Changes to src/vdbemem.c.

1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
....
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240
    apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
    if( apVal==0 ){
      rc = SQLITE_NOMEM;
      goto value_from_function_out;
    }
    for(i=0; i<nVal; i++){
      rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
      if( apVal[i]==0 ) goto value_from_function_out;
      assert( rc==SQLITE_OK );
    }
  }

  pVal = valueNew(db, pCtx);
  if( pVal==0 ){
    rc = SQLITE_NOMEM;
    goto value_from_function_out;
................................................................................
  }

 value_from_function_out:
  if( rc!=SQLITE_OK ){
    if( pCtx==0 ) sqlite3ValueFree(pVal);
    pVal = 0;
  }

  for(i=0; i<nVal; i++){
    sqlite3ValueFree(apVal[i]);
  }
  sqlite3DbFree(db, apVal);


  *ppVal = pVal;
  return rc;
}
#else
# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */







|
<







 







>
|
|
|
|
>







1190
1191
1192
1193
1194
1195
1196
1197

1198
1199
1200
1201
1202
1203
1204
....
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
    apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
    if( apVal==0 ){
      rc = SQLITE_NOMEM;
      goto value_from_function_out;
    }
    for(i=0; i<nVal; i++){
      rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
      if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;

    }
  }

  pVal = valueNew(db, pCtx);
  if( pVal==0 ){
    rc = SQLITE_NOMEM;
    goto value_from_function_out;
................................................................................
  }

 value_from_function_out:
  if( rc!=SQLITE_OK ){
    if( pCtx==0 ) sqlite3ValueFree(pVal);
    pVal = 0;
  }
  if( apVal ){
    for(i=0; i<nVal; i++){
      sqlite3ValueFree(apVal[i]);
    }
    sqlite3DbFree(db, apVal);
  }

  *ppVal = pVal;
  return rc;
}
#else
# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */