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. */
| 3045 | * Prepends base_cols, then appends up to SCHEMA_MAX_JSON_KEYS from the query. |
| 3046 | * Caller must free the returned array and each string in it. */ |
| 3047 | static void schema_discover_props(sqlite3 *db, const char *sql, const char *project, |
| 3048 | const char *filter, const char **base_cols, int base_col_count, |
| 3049 | char ***out_props, int *out_count) { |
| 3050 | int pcap = base_col_count + SCHEMA_MAX_JSON_KEYS; |
| 3051 | char **props = malloc(pcap * sizeof(char *)); |
| 3052 | int pn = 0; |
| 3053 | |
| 3054 | for (int b = 0; b < base_col_count; b++) { |
| 3055 | props[pn++] = heap_strdup(base_cols[b]); |
| 3056 | } |
| 3057 | |
| 3058 | sqlite3_stmt *pstmt = NULL; |
| 3059 | if (sqlite3_prepare_v2(db, sql, CBM_NOT_FOUND, &pstmt, NULL) == SQLITE_OK) { |
| 3060 | bind_text(pstmt, SKIP_ONE, project); |
| 3061 | bind_text(pstmt, PAIR_LEN, filter); |
| 3062 | while (sqlite3_step(pstmt) == SQLITE_ROW && pn < pcap) { |
| 3063 | props[pn++] = heap_strdup((const char *)sqlite3_column_text(pstmt, 0)); |
| 3064 | } |
| 3065 | sqlite3_finalize(pstmt); |
| 3066 | } |
| 3067 | |
| 3068 | *out_props = props; |
| 3069 | *out_count = pn; |
| 3070 | } |
| 3071 | |
| 3072 | /* Path scoping for architecture / schema (shared). */ |
| 3073 | static bool arch_path_is_set(const char *path) { |
no test coverage detected