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

fix(go/adbc/driver/snowflake): fix setting database and schema context after initial connection #2169

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

Conversation

davidhcoe
Copy link
Contributor

This PR removes the parameterization for calls to USE DATABASE and USE SCHEMA, which isn't supported for Snowflake DDL. It also modifies the GetObjects call to set the context to the database and schema, since the GetObjects call uses a sql.DB connection context instead of the snowflakeConn connection context.

Fixes #2167

Fixes #2168

@github-actions github-actions bot added this to the ADBC Libraries 15 milestone Sep 19, 2024
@davidhcoe davidhcoe changed the title fix(go/adbc/driver/snowflake): fix setting database and schema context after initial connection fix(go/adbc/driver/snowflake): fix setting database and schema context after initial connection Sep 19, 2024
Copy link
Contributor

@CurtHagenlocher CurtHagenlocher left a comment

Choose a reason for hiding this comment

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

Thanks for the fix! Please see comments.

public static string CurrentDbSchemaOption = "adbc.connection.db_schema";
public static string ReadOnlyOption = "adbc.connection.readonly";
public static string AutoCommitOption = "adbc.connection.autocommit";

Copy link
Contributor

Choose a reason for hiding this comment

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

These are currently in the AdbcOptions class e.g. AdbcOptions.Connection.CurrentCatalog. Are you thinking that that class should be deprecated in favor of distributing them into the connection/statement/etc. classes? I seem to recall that there were some cross-cutting concerns that made it desirable to keep them under AdbcOptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

honestly, just didn't realize those were even there :/

@@ -239,13 +261,13 @@ func (c *connectionImpl) GetCurrentDbSchema() (string, error) {

// SetCurrentCatalog implements driverbase.CurrentNamespacer.
func (c *connectionImpl) SetCurrentCatalog(value string) error {
_, err := c.cn.ExecContext(context.Background(), "USE DATABASE ?", []driver.NamedValue{{Value: value}})
_, err := c.cn.ExecContext(context.Background(), fmt.Sprintf("USE DATABASE %s", value), nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Bobby Tables says never to forget about quoting SQL identifiers properly. Snowflake identifiers can contain spaces and double-quotes and semicolons, and are quoted by using delimiting with double-quotes and doubling any contained double-quotes. That is, A -> "A", A B -> "A B", A B / C" ; D->"A B / C"" ; D"`. (This is pretty consistent with most SQL dialects.

Copy link
Contributor

Choose a reason for hiding this comment

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

Bah, I've succeeded in confusing the "code" feature of Markdown. That last substitution should be
A B / C" ; D -> "A B / C"" ; D"

Copy link
Member

Choose a reason for hiding this comment

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

Could we use snowflake's IDENTIFIER(...) function here?

e.g. fmt.Sprintf("USE DATABASE IDENTIFIER('%s')", value)

That should eliminate possible injection scenarios, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't work, unfortunately. (I tried it specifically, and it's also not usually how SQL grammars work: you can't usually supply an expression here, only an identifier.)

Copy link
Contributor

@CurtHagenlocher CurtHagenlocher Sep 19, 2024

Choose a reason for hiding this comment

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

(I also feel obliged to point out that any single quotes in the identifier would need to be escaped in that variant, if it did happen to work.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

went with Matt's suggestion

Copy link
Member

Choose a reason for hiding this comment

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

I thought we had a proper quote function? Can we use that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we have quoteTblName(...)

Copy link
Contributor

@CurtHagenlocher CurtHagenlocher Sep 20, 2024

Choose a reason for hiding this comment

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

quoteTblName is what we should be using

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -32,6 +32,7 @@ public abstract class AdbcConnection11 : IDisposable
, IAsyncDisposable
#endif
{

Copy link
Contributor

Choose a reason for hiding this comment

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

Consider removing added whitespace

Copy link
Contributor

@CurtHagenlocher CurtHagenlocher left a comment

Choose a reason for hiding this comment

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

Looks good to me, but I'd be happy for a second opinion.

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