Skip to content

Commit a13cce0

Browse files
aarthy-dkclaude
andcommitted
feat(catalog): surface object type and warn when views skip sampling
- Data Catalog: show 'Object Type' (title-cased) as the first attribute on the table Characteristics card, mirroring 'Data Type' for columns. Sourced from data_table_chars.object_type via get_tables_by_condition. - Table group form: under Sampling Parameters, show a yellow warning icon + note that views are profiled in full, only for flavors whose sample clause skips views (SQL Server, PostgreSQL) and only when sampling is enabled. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4d2eaca commit a13cce0

4 files changed

Lines changed: 29 additions & 2 deletions

File tree

testgen/ui/components/frontend/js/data_profiling/data_characteristics.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ const DataCharacteristicsCard = (/** @type Properties */ props, /** @type Column
3636
);
3737
}
3838
} else {
39+
if (item.object_type) {
40+
attributes.push({ key: 'object_type', label: 'Object Type' });
41+
}
3942
attributes.push(
4043
{ key: 'functional_table_type', label: `Semantic Table Type ${item.is_latest_profile ? '*' : ''}` },
4144
);
@@ -77,6 +80,10 @@ const DataCharacteristicsCard = (/** @type Properties */ props, /** @type Column
7780
);
7881
} else if (key === 'datatype_suggestion') {
7982
value = (value || '').toLowerCase();
83+
} else if (key === 'object_type') {
84+
value = (value || '').split('_')
85+
.map(word => word ? (word[0].toUpperCase() + word.substring(1).toLowerCase()) : '')
86+
.join(' ');
8087
} else if (key === 'functional_table_type') {
8188
value = (value || '').split('-')
8289
.map(word => word ? (word[0].toUpperCase() + word.substring(1)) : '')

testgen/ui/components/frontend/js/data_profiling/data_profiling_utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
* @property {string} connection_id
151151
* @property {string} project_code
152152
* * Characteristics
153+
* @property {string} object_type
153154
* @property {string} functional_table_type
154155
* @property {number} approx_record_ct
155156
* @property {number} record_ct

testgen/ui/queries/profiling_queries.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ def get_tables_by_condition(
255255
table_chars.schema_name,
256256
table_chars.table_groups_id::VARCHAR AS table_group_id,
257257
-- Characteristics
258+
table_chars.object_type,
258259
functional_table_type,
259260
approx_record_ct,
260261
table_chars.record_ct,

testgen/ui/static/js/components/table_group_form.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,12 @@ import { required } from '../form_validators.js';
5555
import { Select } from './select.js';
5656
import { Caption } from './caption.js';
5757
import { Textarea } from './textarea.js';
58+
import { Icon } from './icon.js';
5859

59-
const { div } = van.tags;
60+
// Flavors whose profiling sample clause cannot sample views — views are profiled in full.
61+
const SAMPLE_SKIPS_VIEWS_FLAVORS = ['mssql', 'postgresql'];
62+
63+
const { div, span } = van.tags;
6064

6165
const normalizeTableSet = (value) => {
6266
return value?.split(/[,\n]/)
@@ -119,6 +123,13 @@ const TableGroupForm = (props) => {
119123
return flavor === 'salesforce_data360';
120124
});
121125

126+
const sampleSkipsViews = van.derive(() => {
127+
const connections = getValue(props.connections) ?? [];
128+
const selected = connections.find(c => c.connection_id === tableGroupConnectionId.val);
129+
const flavor = selected?.sql_flavor ?? getValue(props.sqlFlavor);
130+
return SAMPLE_SKIPS_VIEWS_FLAVORS.includes(flavor);
131+
});
132+
122133
const updatedTableGroup = van.derive(() => {
123134
return {
124135
id: tableGroup.id,
@@ -206,7 +217,7 @@ const TableGroupForm = (props) => {
206217
addScorecardDefinition,
207218
),
208219
SamplingForm(
209-
{ setValidity: setFieldValidity },
220+
{ setValidity: setFieldValidity, sampleSkipsViews },
210221
profileUseSampling,
211222
profileSamplePercent,
212223
profileSampleMinCount,
@@ -447,6 +458,13 @@ const SamplingForm = (
447458
},
448459
}),
449460
),
461+
() => (getValue(options.sampleSkipsViews) && profileUseSampling.val)
462+
? div(
463+
{ class: 'flex-row fx-align-center fx-gap-1' },
464+
Icon({ style: 'color: var(--orange); font-size: 18px;' }, 'warning'),
465+
span('Views are profiled in full on this database — sampling applies only to tables and materialized views.'),
466+
)
467+
: '',
450468
),
451469
);
452470
};

0 commit comments

Comments
 (0)