|
32 | 32 | #include "microprotocols.h" |
33 | 33 | #include "row.h" |
34 | 34 | #include "blob.h" |
| 35 | +#include "util.h" |
35 | 36 |
|
36 | 37 | #if SQLITE_VERSION_NUMBER < 3015002 |
37 | 38 | #error "SQLite 3.15.2 or higher required" |
@@ -405,51 +406,39 @@ pysqlite_error_name(int rc) |
405 | 406 | } |
406 | 407 |
|
407 | 408 | static int |
408 | | -add_sequence_constants(PyObject *module) |
| 409 | +add_keyword_tuple(PyObject *module) |
409 | 410 | { |
410 | | - PyObject *kwd; |
411 | | - const char *_keywords[] = { |
412 | | - "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ALWAYS", "ANALYZE", |
413 | | - "AND", "AS", "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", |
414 | | - "BETWEEN", "BY", "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", |
415 | | - "COLUMN", "COMMIT", "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", |
416 | | - "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", |
417 | | - "DATABASE", "DEFAULT", "DEFERRABLE", "DEFERRED", "DELETE", "DESC", |
418 | | - "DETACH", "DISTINCT", "DO", "DROP", "EACH", "ELSE", "END", "ESCAPE", |
419 | | - "EXCEPT", "EXCLUDE", "EXCLUSIVE", "EXISTS", "EXPLAIN", "FAIL", |
420 | | - "FILTER", "FIRST", "FOLLOWING", "FOR", "FOREIGN", "FROM", "FULL", |
421 | | - "GENERATED", "GLOB", "GROUP", "GROUPS", "HAVING", "IF", "IGNORE", |
422 | | - "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", "INSERT", |
423 | | - "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", "LAST", |
424 | | - "LEFT", "LIKE", "LIMIT", "MATCH", "MATERIALIZED", "NATURAL", "NO", |
425 | | - "NOT", "NOTHING", "NOTNULL", "NULL", "NULLS", "OF", "OFFSET", "ON", |
426 | | - "OR", "ORDER", "OTHERS", "OUTER", "OVER", "PARTITION", "PLAN", |
427 | | - "PRAGMA", "PRECEDING", "PRIMARY", "QUERY", "RAISE", "RANGE", |
428 | | - "RECURSIVE", "REFERENCES", "REGEXP", "REINDEX", "RELEASE", "RENAME", |
429 | | - "REPLACE", "RESTRICT", "RETURNING", "RIGHT", "ROLLBACK", "ROW", "ROWS", |
430 | | - "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", "TEMPORARY", "THEN", |
431 | | - "TIES", "TO", "TRANSACTION", "TRIGGER", "UNBOUNDED", "UNION", "UNIQUE", |
432 | | - "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", |
433 | | - "WHERE", "WINDOW", "WITH", "WITHOUT", NULL |
434 | | - }; |
435 | | - PyObject *keywords = PyTuple_New(147); |
436 | | - |
| 411 | + int count = sqlite3_keyword_count(); |
| 412 | + PyObject *keywords = PyTuple_New(count); |
437 | 413 | if (keywords == NULL) { |
438 | | - return -1; |
| 414 | + goto error; |
439 | 415 | } |
440 | | - for (int i = 0; _keywords[i] != NULL; i++) { |
441 | | - kwd = PyUnicode_FromString(_keywords[i]); |
442 | | - if (PyTuple_SetItem(keywords, i, kwd) != 0) { |
| 416 | + for (int i = 0; i < count; i++) { |
| 417 | + const char *keyword; |
| 418 | + int size; |
| 419 | + int result = sqlite3_keyword_name(i, &keyword, &size); |
| 420 | + if (result != SQLITE_OK) { |
| 421 | + pysqlite_state *state = pysqlite_get_state(module); |
| 422 | + set_error_from_code(state, result); |
| 423 | + goto error; |
| 424 | + } |
| 425 | + PyObject *kwd = PyUnicode_FromStringAndSize(keyword, size); |
| 426 | + if (!kwd) { |
| 427 | + goto error; |
| 428 | + } |
| 429 | + if (PyTuple_SetItem(keywords, i, kwd) < 0) { |
443 | 430 | Py_DECREF(kwd); |
444 | | - Py_DECREF(keywords); |
445 | | - return -1; |
| 431 | + goto error; |
446 | 432 | } |
447 | 433 | } |
448 | 434 | if (PyModule_Add(module, "SQLITE_KEYWORDS", keywords) < 0) { |
449 | | - Py_DECREF(keywords); |
450 | | - return -1; |
| 435 | + goto error; |
451 | 436 | } |
452 | 437 | return 0; |
| 438 | + |
| 439 | +error: |
| 440 | + Py_XDECREF(keywords); |
| 441 | + return -1; |
453 | 442 | } |
454 | 443 |
|
455 | 444 | static int |
@@ -750,8 +739,8 @@ module_exec(PyObject *module) |
750 | 739 | goto error; |
751 | 740 | } |
752 | 741 |
|
753 | | - /* Set sequence constants */ |
754 | | - if (add_sequence_constants(module) < 0) { |
| 742 | + /* Set the keyword tuple */ |
| 743 | + if (add_keyword_tuple(module) < 0) { |
755 | 744 | goto error; |
756 | 745 | } |
757 | 746 |
|
|
0 commit comments