/* * test_block_compare.h -- recursive block/column comparators */ #ifndef CLICKHOUSE_TEST_BLOCK_COMPARE_H #define CLICKHOUSE_TEST_BLOCK_COMPARE_H #include #include static int test_col_eq(const chc_column *a, const chc_column *b); CHC_MAYBE_UNUSED static int test_col_eq(const chc_column *a, const chc_column *b) { if (!a || !b) return a == b; if (chc_column_layout(a) != chc_column_layout(b)) return 0; size_t n = chc_column_n_rows(a); if (n != chc_column_n_rows(b)) return 0; switch (chc_column_layout(a)) { case CHC_COL_FIXED: { size_t ea, eb; const void *da = chc_column_fixed_data(a, &ea); const void *db = chc_column_fixed_data(b, &eb); if (ea != eb) return 0; if (n == 0 || ea == 0) return 1; return memcmp(da, db, n * ea) == 0; } case CHC_COL_STRING: { const uint64_t *oa = chc_column_string_offsets(a); const uint64_t *ob = chc_column_string_offsets(b); if (n == 0) return 1; if (memcmp(oa, ob, n * sizeof *oa) != 0) return 0; uint64_t bytes = oa[n - 1]; if (bytes == 0) return 1; return memcmp(chc_column_string_data(a), chc_column_string_data(b), bytes) == 0; } case CHC_COL_NULLABLE: { if (n && memcmp(chc_column_null_map(a), chc_column_null_map(b), n) != 0) return 0; return test_col_eq(chc_column_nullable_inner(a), chc_column_nullable_inner(b)); } case CHC_COL_ARRAY: { const uint64_t *oa = chc_column_array_offsets(a); const uint64_t *ob = chc_column_array_offsets(b); if (n && memcmp(oa, ob, n * sizeof *oa) != 0) return 0; return test_col_eq(chc_column_array_values(a), chc_column_array_values(b)); } case CHC_COL_TUPLE: { size_t arity = chc_column_tuple_arity(a); if (arity != chc_column_tuple_arity(b)) return 0; for (size_t i = 0; i < arity; i++) { if (!test_col_eq(chc_column_tuple_child(a, i), chc_column_tuple_child(b, i))) return 0; } return 1; } case CHC_COL_LOW_CARDINALITY: { int ks = chc_column_lc_key_size(a); if (ks != chc_column_lc_key_size(b)) return 0; if (n && memcmp(chc_column_lc_keys(a), chc_column_lc_keys(b), n * (size_t) ks) != 0) return 0; return test_col_eq(chc_column_lc_dict(a), chc_column_lc_dict(b)); } case CHC_COL_NOTHING: return 1; } return 0; } CHC_MAYBE_UNUSED static int test_block_eq(const chc_block *a, const chc_block *b) { if (!a || !b) return a == b; if (chc_block_n_rows(a) != chc_block_n_rows(b)) return 0; if (chc_block_n_columns(a) != chc_block_n_columns(b)) return 0; for (size_t i = 0; i < chc_block_n_columns(a); i++) { size_t la, lb; const char *na = chc_block_column_name(a, i, &la); const char *nb = chc_block_column_name(b, i, &lb); if (la != lb || (la && memcmp(na, nb, la) != 0)) return 0; if (!test_col_eq(chc_block_column(a, i), chc_block_column(b, i))) return 0; } return 1; } #endif