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

cli: replace libedit with bubbline #86457

Merged
merged 4 commits into from Dec 1, 2022
Merged

Conversation

knz
Copy link
Contributor

@knz knz commented Aug 19, 2022

First commit from #88574.
Benefits from (but is not dependent on) #87606 server-side.

Epic: CRDB-22182
Fixes #21826
Fixes #71207
Fixes #71209
Fixes #57885

NB: this will benefit from upstream library releases based off the still-unmerged PRs listed in knz/bubbline#2.

Release justification: n/a will not merge before stability ends

Release note (cli change): The engine used as line editor in the
interactive shell (cockroach sql, demo) has been updated. It
includes numerous bug fixes and new features.
The previous engine can still be accessed via the env
var COCKROACH_SQL_FORCE_LIBEDIT. This support will be removed
in a later version.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@knz
Copy link
Contributor Author

knz commented Aug 19, 2022

Hi @rickystewart @rail ,could I ask for some assistance, as a result of this dep change I am now encountering the following:

$ bazel build //pkg/cmd/cockroach-sql:cockroach-sql
INFO: Invocation ID: 4ec274e7-2d82-4764-ba4d-87cf550c94f9
INFO: Build option --run_under has changed, discarding analysis cache.
ERROR: /data/home/kena/.cache/bazel/_bazel_kena/9b9f53b7334495d6a871cbb472c466bb/external/com_github_mattn_go_runewidth/BUILD.bazel:3:11: no such package '@com_github_rivo_uniseg//': BUILD file not found in directory '' of external repository @com_github_rivo_uniseg. Add a BUILD file to a directory to mark it as a package. and referenced by '@com_github_mattn_go_runewidth//:go-runewidth'
ERROR: Analysis of target '//pkg/cmd/cockroach-sql:cockroach-sql' failed; build aborted:

How can I fix this?

@knz knz force-pushed the 20220819-bubbline branch 3 times, most recently from d696817 to ab2266c Compare August 19, 2022 15:54
@knz
Copy link
Contributor Author

knz commented Aug 19, 2022

Remaining to do:

  • implement the "is the input complete" predicate using SQL syntax DONE
  • simplify / remove the partial line input logic, which is now unneeded DONE
  • (optionally) sqlfmt integration to reformat the full query DONE
  • (optionally) fix SHOW COMPLETIONS AT OFFSET

@rickystewart
Copy link
Collaborator

It looks like Gazelle is confused about this file which is package main instead of package uniseg. This may be a bug in Gazelle. I'll send you a patch.

@rickystewart
Copy link
Collaborator

@knz Can you add to your go.mod a replace like the following:

replace github.com/rivo/uniseg  => github.com/cockroachdb/uniseg v0.3.4

And then re-generate. I published a fork of uniseg with the problematic files removed. I'll also file a bug upstream against gazelle.

@knz
Copy link
Contributor Author

knz commented Aug 19, 2022

thank you!

@rickystewart
Copy link
Collaborator

bazelbuild/bazel-gazelle#1319

@knz
Copy link
Contributor Author

knz commented Aug 27, 2022

@rickystewart now CI is failing for an interesting reason:

[15:46:59]i:			 [Update checkout directory (/home/agent/work/.go/src/github.com/cockroachdb/cockroach)] fatal: No url found for submodule path 'c-deps/libedit' in .gitmodules

Is the requirement to download libedit hard-coded somewhere in the TC configuration?

@rickystewart
Copy link
Collaborator

Is the requirement to download libedit hard-coded somewhere in the TC configuration?

Not that I'm aware of, but interestingly I get the same error when I check out your commit too. I'm having a look.

@rickystewart
Copy link
Collaborator

@knz Try git rm -rf c-deps/libedit?

@knz knz force-pushed the 20220819-bubbline branch 3 times, most recently from ca4d12b to 66a70ec Compare September 6, 2022 07:01
@knz
Copy link
Contributor Author

