Skip to content

feat: Visualize complex Hive column types v2 - #1091

Merged
czgu merged 1 commit into
pinterest:masterfrom
baumandm:external/struct-types-v2
Jan 10, 2023
Merged

czgu merged 1 commit into
pinterest:masterfrom
baumandm:external/struct-types-v2

Conversation

@baumandm

@baumandm baumandm commented Dec 1, 2022

Copy link
Copy Markdown
Contributor

This is an alternate version of #1072, replacing the JSON viewer with a more natural-looking nested type drilldown. I've also addressed some issues with the original version.

Compared to #1072, the parser is more consistent and does a better job of handling certain types than before. To support the nesting, it always creates nodes with optional children. Now array<> and uniontype<> types will create placeholder <element> nodes underneath them, and map<> types create placeholder <key> and <value> nodes.

Complex type parsing is case-insensitive (e.g. struct vs STRUCT) but otherwise case is preserved.

There are three main features:

  1. Columns with complex types can be expanded directly in the TablePanelView to see a nested representation (initially collapsed).

Screen Shot 2022-12-01 at 4 55 50 PM Screen Shot 2022-12-01 at 4 56 10 PM

  1. The type displayed on the ColumnPanelView is pretty-printed with simple line breaks/indents.

Screen Shot 2022-12-01 at 4 56 35 PM

  1. The DataTableColumnCard shows a similar nested visualization after expanding a column (initially collapsed).

Screen Shot 2022-12-01 at 4 58 06 PM

@baumandm

baumandm commented Dec 2, 2022

Copy link
Copy Markdown
Contributor Author

I've extended the length of DataTableColumn's type column to 1024 characters, since we were running into a number of truncated columns.

In the event that a column type is still longer than the new limit, everything degrades gracefully and the partial type string will be short as before.

@jczhong84 jczhong84 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me overall, thanks for the update!

Also could you update the version in package.json?

Comment on lines +35 to +39
if (!matches || matches.length < 3) {
return { key, type };
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this to handle the truncated case?

  1. could you add a test case for it?
  2. what if the truncated type also matches the regex? like struct<date:struct<hour:int>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a case for non-matching truncated, and the 2nd scenario where the truncated type matches the regex accidentally. I've addressed this by checking the depth field to ensure we've closed all <> pairs

}
*/
export function parseType(key: string, type: string): ComplexType {
const regex = /(struct|array|map|uniontype)<(.*)>/i;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it need to handle spaces? like struct <...>, struct<year : int, day : int>?

also should it match the start and end /^ ... $/?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left spaces out intentionally as I haven't seen that in the wild. If needed it probably wouldn't be too hard, but didn't want to add unnecessary complexity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added start/end to the regex.

if (char === '<') {
prettyString += '<\n';
depth += 1;
prettyString += ' '.repeat(depth);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you use a variable for the 2 spaces ' '?

Comment thread querybook/webapp/components/DataTableViewColumn/DataTableColumnCard.tsx Outdated
Comment on lines +124 to +126
{complexType.type}
</StyledText>
<AccentText weight="extra">{complexType.key}</AccentText>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of displaying it as type key, I'd prefer to have it same as the ColumnRow, which is key type, which I think is more reasonable.

@baumandm
baumandm force-pushed the external/struct-types-v2 branch 2 times, most recently from 645b79f to a030692 Compare January 5, 2023 15:59
jczhong84
jczhong84 previously approved these changes Jan 6, 2023
updateDataColumnDescription,
}) => {
const [expanded, setExpanded] = React.useState(false);
const parsedType = parseType('', column.type);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memo this?

);
};

interface IDataTableColumnCardNestedTypeProps {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you separate this into another file?

IDataTableColumnCardNestedTypeProps
> = ({ complexType }) => {
const hasChildren = complexType.children?.length > 0;
const [expanded, setExpanded] = React.useState(false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use useToggleState then you don't need () => setExpanded(!expanded)

const hasChildren = complexType.children?.length > 0;
const [expanded, setExpanded] = React.useState(false);

const rowProps = {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const rowProps: React.HTMLAttributes = {}

</div>
{hasChildren &&
expanded &&
complexType.children?.map((child) => (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.map is sufficient

'struct<ids:array<string>,data:uniontype<int,float,string>>'
)
).toEqual(`struct<
ids:array<

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a space after : to make it easier to read?

onClick={onColumnRowClick.bind(null, col.id)}
name={col.name}
type={col.type}
typeChildren={parseType('', col.type).children}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memo this?

actually, the parsing can be down in ColumnRow since col.type is passed as a prop

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ColumnRow takes typeChildren because it only parses once, then recursively output nested rows. I've moved the parseType call down and inside useMemo, where it returns either the passed typeChildren or calculates it.

czgu
czgu previously approved these changes Jan 9, 2023
@baumandm

Copy link
Copy Markdown
Contributor Author

Rebased to resolve conflicts / squashed the commits.

@czgu
czgu merged commit 05de0ca into pinterest:master Jan 10, 2023
rohan-sh1 pushed a commit to CAI-TECHNOLOGIES/cai-ext-db-explorer that referenced this pull request Feb 28, 2023
@baumandm
baumandm deleted the external/struct-types-v2 branch September 21, 2023 16:55
aidenprice pushed a commit to arrowtail-precision/querybook that referenced this pull request Jan 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants