Skip to content

Commit

Permalink
Delegate path formatting to NamePath
Browse files Browse the repository at this point in the history
  • Loading branch information
nightscape committed Jan 8, 2025
1 parent 9d65c7d commit 0c73346
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 77 deletions.
1 change: 1 addition & 0 deletions catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type (
NameWithType = internal.NameWithType
ColumnSpec = internal.ColumnSpec
Type = internal.Type
NamePath = internal.NamePath
)

// ChangedCatalogFromRows retrieve modified catalog information from sql.Rows.
Expand Down
4 changes: 2 additions & 2 deletions cmd/zetasqlite-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (cli *CLI) showTablesCommand(ctx context.Context) error {
if err := json.Unmarshal([]byte(spec), &table); err != nil {
return err
}
fmt.Fprintf(cli.out, "%s\n", strings.Join(table.NamePath, "."))
fmt.Fprintf(cli.out, "%s\n", table.NamePath.FormatNamePath())
}
return nil
}
Expand Down Expand Up @@ -231,7 +231,7 @@ func (cli *CLI) showFunctionsCommand(ctx context.Context) error {
if err := json.Unmarshal([]byte(spec), &fn); err != nil {
return err
}
fmt.Fprintf(cli.out, "%s\n", strings.Join(fn.NamePath, "."))
fmt.Fprintf(cli.out, "%s\n", fn.NamePath.FormatNamePath())
}
return nil
}
Expand Down
8 changes: 4 additions & 4 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ CREATE TABLE IF NOT EXISTS Singers (
if len(resultCatalog.Table.Added) != 1 {
t.Fatal("failed to get created table spec")
}
if diff := cmp.Diff(resultCatalog.Table.Added[0].NamePath, []string{"Singers"}); diff != "" {
if diff := cmp.Diff(resultCatalog.Table.Added[0].NamePath.Path(), []string{"Singers"}); diff != "" {
t.Errorf("(-want +got):\n%s", diff)
}
rowsCatalog, err := zetasqlite.ChangedCatalogFromRows(rows)
Expand All @@ -137,7 +137,7 @@ CREATE TABLE IF NOT EXISTS Singers (
if len(rowsCatalog.Table.Deleted) != 1 {
t.Fatal("failed to get deleted table spec")
}
if diff := cmp.Diff(rowsCatalog.Table.Deleted[0].NamePath, []string{"Singers"}); diff != "" {
if diff := cmp.Diff(rowsCatalog.Table.Deleted[0].NamePath.Path(), []string{"Singers"}); diff != "" {
t.Errorf("(-want +got):\n%s", diff)
}
})
Expand Down Expand Up @@ -167,7 +167,7 @@ CREATE TABLE IF NOT EXISTS Singers (
if len(resultCatalog.Function.Added) != 1 {
t.Fatal("failed to get created function spec")
}
if diff := cmp.Diff(resultCatalog.Function.Added[0].NamePath, []string{"ANY_ADD"}); diff != "" {
if diff := cmp.Diff(resultCatalog.Function.Added[0].NamePath.Path(), []string{"ANY_ADD"}); diff != "" {
t.Errorf("(-want +got):\n%s", diff)
}
rowsCatalog, err := zetasqlite.ChangedCatalogFromRows(rows)
Expand All @@ -180,7 +180,7 @@ CREATE TABLE IF NOT EXISTS Singers (
if len(rowsCatalog.Function.Deleted) != 1 {
t.Fatal("failed to get deleted function spec")
}
if diff := cmp.Diff(rowsCatalog.Function.Deleted[0].NamePath, []string{"ANY_ADD"}); diff != "" {
if diff := cmp.Diff(rowsCatalog.Function.Deleted[0].NamePath.Path(), []string{"ANY_ADD"}); diff != "" {
t.Errorf("(-want +got):\n%s", diff)
}
})
Expand Down
2 changes: 1 addition & 1 deletion internal/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (a *Analyzer) SetExplainMode(enabled bool) {
}

func (a *Analyzer) NamePath() []string {
return a.namePath.path
return a.namePath.Path()
}

func (a *Analyzer) SetNamePath(path []string) error {
Expand Down
58 changes: 27 additions & 31 deletions internal/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,23 +147,22 @@ func (c *Catalog) SuggestConstant(mistypedPath []string) string {
return c.catalog.SuggestConstant(mistypedPath)
}

func (c *Catalog) formatNamePath(path []string) string {
return strings.Join(path, "_")
func (c *Catalog) formatNamePath(path *NamePath) string {
return path.FormatNamePath()
}

func (c *Catalog) getFunctions(namePath *NamePath) []*FunctionSpec {
if namePath.empty() {
if namePath.Empty() {
return c.functions
}
key := c.formatNamePath(namePath.path)
key := c.formatNamePath(namePath)
specs := make([]*FunctionSpec, 0, len(c.functions))
for _, fn := range c.functions {
if len(fn.NamePath) == 1 {
// function name only
if fn.NamePath.HasSimpleName() {
specs = append(specs, fn)
continue
}
pathPrefixKey := c.formatNamePath(c.trimmedLastPath(fn.NamePath))
pathPrefixKey := c.formatNamePath(c.trimmedLastPath(&fn.NamePath))
if strings.Contains(pathPrefixKey, key) {
specs = append(specs, fn)
}
Expand Down Expand Up @@ -279,9 +278,9 @@ func (c *Catalog) deleteTableSpecByName(name string) error {
return fmt.Errorf("failed to find table spec from map by %s", name)
}
tables := make([]*TableSpec, 0, len(c.tables))
specName := c.formatNamePath(spec.NamePath)
specName := c.formatNamePath(&spec.NamePath)
for _, table := range c.tables {
if specName == c.formatNamePath(table.NamePath) {
if specName == c.formatNamePath(&table.NamePath) {
continue
}
tables = append(tables, table)
Expand All @@ -298,9 +297,9 @@ func (c *Catalog) deleteFunctionSpecByName(name string) error {
return fmt.Errorf("failed to find function spec from map by %s", name)
}
functions := make([]*FunctionSpec, 0, len(c.functions))
specName := c.formatNamePath(spec.NamePath)
specName := c.formatNamePath(&spec.NamePath)
for _, function := range c.functions {
if specName == c.formatNamePath(function.NamePath) {
if specName == c.formatNamePath(&function.NamePath) {
continue
}
functions = append(functions, function)
Expand Down Expand Up @@ -403,11 +402,8 @@ func (c *Catalog) loadFunctionSpec(spec string) error {
return nil
}

func (c *Catalog) trimmedLastPath(path []string) []string {
if len(path) == 0 {
return path
}
return path[:len(path)-1]
func (c *Catalog) trimmedLastPath(path *NamePath) *NamePath {
return path.dropLast()
}

func (c *Catalog) addFunctionSpec(spec *FunctionSpec) error {
Expand Down Expand Up @@ -439,22 +435,22 @@ func (c *Catalog) addTableSpec(spec *TableSpec) error {
}

func (c *Catalog) addTableSpecRecursive(cat *types.SimpleCatalog, spec *TableSpec) error {
if len(spec.NamePath) > 1 {
subCatalogName := spec.NamePath[0]
if catalogId := spec.NamePath.GetCatalogId(); catalogId != "" {
subCatalogName := catalogId
subCatalog, _ := cat.Catalog(subCatalogName)
if subCatalog == nil {
subCatalog = newSimpleCatalog(subCatalogName)
cat.AddCatalog(subCatalog)
}
fullTableName := strings.Join(spec.NamePath, ".")
fullTableName := spec.NamePath.FormatNamePath()
if !c.existsTable(cat, fullTableName) {
table, err := c.createSimpleTable(fullTableName, spec)
if err != nil {
return err
}
cat.AddTable(table)
}
newNamePath := spec.NamePath[1:]
newNamePath := spec.NamePath.dropFirst()
// add sub catalog to root catalog
if err := c.addTableSpecRecursive(cat, c.copyTableSpec(spec, newNamePath)); err != nil {
return fmt.Errorf("failed to add table spec to root catalog: %w", err)
Expand All @@ -465,11 +461,11 @@ func (c *Catalog) addTableSpecRecursive(cat *types.SimpleCatalog, spec *TableSpe
}
return nil
}
if len(spec.NamePath) == 0 {
tableName := spec.NamePath.GetObjectId()
if spec.NamePath.Empty() {
return fmt.Errorf("table name is not found")
}

tableName := spec.NamePath[0]
if c.existsTable(cat, tableName) {
return nil
}
Expand All @@ -496,14 +492,14 @@ func (c *Catalog) createSimpleTable(tableName string, spec *TableSpec) (*types.S
}

func (c *Catalog) addFunctionSpecRecursive(cat *types.SimpleCatalog, spec *FunctionSpec) error {
if len(spec.NamePath) > 1 {
subCatalogName := spec.NamePath[0]
if catalogId := spec.NamePath.GetCatalogId(); catalogId != "" {
subCatalogName := catalogId
subCatalog, _ := cat.Catalog(subCatalogName)
if subCatalog == nil {
subCatalog = newSimpleCatalog(subCatalogName)
cat.AddCatalog(subCatalog)
}
newNamePath := spec.NamePath[1:]
newNamePath := spec.NamePath.dropFirst()
// add sub catalog to root catalog
if err := c.addFunctionSpecRecursive(cat, c.copyFunctionSpec(spec, newNamePath)); err != nil {
return fmt.Errorf("failed to add function spec to root catalog: %w", err)
Expand All @@ -514,11 +510,11 @@ func (c *Catalog) addFunctionSpecRecursive(cat *types.SimpleCatalog, spec *Funct
}
return nil
}
if len(spec.NamePath) == 0 {
if spec.NamePath.Empty() {
return fmt.Errorf("function name is not found")
}

funcName := spec.NamePath[0]
funcName := spec.NamePath.GetObjectId()
if c.existsFunction(cat, funcName) {
return nil
}
Expand Down Expand Up @@ -558,17 +554,17 @@ func (c *Catalog) isNilTable(t types.Table) bool {
return v.IsNil()
}

func (c *Catalog) copyTableSpec(spec *TableSpec, newNamePath []string) *TableSpec {
func (c *Catalog) copyTableSpec(spec *TableSpec, newNamePath *NamePath) *TableSpec {
return &TableSpec{
NamePath: newNamePath,
NamePath: *newNamePath,
Columns: spec.Columns,
CreateMode: spec.CreateMode,
}
}

func (c *Catalog) copyFunctionSpec(spec *FunctionSpec, newNamePath []string) *FunctionSpec {
func (c *Catalog) copyFunctionSpec(spec *FunctionSpec, newPath *NamePath) *FunctionSpec {
return &FunctionSpec{
NamePath: newNamePath,
NamePath: *newPath,
Language: spec.Language,
Args: spec.Args,
Return: spec.Return,
Expand Down
116 changes: 106 additions & 10 deletions internal/name_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,27 @@ package internal
import (
"fmt"
"strings"

"github.com/goccy/go-json"
)

type NamePath struct {
path []string
maxNum int
}

func (p *NamePath) Clone() *NamePath {
return &NamePath{path: append([]string{}, p.path...)}
}

func (p *NamePath) MarshalJSON() ([]byte, error) {
return json.Marshal(p.path)
}

func (p *NamePath) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, &p.path)
}

func (p *NamePath) isInformationSchema(path []string) bool {
if len(path) == 0 {
return false
Expand Down Expand Up @@ -50,14 +64,14 @@ func (p *NamePath) normalizePath(path []string) []string {
return ret
}

func (p *NamePath) mergePath(path []string) []string {
func (p *NamePath) mergePath(path []string) *NamePath {
path = p.normalizePath(path)
maxNum := p.getMaxNum(path)
if maxNum > 0 && len(path) == maxNum {
return path
if maxNum > 0 && p.hasMaxComponents(path) {
return &NamePath{path: path}
}
if len(path) == 0 {
return p.path
return &NamePath{path: p.path}
}
merged := []string{}
for _, basePath := range p.path {
Expand All @@ -69,15 +83,37 @@ func (p *NamePath) mergePath(path []string) []string {
}
merged = append(merged, basePath)
}
return append(merged, path...)
return &NamePath{path: append(merged, path...)}
}

func (p *NamePath) format(path []string) string {
return formatPath(p.mergePath(path))
mergedPath := p.mergePath(path)
return mergedPath.FormatNamePath()
}

func (p *NamePath) dropFirst() *NamePath {
if p.Empty() {
return p
}
return &NamePath{path: p.path[1:]}
}

func (p *NamePath) dropLast() *NamePath {
if p.Empty() {
return p
}
return &NamePath{path: p.path[:len(p.path)-1]}
}

func (p *NamePath) FormatNamePath() string {
if p.HasFullyQualifiedName() {
return fmt.Sprintf("%s.%s", p.GetProjectId(), strings.Join(p.path[1:], "_"))
}
return strings.Join(p.path, "_")
}

func formatPath(path []string) string {
return strings.Join(path, "_")
func (p *NamePath) Path() []string {
return p.path
}

func (p *NamePath) setPath(path []string) error {
Expand Down Expand Up @@ -106,6 +142,66 @@ func (p *NamePath) addPath(path string) error {
return nil
}

func (p *NamePath) empty() bool {
return len(p.path) == 0
func (p *NamePath) replace(index int, value string) {
p.path[index] = value
}

func (p *NamePath) Length() int {
return len(p.path)
}

func (p *NamePath) Empty() bool {
return p.Length() == 0
}

func (p *NamePath) GetCatalogId() string {
if p.Length() < 2 {
return ""
}
return p.path[0]
}

func (p *NamePath) GetProjectId() string {
if p.Length() < 3 {
return ""
}
return p.path[0]
}

func (p *NamePath) GetDatasetId() string {
if p.Length() < 2 {
return ""
} else if p.Length() == 2 {
return p.path[0]
} else {
return p.path[1]
}
}

func (p *NamePath) GetObjectId() string {
if p.Empty() {
return ""
}
return p.path[p.Length()-1]
}

func (p *NamePath) HasSimpleName() bool {
return p.Length() == 1
}

func (p *NamePath) HasQualifiers() bool {
return p.Length() > 1
}

func (p *NamePath) HasFullyQualifiedName() bool {
return p.Length() > 2
}

func (p *NamePath) hasMaxComponents(path []string) bool {
maxNum := p.getMaxNum(path)
return maxNum > 0 && len(path) == maxNum
}

func NewNamePath(path []string) *NamePath {
return &NamePath{path: path}
}
Loading

0 comments on commit 0c73346

Please sign in to comment.