Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create dolt_help system table #8739

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open

Conversation

milogreg
Copy link
Contributor

Created the dolt_help system table. This table is meant to store documentation for system tables, procedures, functions, and variables. Currently dolt_help is only populated with documentation for procedures, and only procedures that have equivalent CLI commands.

Part of #7984

Copy link
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

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

This is the right idea, but it's missing a few things. Check out the difference between the command line and sql output here:

select arguments from dolt_help where target = 'dolt_add';
+-------------------------------------------------------------------------------------------------------------------------------------+
| arguments                                                                                                                           |
+-------------------------------------------------------------------------------------------------------------------------------------+
| {"table": "Working table(s) to add to the list tables staged to be committed. The abbreviation '.' can be used to add all tables."} |
+-------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

v. command line:

% dolt add --help
NAME
        dolt add - Add table contents to the list of staged tables

SYNOPSIS
        dolt add [<table>...]

DESCRIPTION

        This command updates the list of tables using the current content found in the working root, to prepare the content staged for the next commit. It adds the current content of existing
        tables as a whole or remove tables that do not exist in the working root anymore.

        This command can be performed multiple times before a commit. It only adds the content of the specified table(s) at the time the add command is run; if you want subsequent changes
        included in the next commit, then you must run dolt add again to add the new content to the index.

        The dolt status command can be used to obtain a summary of which tables have changes that are staged for the next commit.

OPTIONS
        <table>
          Working table(s) to add to the list tables staged to be committed. The abbreviation '.' can be used to add all tables.

        -A, --all
          Stages any and all changes (adds, deletes, and modifications) except for ignored tables.

        -f, --force
          Allow adding otherwise ignored tables.

        -p, --patch
          Interactively select changes to add to the staged set.

So relative to the CLI, this is missing:

  • options (flags)
  • synopsis
  • <table> formatting for arguments

return NewHelpRowIter(), nil
}

