Skip to content
13 changes: 11 additions & 2 deletions cli/cmd/project/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package project

import (
"fmt"
"strings"

"github.com/rilldata/rill/cli/pkg/cmdutil"
runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1"
"github.com/rilldata/rill/runtime/drivers"
"github.com/spf13/cobra"
"google.golang.org/protobuf/types/known/structpb"
)
Expand Down Expand Up @@ -90,7 +90,7 @@ func TablesCmd(ch *cmdutil.Helper) *cobra.Command {

// Get row count using SQL query
var rowCount string
countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s", drivers.DialectDuckDB.EscapeIdentifier(table.Name))
countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s", escapeIdentifier(table.Name))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Actually on reflection this will fail for BigQuery and possible Snowflake but lets take it up separately.

queryRes, err := rt.RuntimeServiceClient.QueryResolver(cmd.Context(), &runtimev1.QueryResolverRequest{
InstanceId: instanceID,
Resolver: "sql",
Expand Down Expand Up @@ -140,3 +140,12 @@ func must[T any](v T, err error) T {
}
return v
}

func escapeIdentifier(ident string) string {
if ident == "" {
return ident
}
// Most other dialects follow ANSI SQL: use double quotes.
// Replace any internal double quotes with escaped double quotes.
return fmt.Sprintf(`"%s"`, strings.ReplaceAll(ident, `"`, `""`)) // nolint:gocritic
}
15 changes: 15 additions & 0 deletions runtime/drivers/athena/dialect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package athena

import (
"github.com/rilldata/rill/runtime/drivers"
)

type dialect struct {
drivers.BaseDialect
}

var DialectAthena drivers.Dialect = func() drivers.Dialect {
d := &dialect{}
d.BaseDialect = drivers.NewBaseDialect(drivers.DialectNameAthena, drivers.DoubleQuotesEscapeIdentifier, drivers.DoubleQuotesEscapeIdentifier)
return d
}()
2 changes: 1 addition & 1 deletion runtime/drivers/athena/olap.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var _ drivers.OLAPStore = &Connection{}

// Dialect implements drivers.OLAPStore.
func (c *Connection) Dialect() drivers.Dialect {
return drivers.DialectAthena
return DialectAthena
}

// Exec implements drivers.OLAPStore.
Expand Down
27 changes: 27 additions & 0 deletions runtime/drivers/bigquery/dialect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package bigquery

import (
"fmt"
"strings"

"github.com/rilldata/rill/runtime/drivers"
)

type dialect struct {
drivers.BaseDialect
}

var DialectBigQuery drivers.Dialect = func() drivers.Dialect {
d := &dialect{}
d.BaseDialect = drivers.NewBaseDialect(drivers.DialectNameBigQuery, BigQueryEscapeIdentifier, BigQueryEscapeIdentifier)
return d
}()

func BigQueryEscapeIdentifier(ident string) string {
if ident == "" {
return ident
}
// Bigquery uses backticks for quoting identifiers
// Replace any backticks inside the identifier with double backticks
return fmt.Sprintf("`%s`", strings.ReplaceAll(ident, "`", "``"))
}
2 changes: 1 addition & 1 deletion runtime/drivers/bigquery/olap.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var _ drivers.OLAPStore = (*Connection)(nil)

// Dialect implements drivers.OLAPStore.
func (c *Connection) Dialect() drivers.Dialect {
return drivers.DialectBigQuery
return DialectBigQuery
}

// Exec implements drivers.OLAPStore.
Expand Down
6 changes: 3 additions & 3 deletions runtime/drivers/clickhouse/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,12 @@ func (c *Connection) createDictionary(ctx context.Context, name, sql string, out
return fmt.Errorf("clickhouse: no primary key specified for dictionary %q", name)
}

srcTbl := fmt.Sprintf("CLICKHOUSE(TABLE %s)", c.Dialect().EscapeStringValue(tempTable))
srcTbl := fmt.Sprintf("CLICKHOUSE(TABLE %s)", drivers.EscapeStringValue(tempTable))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

May be directly use DialectClickHouse.EscapeStringValue ?

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.

it's same for all.

if outputProps.DictionarySourceUser != "" {
if outputProps.DictionarySourcePassword == "" {
return fmt.Errorf("clickhouse: no password specified for dictionary user")
}
srcTbl = fmt.Sprintf("CLICKHOUSE(TABLE %s USER %s PASSWORD %s)", c.Dialect().EscapeStringValue(tempTable), safeSQLString(outputProps.DictionarySourceUser), safeSQLString(outputProps.DictionarySourcePassword))
srcTbl = fmt.Sprintf("CLICKHOUSE(TABLE %s USER %s PASSWORD %s)", drivers.EscapeStringValue(tempTable), safeSQLString(outputProps.DictionarySourceUser), safeSQLString(outputProps.DictionarySourcePassword))
}

// create dictionary
Expand Down Expand Up @@ -731,5 +731,5 @@ func tempTableForDictionary(name string) string {
}

func safeSQLString(name string) string {
return drivers.DialectClickHouse.EscapeStringValue(name)
return drivers.EscapeStringValue(name)
}
Loading
Loading