Skip to content

Instantly share code, notes, and snippets.

@LalitMaganti
Last active July 20, 2020 11:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LalitMaganti/41a1b569480e99b712833c66b0cf4f04 to your computer and use it in GitHub Desktop.
Save LalitMaganti/41a1b569480e99b712833c66b0cf4f04 to your computer and use it in GitHub Desktop.
// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Cursor {
sqlite3_vtab_cursor c;
int index;
} Cursor;
int create(sqlite3* xdb, void* x, int y, const char* const* z, sqlite3_vtab** v,
char** a) {
sqlite3_declare_vtab(xdb, "CREATE TABLE x(ts INT, dur INT);");
*v = malloc(sizeof(sqlite3_vtab));
return SQLITE_OK;
}
int destroy(sqlite3_vtab* v) {
free(v);
return SQLITE_OK;
}
int open(sqlite3_vtab* v, sqlite3_vtab_cursor** c) {
*c = malloc(sizeof(Cursor));
memset(*c, 0, sizeof(Cursor));
return SQLITE_OK;
}
int bestindex(sqlite3_vtab* v, sqlite3_index_info* i) {
int c = 0;
for (int j = 0; j < i->nConstraint; ++j) {
if (i->aConstraint[j].usable) i->aConstraintUsage[j].argvIndex = ++c;
}
i->orderByConsumed = 1;
return SQLITE_OK;
}
int filter(sqlite3_vtab_cursor* c, int x, const char* y, int z,
sqlite3_value** v) {
return SQLITE_OK;
}
int close(sqlite3_vtab_cursor* c) {
free(c);
return SQLITE_OK;
}
int next(sqlite3_vtab_cursor* c) {
((Cursor*)c)->index++;
return SQLITE_OK;
}
int eof(sqlite3_vtab_cursor* c) { return ((Cursor*)c)->index >= 100; }
int column(sqlite3_vtab_cursor* c, sqlite3_context* a, int col) {
if (col == 0) {
sqlite3_result_int64(a, ((Cursor*)c)->index * 1e8);
} else {
sqlite3_result_int64(a, ((Cursor*)c)->index);
}
return SQLITE_OK;
}
int callback(void* noop, int c, char** col, char** name) {
for (int i = 0; i < c; ++i) printf("%s ", col[i]);
printf("\n");
return SQLITE_OK;
}
void MonotoneFn(sqlite3_context* a, int argc, sqlite3_value** argv) {
sqlite3_result_int64(a, sqlite3_value_int(argv[0]) / ((int64_t)1e9));
}
void run_query(sqlite3* db, const char* query) {
char* err;
printf("%s\n", query);
sqlite3_exec(db, query, &callback, NULL, &err);
printf("\n");
}
int main(int argc, char** argv) {
sqlite3* db = NULL;
sqlite3_initialize();
sqlite3_open(":memory:", &db);
sqlite3_module* module = malloc(sizeof(sqlite3_module));
memset(module, 0, sizeof(*module));
module->xCreate = &create;
module->xConnect = &create;
module->xDisconnect = &destroy;
module->xDestroy = &destroy;
module->xOpen = &open;
module->xClose = &close;
module->xBestIndex = &bestindex;
module->xFilter = &filter;
module->xNext = &next;
module->xEof = &eof;
module->xColumn = &column;
sqlite3_create_function_v2(db, "quantize", 1,
SQLITE_DETERMINISTIC | SQLITE_UTF8, NULL,
&MonotoneFn, NULL, NULL, NULL);
sqlite3_create_module_v2(db, "event", module, NULL, NULL);
run_query(db, "EXPLAIN QUERY PLAN SELECT ts FROM event GROUP BY 1");
run_query(
db,
"EXPLAIN QUERY PLAN SELECT quantize(ts), max(dur) FROM event GROUP BY 1");
run_query(db,
"EXPLAIN QUERY PLAN SELECT ts / CAST(1e9 AS int), max(dur) FROM "
"event GROUP BY 1");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment