{"id":17856059,"url":"https://github.com/0x09/sqlite-statement-vtab","last_synced_at":"2026-02-25T10:50:52.490Z","repository":{"id":47644041,"uuid":"221619885","full_name":"0x09/sqlite-statement-vtab","owner":"0x09","description":"SQLite module to define virtual tables and table-valued functions natively using SQL.","archived":false,"fork":false,"pushed_at":"2024-08-19T23:56:00.000Z","size":46,"stargazers_count":28,"open_issues_count":1,"forks_count":6,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-10-28T05:33:01.612Z","etag":null,"topics":["sqlite","virtual-tables"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0x09.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-14T05:35:49.000Z","updated_at":"2024-08-19T23:56:05.000Z","dependencies_parsed_at":"2024-08-16T22:57:51.761Z","dependency_job_id":"3f32e84c-d3b6-4a84-98c3-7859014910ae","html_url":"https://github.com/0x09/sqlite-statement-vtab","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x09%2Fsqlite-statement-vtab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x09%2Fsqlite-statement-vtab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x09%2Fsqlite-statement-vtab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x09%2Fsqlite-statement-vtab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0x09","download_url":"https://codeload.github.com/0x09/sqlite-statement-vtab/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244630050,"owners_count":20484306,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sqlite","virtual-tables"],"created_at":"2024-10-28T03:00:45.802Z","updated_at":"2026-02-25T10:50:52.431Z","avatar_url":"https://github.com/0x09.png","language":"C","readme":"SQLite module to define virtual tables and table-valued functions natively using SQL.\n\nstatement_vtab is particularly handy as an interface for deriving multiple outputs from built-in or user-defined functions without the need to create a specialized module.\n\n# Example\nExample which dynamically creates a virtual table `split_date` that uses the built-in `strftime` function to extract year, month, and day from a date input into columns:\n```SQL\n.load statement_vtab\n\n-- define a virtual table with columns \"year\", \"month\", \"day\", and hidden column \"date\" for input\nCREATE VIRTUAL TABLE split_date USING statement((\n  SELECT\n    strftime('%Y', :date) AS year,\n    strftime('%m', :date) AS month,\n    strftime('%d', :date) AS day\n));\n\n-- split_date can be used as a table-valued function\nSELECT * FROM split_date('2019-11-13');\nyear        month       day       \n----------  ----------  ----------\n2019        11          13        \n\n-- or as a regular virtual table if the arguments are provided as equal constraints\nSELECT * FROM split_date WHERE date = '2019-11-13';\nyear        month       day       \n----------  ----------  ----------\n2019        11          13        \n\n-- when used with an \"in\" clause, yields multiple rows from one statement\nSELECT * FROM split_date WHERE date IN('2019-11-13','2020-11-13','2021-11-13');\nyear        month       day       \n----------  ----------  ----------\n2019        11          13        \n2020        11          13        \n2021        11          13        \n\n-- apply split_date to values from some other table\nCREATE TABLE dates (date TEXT);\nINSERT INTO dates VALUES('2019-11-13'), ('2020-11-13'), ('2021-11-13');\n\n-- as a table-valued function\nSELECT * FROM dates, split_date(dates.date);\ndate        year        month       day       \n----------  ----------  ----------  ----------\n2019-11-13  2019        11          13        \n2020-11-13  2020        11          13        \n2021-11-13  2021        11          13        \n\n-- equivalently using the usual table syntax\nSELECT * FROM dates INNER JOIN split_date ON split_date.date = dates.date;\ndate        year        month       day       \n----------  ----------  ----------  ----------\n2019-11-13  2019        11          13        \n2020-11-13  2020        11          13        \n2021-11-13  2021        11          13        \n-- (in this case a natural join would work just as well)\n```\n\n# Syntax\n`CREATE VIRTUAL TABLE tablename USING statement((stmt))`\n\nWhere `stmt` may be any select statement supported by SQLite: https://www.sqlite.org/lang_select.html\n\n## Column definitions\nColumns defined by the provided statement become columns in the resulting virtual table:\n```SQL\nCREATE VIRTUAL TABLE abc USING statement((select 1 as a, 2 as b, 3 as c));\n\nSELECT * FROM abc;\na           b           c         \n----------  ----------  ----------\n1           2           3         \n```\nThis extends to other (virtual) tables as well. Using the built in [dbstat](https://www.sqlite.org/dbstat.html) virtual table as an example, we can reproduce its columns with:\n```SQL\nCREATE VIRTUAL TABLE another_dbstat USING statement((SELECT * FROM dbstat));\n\nSELECT * FROM another_dbstat;\nname           path        pageno      pagetype    ncell       payload     unused      mx_payload  pgoffset    pgsize    \n-------------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------\nsqlite_master  /           1           leaf        2           206         3774        115         0           4096      \n```\nAnd in this case the declared type affinity of the columns is preserved as well.\n\n## Parameter binding\nFor substituting values into the statement, statement_vtab relies on SQLite's parameter binding syntax. Any bound parameter names become hidden columns in the virtual table, and so can be used as arguments to the resulting table-valued function or referenced directly. See https://www.sqlite.org/lang_expr.html#varparam for a detailed description of SQLite's syntax for parameter binding.\n\n### Anonymous params\nUnnamed arguments are indexed by position:\n```SQL\nCREATE VIRTUAL TABLE arguments USING statement((SELECT ? AS a, ? AS b, ? AS c));\n\n-- call with table-valued function syntax\nSELECT * FROM arguments('x','y','z');\na           b           c         \n----------  ----------  ----------\nx           y           z         \n\n-- or using the indexes as column names\nSELECT * from ARGUMENTS WHERE [1] = 'x' AND [2] = 'y' AND [3] = 'z';\na           b           c         \n----------  ----------  ----------\nx           y           z         \n\n```\nNote that this will create a new numbered parameter for each `?`. Unnamed parameters can be referenced multiple times with the ?NNN syntax.\n```SQL\nCREATE VIRTUAL TABLE sumdiff USING statement((SELECT ? + ? AS sum, ?1 - ?2 AS difference));\n\nSELECT * FROM sumdiff(1,3);\nsum         difference\n----------  ----------\n4           -2        \n\n-- Though it's usually better to be explicit and number all params in that case. The following definition of `sumdiff` is equivalent to the first.\nCREATE VIRTUAL TABLE sumdiff USING statement((SELECT ?1 + ?2 AS sum, ?1 - ?2 AS difference));\n```\n\n### Named params\nNamed parameters may be used; these will still be treated positionally when using the table-valued function syntax:\n```SQL\n-- this example uses the `sqrt` function from https://www.sqlite.org/contrib/download/extension-functions.c\nCREATE VIRTUAL TABLE hypot USING statement((SELECT sqrt(:x * :x + :y * :y) AS hypotenuse));\n\n-- call \"hypot\" as a table-valued function\nSELECT * FROM hypot(3,4);\nhypotenuse\n----------\n5.0       \n\n-- or by referencing the named parameter columns \"x\" and \"y\" directly\nSELECT * FROM hypot WHERE x = 3 AND y = 4;\nhypotenuse\n----------\n5.0       \n\n-- though inputs will be suppressed from *, we can ask for these explicitly\nSELECT x, y, * FROM hypot(3,4);\nx           y           hypotenuse\n----------  ----------  ----------\n3           4           5.0       \n\nSELECT x, y, * FROM hypot WHERE x = 3 AND y = 4;\nx           y           hypotenuse\n----------  ----------  ----------\n3           4           5.0       \n```\n\nAny parameters not provided when querying the resulting vtab are treated as NULLs. The `coalesce`/`ifnull` SQL functions can thus be used to supply argument defaults, though note that this vtab does not attempt to differentiate between an argument that was simply omitted vs one that was explicitly provided as NULL.\n","funding_links":[],"categories":["Extensions"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0x09%2Fsqlite-statement-vtab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0x09%2Fsqlite-statement-vtab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0x09%2Fsqlite-statement-vtab/lists"}