type HelpRowIter struct {
Copy link
Member

Choose a reason for hiding this comment

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

Best practice here is to use a pointer for the receiver type and not the fields


if hasProcedure && docs != nil {
argsMap := map[string]string{}
for _, argHelp := range curr.Docs().ArgParser.ArgListHelp {
Copy link
Member

Choose a reason for hiding this comment

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

This is missing all the options (flags)

func (ht *HelpTable) Schema() sql.Schema {
return []*sql.Column{
{
Name: "target",
Copy link
Member

Choose a reason for hiding this comment

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

Would call this name instead

@milogreg milogreg requested a review from zachmu January 14, 2025 21:19
Copy link
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

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

This looks great with the exception of a couple weird bugs I found during testing.

The other high level comment is you should add a couple spot check tests in the enginetest package. Add a new method in dolt_engine_test.go that verifies the output of a couple commands (and verifies the synopsis behavior bug below isn't there anymore).

Fix those things and you're good to merge this.

argsMap[usage[0]] = usage[1]
}

argsJson, err := json.Marshal(argsMap)
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure why, but something about this seems to be producing invalid json in a subtle and weird way. Check this out:

db1/main> select json_pretty(arguments) from dolt_help where name = 'dolt_revert';
invalid data type for JSON data in argument 1 to function json_pretty; a JSON string or JSON type is required

db1/main> create table json_test (j json);
db1/main*> insert into json_test (select arguments from dolt_help where name = 'dolt_revert');
db1/main*> select json_pretty(j) from json_test;
+-----------------------------------------------------------------------------------------------------------------------------------+
| json_pretty(j)
  |
+-----------------------------------------------------------------------------------------------------------------------------------+
| {
  |
|   "--author=\u003cauthor\u003e": "Specify an explicit author using the standard A U Thor \[email protected]\u003e format.", |
|   "\u003crevision\u003e": "The commit revisions. If multiple revisions are given, they're applied in the order given."
  |
| }
  |
+-----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

So whatever it is, it's getting handled by our round-trip into storage, but can't get processed by as returned by this table. This seems to affect all our json functions, so it needs to be fixed. Another example:

db1/main*> select arguments->>"$.<revision>" from dolt_help where name = 'dolt_revert';
invalid data type for JSON data in argument 1 to function json_extract; a JSON string or JSON type is required

db1/main*> select j->>"$.<revision>" from json_test;
+--------------------------------------------------------------------------------------------+
| j->>"$.<revision>"                                                                         |
+--------------------------------------------------------------------------------------------+
| The commit revisions. If multiple revisions are given, they're applied in the order given. |
+--------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Copy link
Member

Choose a reason for hiding this comment

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

I think it has something to do with the < and > characters. I would expect json.Marshall to do something reasonable there but it apparently is not.

Copy link
Member

Choose a reason for hiding this comment

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

Above examples work great now, but there's a related problem where ascii command characters (used for bolding on the terminal) are making it into the SQL output like this:

 "-f, --force": "Reset \u003cbranchname\u003e to \u003cstartpoint\u003e, even if \u003cbranchname\u003e exists already

I think what we need here is the OptionsUsageList() method to accept a Formatter object (needs to be defined) that we can use to change out the formatting behavior. For the SQL use case, we want to pass a formatter that just deletes the template options, rather than replacing them with command chars like the CLI implementation does.

@milogreg milogreg requested a review from zachmu January 16, 2025 23:25
Copy link
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

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

This is looking pretty good. One major comment about this, which is that we need configurable format options for the OptionUsageList method.

Fix that and we're good to merge.

LongDesc: `Dolt comprises of multiple subcommands that allow users to import, export, update, and manipulate data with SQL.`,

Synopsis: []string{
"<--data-dir=<path>> subcommand <subcommand arguments>",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"<--data-dir=<path>> subcommand <subcommand arguments>",
"[global flags] subcommand [subcommand arguments]",

return NewHelpRowIter(), nil
}

type HelpRowIter []sql.Row
Copy link
Member

Choose a reason for hiding this comment

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

Prefer to define an actual struct here, with []sql.Row field and a counter int to keep track of the place in it.

procedureName := strings.ReplaceAll(fullName, "-", "_")

hasProcedure := false
for _, procedure := range dprocedures.DoltProcedures {
Copy link
Member

Choose a reason for hiding this comment

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

Would pull out a boolean procedureExists method for this, and check for this condition before beginning the loop

continue
}

if subCmdHandler, ok := curr.(cli.SubCommandHandler); ok {
Copy link
Member

Choose a reason for hiding this comment

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

This loop can be simplified, because there are no procedures that correspond to sub commands. E.g. there is no dolt_table_ls command.

argsMap[usage[0]] = usage[1]
}

argsJson, err := json.Marshal(argsMap)
Copy link
Member

Choose a reason for hiding this comment

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

Above examples work great now, but there's a related problem where ascii command characters (used for bolding on the terminal) are making it into the SQL output like this:

 "-f, --force": "Reset \u003cbranchname\u003e to \u003cstartpoint\u003e, even if \u003cbranchname\u003e exists already

I think what we need here is the OptionsUsageList() method to accept a Formatter object (needs to be defined) that we can use to change out the formatting behavior. For the SQL use case, we want to pass a formatter that just deletes the template options, rather than replacing them with command chars like the CLI implementation does.

SetUpScript: []string{},
Assertions: []queries.ScriptTestAssertion{
{
Query: "select long_description from dolt_help where name='dolt_add'",
Copy link
Member

Choose a reason for hiding this comment

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

This test is probably over specified -- we tweak these pretty often, don't want to check the whole thing.

I would probably do something like select INSTR(long_description, "add") > 0, the idea is just a spot test to be sure this returns the correct contents, not to check the contents verbatim.

},

{
Name: "dolt_help arguments are correct",
Copy link
Member

Choose a reason for hiding this comment

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

Same comment here, loosen up these test to make them less likely to break when we change things in the future.

Copy link
Member

Choose a reason for hiding this comment

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

What you have in the bats tests is much closer to what we want here.

@zachmu
Copy link
Member

zachmu commented Jan 18, 2025

Also fix the copyright header on your new file, it needs to match other files exactly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants