Discover distinct JSON property keys for a table/column via json_each(). * Prepends base_cols, then appends up to SCHEMA_MAX_JSON_KEYS from the query. * Caller must free the returned array and each string in it. */
| 5054 | * Prepends base_cols, then appends up to SCHEMA_MAX_JSON_KEYS from the query. |
| 5055 | * Caller must free the returned array and each string in it. */ |
| 5056 | static void schema_discover_props(sqlite3 *db, const char *sql, const char *project, |
| 5057 | const char *filter, const char **base_cols, int base_col_count, |
| 5058 | char ***out_props, int *out_count) { |
| 5059 | int pcap = base_col_count + SCHEMA_MAX_JSON_KEYS; |
| 5060 | char **props = malloc(pcap * sizeof(char *)); |
| 5061 | int pn = 0; |
| 5062 | |
| 5063 | for (int b = 0; b < base_col_count; b++) { |
| 5064 | props[pn++] = heap_strdup(base_cols[b]); |
| 5065 | } |
| 5066 | |
| 5067 | sqlite3_stmt *pstmt = NULL; |
| 5068 | if (sqlite3_prepare_v2(db, sql, CBM_NOT_FOUND, &pstmt, NULL) == SQLITE_OK) { |
| 5069 | bind_text(pstmt, SKIP_ONE, project); |
| 5070 | bind_text(pstmt, PAIR_LEN, filter); |
| 5071 | while (sqlite3_step(pstmt) == SQLITE_ROW && pn < pcap) { |
| 5072 | props[pn++] = heap_strdup((const char *)sqlite3_column_text(pstmt, 0)); |
| 5073 | } |
| 5074 | sqlite3_finalize(pstmt); |
| 5075 | } |
| 5076 | |
| 5077 | *out_props = props; |
| 5078 | *out_count = pn; |
| 5079 | } |
| 5080 | |
| 5081 | /* Path scoping for architecture / schema (shared). */ |
| 5082 | static bool arch_path_is_set(const char *path) { |
no test coverage detected