knz commented Sep 6, 2022

@rickystewart thanks, that worked, and got me one step further.

Now I'm running into a different issue: the nogo code is panicing because one of the vendored dependencies uses templates internally.

Is it possible to exclude certain packages from nogo processing?

(Also, I'm noticing that nogo is being used for all the CI targets; wouldn't it be more meaningful to only use it for 1 (e.g. the test or lint targets, and not the others, so as to speed up the CI build overall?)

[09:54:29]W:			 [UnusedLint] ERROR: /home/roach/.cache/bazel/_bazel_roach/c5a4e7d36696d9cd970af2045211a7df/external/com_github_rivo_uniseg/BUILD.bazel:3:11: GoCompilePkg external/com_github_rivo_uniseg/uniseg.a failed: (Exit 1): builder failed: error executing command bazel-out/k8-opt-exec-2B5CBBC6-ST-9cec1ec31dd7/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix linux_amd64 -tags acceptance,bazel,gss,bazel,gss -src ... (remaining 53 arguments skipped)
[09:54:29]W:			 [UnusedLint] 
[09:54:29]W:			 [UnusedLint] Use --sandbox_debug to see verbose messages from the sandbox
[09:54:29]W:			 [UnusedLint] compilepkg: panic: 0: got 0 arguments but 1 type parameters
[09:54:29]W:			 [UnusedLint] 
[09:54:29]W:			 [UnusedLint] goroutine 339 [running]:
[09:54:29]W:			 [UnusedLint] go/types.(*Checker).validateTArgLen(0xc000d12040?, 0xc0064b6270?, 0x1, 0x0)
[09:54:29]W:			 [UnusedLint] 	GOROOT/src/go/types/instantiate.go:131 +0x1b4
[09:54:29]W:			 [UnusedLint] go/types.(*Checker).instance(0x0, 0x0, {0xbc0ce0?, 0xc001adbe40?}, {0xfbeec0?, 0x0, 0x0}, 0xc000d12040)
[09:54:29]W:			 [UnusedLint] 	GOROOT/src/go/types/instantiate.go:89 +0x1a5
[09:54:29]W:			 [UnusedLint] go/types.Instantiate(0xc0064e3400?, {0xbc0ce0?, 0xc001adbe40?}, {0xfbeec0?, 0x40ed14?, 0xc006491598?}, 0x30?)
[09:54:29]W:			 [UnusedLint] 	GOROOT/src/go/types/instantiate.go:59 +0x2e9
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/internal/typeparams.Instantiate(...)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/internal/typeparams/external/org_golang_x_tools/internal/typeparams/typeparams_go118.go:150
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.createInstance(0xc000c321a0, {0xfbeec0?, 0x0, 0x0}, 0xc0005e8690, {0xbc0588?, 0xc000928240}, 0xc0001a43e0)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/instantiate.go:128 +0x105
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*instanceSet).lookupOrCreate(0xc0004dc4e0, {0xfbeec0, 0x0, 0x0}, 0xc0064907c8?)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/instantiate.go:110 +0x105
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*Program).needsInstance(0xa29280?, 0x0?, {0xfbeec0, 0x0, 0x0}, 0xaaaaaaaaaaa?)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/instantiate.go:85 +0xfb
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).expr0(0xc006491a28, 0xc000c32340, {0xbc3438?, 0xc000926e80?}, {0x7, {0xbc0ce0, 0xc0007afa00}, {0x0, 0x0}})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:781 +0xc07
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).expr(0x203001?, 0xc000c32340, {0xbc3438?, 0xc000926e80?})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:610 +0x18e
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).setCallFunc(0x7f4c0b228948?, 0x80?, 0xc000184400?, 0xc0064e8040)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:1006 +0x316
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).setCall(0xa27060?, 0xc000395e90?, 0xc0009132c0, 0xc0064e8040)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:1085 +0x34
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).expr0(0xc006491a28, 0xc000c32340, {0xbc3138?, 0xc0009132c0?}, {0x7, {0xbc0ba0, 0xc0005e4fa8}, {0x0, 0x0}})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:686 +0x27d3
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).expr(0xc000c32340?, 0xc000c32340, {0xbc3138?, 0xc0009132c0?})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:610 +0x18e
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).expr0(0xc006491a28, 0xc000c32340, {0xbc34f8?, 0xc000928360?}, {0x7, {0xbc0bc8, 0xf76060}, {0x0, 0x0}})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:862 +0x1a10
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).expr(0x2?, 0xc000c32340, {0xbc34f8?, 0xc000928360?})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:610 +0x18e
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).stmt(0x44c014?, 0xc000c32340, {0xbc3678?, 0xc000926f20?})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:2161 +0x157e
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).stmtList(0x1?, 0xc0064cf590?, {0xc00072d530?, 0x1, 0xc000184400?})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:911 +0x67
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).stmt(0xc000c32340?, 0xc000c32340, {0xbc30d8?, 0xc000928390?})
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:2218 +0x9d1
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).buildFunctionBody(0x729051?, 0xc000c32340)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:2327 +0x472
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).buildFunction(0x7290a0?, 0xc000c32340)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:2267 +0x2e
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*builder).buildCreated(0xc006491a28)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:2349 +0x25
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*Package).build(0xc0001a4380)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:2529 +0xca5
[09:54:29]W:			 [UnusedLint] sync.(*Once).doSlow(0xc00027e0c0?, 0xc0005e86e0?)
[09:54:29]W:			 [UnusedLint] 	GOROOT/src/sync/once.go:68 +0xc2
[09:54:29]W:			 [UnusedLint] sync.(*Once).Do(...)
[09:54:29]W:			 [UnusedLint] 	GOROOT/src/sync/once.go:59
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/ssa.(*Package).Build(...)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/ssa/external/org_golang_x_tools/go/ssa/builder.go:2413
[09:54:29]W:			 [UnusedLint] golang.org/x/tools/go/analysis/passes/buildssa.run(0xc000341c70)
[09:54:29]W:			 [UnusedLint] 	golang.org/x/tools/go/analysis/passes/buildssa/external/org_golang_x_tools/go/analysis/passes/buildssa/buildssa.go:73 +0x1a8
[09:54:29]W:			 [UnusedLint] main.(*action).execOnce(0xc0001cc510)
[09:54:29]W:			 [UnusedLint] 	main/external/io_bazel_rules_go/go/tools/builders/nogo_main.go:392 +0x817
[09:54:29]W:			 [UnusedLint] sync.(*Once).doSlow(0x0?, 0x0?)
[09:54:29]W:			 [UnusedLint] 	GOROOT/src/sync/once.go:68 +0xc2
[09:54:29]W:			 [UnusedLint] sync.(*Once).Do(...)
[09:54:29]W:			 [UnusedLint] 	GOROOT/src/sync/once.go:59
[09:54:29]W:			 [UnusedLint] main.(*action).exec(0x0?)
[09:54:29]W:			 [UnusedLint] 	main/external/io_bazel_rules_go/go/tools/builders/nogo_main.go:336 +0x3d
[09:54:29]W:			 [UnusedLint] main.execAll.func1(0x0?)
[09:54:29]W:			 [UnusedLint] 	main/external/io_bazel_rules_go/go/tools/builders/nogo_main.go:330 +0x54
[09:54:29]W:			 [UnusedLint] created by main.execAll
[09:54:29]W:			 [UnusedLint] 	main/external/io_bazel_rules_go/go/tools/builders/nogo_main.go:328 +0x47
[09:54:29]W:			 [UnusedLint] INFO: Elapsed time: 146.194s, Critical Path: 39.33s
[09:54:29]W:			 [UnusedLint] INFO: 3980 processes: 977 internal, 3003 processwrapper-sandbox.
[09:54:29]W:			 [UnusedLint] FAILED: Build did NOT complete successfully
[09:54:29]W:			 [UnusedLint] FAILED: Build did NOT complete successfully

