Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_dbstat_statBestIndex.c306 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* The target function wrapper provided in the module */7extern int test_statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo);8 9static void initIndexInfo(10  sqlite3_index_info *p,11  sqlite3_index_constraint *aCons, int nCons,12  sqlite3_index_orderby *aOb, int nOb,13  sqlite3_index_constraint_usage *aUsage14){15  memset(p, 0, sizeof(*p));16  p->nConstraint = nCons;17  p->aConstraint = aCons;18  p->aConstraintUsage = aUsage;19  p->nOrderBy = nOb;20  p->aOrderBy = aOb;21  p->idxNum = 0;22  p->idxFlags = 0;23  p->orderByConsumed = 0;24  p->estimatedCost = 0.0;25}26 27void setUp(void) {28  /* Setup code here, or leave empty */29}30 31void tearDown(void) {32  /* Cleanup code here, or leave empty */33}34 35/* Test: No constraints or order by. Check defaults and flags. */36void test_statBestIndex_no_constraints_sets_flags_and_cost(void) {37  sqlite3_index_info idx;38  sqlite3_index_constraint_usage usage[1];39  sqlite3_index_constraint cons[1];40  sqlite3_index_orderby ob[1];41  memset(usage, 0, sizeof(usage));42  memset(cons, 0, sizeof(cons));43  memset(ob, 0, sizeof(ob));44  initIndexInfo(&idx, cons, 0, ob, 0, usage);45 46  int rc = test_statBestIndex(NULL, &idx);47  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);48  TEST_ASSERT_EQUAL_INT(0, idx.idxNum);49  TEST_ASSERT_EQUAL_INT(0, idx.orderByConsumed);50  TEST_ASSERT_EQUAL_DOUBLE(1.0, idx.estimatedCost);51  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);52}53 54/* Test: schema=? usable constraint */55void test_statBestIndex_schema_eq_sets_argvIndex_and_omit_and_idxNum(void) {56  sqlite3_index_info idx;57  sqlite3_index_constraint cons[1];58  sqlite3_index_constraint_usage usage[1];59  sqlite3_index_orderby ob[1];60  memset(usage, 0, sizeof(usage));61  memset(cons, 0, sizeof(cons));62  memset(ob, 0, sizeof(ob));63 64  cons[0].iColumn = 10; /* schema */65  cons[0].op = SQLITE_INDEX_CONSTRAINT_EQ;66  cons[0].usable = 1;67 68  initIndexInfo(&idx, cons, 1, ob, 0, usage);69 70  int rc = test_statBestIndex(NULL, &idx);71  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);72  TEST_ASSERT_EQUAL_INT(1, idx.aConstraintUsage[0].argvIndex);73  TEST_ASSERT_EQUAL_INT(1, idx.aConstraintUsage[0].omit);74  TEST_ASSERT_TRUE((idx.idxNum & 0x01) != 0);75  TEST_ASSERT_EQUAL_DOUBLE(1.0, idx.estimatedCost);76  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);77}78 79/* Test: schema=? and name=? constraints, regardless of array order */80void test_statBestIndex_schema_and_name_ordering(void) {81  sqlite3_index_info idx;82  sqlite3_index_constraint cons[2];83  sqlite3_index_constraint_usage usage[2];84  sqlite3_index_orderby ob[1];85  memset(usage, 0, sizeof(usage));86  memset(cons, 0, sizeof(cons));87  memset(ob, 0, sizeof(ob));88 89  /* Put name first then schema to ensure function still orders argvIndex90     as schema=1, name=2 */91  cons[0].iColumn = 0;  /* name */92  cons[0].op = SQLITE_INDEX_CONSTRAINT_EQ;93  cons[0].usable = 1;94 95  cons[1].iColumn = 10; /* schema */96  cons[1].op = SQLITE_INDEX_CONSTRAINT_EQ;97  cons[1].usable = 1;98 99  initIndexInfo(&idx, cons, 2, ob, 0, usage);100 101  int rc = test_statBestIndex(NULL, &idx);102  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);103 104  TEST_ASSERT_EQUAL_INT(2, idx.aConstraintUsage[0].argvIndex); /* name gets 2 */105  TEST_ASSERT_EQUAL_INT(0, idx.aConstraintUsage[0].omit);106 107  TEST_ASSERT_EQUAL_INT(1, idx.aConstraintUsage[1].argvIndex); /* schema gets 1 */108  TEST_ASSERT_EQUAL_INT(1, idx.aConstraintUsage[1].omit);109 110  TEST_ASSERT_TRUE((idx.idxNum & 0x01) != 0); /* schema bit */111  TEST_ASSERT_TRUE((idx.idxNum & 0x02) != 0); /* name bit */112  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);113}114 115/* Test: All three constraints: schema, name, aggregate */116void test_statBestIndex_all_three_constraints(void) {117  sqlite3_index_info idx;118  sqlite3_index_constraint cons[3];119  sqlite3_index_constraint_usage usage[3];120  sqlite3_index_orderby ob[1];121  memset(usage, 0, sizeof(usage));122  memset(cons, 0, sizeof(cons));123  memset(ob, 0, sizeof(ob));124 125  cons[0].iColumn = 11; /* aggregate */126  cons[0].op = SQLITE_INDEX_CONSTRAINT_EQ;127  cons[0].usable = 1;128 129  cons[1].iColumn = 0;  /* name */130  cons[1].op = SQLITE_INDEX_CONSTRAINT_EQ;131  cons[1].usable = 1;132 133  cons[2].iColumn = 10; /* schema */134  cons[2].op = SQLITE_INDEX_CONSTRAINT_EQ;135  cons[2].usable = 1;136 137  initIndexInfo(&idx, cons, 3, ob, 0, usage);138 139  int rc = test_statBestIndex(NULL, &idx);140  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);141 142  /* argvIndex assignment order: schema=1, name=2, aggregate=3 */143  TEST_ASSERT_EQUAL_INT(3, idx.aConstraintUsage[0].argvIndex); /* aggregate */144  TEST_ASSERT_EQUAL_INT(0, idx.aConstraintUsage[0].omit);145 146  TEST_ASSERT_EQUAL_INT(2, idx.aConstraintUsage[1].argvIndex); /* name */147  TEST_ASSERT_EQUAL_INT(0, idx.aConstraintUsage[1].omit);148 149  TEST_ASSERT_EQUAL_INT(1, idx.aConstraintUsage[2].argvIndex); /* schema */150  TEST_ASSERT_EQUAL_INT(1, idx.aConstraintUsage[2].omit);151 152  TEST_ASSERT_TRUE((idx.idxNum & 0x01) != 0);153  TEST_ASSERT_TRUE((idx.idxNum & 0x02) != 0);154  TEST_ASSERT_TRUE((idx.idxNum & 0x04) != 0);155  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);156}157 158/* Test: Unusable EQ constraint causes SQLITE_CONSTRAINT early return */159void test_statBestIndex_unusable_eq_causes_SQLITE_CONSTRAINT(void) {160  sqlite3_index_info idx;161  sqlite3_index_constraint cons[1];162  sqlite3_index_constraint_usage usage[1];163  sqlite3_index_orderby ob[1];164  memset(usage, 0, sizeof(usage));165  memset(cons, 0, sizeof(cons));166  memset(ob, 0, sizeof(ob));167 168  cons[0].iColumn = 0;  /* name */169  cons[0].op = SQLITE_INDEX_CONSTRAINT_EQ;170  cons[0].usable = 0;   /* unusable */171 172  initIndexInfo(&idx, cons, 1, ob, 0, usage);173 174  int rc = test_statBestIndex(NULL, &idx);175  TEST_ASSERT_EQUAL_INT(SQLITE_CONSTRAINT, rc);176}177 178/* Test: ORDER BY name ASC is consumed and sets bit 0x08 */179void test_statBestIndex_orderBy_consumed_one_column(void) {180  sqlite3_index_info idx;181  sqlite3_index_constraint cons[1];182  sqlite3_index_constraint_usage usage[1];183  sqlite3_index_orderby ob[1];184  memset(usage, 0, sizeof(usage));185  memset(cons, 0, sizeof(cons));186  memset(ob, 0, sizeof(ob));187 188  ob[0].iColumn = 0; /* name */189  ob[0].desc = 0;    /* ASC */190 191  initIndexInfo(&idx, cons, 0, ob, 1, usage);192 193  int rc = test_statBestIndex(NULL, &idx);194  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);195  TEST_ASSERT_EQUAL_INT(1, idx.orderByConsumed);196  TEST_ASSERT_TRUE((idx.idxNum & 0x08) != 0);197  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);198}199 200/* Test: ORDER BY name ASC, path ASC is consumed and sets bit 0x08 */201void test_statBestIndex_orderBy_consumed_two_columns(void) {202  sqlite3_index_info idx;203  sqlite3_index_constraint cons[1];204  sqlite3_index_constraint_usage usage[1];205  sqlite3_index_orderby ob[2];206  memset(usage, 0, sizeof(usage));207  memset(cons, 0, sizeof(cons));208  memset(ob, 0, sizeof(ob));209 210  ob[0].iColumn = 0; /* name */211  ob[0].desc = 0;    /* ASC */212  ob[1].iColumn = 1; /* path */213  ob[1].desc = 0;    /* ASC */214 215  initIndexInfo(&idx, cons, 0, ob, 2, usage);216 217  int rc = test_statBestIndex(NULL, &idx);218  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);219  TEST_ASSERT_EQUAL_INT(1, idx.orderByConsumed);220  TEST_ASSERT_TRUE((idx.idxNum & 0x08) != 0);221  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);222}223 224/* Test: ORDER BY name DESC is not consumed */225void test_statBestIndex_orderBy_not_consumed_desc(void) {226  sqlite3_index_info idx;227  sqlite3_index_constraint cons[1];228  sqlite3_index_constraint_usage usage[1];229  sqlite3_index_orderby ob[1];230  memset(usage, 0, sizeof(usage));231  memset(cons, 0, sizeof(cons));232  memset(ob, 0, sizeof(ob));233 234  ob[0].iColumn = 0; /* name */235  ob[0].desc = 1;    /* DESC */236 237  initIndexInfo(&idx, cons, 0, ob, 1, usage);238 239  int rc = test_statBestIndex(NULL, &idx);240  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);241  TEST_ASSERT_EQUAL_INT(0, idx.orderByConsumed);242  TEST_ASSERT_TRUE((idx.idxNum & 0x08) == 0);243  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);244}245 246/* Test: ORDER BY wrong columns is not consumed */247void test_statBestIndex_orderBy_not_consumed_wrong_columns(void) {248  sqlite3_index_info idx;249  sqlite3_index_constraint cons[1];250  sqlite3_index_constraint_usage usage[1];251  sqlite3_index_orderby ob[2];252  memset(usage, 0, sizeof(usage));253  memset(cons, 0, sizeof(cons));254  memset(ob, 0, sizeof(ob));255 256  /* First order by path, not name */257  ob[0].iColumn = 1; /* path */258  ob[0].desc = 0;    /* ASC */259  ob[1].iColumn = 0; /* name */260  ob[1].desc = 0;261 262  initIndexInfo(&idx, cons, 0, ob, 2, usage);263 264  int rc = test_statBestIndex(NULL, &idx);265  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);266  TEST_ASSERT_EQUAL_INT(0, idx.orderByConsumed);267  TEST_ASSERT_TRUE((idx.idxNum & 0x08) == 0);268  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);269}270 271/* Test: Non-EQ unusable constraint should be ignored (no SQLITE_CONSTRAINT) */272void test_statBestIndex_non_eq_unusable_does_not_fail(void) {273  sqlite3_index_info idx;274  sqlite3_index_constraint cons[1];275  sqlite3_index_constraint_usage usage[1];276  sqlite3_index_orderby ob[1];277  memset(usage, 0, sizeof(usage));278  memset(cons, 0, sizeof(cons));279  memset(ob, 0, sizeof(ob));280 281  cons[0].iColumn = 0;  /* name */282  cons[0].op = SQLITE_INDEX_CONSTRAINT_LT; /* not EQ */283  cons[0].usable = 0;   /* unusable but should be ignored */284 285  initIndexInfo(&idx, cons, 1, ob, 0, usage);286 287  int rc = test_statBestIndex(NULL, &idx);288  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);289  TEST_ASSERT_EQUAL_INT(0, idx.idxNum);290  TEST_ASSERT_TRUE((idx.idxFlags & SQLITE_INDEX_SCAN_HEX) != 0);291}292 293int main(void) {294  UNITY_BEGIN();295  RUN_TEST(test_statBestIndex_no_constraints_sets_flags_and_cost);296  RUN_TEST(test_statBestIndex_schema_eq_sets_argvIndex_and_omit_and_idxNum);297  RUN_TEST(test_statBestIndex_schema_and_name_ordering);298  RUN_TEST(test_statBestIndex_all_three_constraints);299  RUN_TEST(test_statBestIndex_unusable_eq_causes_SQLITE_CONSTRAINT);300  RUN_TEST(test_statBestIndex_orderBy_consumed_one_column);301  RUN_TEST(test_statBestIndex_orderBy_consumed_two_columns);302  RUN_TEST(test_statBestIndex_orderBy_not_consumed_desc);303  RUN_TEST(test_statBestIndex_orderBy_not_consumed_wrong_columns);304  RUN_TEST(test_statBestIndex_non_eq_unusable_does_not_fail);305  return UNITY_END();306}