engine/sqlite/src/func.cpp
author Sebastian Brannstrom <sebastianb@symbian.org>
Mon, 19 Jul 2010 16:51:10 +0100
branch3rded
changeset 191 a452d138726a
parent 2 29cda98b007e
permissions -rw-r--r--
Merged Jakl's fix for 2716
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2002 February 23
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** This file contains the C functions that implement various SQL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** functions of SQLite.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** There is only one exported symbol in this file - the function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
** All other code has file scope.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
** $Id: func.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
#include <ctype.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
#include <stdlib.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
#include <assert.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
#include "vdbeInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
** Return the collating function associated with a function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
  return context->pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
** Implementation of the non-aggregate min() and max() functions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
static void minmaxFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
  int mask;    /* 0 for min() or 0xffffffff for max() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
  int iBest;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  CollSeq *pColl;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
  if( argc==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
  mask = sqlite3_user_data(context)==0 ? 0 : -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
  pColl = sqlite3GetFuncCollSeq(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
  assert( pColl );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
  assert( mask==-1 || mask==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
  iBest = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
  for(i=1; i<argc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
    if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
      iBest = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
  sqlite3_result_value(context, argv[iBest]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
** Return the type of the argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
static void typeofFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
  const char *z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
    case SQLITE_NULL:    z = "null";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
    case SQLITE_INTEGER: z = "integer"; break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
    case SQLITE_TEXT:    z = "text";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
    case SQLITE_FLOAT:   z = "real";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
    case SQLITE_BLOB:    z = "blob";    break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  sqlite3_result_text(context, z, -1, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
** Implementation of the length() function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
static void lengthFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
  int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
    case SQLITE_BLOB:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
    case SQLITE_INTEGER:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
    case SQLITE_FLOAT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
      sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
    case SQLITE_TEXT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
      const unsigned char *z = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
      if( z==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
      len = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
      while( *z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
        len++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
        SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
      sqlite3_result_int(context, len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
      sqlite3_result_null(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
** Implementation of the abs() function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
    case SQLITE_INTEGER: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
      i64 iVal = sqlite3_value_int64(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
      if( iVal<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
        if( (iVal<<1)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
          sqlite3_result_error(context, "integer overflow", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
          return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
        iVal = -iVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
      } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
      sqlite3_result_int64(context, iVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
    case SQLITE_NULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
      sqlite3_result_null(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
      double rVal = sqlite3_value_double(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
      if( rVal<0 ) rVal = -rVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
      sqlite3_result_double(context, rVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
** Implementation of the substr() function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
** substr(x,p1,p2)  returns p2 characters of x[] beginning with p1.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
** p1 is 1-indexed.  So substr(x,1,1) returns the first character
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
** of x.  If x is text, then we actually count UTF-8 characters.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
** If x is a blob, then we count bytes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
** If p1 is negative, then we begin abs(p1) from the end of x[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
static void substrFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
  const unsigned char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
  const unsigned char *z2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
  int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
  int p0type;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
  i64 p1, p2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
  assert( argc==3 || argc==2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
  p0type = sqlite3_value_type(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
  if( p0type==SQLITE_BLOB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
    len = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
    z = (const unsigned char*)sqlite3_value_blob(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
    if( z==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
    assert( len==sqlite3_value_bytes(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
    z = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
    if( z==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
    len = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
    for(z2=z; *z2; len++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
      SQLITE_SKIP_UTF8(z2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
  p1 = sqlite3_value_int(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
  if( argc==3 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
    p2 = sqlite3_value_int(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
    p2 = SQLITE_MAX_LENGTH;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
  if( p1<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
    p1 += len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
    if( p1<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
      p2 += p1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
      p1 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
  }else if( p1>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
    p1--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
  if( p1+p2>len ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
    p2 = len-p1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
  if( p0type!=SQLITE_BLOB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
    while( *z && p1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
      SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
      p1--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
    for(z2=z; *z2 && p2; p2--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
      SQLITE_SKIP_UTF8(z2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
    sqlite3_result_text(context, (char*)z, z2-z, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
    if( p2<0 ) p2 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
    sqlite3_result_blob(context, (char*)&z[p1], p2, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
** Implementation of the round() function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
  int n = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
  double r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
  char zBuf[500];  /* larger than the %f representation of the largest double */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
  assert( argc==1 || argc==2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  if( argc==2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
    n = sqlite3_value_int(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
    if( n>30 ) n = 30;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
    if( n<0 ) n = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
  r = sqlite3_value_double(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
  sqlite3AtoF(zBuf, &r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  sqlite3_result_double(context, r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
** Allocate nByte bytes of space using sqlite3_malloc(). If the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
** allocation fails, call sqlite3_result_error_nomem() to notify
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
** the database handle that malloc() has failed.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
static void *contextMalloc(sqlite3_context *context, int nByte){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
  char *z = (char*)sqlite3_malloc(nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
  if( !z && nByte>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
    sqlite3_result_error_nomem(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  return z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
** Implementation of the upper() and lower() SQL functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
  char *z1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  const char *z2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
  z2 = (char*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  n = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
  assert( z2==(char*)sqlite3_value_text(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
  if( z2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
    z1 = (char*)contextMalloc(context, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
    if( z1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
      memcpy(z1, z2, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
      for(i=0; z1[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
        z1[i] = toupper(z1[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
      sqlite3_result_text(context, z1, -1, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  char *z1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  const char *z2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
  int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
  z2 = (char*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
  n = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  assert( z2==(char*)sqlite3_value_text(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  if( z2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
    z1 = (char*)contextMalloc(context, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
    if( z1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
      memcpy(z1, z2, n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
      for(i=0; z1[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
        z1[i] = tolower(z1[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
      sqlite3_result_text(context, z1, -1, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
** All three do the same thing.  They return the first non-NULL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
** argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
static void ifnullFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
  for(i=0; i<argc; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
    if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
      sqlite3_result_value(context, argv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
** Implementation of random().  Return a random integer.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
static void randomFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
  sqlite_int64 r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
  sqlite3Randomness(sizeof(r), &r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
  if( (r<<1)==0 ) r = 0;  /* Prevent 0x8000.... as the result so that we */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
                          /* can always do abs() of the result */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
  sqlite3_result_int64(context, r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
** Implementation of randomblob(N).  Return a random blob
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
** that is N bytes long.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
static void randomBlob(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
  unsigned char *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
  n = sqlite3_value_int(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
  if( n<1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
    n = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
  if( n>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
    sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
  p = (unsigned char*)contextMalloc(context, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
    sqlite3Randomness(n, p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
    sqlite3_result_blob(context, (char*)p, n, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
** Implementation of the last_insert_rowid() SQL function.  The return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
** value is the same as the sqlite3_last_insert_rowid() API function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
static void last_insert_rowid(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
  sqlite3_context *context, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
  int arg, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
  sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
** Implementation of the changes() SQL function.  The return value is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
** same as the sqlite3_changes() API function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
static void changes(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
  int arg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
  sqlite3_result_int(context, sqlite3_changes(db));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
** Implementation of the total_changes() SQL function.  The return value is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
** the same as the sqlite3_total_changes() API function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
static void total_changes(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  int arg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
  sqlite3_result_int(context, sqlite3_total_changes(db));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
** A structure defining how to do GLOB-style comparisons.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
struct compareInfo {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
  u8 matchAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
  u8 matchOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
  u8 matchSet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
  u8 noCase;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
** For LIKE and GLOB matching on EBCDIC machines, assume that every
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
** character is exactly one byte in size.  Also, all characters are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
** able to participate in upper-case-to-lower-case mappings in EBCDIC
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
** whereas only characters less than 0x80 do in ASCII.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
#if defined(SQLITE_EBCDIC)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
# define sqlite3Utf8Read(A,B,C)  (*(A++))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
# define GlogUpperToLower(A)     A = sqlite3UpperToLower[A]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
# define GlogUpperToLower(A)     if( A<0x80 ){ A = sqlite3UpperToLower[A]; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
/* The correct SQL-92 behavior is for the LIKE operator to ignore
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
** case.  Thus  'a' LIKE 'A' would be true. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
static const struct compareInfo likeInfoNorm = { '%', '_',   0, 1 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
** is case sensitive causing 'a' LIKE 'A' to be false */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
** Compare two UTF-8 strings for equality where the first string can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
** potentially be a "glob" expression.  Return true (1) if they
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
** are the same and false (0) if they are different.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
** Globbing rules:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
**      '*'       Matches any sequence of zero or more characters.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
**      '?'       Matches exactly one character.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
**     [...]      Matches one character from the enclosed list of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
**                characters.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
**     [^...]     Matches one character not in the enclosed list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
** With the [...] and [^...] matching, a ']' character can be included
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
** in the list by making it the first character after '[' or '^'.  A
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
** range of characters can be specified using '-'.  Example:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
** "[a-z]" matches any single lower-case letter.  To match a '-', make
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
** it the last character in the list.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
** This routine is usually quick, but can be N**2 in the worst case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
** Hints: to match '*' or '?', put them in "[]".  Like this:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
**         abc[*]xyz        Matches "abc*xyz" only
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
static int patternCompare(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
  const u8 *zPattern,              /* The glob pattern */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
  const u8 *zString,               /* The string to compare against the glob */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
  const struct compareInfo *pInfo, /* Information about how to do the compare */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
  const int esc                    /* The escape character */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
  int c, c2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
  int invert;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
  int seen;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
  u8 matchOne = pInfo->matchOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
  u8 matchAll = pInfo->matchAll;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
  u8 matchSet = pInfo->matchSet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
  u8 noCase = pInfo->noCase; 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
  int prevEscape = 0;     /* True if the previous character was 'escape' */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
  while( (c = sqlite3Utf8Read(zPattern,0,&zPattern))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
    if( !prevEscape && c==matchAll ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
      while( (c=sqlite3Utf8Read(zPattern,0,&zPattern)) == matchAll
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
               || c == matchOne ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
        if( c==matchOne && sqlite3Utf8Read(zString, 0, &zString)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
          return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
      if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
        return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
      }else if( c==esc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
        c = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
        if( c==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
          return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
      }else if( c==matchSet ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
        assert( esc==0 );         /* This is GLOB, not LIKE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
        assert( matchSet<0x80 );  /* '[' is a single-byte character */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
        while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
          SQLITE_SKIP_UTF8(zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
        return *zString!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
      while( (c2 = sqlite3Utf8Read(zString,0,&zString))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
        if( noCase ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
          GlogUpperToLower(c2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
          GlogUpperToLower(c);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
          while( c2 != 0 && c2 != c ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
            c2 = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
            GlogUpperToLower(c2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
          while( c2 != 0 && c2 != c ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
            c2 = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
        if( c2==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
        if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
    }else if( !prevEscape && c==matchOne ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
      if( sqlite3Utf8Read(zString, 0, &zString)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
        return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
    }else if( c==matchSet ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
      int prior_c = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
      assert( esc==0 );    /* This only occurs for GLOB, not LIKE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
      seen = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
      invert = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
      c = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
      if( c==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
      c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
      if( c2=='^' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
        invert = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
        c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
      if( c2==']' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
        if( c==']' ) seen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
        c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
      while( c2 && c2!=']' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
        if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
          c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
          if( c>=prior_c && c<=c2 ) seen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
          prior_c = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
          if( c==c2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
            seen = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
          prior_c = c2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
        c2 = sqlite3Utf8Read(zPattern, 0, &zPattern);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
      if( c2==0 || (seen ^ invert)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
        return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
    }else if( esc==c && !prevEscape ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
      prevEscape = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
      c2 = sqlite3Utf8Read(zString, 0, &zString);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
      if( noCase ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
        GlogUpperToLower(c);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
        GlogUpperToLower(c2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
      if( c!=c2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
        return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
      prevEscape = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
  return *zString==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
** Count the number of times that the LIKE operator (or GLOB which is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
** just a variation of LIKE) gets called.  This is used for testing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
** only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
int sqlite3_like_count = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
** Implementation of the like() SQL function.  This function implements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
** the build-in LIKE operator.  The first argument to the function is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
** pattern and the second argument is the string.  So, the SQL statements:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
**       A LIKE B
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
** is implemented as like(B,A).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
** This same function (with a different compareInfo structure) computes
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
** the GLOB operator.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
static void likeFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
  sqlite3_context *context, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
  int argc, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
  const unsigned char *zA, *zB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
  int escape = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
  zB = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
  zA = sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
  /* Limit the length of the LIKE or GLOB pattern to avoid problems
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  ** of deep recursion and N*N behavior in patternCompare().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
  if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
    sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
  assert( zB==sqlite3_value_text(argv[0]) );  /* Encoding did not change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
  if( argc==3 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
    /* The escape character string must consist of a single UTF-8 character.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
    ** Otherwise, return an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
    if( zEsc==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
    if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
      sqlite3_result_error(context, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
          "ESCAPE expression must be a single character", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
    escape = sqlite3Utf8Read(zEsc, 0, &zEsc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  if( zA && zB ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
    compareInfo *pInfo = (compareInfo*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
    sqlite3_like_count++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
** Implementation of the NULLIF(x,y) function.  The result is the first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
** argument if the arguments are different.  The result is NULL if the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
** arguments are equal to each other.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
static void nullifFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   640
  CollSeq *pColl = sqlite3GetFuncCollSeq(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   641
  if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   642
    sqlite3_result_value(context, argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   646
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   647
** Implementation of the VERSION(*) function.  The result is the version
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   648
** of the SQLite library that is running.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
static void versionFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   655
  sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   656
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   657
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
/* Array for converting from half-bytes (nybbles) into ASCII hex
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
** digits. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
static const char hexdigits[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
  '0', '1', '2', '3', '4', '5', '6', '7',
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
** EXPERIMENTAL - This is not an official function.  The interface may
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
** change.  This function may disappear.  Do not write code that depends
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
** on this function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
** Implementation of the QUOTE() function.  This function takes a single
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   671
** argument.  If the argument is numeric, the return value is the same as
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   672
** the argument.  If the argument is NULL, the return value is the string
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
** "NULL".  Otherwise, the argument is enclosed in single quotes with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   674
** single-quote escapes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   675
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
  if( argc<1 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
  switch( sqlite3_value_type(argv[0]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
    case SQLITE_NULL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
      sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
    case SQLITE_INTEGER:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
    case SQLITE_FLOAT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
      sqlite3_result_value(context, argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
    case SQLITE_BLOB: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
      char *zText = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
      char const *zBlob = (const char*)sqlite3_value_blob(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
      int nBlob = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
      assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
      if( 2*nBlob+4>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
        sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
      zText = (char *)contextMalloc(context, (2*nBlob)+4); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
      if( zText ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
        int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
        for(i=0; i<nBlob; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
          zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
          zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   704
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   705
        zText[(nBlob*2)+2] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
        zText[(nBlob*2)+3] = '\0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
        zText[0] = 'X';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   708
        zText[1] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   709
        sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
        sqlite3_free(zText);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   712
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   713
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
    case SQLITE_TEXT: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
      int i,j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
      u64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
      const unsigned char *zArg = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
      char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
      if( zArg==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
      for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
      if( i+n+3>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
        sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
      z = (char*)contextMalloc(context, i+n+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
      if( z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
        z[0] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
        for(i=0, j=1; zArg[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
          z[j++] = zArg[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
          if( zArg[i]=='\'' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
            z[j++] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
        z[j++] = '\'';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
        z[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
        sqlite3_result_text(context, z, j, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   744
** The hex() function.  Interpret the argument as a blob.  Return
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   745
** a hexadecimal rendering as text.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
static void hexFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
  int i, n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
  const unsigned char *pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
  char *zHex, *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
  pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
  n = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   758
  if( n*2+1>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   759
    sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   760
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
  assert( pBlob==sqlite3_value_blob(argv[0]) );  /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
  z = zHex = (char*)contextMalloc(context, n*2 + 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
  if( zHex ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
    for(i=0; i<n; i++, pBlob++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
      unsigned char c = *pBlob;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
      *(z++) = hexdigits[(c>>4)&0xf];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
      *(z++) = hexdigits[c&0xf];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   769
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   770
    *z = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   771
    sqlite3_result_text(context, zHex, n*2, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   777
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   778
static void zeroblobFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   781
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   782
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
  i64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   784
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   785
  n = sqlite3_value_int64(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
  if( n>SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
    sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   788
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   789
    sqlite3_result_zeroblob(context, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   790
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
** The replace() function.  Three arguments are all strings: call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
** them A, B, and C. The result is also a string which is derived
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   796
** from A by replacing every occurance of B with C.  The match
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   797
** must be exact.  Collating sequences are not used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   799
static void replaceFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   800
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
  const unsigned char *zStr;        /* The input string A */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
  const unsigned char *zPattern;    /* The pattern string B */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
  const unsigned char *zRep;        /* The replacement string C */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
  unsigned char *zOut;              /* The output */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
  int nStr;                /* Size of zStr */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
  int nPattern;            /* Size of zPattern */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
  int nRep;                /* Size of zRep */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
  i64 nOut;                /* Maximum size of zOut */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
  int loopLimit;           /* Last zStr[] that might match zPattern[] */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
  int i, j;                /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
  assert( argc==3 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
  zStr = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
  if( zStr==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
  nStr = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
  assert( zStr==sqlite3_value_text(argv[0]) );  /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
  zPattern = sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
  if( zPattern==0 || zPattern[0]==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
  nPattern = sqlite3_value_bytes(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
  assert( zPattern==sqlite3_value_text(argv[1]) );  /* No encoding change */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   824
  zRep = sqlite3_value_text(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   825
  if( zRep==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   826
  nRep = sqlite3_value_bytes(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   827
  assert( zRep==sqlite3_value_text(argv[2]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
  nOut = nStr + 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
  assert( nOut<SQLITE_MAX_LENGTH );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
  zOut = (unsigned char*)contextMalloc(context, (int)nOut);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
  if( zOut==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   834
  loopLimit = nStr - nPattern;  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   835
  for(i=j=0; i<=loopLimit; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
    if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
      zOut[j++] = zStr[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
      u8 *zOld;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
      nOut += nRep - nPattern;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
      if( nOut>=SQLITE_MAX_LENGTH ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
        sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   843
        sqlite3_free(zOut);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   844
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   845
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   846
      zOld = zOut;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   847
      zOut = (unsigned char*)sqlite3_realloc(zOut, (int)nOut);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
      if( zOut==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
        sqlite3_result_error_nomem(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
        sqlite3_free(zOld);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
      memcpy(&zOut[j], zRep, nRep);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
      j += nRep;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
      i += nPattern-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
  assert( j+nStr-i+1==nOut );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
  memcpy(&zOut[j], &zStr[i], nStr-i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
  j += nStr - i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   861
  assert( j<=nOut );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   862
  zOut[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
  sqlite3_result_text(context, (char*)zOut, j, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   868
** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   869
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   870
static void trimFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
  const unsigned char *zIn;         /* Input string */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
  const unsigned char *zCharSet;    /* Set of characters to trim */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
  int nIn;                          /* Number of bytes in input */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
  int flags;                        /* 1: trimleft  2: trimright  3: trim */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
  int i;                            /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
  unsigned char *aLen;              /* Length of each character in zCharSet */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
  unsigned char **azChar;           /* Individual characters in zCharSet */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
  int nChar;                        /* Number of characters in zCharSet */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
  zIn = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
  if( zIn==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
  nIn = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
  assert( zIn==sqlite3_value_text(argv[0]) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
  if( argc==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
    static const unsigned char lenOne[] = { 1 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
    static const unsigned char *azOne[] = { (u8*)" " };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   894
    nChar = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   895
    aLen = (u8*)lenOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
    azChar = (unsigned char **)azOne;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
    zCharSet = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
  }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
    const unsigned char *z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
    for(z=zCharSet, nChar=0; *z; nChar++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
      SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
    if( nChar>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
      azChar = (unsigned char**)contextMalloc(context, nChar*(sizeof(char*)+1));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
      if( azChar==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
      aLen = (unsigned char*)&azChar[nChar];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   911
      for(z=zCharSet, nChar=0; *z; nChar++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   912
        azChar[nChar] = (unsigned char *)z;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
        SQLITE_SKIP_UTF8(z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
        aLen[nChar] = z - azChar[nChar];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
  if( nChar>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
    flags = (int)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
    if( flags & 1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
      while( nIn>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
        int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
        for(i=0; i<nChar; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
          len = aLen[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
          if( memcmp(zIn, azChar[i], len)==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
        if( i>=nChar ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
        zIn += len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
        nIn -= len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   931
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   932
    if( flags & 2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
      while( nIn>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
        int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
        for(i=0; i<nChar; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
          len = aLen[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
          if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   938
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   939
        if( i>=nChar ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
        nIn -= len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
    if( zCharSet ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
      sqlite3_free(azChar);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   946
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   947
  sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   949
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   950
#ifdef SQLITE_SOUNDEX
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
** Compute the soundex encoding of a word.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   954
static void soundexFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   955
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   958
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   959
  char zResult[8];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
  const u8 *zIn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
  int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   962
  static const unsigned char iCode[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   963
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   964
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   966
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   967
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
  zIn = (u8*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
  if( zIn==0 ) zIn = (u8*)"";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
  for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
  if( zIn[i] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
    u8 prevcode = iCode[zIn[i]&0x7f];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   978
    zResult[0] = toupper(zIn[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   979
    for(j=1; j<4 && zIn[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
      int code = iCode[zIn[i]&0x7f];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
      if( code>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
        if( code!=prevcode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   983
          prevcode = code;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   984
          zResult[j++] = code + '0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
        prevcode = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   990
    while( j<4 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   991
      zResult[j++] = '0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
    zResult[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   994
    sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   995
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
    sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1001
#ifndef SQLITE_OMIT_LOAD_EXTENSION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1002
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
** A function that loads a shared-library extension then returns NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
  const char *zFile = (const char *)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
  const char *zProc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
  sqlite3 *db = (sqlite3*)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
  char *zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1010
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1011
  if( argc==2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
    zProc = (const char *)sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
    zProc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
  if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
    sqlite3_result_error(context, zErrMsg, -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
    sqlite3_free(zErrMsg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1023
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1024
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
** This function generates a string of random characters.  Used for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
** generating test data.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
  static const unsigned char zSrc[] = 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1030
     "abcdefghijklmnopqrstuvwxyz"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1031
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
     "0123456789"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
     ".-!,:*^+=_|?/<> ";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
  int iMin, iMax, n, r, i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
  unsigned char zBuf[1000];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
  /* It used to be possible to call randstr() with any number of arguments,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
  ** but now it is registered with SQLite as requiring exactly 2.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
  assert(argc==2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
  iMin = sqlite3_value_int(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
  if( iMin<0 ) iMin = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
  if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
  iMax = sqlite3_value_int(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1046
  if( iMax<iMin ) iMax = iMin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1047
  if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
  n = iMin;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
  if( iMax>iMin ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
    sqlite3Randomness(sizeof(r), &r);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
    r &= 0x7fffffff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
    n += r%(iMax + 1 - iMin);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
  assert( n<sizeof(zBuf) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
  sqlite3Randomness(n, zBuf);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
  for(i=0; i<n; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
  zBuf[n] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
  sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1062
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1063
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
** The following two SQL functions are used to test returning a text
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
** result with a destructor. Function 'test_destructor' takes one argument
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
** and returns the same argument interpreted as TEXT. A destructor is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
** passed with the sqlite3_result_text() call.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
** SQL function 'test_destructor_count' returns the number of outstanding 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
** allocations made by 'test_destructor';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
** WARNING: Not threadsafe.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
static int test_destructor_count_var = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
static void destructor(void *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
  char *zVal = (char *)p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
  assert(zVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
  zVal--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
  sqlite3_free(zVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
  test_destructor_count_var--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
static void test_destructor(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1089
  char *zVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1090
  int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
  sqlite3 *db = sqlite3_user_data(pCtx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1093
  test_destructor_count_var++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1094
  assert( nArg==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
  len = sqlite3ValueBytes(argv[0], ENC(db)); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
  zVal = contextMalloc(pCtx, len+3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
  if( !zVal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1099
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1100
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
  zVal[len+1] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
  zVal[len+2] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
  zVal++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
  memcpy(zVal, sqlite3ValueText(argv[0], ENC(db)), len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
  if( ENC(db)==SQLITE_UTF8 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
    sqlite3_result_text(pCtx, zVal, -1, destructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
#ifndef SQLITE_OMIT_UTF16
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
  }else if( ENC(db)==SQLITE_UTF16LE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
    sqlite3_result_text16le(pCtx, zVal, -1, destructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1111
    sqlite3_result_text16be(pCtx, zVal, -1, destructor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1112
#endif /* SQLITE_OMIT_UTF16 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
static void test_destructor_count(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
  sqlite3_result_int(pCtx, test_destructor_count_var);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
** interface.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
** The test_auxdata() SQL function attempts to register each of its arguments
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
** as auxiliary data.  If there are no prior registrations of aux data for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
** that argument (meaning the argument is not a constant or this is its first
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
** call) then the result for that argument is 0.  If there is a prior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
** registration, the result for that argument is 1.  The overall result
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1134
** is the individual argument results separated by spaces.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1135
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
static void free_test_auxdata(void *p) {sqlite3_free(p);}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1137
static void test_auxdata(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1138
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
  char *zRet = contextMalloc(pCtx, nArg*2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
  if( !zRet ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1145
  memset(zRet, 0, nArg*2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1146
  for(i=0; i<nArg; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1147
    char const *z = (char*)sqlite3_value_text(argv[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
    if( z ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
      char *zAux = sqlite3_get_auxdata(pCtx, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
      if( zAux ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1151
        zRet[i*2] = '1';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1152
        if( strcmp(zAux, z) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
          sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
          return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
      }else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
        zRet[i*2] = '0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1158
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1159
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
      zAux = contextMalloc(pCtx, strlen(z)+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1161
      if( zAux ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1162
        strcpy(zAux, z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
        sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
      zRet[i*2+1] = ' ';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
  sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
** A function to test error reporting from user functions. This function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
** returns a copy of its first argument as an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1177
static void test_error(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1178
  sqlite3_context *pCtx, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
  int nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1181
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1182
  sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
#endif /* SQLITE_TEST */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
** An instance of the following structure holds the context of a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
** sum() or avg() aggregate computation.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
typedef struct SumCtx SumCtx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1191
struct SumCtx {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1192
  double rSum;      /* Floating point sum */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
  i64 iSum;         /* Integer sum */   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
  i64 cnt;          /* Number of elements summed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
  u8 overflow;      /* True if integer overflow seen */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
  u8 approx;        /* True if non-integer value was input to the sum */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
** Routines used to compute the sum, average, and total.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1201
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1202
** The SUM() function follows the (broken) SQL standard which means
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
** that it returns NULL if it sums over no inputs.  TOTAL returns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
** 0.0 in that case.  In addition, TOTAL always returns a float where
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
** SUM might return an integer if it never encounters a floating point
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
** value.  TOTAL never fails, but SUM might through an exception if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
** it overflows an integer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1209
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1210
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
  int type;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1212
  assert( argc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1213
  p = (SumCtx*)sqlite3_aggregate_context(context, sizeof(*p));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
  type = sqlite3_value_numeric_type(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
  if( p && type!=SQLITE_NULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
    p->cnt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
    if( type==SQLITE_INTEGER ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
      i64 v = sqlite3_value_int64(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
      p->rSum += v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
      if( (p->approx|p->overflow)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1221
        i64 iNewSum = p->iSum + v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1222
        int s1 = p->iSum >> (sizeof(i64)*8-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
        int s2 = v       >> (sizeof(i64)*8-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
        int s3 = iNewSum >> (sizeof(i64)*8-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
        p->overflow = (s1&s2&~s3) | (~s1&~s2&s3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
        p->iSum = iNewSum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
      p->rSum += sqlite3_value_double(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
      p->approx = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1231
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1232
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
static void sumFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
  p = (SumCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
  if( p && p->cnt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
    if( p->overflow ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
      sqlite3_result_error(context,"integer overflow",-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
    }else if( p->approx ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
      sqlite3_result_double(context, p->rSum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
      sqlite3_result_int64(context, p->iSum);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1244
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1245
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
static void avgFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
  p = (SumCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
  if( p && p->cnt>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
    sqlite3_result_double(context, p->rSum/(double)p->cnt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
static void totalFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
  SumCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1256
  p = (SumCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1257
  sqlite3_result_double(context, p ? p->rSum : 0.0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
** The following structure keeps track of state information for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
** count() aggregate function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
typedef struct CountCtx CountCtx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
struct CountCtx {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
  i64 n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
};
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
** Routines to implement the count() aggregate function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
  CountCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
  p = (CountCtx*)sqlite3_aggregate_context(context, sizeof(*p));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
    p->n++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
}   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
static void countFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
  CountCtx *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
  p = (CountCtx*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
  sqlite3_result_int64(context, p ? p->n : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
** Routines to implement min() and max() aggregate functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1288
static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1289
  Mem *pArg  = (Mem *)argv[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1290
  Mem *pBest;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
  pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
  if( !pBest ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
  if( pBest->flags ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
    int max;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
    int cmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
    CollSeq *pColl = sqlite3GetFuncCollSeq(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
    /* This step function is used for both the min() and max() aggregates,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
    ** the only difference between the two being that the sense of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
    ** comparison is inverted. For the max() aggregate, the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
    ** sqlite3_user_data() function returns (void *)-1. For min() it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
    ** returns (void *)db, where db is the sqlite3* database pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
    ** Therefore the next statement sets variable 'max' to 1 for the max()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
    ** aggregate, or 0 for min().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
    max = sqlite3_user_data(context)!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
    cmp = sqlite3MemCompare(pBest, pArg, pColl);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
    if( (max && cmp<0) || (!max && cmp>0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
      sqlite3VdbeMemCopy(pBest, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
    sqlite3VdbeMemCopy(pBest, pArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
static void minMaxFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
  sqlite3_value *pRes;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
  if( pRes ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
    if( pRes->flags ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
      sqlite3_result_value(context, pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
    sqlite3VdbeMemRelease(pRes);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
** group_concat(EXPR, ?SEPARATOR?)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
static void groupConcatStep(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1336
  const char *zVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1337
  StrAccum *pAccum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
  const char *zSep;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
  int nVal, nSep;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1341
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1342
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
  if( pAccum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
    pAccum->useMalloc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
    if( pAccum->nChar ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
      if( argc==2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
        zSep = (char*)sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
        nSep = sqlite3_value_bytes(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
        zSep = ",";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
        nSep = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1352
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1353
      sqlite3StrAccumAppend(pAccum, zSep, nSep);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1354
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
    zVal = (char*)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
    nVal = sqlite3_value_bytes(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
    sqlite3StrAccumAppend(pAccum, zVal, nVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1358
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1359
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
static void groupConcatFinalize(sqlite3_context *context){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
  StrAccum *pAccum;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
  if( pAccum ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
    if( pAccum->tooBig ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
      sqlite3_result_error_toobig(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
    }else if( pAccum->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
      sqlite3_result_error_nomem(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
    }else{    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
                          sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
** This function registered all of the above C functions as SQL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
** functions.  This should be the only routine in this file with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
** external linkage.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
  static const struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
     char *zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
     signed char nArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1384
     u8 argType;           /* ff: db   1: 0, 2: 1, 3: 2,...  N:  N-1. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1385
     u8 eTextRep;          /* 1: UTF-16.  0: UTF-8 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1386
     u8 needCollSeq;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1387
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1388
  } aFuncs[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1389
    { "min",               -1, 0, SQLITE_UTF8,    1, minmaxFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
    { "min",                0, 0, SQLITE_UTF8,    1, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
    { "max",               -1, 1, SQLITE_UTF8,    1, minmaxFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
    { "max",                0, 1, SQLITE_UTF8,    1, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
    { "typeof",             1, 0, SQLITE_UTF8,    0, typeofFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1394
    { "length",             1, 0, SQLITE_UTF8,    0, lengthFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1395
    { "substr",             2, 0, SQLITE_UTF8,    0, substrFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
    { "substr",             3, 0, SQLITE_UTF8,    0, substrFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
    { "abs",                1, 0, SQLITE_UTF8,    0, absFunc    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
    { "round",              1, 0, SQLITE_UTF8,    0, roundFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
    { "round",              2, 0, SQLITE_UTF8,    0, roundFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1400
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1401
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1402
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
    { "hex",                1, 0, SQLITE_UTF8,    0, hexFunc    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
    { "randomblob",         1, 0, SQLITE_UTF8,    0, randomBlob },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
    { "last_insert_rowid",  0, 0xff, SQLITE_UTF8, 0, last_insert_rowid },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
    { "changes",            0, 0xff, SQLITE_UTF8, 0, changes           },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1414
    { "total_changes",      0, 0xff, SQLITE_UTF8, 0, total_changes     },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1415
    { "replace",            3, 0, SQLITE_UTF8,    0, replaceFunc       },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
    { "ltrim",              1, 1, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1417
    { "ltrim",              2, 1, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1418
    { "rtrim",              1, 2, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1419
    { "rtrim",              2, 2, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1420
    { "trim",               1, 3, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1421
    { "trim",               2, 3, SQLITE_UTF8,    0, trimFunc          },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1422
    { "zeroblob",           1, 0, SQLITE_UTF8,    0, zeroblobFunc      },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1423
#ifdef SQLITE_SOUNDEX
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1424
    { "soundex",            1, 0, SQLITE_UTF8,    0, soundexFunc},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1425
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
#ifndef SQLITE_OMIT_LOAD_EXTENSION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
    { "load_extension",     1, 0xff, SQLITE_UTF8, 0, loadExt },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
    { "load_extension",     2, 0xff, SQLITE_UTF8, 0, loadExt },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
    { "randstr",               2, 0,    SQLITE_UTF8, 0, randStr    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
    { "test_destructor",       1, 0xff, SQLITE_UTF8, 0, test_destructor},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
    { "test_destructor_count", 0, 0,    SQLITE_UTF8, 0, test_destructor_count},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
    { "test_auxdata",         -1, 0,    SQLITE_UTF8, 0, test_auxdata},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
    { "test_error",            1, 0,    SQLITE_UTF8, 0, test_error},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
  static const struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
    char *zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1440
    signed char nArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1441
    u8 argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
    u8 needCollSeq;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
    void (*xFinalize)(sqlite3_context*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1445
  } aAggs[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1446
    { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1447
    { "max",    1, 1, 1, minmaxStep,   minMaxFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
    { "sum",    1, 0, 0, sumStep,      sumFinalize    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
    { "total",  1, 0, 0, sumStep,      totalFinalize    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
    { "avg",    1, 0, 0, sumStep,      avgFinalize    },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
    { "count",  0, 0, 0, countStep,    countFinalize  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1452
    { "count",  1, 0, 0, countStep,    countFinalize  },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1453
    { "group_concat", 1, 0, 0, groupConcatStep, groupConcatFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
    { "group_concat", 2, 0, 0, groupConcatStep, groupConcatFinalize },
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1455
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1456
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1457
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1458
  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1459
    void *pArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1460
    u8 argType = aFuncs[i].argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1461
    if( argType==0xff ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
      pArg = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
      pArg = (void*)(int)argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
        aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
    if( aFuncs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
      FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
          strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
      if( pFunc && aFuncs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
        pFunc->needCollSeq = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1474
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1475
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
#ifndef SQLITE_OMIT_ALTERTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
  sqlite3AlterFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1478
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1479
#ifndef SQLITE_OMIT_PARSER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
  sqlite3AttachFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1481
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1482
  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
    void *pArg = (void*)(int)aAggs[i].argType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
    sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
        pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
    if( aAggs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
      FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
          strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
      if( pFunc && aAggs[i].needCollSeq ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
        pFunc->needCollSeq = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
  sqlite3RegisterDateTimeFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1495
  if( !db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1496
    int rc = sqlite3_overload_function(db, "MATCH", 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
    assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
    if( rc==SQLITE_NOMEM ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
#ifdef SQLITE_SSE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
  (void)sqlite3SseFunctions(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
#ifdef SQLITE_CASE_SENSITIVE_LIKE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
  sqlite3RegisterLikeFunctions(db, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
  sqlite3RegisterLikeFunctions(db, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1511
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1512
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1513
** Set the LIKEOPT flag on the 2-argument function with the given name.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1514
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1515
static void setLikeOptFlag(sqlite3 *db, const char *zName, int flagVal){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
  FuncDef *pDef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
  pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
  if( pDef ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
    pDef->flags = flagVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
** Register the built-in LIKE and GLOB functions.  The caseSensitive
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
** parameter determines whether or not the LIKE operator is case
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
** sensitive.  GLOB is always case sensitive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
  struct compareInfo *pInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
  if( caseSensitive ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
    pInfo = (struct compareInfo*)&likeInfoAlt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
    pInfo = (struct compareInfo*)&likeInfoNorm;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
      (struct compareInfo*)&globInfo, likeFunc, 0,0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
  setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
  setLikeOptFlag(db, "like", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
      caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
** pExpr points to an expression which implements a function.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
** it is appropriate to apply the LIKE optimization to that function
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1547
** then set aWc[0] through aWc[2] to the wildcard characters and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1548
** return TRUE.  If the function is not a LIKE-style function then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
** return FALSE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1550
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1551
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1552
  FuncDef *pDef;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
  if( pExpr->op!=TK_FUNCTION || !pExpr->pList ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
  if( pExpr->pList->nExpr!=2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
  pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
                             SQLITE_UTF8, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
  if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
  /* The memcpy() statement assumes that the wildcard characters are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
  ** the first three statements in the compareInfo structure.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1567
  ** asserts() that follow verify that assumption
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1568
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  memcpy(aWc, pDef->pUserData, 3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
  assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1572
  assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1573
  *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
}