@knz knz force-pushed the 20220819-bubbline branch 2 times, most recently from 828132e to 1d5c7bb Compare September 6, 2022 09:52
@knz
Copy link
Contributor Author

knz commented Sep 6, 2022

I have downgraded uniseg which removes the error above and also (temporarily) removes the need for a fork.

@knz knz requested review from a team as code owners November 8, 2022 13:28
@knz
Copy link
Contributor Author

knz commented Nov 8, 2022

rebased & ready for review.

Copy link
Collaborator

@ZhouXing19 ZhouXing19 left a comment

Choose a reason for hiding this comment

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

:lgtm_strong: My comments are mostly for nits.

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @knz)


pkg/cli/clisqlshell/complete.go line 1 at r8 (raw file):

// Copyright 2022 The Cockroach Authors.

Do you think we can add an interactive test for the auto-completion functionality?


pkg/cli/clisqlshell/complete.go line 118 at r8 (raw file):

		category := "completions"
		if len(row) >= 5 {
			// New-gen server-side completion engine.

I played around with it for a bit but can't see how I can trigger this new-gen completion engine from the cli.
Seems to me that b.sql.runShowCompletions() will always run delegate.RunShowCompletions() that returns a list of completion keywords.


pkg/cli/clisqlshell/editor_bubbline.go line 32 at r8 (raw file):

	win, wout, werr *os.File, sqlS sqlShell, maxHistEntries int, histFile string,
) (cleanupFn func(), err error) {
	cleanupFn = func() {}

nit: this line is never used, remove?


pkg/cli/clisqlshell/editor_bubbline.go line 64 at r8 (raw file):

		prevCleanup := cleanupFn
		cleanupFn = func() {
			if err := b.ins.SaveHistory(); err != nil {

This is a more general question about cli history: do we clean it up under certain circumstances?
Also, would it be a security vulnerability? Do we consider the case that the history may contain sensitive information?


pkg/cli/clisqlshell/editor_bubbline.go line 116 at r8 (raw file):

	// OR:
	// - or the last token in the input is a semicolon;
	//   and the cursor is either at the end of the input,

I don't quite understand the and the cursor... part here. Does it mean that

CREATE TABLE           t (x int);
                  ^

should not work? (as the last token is a semicolon but the cursor is on a space and the position before it is a space too)


pkg/cli/clisqlshell/sql.go line 430 at r8 (raw file):

			i, err := strconv.Atoi(v)
			if err != nil {
				return err

nit: do we want to wrap the err with hint that please choose from (0 = no, 1 = partial, 2 = full, 3 = extra)?


pkg/cli/clisqlshell/sql.go line 449 at r8 (raw file):

			}
			if i < 0 || i > 1 {
				return errors.New("value must be between 0 and 1")

nit: value must be 0 for lowercase, or 1 for uppercase


pkg/cli/interactive_tests/test_multiline_statements.tcl line 35 at r8 (raw file):

end_test

#start_test "Test that \p does what it says."

Just wanted to confirm -- here and the following commented tests are all pending for certain changes from bubbletea, right?

@ZhouXing19
Copy link
Collaborator

ZhouXing19 commented Nov 14, 2022

I played around the cool new sql shell and found something, not sure if they are expected:

  1. For the M-? toggle key help hint, on macos, I did option+shift+? and option+?, none of them worked. Not sure if I pressed the right keys.
  2. When I do control+space or control+"-", the shell seems to print out all my shell history with fixed width. The latter made the shell keep on printing white lines if not interrupted.

Copy link
Contributor Author

@knz knz left a comment

Choose a reason for hiding this comment

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

TFYR, but PTAL.

I did option+shift+? and option+?, none of them worked

"M" stands for meta/alt, not option. Try the alt key.

When I do control+space or control+"-", the shell seems to print out all my shell history with fixed width.

You're entering the key to enable debug mode -- debug mode prints the internal state of the editor continuously, including the history lines. That's what you see. You can press the key again to cancel.
To avoid confusion, i've added a commit to hide this functionality behind --debug-sql-cli

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @ZhouXing19)


pkg/cli/clisqlshell/complete.go line 1 at r8 (raw file):

Previously, ZhouXing19 (Jane Xing) wrote…

Do you think we can add an interactive test for the auto-completion functionality?

These changes belong to #87606. At the time this PR was created, it wasn't clear which one of the two would be reviewed first, so I made the changes to be independent. I'll extract this bit in a separate PR instead.


pkg/cli/clisqlshell/complete.go line 118 at r8 (raw file):

Previously, ZhouXing19 (Jane Xing) wrote…

I played around with it for a bit but can't see how I can trigger this new-gen completion engine from the cli.
Seems to me that b.sql.runShowCompletions() will always run delegate.RunShowCompletions() that returns a list of completion keywords.

Again that's #87606. You can test it by running the server from #87606 and the client from this PR.
(But not after this review: I'm removing this code from this PR, will re-add it into a later PR on top of #87606)


pkg/cli/clisqlshell/editor_bubbline.go line 32 at r8 (raw file):

Previously, ZhouXing19 (Jane Xing) wrote…

nit: this line is never used, remove?

Done.


pkg/cli/clisqlshell/editor_bubbline.go line 64 at r8 (raw file):

do we clean it up under certain circumstances?
Old entries beyond the configured maxHistEntries are removed.

Do we consider the case that the history may contain sensitive information?

It's a regular file. A security-conscious user can simply remove it, or even set the env var COCKROACH_SQL_CLI_HISTORY to an impossible path.


pkg/cli/clisqlshell/editor_bubbline.go line 116 at r8 (raw file):

Previously, ZhouXing19 (Jane Xing) wrote…

I don't quite understand the and the cursor... part here. Does it mean that

CREATE TABLE           t (x int);
                  ^

should not work? (as the last token is a semicolon but the cursor is on a space and the position before it is a space too)

Good call; this comment was stale. Updated, and also added some unit tests for this logic.


pkg/cli/clisqlshell/sql.go line 430 at r8 (raw file):

Previously, ZhouXing19 (Jane Xing) wrote…

nit: do we want to wrap the err with hint that please choose from (0 = no, 1 = partial, 2 = full, 3 = extra)?

Good idea. done.


pkg/cli/clisqlshell/sql.go line 449 at r8 (raw file):

Previously, ZhouXing19 (Jane Xing) wrote…

nit: value must be 0 for lowercase, or 1 for uppercase

Done.


pkg/cli/interactive_tests/test_multiline_statements.tcl line 35 at r8 (raw file):

Previously, ZhouXing19 (Jane Xing) wrote…

Just wanted to confirm -- here and the following commented tests are all pending for certain changes from bubbletea, right?

Nah, they were stale tests. I removed them entirely.

@knz
Copy link
Contributor Author

knz commented Nov 20, 2022

"M" stands for meta/alt, not option. Try the alt key.

I meant it stands for alt, not command.
The mac option key is also called "alt". Try that.

Copy link
Collaborator

@ZhouXing19 ZhouXing19 left a comment

Choose a reason for hiding this comment

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

:lgtm_strong: thanks!

The mac option key is also called "alt". Try that.

Oh, I was pressing the option (⌥) key on my mac.
I did ⌥+shift+/ and ⌥+/, none of them worked. (?== shift + / IIUC)
I also found that "alt+." is for hide/show prompt, but I tried pressing ⌥ + . and it doesn't work either.

Still a bit confused about this but we can bring this offline.

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained

@knz
Copy link
Contributor Author

knz commented Nov 22, 2022

I'm curious which terminal app are you using?

@ZhouXing19
Copy link
Collaborator

Oh, I was pressing the option (⌥) key on my mac.
I did ⌥+shift+/ and ⌥+/, none of them worked. (?== shift + / IIUC)
I also found that "alt+." is for hide/show prompt, but I tried pressing ⌥ + . and it doesn't work either.

Per an offline convo with @knz , this was solved by having Left option key binding to Esc+ in my terminal app. I was having it with Normal.

Release note (cli change): The engine used as line editor in the
interactive shell (`cockroach sql`, `demo`) has been updated. It
includes numerous bug fixes and new features.
The previous engine can still be accessed via the env
var COCKROACH_SQL_FORCE_LIBEDIT. This support will be removed
in a later version.
Release note (cli change): The interactive SQL shell now supports an
advanced debug mode for troubleshooting when `--debug-sql-cli` is
specified on the command line. The debug mode can be enabled with
Ctrl+@ or Ctrl+_ (Ctrl+space on macOS).
@knz
Copy link
Contributor Author

knz commented Dec 1, 2022

bors r=ZhouXing19

@craig
Copy link
Contributor

craig bot commented Dec 1, 2022

Build succeeded:

@craig craig bot merged commit f8bf34c into cockroachdb:master Dec 1, 2022
@knz knz deleted the 20220819-bubbline branch December 4, 2022 13:35
craig bot pushed a commit that referenced this pull request Dec 6, 2022
87606: sql: new heuristic-based completion engine r=rytaft,ZhouXing19 a=knz

This PR extends the server-side completion logic available under SHOW COMPLETIONS.

Fixes #37355.
Intended for use together with #86457.

The statement now returns 5 columns: completion, category, description, start, end.
This change is backward-compatible with the CLI code in previous versions, which was not checking the number of columns.

It works roughly as follows:

1. first the input is scanned into a token array.

2. then the token array is translated to a *sketch*: a string with the
   same length as the token array, where each character corresponds to an
   input token and an extra character indicating where the completion was
   requested.

3. then the completion rules are applied in sequence. Each rule
   inspects the sketch (and/or the token sequence) and decides whether
   to do nothing (skip to next rule), or to run some SQL which will
   return a batch of completion candidates.

   Each method operates exclusively on the token sequence, and does
   not require the overall SQL syntax to be valid or complete.

Also, the completion engine executes in a streaming fashion, so that
there is no need to accumulate all the completion candidates in RAM
before returning them to the client. This prevents excessive
memory usage server-side, and offers the client an option to cancel
the search once enough suggestions have been received.

Code organization:

- new package `sql/compengine`: the core completion engine, also
  where sketches are computed.

  Suggested reading: `api.go` in the new package.

- new package `sql/comprules`: the actual completion
  methods/heuristics, where sketches are mapped into SQL queries
  that provide the completion candidates.

  Suggested reading: the test cases under `testdata`.

Some more words about sketches:

For example, `SHOW COMPLETIONS AT OFFSET 10 FOR 'select myc from
sc.mytable;'` produces the sketch `"ii'ii.i;"` where `i` indicates an
identifier-like token and `'` indicates the cursor position.

The purpose of the sketch is to simplify the pattern matching
performed by the completion heuristics, and enables the application of
regular expressions on the token sequence.

For example, a heuristic to complete schema-qualified relations in
the current database, or a database-qualified relation, would use
the regexp `[^.;]i\.(['_]|i')`: an identifier not following a
period or a semicolon, followed by a period, followed by the
completion cursor (with the cursor either directly after the period
or on an identifier after the period).

Supersedes #45186.



93158: dev: fix bep temporary dir path r=rickystewart a=healthy-pod

Release note: None
Epic: none

Co-authored-by: Raphael 'kena' Poss <knz@thaumogen.net>
Co-authored-by: healthy-pod <ahmad@cockroachlabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants