# 2024 Sep 27
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    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 script is testing the FTS5 module.
#

source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5update2

# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
  finish_test
  return
}


#-------------------------------------------------------------------------
# Test that the various types of UPDATE statement are handled correctly
# by different table types.
#
foreach_detail_mode $testprefix {
foreach {tn cu} {
  1 0
  2 1
} {
  reset_db
  do_execsql_test 1.$tn.1 "
    CREATE VIRTUAL TABLE ft1 USING fts5(a, b UNINDEXED, c UNINDEXED, d,
        content='',
        contentless_unindexed=$cu,
        detail=%DETAIL%
    );
    CREATE VIRTUAL TABLE ft2 USING fts5(a, b UNINDEXED, c UNINDEXED, d,
        content='',
        contentless_unindexed=$cu, contentless_delete=1,
        detail=%DETAIL%
    );
  "

  do_execsql_test 1.$tn.2 {
    INSERT INTO ft1(rowid, a, b, c, d) VALUES(1, 'a1', 'b1', 'c1', 'd1');
    INSERT INTO ft1(rowid, a, b, c, d) VALUES(2, 'a2', 'b2', 'c2', 'd2');
    INSERT INTO ft1(rowid, a, b, c, d) VALUES(3, 'a3', 'b3', 'c3', 'd3');

    INSERT INTO ft2(rowid, a, b, c, d) VALUES(1, 'a1', 'b1', 'c1', 'd1');
    INSERT INTO ft2(rowid, a, b, c, d) VALUES(2, 'a2', 'b2', 'c2', 'd2');
    INSERT INTO ft2(rowid, a, b, c, d) VALUES(3, 'a3', 'b3', 'c3', 'd3');
  }

  # It should be possible to update a subset of the UNINDEXED columns of
  # a contentless table. Regardless of whether or not contentless_unindexed=1
  # or contentless_delete=1 is set.
  do_execsql_test 1.$tn.3 {
    UPDATE ft1 SET b=b||'.1';
    UPDATE ft2 SET b=b||'.1';
  }
  do_execsql_test 1.$tn.4 {
    UPDATE ft1 SET b=b||'.2', c=c||'.2';
    UPDATE ft2 SET b=b||'.2', c=c||'.2';
  }

  set res(0) {
    1 {} {} {} {}
    2 {} {} {} {}
    3 {} {} {} {}
  }
  set res(1) {
    1 {} b1.1.2 c1.2 {}
    2 {} b2.1.2 c2.2 {}
    3 {} b3.1.2 c3.2 {}
  }

  do_execsql_test 1.$tn.5 {
    SELECT rowid, * FROM ft2
  } $res($cu)

  do_execsql_test 1.6.1 { SELECT rowid FROM ft1('a2') } {2}
  do_execsql_test 1.6.2 { SELECT rowid FROM ft2('a2') } {2}

  # It should be possible to update all indexed columns (but no other subset)
  # if the contentless_delete=1 option is set, as it is for "ft2".
  do_execsql_test 1.$tn.7 {
    UPDATE ft2 SET a='a22', d='d22' WHERE rowid=2;
  }
  do_execsql_test 1.$tn.8 { SELECT rowid FROM ft2('a22 AND d22') } {2}

  do_execsql_test 1.$tn.9 {
    UPDATE ft2 SET a='a33', d='d33', b='b3' WHERE rowid=3;
  }

  set res(1) {
    1 {} b1.1.2 c1.2 {}
    2 {} b2.1.2 c2.2 {}
    3 {} b3 c3.2 {}
  }
  do_execsql_test 1.$tn.10 {
    SELECT rowid, * FROM ft2
  } $res($cu)

  do_catchsql_test 1.$tn.11 {
    UPDATE ft2 SET a='a11' WHERE rowid=1
  } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}}
  do_catchsql_test 1.$tn.12 {
    UPDATE ft2 SET d='d11' WHERE rowid=1
  } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}}

  # It is not possible to update the values of indexed columns if
  # contentless_delete=1 is not set.
  do_catchsql_test 1.$tn.13 {
    UPDATE ft1 SET a='a11' WHERE rowid=1
  } {1 {cannot UPDATE contentless fts5 table: ft1}}
  do_catchsql_test 1.$tn.14 {
    UPDATE ft1 SET d='d11' WHERE rowid=1
  } {1 {cannot UPDATE contentless fts5 table: ft1}}

  # It should be possible to update the rowid if contentless_delete=1 is
  # set and all indexed columns are updated.
  do_execsql_test 1.$tn.15 {
    UPDATE ft2 SET a='aXone', d='dXone', rowid=11 WHERE rowid=1
  } 

  set res(0) {
    2 {} {} {} {}
    3 {} {} {} {}
    11 {} {} {} {}
  }
  set res(1) {
    2 {} b2.1.2 c2.2 {}
    3 {} b3 c3.2 {}
    11 {} b1.1.2 c1.2 {}
  }
  do_execsql_test 1.$tn.16 {
    SELECT rowid, * FROM ft2
  } $res($cu)

  # Should not be possible to update the rowid of a contentless_delete=1
  # table if no indexed columns are updated.
  do_catchsql_test 1.$tn.17 {
    UPDATE ft2 SET rowid=12 WHERE rowid=11
  } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}}
  do_catchsql_test 1.$tn.18 {
    UPDATE ft1 SET rowid=12 WHERE rowid=1
  } {1 {cannot UPDATE contentless fts5 table: ft1}}

  do_execsql_test 1.$tn.19 {
    UPDATE ft2 SET a='aXtwo', d='dXtwo', c='newval', rowid=12 WHERE rowid=2
  }  {}

  set res(0) {
    3 {} {} {} {}
    11 {} {} {} {}
    12 {} {} {} {}
  }
  set res(1) {
    3 {} b3 c3.2 {}
    11 {} b1.1.2 c1.2 {}
    12 {} b2.1.2 newval {}
  }
  do_execsql_test 1.$tn.20 {
    SELECT rowid, * FROM ft2
  } $res($cu)

  do_execsql_test 1.$tn.21 {
    SELECT rowid, * FROM ft2('aXtwo AND dXtwo')
  } [lrange $res($cu) 10 end]

}} ;# end of [foreach_detail_mode] loop

finish_test
