| 783 | } |
| 784 | |
| 785 | static int init(sqlite3 *db, |
| 786 | void *pAux, |
| 787 | int argc, |
| 788 | const char *const *argv, |
| 789 | sqlite3_vtab **ppVtab, |
| 790 | char **pzErr, |
| 791 | bool isCreate) { |
| 792 | |
| 793 | sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); |
| 794 | int rc; |
| 795 | |
| 796 | sqlite3_str *str = sqlite3_str_new(nullptr); |
| 797 | sqlite3_str_appendall(str, |
| 798 | "create table x(distance hidden, operation hidden"); |
| 799 | |
| 800 | unique_ptr<vector<VssIndexColumn>> columns; |
| 801 | try { |
| 802 | columns = parse_constructor(argc, argv); |
| 803 | } catch (const invalid_argument& e) { |
| 804 | *pzErr = sqlite3_mprintf(e.what()); |
| 805 | return SQLITE_ERROR; |
| 806 | } |
| 807 | |
| 808 | if (columns == nullptr) { |
| 809 | *pzErr = sqlite3_mprintf("Error parsing constructor"); |
| 810 | return rc; |
| 811 | } |
| 812 | |
| 813 | for (auto column = columns->begin(); column != columns->end(); ++column) { |
| 814 | sqlite3_str_appendf(str, ", \"%w\"", column->name.c_str()); |
| 815 | } |
| 816 | |
| 817 | sqlite3_str_appendall(str, ")"); |
| 818 | auto sql = sqlite3_str_finish(str); |
| 819 | rc = sqlite3_declare_vtab(db, sql); |
| 820 | sqlite3_free(sql); |
| 821 | |
| 822 | #define VSS_INDEX_COLUMN_DISTANCE 0 |
| 823 | #define VSS_INDEX_COLUMN_OPERATION 1 |
| 824 | #define VSS_INDEX_COLUMN_VECTORS 2 |
| 825 | |
| 826 | if (rc != SQLITE_OK) |
| 827 | return rc; |
| 828 | |
| 829 | auto pTable = new vss_index_vtab(db, |
| 830 | (vector0_api *)pAux, |
| 831 | sqlite3_mprintf("%s", argv[1]), |
| 832 | sqlite3_mprintf("%s", argv[2])); |
| 833 | *ppVtab = pTable; |
| 834 | |
| 835 | if (isCreate) { |
| 836 | |
| 837 | for (auto iter = columns->begin(); iter != columns->end(); ++iter) { |
| 838 | |
| 839 | try { |
| 840 | |
| 841 | auto index = faiss::index_factory(iter->dimensions, iter->factory.c_str(), iter->metric); |
| 842 | pTable->indexes.push_back(new vss_index(index)); |
no test coverage detected