From 83e84b6917779983ac8cdeeaa9a1e35bddf68a1e Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 17 Jan 2025 13:43:52 -0700 Subject: [PATCH] write to stdout instead of db file columns all have TEXT type, so sorting by numerical columns requires casting --- src/gufi_vt.c | 279 +++++++++++++++---------------- test/regression/gufi_vt.expected | 50 ++---- test/regression/gufi_vt.sh.in | 27 +-- 3 files changed, 148 insertions(+), 208 deletions(-) diff --git a/src/gufi_vt.c b/src/gufi_vt.c index d7e1c0c1b..e6ebbd430 100644 --- a/src/gufi_vt.c +++ b/src/gufi_vt.c @@ -144,6 +144,8 @@ static int addvtfuncs(sqlite3 *db) { ); } +#define delim "|" /* record separator */ + typedef struct gufi_query_sql { const char *I; const char *T; @@ -162,28 +164,10 @@ typedef struct gufi_query_sql { * everything to link dynamically */ static int gufi_query_aggregate_db(const char *indexroot, const char *threads, const gq_sql_t *sql, - const char *prefix, char **outdb, char **errmsg) { - /* allow for aggregate databases to be placed anywhere */ - const size_t outdb_len = (prefix?strlen(prefix):0) + 15; - *outdb = sqlite3_malloc(outdb_len + 1); - if (prefix) { - snprintf(*outdb, outdb_len + 1, "%s/gufi_vt.XXXXXX", prefix); - } - else { - snprintf(*outdb, outdb_len + 1, "gufi_vt.XXXXXX"); - } - - const int fd = mkstemp(*outdb); - if (fd < 0) { - const int err = errno; - *errmsg = sqlite3_mprintf("mkstemp('%s') failed: %s (%d)", *outdb, strerror(err), err); - goto error; - } - close(fd); - + FILE **output, char **errmsg) { const char *argv[23] = { "gufi_query", - "-O", *outdb, + "-d", delim, }; #define set_argv(argc, argv, flag, value) if (value) { argv[argc++] = flag; argv[argc++] = value; } @@ -202,48 +186,30 @@ static int gufi_query_aggregate_db(const char *indexroot, const char *threads, c argv[argc++] = indexroot; argv[argc] = NULL; - const pid_t pid = fork(); - if (pid == -1) { - const int err = errno; - *errmsg = sqlite3_mprintf("Failed to fork: %s (%d)", strerror(err), err); - goto error; + size_t len = 0; + for(int i = 0; i < argc; i++) { + len += strlen(argv[i]) + 3; /* + 2 for quotes around each argument + 1 for space between args */ } - /* child */ - if (pid == 0) { - /* using execvp to allow for gufi_query executable to be selected by PATH */ - const int rc = execvp("gufi_query", (char * const *) argv); - if (rc != 0) { - const int err = errno; - fprintf(stderr, "Failed to start gufi_query: %s (%d)\n", strerror(err), err); - sqlite3_free(*outdb); - *outdb = NULL; - exit(EXIT_FAILURE); /* child needs to exit here and now */ - } - /* can't get here */ + /* convert array of args to single string */ + char *cmd = malloc(len + 1); + char *curr = cmd; + for(int i = 0; i < argc; i++) { + /* FIXME: this should use single quotes to avoid potentially processing variables, but needs to be double quotes to handle strings in SQLite properly */ + curr += snprintf(curr, len + 1 - (curr - cmd), "\"%s\" ", argv[i]); } - /* parent */ - int status = EXIT_SUCCESS; - const int rc = waitpid(pid, &status, 0); - if (rc != pid) { + /* pass command to popen */ + FILE *out = popen(cmd, "re"); + if (!out) { const int err = errno; - *errmsg = sqlite3_mprintf("Failed to wait for gufi_query: %s (%d)\n", strerror(err), err); - goto error; + *errmsg = sqlite3_mprintf("popen failed: %s (%d)", strerror(err), err); + return SQLITE_ERROR; } - if (status != EXIT_SUCCESS) { - *errmsg = sqlite3_mprintf("gufi_query returned error: %d\n", status); - goto error; - } + *output = out; return SQLITE_OK; - - error: - remove(*outdb); /* not checking for error */ - sqlite3_free(*outdb); - *outdb = NULL; - return SQLITE_ERROR; } typedef struct gufi_vtab { @@ -258,10 +224,12 @@ typedef struct gufi_vtab { typedef struct gufi_vtab_cursor { sqlite3_vtab_cursor base; - sqlite3 *db; /* the aggregated results database file */ - sqlite3_stmt *stmt; /* compiled SQL pulling from aggregate database */ + + FILE *output; /* result of popen */ + char *row; /* current row */ + ssize_t len; /* length of current row */ + sqlite_int64 rowid; /* current row id */ - int res; /* previous sqlite3_step return code */ } gufi_vtab_cursor; /* generic connect function */ @@ -292,15 +260,14 @@ static int gufi_vtConnect(sqlite3 *db, /* positional arguments to virtual table/table-valued function */ #define GUFI_VT_COLUMN_INDEXROOT 0 #define GUFI_VT_COLUMN_THREADS 1 -#define GUFI_VT_COLUMN_OUTPUT_PREFIX 2 -#define GUFI_VT_COLUMN_I 3 -#define GUFI_VT_COLUMN_T 4 -#define GUFI_VT_COLUMN_S 5 -#define GUFI_VT_COLUMN_E 6 -#define GUFI_VT_COLUMN_K 7 -#define GUFI_VT_COLUMN_J 8 -#define GUFI_VT_COLUMN_G 9 -#define GUFI_VT_COLUMN_F 10 +#define GUFI_VT_COLUMN_I 2 +#define GUFI_VT_COLUMN_T 3 +#define GUFI_VT_COLUMN_S 4 +#define GUFI_VT_COLUMN_E 5 +#define GUFI_VT_COLUMN_K 6 +#define GUFI_VT_COLUMN_J 7 +#define GUFI_VT_COLUMN_G 8 +#define GUFI_VT_COLUMN_F 9 #define GUFI_VT_HIDDEN_COLUMNS ", indexroot TEXT HIDDEN, threads INT64 HIDDEN, output_prefix TEXT HIDDEN" \ ", I TEXT HIDDEN" \ @@ -320,8 +287,9 @@ static int gufi_vtConnect(sqlite3 *db, #define INTERMEDIATE "intermediate" #define AGGREGATE "aggregate" -#define SELECT_FROM(name, extra) ("INSERT INTO " INTERMEDIATE " SELECT * FROM " name ";" extra) -#define INSERT_AGG ("INSERT INTO " AGGREGATE " SELECT * FROM " INTERMEDIATE ";") +#define SELECT_FROM(name, extra) ("INSERT INTO " INTERMEDIATE " SELECT * FROM " name ";" extra) +#define INSERT_AGG ("INSERT INTO " AGGREGATE " SELECT * FROM " INTERMEDIATE ";") +#define SELECT_AGG ("SELECT * FROM " AGGREGATE ";") /* generate xConnect function for each virtual table */ #define gufi_vt_XConnect(name, abbrev, t, s, e) \ @@ -342,7 +310,7 @@ static int gufi_vtConnect(sqlite3 *db, .E = e?SELECT_FROM(name, ""):NULL, \ .K = name ##_SCHEMA(AGGREGATE, ""), \ .J = INSERT_AGG, \ - .G = NULL, \ + .G = SELECT_AGG, \ .F = NULL, \ }; \ \ @@ -409,12 +377,8 @@ static int gufi_vtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor) { static int gufi_vtClose(sqlite3_vtab_cursor *cur) { gufi_vtab_cursor *pCur = (gufi_vtab_cursor *) cur; - if (pCur->stmt) { - sqlite3_finalize(pCur->stmt); - } - if (pCur->db) { - sqlite3_close(pCur->db); - } + free(pCur->row); + pCur->row = NULL; sqlite3_free(cur); return SQLITE_OK; } @@ -431,7 +395,6 @@ static int gufi_vtFilter(sqlite3_vtab_cursor *cur, /* indexroot must be present */ const char *indexroot = (const char *) sqlite3_value_text(argv[GUFI_VT_COLUMN_INDEXROOT]); const char *threads = NULL; - const char *output_prefix = NULL; if (argc > GUFI_VT_COLUMN_THREADS) { /* passing NULL in the SQL will result in a NULL pointer */ @@ -453,8 +416,6 @@ static int gufi_vtFilter(sqlite3_vtab_cursor *cur, } \ } - set_str(argc, argv, GUFI_VT_COLUMN_OUTPUT_PREFIX, output_prefix); - /* change default queries if they were provided */ set_str(argc, argv, GUFI_VT_COLUMN_I, vtab->sql.I); set_str(argc, argv, GUFI_VT_COLUMN_T, vtab->sql.T); @@ -465,108 +426,132 @@ static int gufi_vtFilter(sqlite3_vtab_cursor *cur, set_str(argc, argv, GUFI_VT_COLUMN_G, vtab->sql.G); set_str(argc, argv, GUFI_VT_COLUMN_F, vtab->sql.F); - /* run gufi_query to get aggregate results */ + /* kick off gufi_query */ const int rc = gufi_query_aggregate_db(indexroot, threads, &vtab->sql, - output_prefix, &vtab->dbname, &vtab->base.zErrMsg); - - if (rc != EXIT_SUCCESS) { - /* output file has already been removed */ + &pCur->output, &vtab->base.zErrMsg); + if (rc != SQLITE_OK) { return SQLITE_ERROR; } - /* open the aggregate db file */ - if (sqlite3_open_v2(vtab->dbname, &pCur->db, SQLITE_OPEN_READONLY, GUFI_SQLITE_VFS) != SQLITE_OK) { - sqlite3_free(vtab->base.zErrMsg); - vtab->base.zErrMsg = sqlite3_mprintf("Could not open aggregate db %s", vtab->dbname); - goto error; - } + pCur->rowid = 0; + pCur->row = NULL; - /* set up SQL for retreiving data from results table */ - static const char SELECT_AGG[] = "SELECT * FROM " AGGREGATE ";"; - if (sqlite3_prepare_v2(pCur->db, SELECT_AGG, sizeof(SELECT_AGG), &pCur->stmt, NULL) != SQLITE_OK) { + /* wait for first row */ + size_t len = 0; + pCur->len = getline(&pCur->row, &len, pCur->output); + + if (pCur->len < 0) { /* failed or reached EOF */ + const int err = errno; sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = sqlite3_mprintf("Could not prepare SQL for aggregate db: %s", - sqlite3_errmsg(pCur->db)); - goto error; + cur->pVtab->zErrMsg = sqlite3_mprintf("Could not read first result: %s (%d)", + strerror(err), err); + return SQLITE_ERROR; } - pCur->rowid = 0; - pCur->res = sqlite3_step(pCur->stmt); /* go to first result */ - if ((pCur->res != SQLITE_ROW) && (pCur->res != SQLITE_DONE)) { - sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = sqlite3_mprintf("Could not prepare step into aggregate results: %s", - sqlite3_errmsg(pCur->db)); - goto error; + if (pCur->row[pCur->len - 1] == '\n') { + pCur->row[pCur->len - 1] = '\0'; + pCur->len--; } return SQLITE_OK; - - error: - remove(vtab->dbname); - sqlite3_free(vtab->dbname); - vtab->dbname = NULL; - return SQLITE_ERROR; } static int gufi_vtNext(sqlite3_vtab_cursor *cur) { gufi_vtab_cursor *pCur = (gufi_vtab_cursor *) cur; - pCur->res = sqlite3_step(pCur->stmt); - if ((pCur->res != SQLITE_ROW) && (pCur->res != SQLITE_DONE)) { - return SQLITE_ERROR; + + size_t len = 0; + free(pCur->row); + pCur->row = NULL; + pCur->len = getline(&pCur->row, &len, pCur->output); + + /* no more to read */ + if (pCur->len == -1) { + return SQLITE_OK; } - if (pCur->res == SQLITE_ROW) { - pCur->rowid++; + + /* remove trailing newline */ + if (pCur->row[pCur->len - 1] == '\n') { + pCur->len--; } + pCur->rowid++; + return SQLITE_OK; } static int gufi_vtEof(sqlite3_vtab_cursor *cur) { gufi_vtab_cursor *pCur = (gufi_vtab_cursor *) cur; - const int eof = (pCur->res != SQLITE_ROW); + + const int eof = (pCur->len < 1); if (eof) { - sqlite3_reset(pCur->stmt); + pclose(pCur->output); + pCur->output = NULL; } + return eof; } +static int find_col(const char *str, const size_t len, const char c, const size_t n, + const char **ptr, size_t *col_len) { + if (!str) { + *ptr = NULL; + *col_len = 0; + return 1; + } + + size_t start = 0; + size_t end = 0; + + /* find first column */ + while ((end < len) && (str[end] != c)) { + end++; + } + + if (n == 0) { + *ptr = str + start; + *col_len = end - start; + return 0; + } + + /* columns > 0 */ + size_t col = 1; + while ((end < len) && (col <= n)) { + start = end + 1; + end = start; + + while ((end < len) && (str[end] != c)) { + end++; + } + + col++; + } + + if (col == (n + 1)) { + *ptr = str + start; + *col_len = end - start; + return 0; + } + + *ptr = NULL; + *col_len = 0; + + return 1; +} + static int gufi_vtColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, - int i) { + int N) { gufi_vtab_cursor *pCur = (gufi_vtab_cursor *) cur; - const int coltype = sqlite3_column_type(pCur->stmt, i); - switch (coltype) { - case SQLITE_INTEGER: - { - const int col = sqlite3_column_int(pCur->stmt, i); - sqlite3_result_int(ctx, col); - } - break; - case SQLITE_FLOAT: - { - const double col = sqlite3_column_int(pCur->stmt, i); - sqlite3_result_double(ctx, col); - } - break; - case SQLITE_TEXT: - { - const char *col = (char *) sqlite3_column_text(pCur->stmt, i); - const int bytes = sqlite3_column_bytes(pCur->stmt, i); - sqlite3_result_text(ctx, col, bytes, SQLITE_TRANSIENT); - } - break; - case SQLITE_BLOB: - { - const void *col = sqlite3_column_blob(pCur->stmt, i); - const int bytes = sqlite3_column_bytes(pCur->stmt, i); - sqlite3_result_blob(ctx, col, bytes, SQLITE_TRANSIENT); - } - break; - case SQLITE_NULL: - default: - sqlite3_result_null(ctx); - break; + const char *col = NULL; + size_t len = 0; + find_col(pCur->row, strlen(pCur->row), delim[0], N, &col, &len); + + if (col && len) { + sqlite3_result_text(ctx, col, len, SQLITE_TRANSIENT); + } + else { + sqlite3_result_null(ctx); } return SQLITE_OK; diff --git a/test/regression/gufi_vt.expected b/test/regression/gufi_vt.expected index 9d22cfb45..61954c420 100644 --- a/test/regression/gufi_vt.expected +++ b/test/regression/gufi_vt.expected @@ -6,23 +6,17 @@ $ ( echo ".load gufi_vt" echo "SELECT minsize, maxsize, minmtime, maxmtime FROM gufi_vt_treesummary('prefix', 2) ORDER BY minsize ASC, maxsize ASC;" ) | sqlite3 - - - - - - --1|0|-1|0 0|1048576|0|1048576 1|5|1|5 -5|5|4|5 11|12|11|12 15|15|15|15 +5|5|4|5 +9223372036854775807|-9223372036854775808|9223372036854775807|-9223372036854775808 # Query summary $ ( echo ".load gufi_vt" - echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_summary('prefix', 2) ORDER BY name ASC, size ASC;" + echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_summary('prefix', 2) ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 directory|7|drwxrwxr-x|Thu Jan 01 00:00:07 UTC 1970 empty_directory|8|drwxrwxr-x|Thu Jan 01 00:00:08 UTC 1970 @@ -34,7 +28,7 @@ unusual#? directory ,|16|drwxrwxr-x|Thu Jan 01 00:00:16 UTC 1970 # Query entries $ ( echo ".load gufi_vt" - echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_entries('prefix', 2) ORDER BY name ASC, size ASC;" + echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_entries('prefix', 2) ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 .hidden|10|-rw-rw-r--|Thu Jan 01 00:00:10 UTC 1970 1KB|1024|-rw-rw-r--|Thu Jan 01 00:17:04 UTC 1970 @@ -54,7 +48,7 @@ writable|3|-rw-rw-rw-|Thu Jan 01 00:00:03 UTC 1970 # Query pentries $ ( echo ".load gufi_vt" - echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_pentries('prefix', 2) ORDER BY name ASC, size ASC;" + echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_pentries('prefix', 2) ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 .hidden|10|-rw-rw-r--|Thu Jan 01 00:00:10 UTC 1970 1KB|1024|-rw-rw-r--|Thu Jan 01 00:17:04 UTC 1970 @@ -74,7 +68,7 @@ writable|3|-rw-rw-rw-|Thu Jan 01 00:00:03 UTC 1970 # Query vrsummary $ ( echo ".load gufi_vt" - echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_vrsummary('prefix', 2) ORDER BY name ASC, size ASC;" + echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_vrsummary('prefix', 2) ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 directory|7|drwxrwxr-x|Thu Jan 01 00:00:07 UTC 1970 empty_directory|8|drwxrwxr-x|Thu Jan 01 00:00:08 UTC 1970 @@ -86,7 +80,7 @@ unusual#? directory ,|16|drwxrwxr-x|Thu Jan 01 00:00:16 UTC 1970 # Query vrpentries $ ( echo ".load gufi_vt" - echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_vrpentries('prefix', 2) ORDER BY name ASC, size ASC;" + echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_vrpentries('prefix', 2) ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 .hidden|10|-rw-rw-r--|Thu Jan 01 00:00:10 UTC 1970 1KB|1024|-rw-rw-r--|Thu Jan 01 00:17:04 UTC 1970 @@ -106,7 +100,7 @@ writable|3|-rw-rw-rw-|Thu Jan 01 00:00:03 UTC 1970 # Query with WHERE size < 10 $ ( echo ".load gufi_vt" - echo "SELECT name, size FROM gufi_vt_pentries('prefix', 2) WHERE size < 10 ORDER BY name ASC, size ASC;" + echo "SELECT name, size FROM gufi_vt_pentries('prefix', 2) WHERE size < 10 ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 directory_symlink|4 executable|1 @@ -119,7 +113,7 @@ writable|3 # Query with WHERE size > 10 $ ( echo ".load gufi_vt" - echo "SELECT name, size FROM gufi_vt_pentries('prefix', 2) WHERE size > 10 ORDER BY name ASC, size ASC;" + echo "SELECT name, size FROM gufi_vt_pentries('prefix', 2) WHERE size > 10 ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 1KB|1024 1MB|1048576 @@ -131,9 +125,8 @@ unusual, name?#|15 # Query entries in directory where name == 'directory' $ ( echo ".load gufi_vt" - echo "SELECT name FROM gufi_vt_pentries('prefix', 2, NULL, NULL, NULL, 'SELECT NULL FROM summary WHERE name == ''directory'';') ORDER BY name ASC, size ASC;" + echo "SELECT name FROM gufi_vt_pentries('prefix', 2, NULL, NULL, 'SELECT NULL FROM summary WHERE name == ''directory'';') ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 - executable readonly writable @@ -141,9 +134,8 @@ writable # Query directories that contain entries larger than 1024 (only 1: prefix) $ ( echo ".load gufi_vt" - echo "SELECT name, size, mtime FROM gufi_vt_pentries('prefix', 2, NULL, NULL, NULL, 'SELECT NULL FROM summary WHERE maxsize > 1024;') ORDER BY name ASC, size ASC;" + echo "SELECT name, size, mtime FROM gufi_vt_pentries('prefix', 2, NULL, NULL, 'SELECT NULL FROM summary WHERE maxsize > 1024;') ORDER BY name ASC, CAST(size AS INT64) ASC;" ) | sqlite3 - .hidden|10|10 1KB|1024|1024 1MB|1048576|1048576 @@ -191,26 +183,6 @@ repeat_name unusual, name?# writable -# Place results in a specific directory -$ ( - echo ".load gufi_vt" - echo "SELECT name, size, mtime FROM gufi_vt_pentries('prefix', 2, 'alt_dir') ORDER BY name ASC, size ASC;" -) | sqlite3 -.hidden|10|10 -1KB|1024|1024 -1MB|1048576|1048576 -directory_symlink|4|4 -executable|1|1 -file_symlink|9|9 -leaf_file1|11|11 -leaf_file2|12|12 -old_file|0|0 -readonly|2|2 -repeat_name|5|5 -repeat_name|14|14 -unusual, name?#|15|15 -writable|3|3 - # Make sure all types work $ ( echo ".load gufi_vt" diff --git a/test/regression/gufi_vt.sh.in b/test/regression/gufi_vt.sh.in index 9b933ba1c..a2efce4b0 100755 --- a/test/regression/gufi_vt.sh.in +++ b/test/regression/gufi_vt.sh.in @@ -67,20 +67,6 @@ source @CMAKE_CURRENT_BINARY_DIR@/setup.sh 1 OUTPUT="gufi_vt.out" LOAD=".load @CMAKE_BINARY_DIR@/src/gufi_vt" -ALT_DIR="$(mktemp -d XXXXXX)" - -cleanup() { - rm -rf "${ALT_DIR}" -} - -cleanup_exit() { - cleanup - setup_cleanup -} - -trap cleanup_exit EXIT - -# no initial cleanup query_vt() { sql="$1" @@ -105,20 +91,20 @@ query_vt "SELECT minsize, maxsize, minmtime, maxmtime FROM gufi_vt_treesummary(' for name in summary entries pentries vrsummary vrpentries do echo "# Query ${name}" - query_vt "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_${name}('${INDEXROOT}', ${THREADS}) ORDER BY name ASC, size ASC;" + query_vt "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_${name}('${INDEXROOT}', ${THREADS}) ORDER BY name ASC, CAST(size AS INT64) ASC;" done echo "# Query with WHERE size < 10" -query_vt "SELECT name, size FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}) WHERE size < 10 ORDER BY name ASC, size ASC;" +query_vt "SELECT name, size FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}) WHERE size < 10 ORDER BY name ASC, CAST(size AS INT64) ASC;" echo "# Query with WHERE size > 10" -query_vt "SELECT name, size FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}) WHERE size > 10 ORDER BY name ASC, size ASC;" +query_vt "SELECT name, size FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}) WHERE size > 10 ORDER BY name ASC, CAST(size AS INT64) ASC;" echo "# Query entries in directory where name == 'directory'" -query_vt "SELECT name FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, NULL, NULL, 'SELECT NULL FROM summary WHERE name == ''directory'';') ORDER BY name ASC, size ASC;" +query_vt "SELECT name FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, NULL, 'SELECT NULL FROM summary WHERE name == ''directory'';') ORDER BY name ASC, CAST(size AS INT64) ASC;" echo "# Query directories that contain entries larger than 1024 (only 1: ${INDEXROOT})" -query_vt "SELECT name, size, mtime FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, NULL, NULL, 'SELECT NULL FROM summary WHERE maxsize > 1024;') ORDER BY name ASC, size ASC;" +query_vt "SELECT name, size, mtime FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, NULL, 'SELECT NULL FROM summary WHERE maxsize > 1024;') ORDER BY name ASC, CAST(size AS INT64) ASC;" echo "# Missing thread count (not an error)" query_vt "SELECT name FROM gufi_vt_pentries('${INDEXROOT}') ORDER BY name ASC, size ASC;" @@ -126,9 +112,6 @@ query_vt "SELECT name FROM gufi_vt_pentries('${INDEXROOT}') ORDER BY name ASC, s echo "# NULL thread count (not an error)" query_vt "SELECT name FROM gufi_vt_pentries('${INDEXROOT}', NULL) ORDER BY name ASC, size ASC;" -echo "# Place results in a specific directory" -query_vt "SELECT name, size, mtime FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, '${ALT_DIR}') ORDER BY name ASC, size ASC;" | sed "s/${ALT_DIR}/alt_dir/g;" - echo "# Make sure all types work" query_vt "SELECT rowid, 1, 1.0, 'text', CAST('blob' AS BLOB), NULL FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}) LIMIT 5;"