SQLite

Check-in [de8182cf]
Login

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

Overview
Comment:Fix the -> and ->> operators so that when the RHS is a string that looks like a number, it is still treated as a string, because that is what PG does. Forum post 9e52cdfe15c3926e.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: de8182cf1773ac0d04268d896a613841cf6bf61f9f030342170657d5e06f2acb
User & Date: drh 2024-05-21 11:11:29
Context
2024-05-21
13:34
Fix harmless compiler warnings. (check-in: aab59f9f user: drh tags: trunk)
11:11
Fix the -> and ->> operators so that when the RHS is a string that looks like a number, it is still treated as a string, because that is what PG does. Forum post 9e52cdfe15c3926e. (check-in: de8182cf user: drh tags: trunk)
2024-05-20
19:59
Omit a capi3 test from 2007 that depends upon undefined behavior (UAF). (check-in: a60a0b75 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/json.c.

3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
  if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){
    cnt = jsonbArrayCount(p, i);
  }
  if( !eErr ) sqlite3_result_int64(ctx, cnt);
  jsonParseFree(p);
}

/* True if the string is all digits */
static int jsonAllDigits(const char *z, int n){
  int i;
  for(i=0; i<n && sqlite3Isdigit(z[i]); i++){}
  return i==n;
}

/* True if the string is all alphanumerics and underscores */
static int jsonAllAlphanum(const char *z, int n){
  int i;
  for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){}
  return i==n;
}








<
<
<
<
<
<
<







3791
3792
3793
3794
3795
3796
3797







3798
3799
3800
3801
3802
3803
3804
  if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){
    cnt = jsonbArrayCount(p, i);
  }
  if( !eErr ) sqlite3_result_int64(ctx, cnt);
  jsonParseFree(p);
}








/* True if the string is all alphanumerics and underscores */
static int jsonAllAlphanum(const char *z, int n){
  int i;
  for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){}
  return i==n;
}

3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
      ** convenience.
      **
      **     NUMBER   ==>  $[NUMBER]     // PG compatible
      **     LABEL    ==>  $.LABEL       // PG compatible
      **     [NUMBER] ==>  $[NUMBER]     // Not PG.  Purely for convenience
      */
      jsonStringInit(&jx, ctx);
      if( jsonAllDigits(zPath, nPath) ){
        jsonAppendRawNZ(&jx, "[", 1);
        jsonAppendRaw(&jx, zPath, nPath);
        jsonAppendRawNZ(&jx, "]", 2);
      }else if( jsonAllAlphanum(zPath, nPath) ){
        jsonAppendRawNZ(&jx, ".", 1);
        jsonAppendRaw(&jx, zPath, nPath);
      }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){







|







3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
      ** convenience.
      **
      **     NUMBER   ==>  $[NUMBER]     // PG compatible
      **     LABEL    ==>  $.LABEL       // PG compatible
      **     [NUMBER] ==>  $[NUMBER]     // Not PG.  Purely for convenience
      */
      jsonStringInit(&jx, ctx);
      if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){
        jsonAppendRawNZ(&jx, "[", 1);
        jsonAppendRaw(&jx, zPath, nPath);
        jsonAppendRawNZ(&jx, "]", 2);
      }else if( jsonAllAlphanum(zPath, nPath) ){
        jsonAppendRawNZ(&jx, ".", 1);
        jsonAppendRaw(&jx, zPath, nPath);
      }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){

Changes to test/json102.test.

759
760
761
762
763
764
765































766
767
} {ok 2023-08-03 876 5 {{"x":77}}}
do_execsql_test json102-1720 {
  UPDATE t1 SET memo = JSON_SET(memo, '$.y', 6)
    WHERE a2 IN (876) AND JSON_TYPE(memo, '$.y') IS NULL;
  PRAGMA integrity_check;
  SELECT * FROM t1;
} {ok 2023-08-03 876 5 {{"x":77,"y":6}}}
































finish_test







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


759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
} {ok 2023-08-03 876 5 {{"x":77}}}
do_execsql_test json102-1720 {
  UPDATE t1 SET memo = JSON_SET(memo, '$.y', 6)
    WHERE a2 IN (876) AND JSON_TYPE(memo, '$.y') IS NULL;
  PRAGMA integrity_check;
  SELECT * FROM t1;
} {ok 2023-08-03 876 5 {{"x":77,"y":6}}}

# 2024-05-21 https://sqlite.org/forum/forumpost/9e52cdfe15c3926e
# What if the RHS of the -> or ->> operator is a string that looks
# like a number?  PostgreSQL treats it as a string.
#
do_execsql_test json102-1800 {
  SELECT '{"1":"one","2":"two","3":"three"}'->>'2';
} two
db null NULL
do_execsql_test json102-1801 {
  SELECT '{"1":"one","2":"two","3":"three"}'->>2;
} NULL
do_execsql_test json102-1810 {
  SELECT '["zero","one","two"]'->>'1';
} NULL
do_execsql_test json102-1811 {
  SELECT '["zero","one","two"]'->>1;
} one
do_execsql_test json102-1820 {
  SELECT '{"1":"one","2":"two","3":"three"}'->'2';
} {{"two"}}
do_execsql_test json102-1821 {
  SELECT '{"1":"one","2":"two","3":"three"}'->2;
} {NULL}
do_execsql_test json102-1830 {
  SELECT '["zero","one","two"]'->'1';
} {NULL}
do_execsql_test json102-1831 {
  SELECT '["zero","one","two"]'->1;
} {{"one"}}


finish_test