/ Check-in [90c3b23c]
Login

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

Overview
Comment:Make sure group_concat() ignores initial NULL values. (CVS 6787)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:90c3b23ccac8a9e7fc1cc831e43888e4e43badc9
User & Date: drh 2009-06-19 16:44:41
Context
2009-06-19
17:50
If a call is made to sqlite3PagerAcquire when there are no outstanding references to any pages and the pager is in the error-state, try to exit the error-state at this point. Previously this was only attempted if the pager was configured to use exclusive mode. (CVS 6788) check-in: 62db08bc user: danielk1977 tags: trunk
16:44
Make sure group_concat() ignores initial NULL values. (CVS 6787) check-in: 90c3b23c user: drh tags: trunk
14:06
Reorganize and cleanup the prepared statement object. Remove code that has been commented out for ages and is no longer relevant to anything. (CVS 6786) check-in: 37ae5f5e user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.238 2009/06/19 14:06:03 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

/*
................................................................................
  int nVal, nSep;
  assert( argc==1 || argc==2 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));

  if( pAccum ){
    sqlite3 *db = sqlite3_context_db_handle(context);
    int n;
    pAccum->useMalloc = 1;
    pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
#ifdef SQLITE_OMIT_DEPRECATED
    n = context->pMem->n;
#else
    n = sqlite3_aggregate_count(context);
#endif
    if( n>1 ){
      if( argc==2 ){
        zSep = (char*)sqlite3_value_text(argv[1]);
        nSep = sqlite3_value_bytes(argv[1]);
      }else{
        zSep = ",";
        nSep = 1;
      }







|







 







|


|
<
<
<
<
<







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271





1272
1273
1274
1275
1276
1277
1278
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.239 2009/06/19 16:44:41 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

/*
................................................................................
  int nVal, nSep;
  assert( argc==1 || argc==2 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));

  if( pAccum ){
    sqlite3 *db = sqlite3_context_db_handle(context);
    int firstTerm = pAccum->useMalloc==0;
    pAccum->useMalloc = 1;
    pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
    if( !firstTerm ){





      if( argc==2 ){
        zSep = (char*)sqlite3_value_text(argv[1]);
        nSep = sqlite3_value_bytes(argv[1]);
      }else{
        zSep = ",";
        nSep = 1;
      }

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071





















1072
1073
1074
1075
1076
1077
1078
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.92 2009/04/15 15:16:53 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
  set sql "SELECT md5sum(t1$midargs) FROM tbl1"
  do_test func-24.7.$i {
     db eval $::sql
  } $result
}

# Ticket #3806.  If the initial string in a group_concat is an empty
# string, the separate that follows should still be present.
#
do_test func-24.8 {
  execsql {
    SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
  }
} {,program,is,free,software}
do_test func-24.9 {
  execsql {
    SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
  }
} {,,,,software}






















# Use the test_isolation function to make sure that type conversions
# on function arguments do not effect subsequent arguments.
#
do_test func-25.1 {
  execsql {SELECT test_isolation(t1,t1) FROM tbl1}
} {this program is free software}







|







 







|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.93 2009/06/19 16:44:41 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
  set sql "SELECT md5sum(t1$midargs) FROM tbl1"
  do_test func-24.7.$i {
     db eval $::sql
  } $result
}

# Ticket #3806.  If the initial string in a group_concat is an empty
# string, the separator that follows should still be present.
#
do_test func-24.8 {
  execsql {
    SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
  }
} {,program,is,free,software}
do_test func-24.9 {
  execsql {
    SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
  }
} {,,,,software}

# Ticket #3923.  Initial empty strings have a separator.  But initial
# NULLs do not.
#
do_test func-24.10 {
  execsql {
    SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1
  }
} {program,is,free,software}
do_test func-24.11 {
  execsql {
   SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1
  }
} {software}
do_test func-24.12 {
  execsql {
    SELECT group_concat(CASE t1 WHEN 'this' THEN ''
                          WHEN 'program' THEN null ELSE t1 END) FROM tbl1
  }
} {,is,free,software}


# Use the test_isolation function to make sure that type conversions
# on function arguments do not effect subsequent arguments.
#
do_test func-25.1 {
  execsql {SELECT test_isolation(t1,t1) FROM tbl1}
} {this program is free software}