From 8d6bdf7bc016cb8c6c126d0662004d30eaccab1d Mon Sep 17 00:00:00 2001 From: James Cor Date: Wed, 16 Oct 2024 16:21:42 -0700 Subject: [PATCH 1/6] remove unused code/parameters --- sql/analyzer/analyzer.go | 2 +- sql/analyzer/autocommit.go | 16 +--------------- sql/analyzer/node_batches.go | 4 ++-- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/sql/analyzer/analyzer.go b/sql/analyzer/analyzer.go index 227d3aafd7..1ecc17bbad 100644 --- a/sql/analyzer/analyzer.go +++ b/sql/analyzer/analyzer.go @@ -518,7 +518,7 @@ func (a *Analyzer) analyzeWithSelector(ctx *sql.Context, n sql.Node, scope *plan a.LogNode(n) batches := a.Batches - if b, ok := getBatchesForNode(n, batches); ok { + if b, ok := getBatchesForNode(n); ok { batches = b } diff --git a/sql/analyzer/autocommit.go b/sql/analyzer/autocommit.go index f720736be9..3af97ef7cb 100644 --- a/sql/analyzer/autocommit.go +++ b/sql/analyzer/autocommit.go @@ -31,18 +31,4 @@ func addAutocommit(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, return n, transform.SameTree, nil } return plan.NewTransactionCommittingNode(n), transform.NewTree, nil -} - -func hasShowWarningsNode(n sql.Node) bool { - var ret bool - transform.Inspect(n, func(n sql.Node) bool { - if _, ok := n.(plan.ShowWarnings); ok { - ret = true - return false - } - - return true - }) - - return ret -} +} \ No newline at end of file diff --git a/sql/analyzer/node_batches.go b/sql/analyzer/node_batches.go index d824d58dfd..78fa6e234a 100644 --- a/sql/analyzer/node_batches.go +++ b/sql/analyzer/node_batches.go @@ -7,8 +7,8 @@ import ( // getBatchesForNode returns a partial analyzer ruleset for simple node // types that require little prior validation before execution. -func getBatchesForNode(n sql.Node, orig []*Batch) ([]*Batch, bool) { - switch n := n.(type) { +func getBatchesForNode(node sql.Node) ([]*Batch, bool) { + switch n := node.(type) { case *plan.Commit: return nil, true case *plan.StartTransaction: From 427bb036ce284200583ca70e184eba3f71711590 Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 17 Oct 2024 11:11:16 -0700 Subject: [PATCH 2/6] remove unused aggregation rules --- sql/analyzer/aggregations.go | 257 ----------------------------------- 1 file changed, 257 deletions(-) delete mode 100644 sql/analyzer/aggregations.go diff --git a/sql/analyzer/aggregations.go b/sql/analyzer/aggregations.go deleted file mode 100644 index cf5d85031c..0000000000 --- a/sql/analyzer/aggregations.go +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright 2020-2021 Dolthub, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package analyzer - -import ( - "github.com/dolthub/go-mysql-server/sql" - "github.com/dolthub/go-mysql-server/sql/expression" - "github.com/dolthub/go-mysql-server/sql/expression/function/aggregation" - "github.com/dolthub/go-mysql-server/sql/plan" - "github.com/dolthub/go-mysql-server/sql/transform" - "github.com/dolthub/go-mysql-server/sql/types" -) - -// flattenAggregationExpressions flattens any complex aggregate or window expressions in a GroupBy or Window node and -// adds a projection on top of the result. The child terms of any complex expressions get pushed down to become selected -// expressions in the GroupBy or Window, and then a new project node re-applies the original expression to the new -// schema of the flattened node. -// e.g. GroupBy(sum(a) + sum(b)) becomes project(sum(a) + sum(b), GroupBy(sum(a), sum(b)). -// e.g. Window(sum(a) + sum(b) over (partition by a)) becomes -// project(sum(a) + sum(b) over (partition by a), Window(sum(a), sum(b) over (partition by a))). -func flattenAggregationExpressions(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) { - span, ctx := ctx.Span("flatten_aggregation_exprs") - defer span.End() - - if !n.Resolved() { - return n, transform.SameTree, nil - } - - return transform.Node(n, func(n sql.Node) (sql.Node, transform.TreeIdentity, error) { - switch n := n.(type) { - case *plan.Window: - if !hasHiddenAggregations(n.SelectExprs) && !hasHiddenWindows(n.SelectExprs) { - return n, transform.SameTree, nil - } - - return flattenedWindow(ctx, scope, n.SelectExprs, n.Child) - case *plan.GroupBy: - if !hasHiddenAggregations(n.SelectedExprs) { - return n, transform.SameTree, nil - } - - return flattenedGroupBy(ctx, scope, n.SelectedExprs, n.GroupByExprs, n.Child) - default: - return n, transform.SameTree, nil - } - }) -} - -func flattenedGroupBy(ctx *sql.Context, scope *plan.Scope, projection, grouping []sql.Expression, child sql.Node) (sql.Node, transform.TreeIdentity, error) { - newProjection, newAggregates, allSame, err := replaceAggregatesWithGetFieldProjections(ctx, scope, projection) - if err != nil { - return nil, transform.SameTree, err - } - if allSame { - return nil, transform.SameTree, nil - } - return plan.NewProject( - newProjection, - plan.NewGroupBy(newAggregates, grouping, child), - ), transform.NewTree, nil -} - -// replaceAggregatesWithGetFieldProjections inserts an indirection Projection -// between an aggregation and its scope output, resulting in two buckets of -// expressions: -// 1) Parent projection expressions. -// 2) Child aggregation expressions. -// -// A scope always returns a fixed number of columns, so the number of projection -// inputs and outputs must match. -// -// The aggregation must provide input dependencies for parent projections. -// Each parent expression can depend on zero or many aggregation expressions. -// There are two basic kinds of aggregation expressions: -// 1) Passthrough columns from scope input relation. -// 2) Synthesized columns from in-scope aggregation relation. -func replaceAggregatesWithGetFieldProjections(_ *sql.Context, scope *plan.Scope, projection []sql.Expression) (projections, aggregations []sql.Expression, identity transform.TreeIdentity, err error) { - var newProjection = make([]sql.Expression, len(projection)) - var newAggregates []sql.Expression - scopeLen := len(scope.Schema()) - aggPassthrough := make(map[string]struct{}) - /* every aggregation creates one pass-through reference into parent */ - for i, p := range projection { - e, same, err := transform.Expr(p, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) { - switch e := e.(type) { - case sql.Aggregation, sql.WindowAggregation: - newAggregates = append(newAggregates, e) - aggPassthrough[e.String()] = struct{}{} - typ := e.Type() - switch e.(type) { - case *aggregation.Sum, *aggregation.Avg: - typ = types.Float64 - case *aggregation.Count: - typ = types.Int64 - } - return expression.NewGetField(scopeLen+len(newAggregates)-1, typ, e.String(), e.IsNullable()), transform.NewTree, nil - default: - return e, transform.SameTree, nil - } - }) - if err != nil { - return nil, nil, transform.SameTree, err - } - - if same { - var getField *expression.GetField - // add to plan.GroupBy.SelectedExprs iff expression has an expression.GetField - hasGetField := transform.InspectExpr(e, func(expr sql.Expression) bool { - gf, ok := expr.(*expression.GetField) - if ok { - getField = gf - } - return ok - }) - if hasGetField { - newAggregates = append(newAggregates, e) - name, source := getNameAndSource(e) - newProjection[i] = expression.NewGetFieldWithTable( - scopeLen+len(newAggregates)-1, int(getField.TableId()), e.Type(), getField.Database(), source, name, e.IsNullable(), - ) - } else { - newProjection[i] = e - } - } else { - newProjection[i] = e - transform.InspectExpr(e, func(e sql.Expression) bool { - // clean up projection dependency columns not synthesized by - // aggregation. - switch e := e.(type) { - case *expression.GetField: - if _, ok := aggPassthrough[e.Name()]; !ok { - // this is a column input to the projection that - // the aggregation parent has not passed-through. - // TODO: for functions without aggregate dependency, - // we just execute the function in the aggregation. - // why don't we do that for both? - newAggregates = append(newAggregates, e) - } - default: - } - return false - }) - } - } - - return newProjection, newAggregates, transform.NewTree, nil -} - -func flattenedWindow(ctx *sql.Context, scope *plan.Scope, projection []sql.Expression, child sql.Node) (sql.Node, transform.TreeIdentity, error) { - newProjection, newAggregates, allSame, err := replaceAggregatesWithGetFieldProjections(ctx, scope, projection) - if err != nil { - return nil, transform.SameTree, err - } - if allSame { - return nil, allSame, nil - } - return plan.NewProject( - newProjection, - plan.NewWindow(newAggregates, child), - ), transform.NewTree, nil -} - -func getNameAndSource(e sql.Expression) (name, source string) { - if n, ok := e.(sql.Nameable); ok { - name = n.Name() - } else { - name = e.String() - } - - if t, ok := e.(sql.Tableable); ok { - source = t.Table() - } - - return -} - -// hasHiddenAggregations returns whether any of the given expressions has a hidden aggregation. That is, an aggregation -// that is not at the root of the expression. -func hasHiddenAggregations(exprs []sql.Expression) bool { - for _, e := range exprs { - if containsHiddenAggregation(e) { - return true - } - } - return false -} - -// containsHiddenAggregation returns whether the given expressions has a hidden aggregation. That is, an aggregation -// that is not at the root of the expression. -func containsHiddenAggregation(e sql.Expression) bool { - _, ok := e.(sql.Aggregation) - if ok { - return false - } - - return containsAggregation(e) -} - -// containsAggregation returns whether the expression given contains any sql.Aggregation terms. -func containsAggregation(e sql.Expression) bool { - var hasAgg bool - sql.Inspect(e, func(e sql.Expression) bool { - if _, ok := e.(sql.Aggregation); ok { - hasAgg = true - return false - } - return true - }) - return hasAgg -} - -// hasHiddenWindows returns whether any of the given expression have a hidden window function. That is, a window -// function that is not at the root of the expression. -func hasHiddenWindows(exprs []sql.Expression) bool { - for _, e := range exprs { - if containsHiddenWindow(e) { - return true - } - } - return false -} - -// containsHiddenWindow returns whether the given expression has a hidden window function. That is, a window function -// that is not at the root of the expression. -func containsHiddenWindow(e sql.Expression) bool { - _, ok := e.(sql.WindowAggregation) - if ok { - return false - } - - return containsWindow(e) -} - -// containsWindow returns whether the expression given contains any sql.WindowAggregation terms. -func containsWindow(e sql.Expression) bool { - var hasAgg bool - sql.Inspect(e, func(e sql.Expression) bool { - if _, ok := e.(sql.WindowAggregation); ok { - hasAgg = true - return false - } - return true - }) - return hasAgg -} From e5fa6c12ad500a354c2c143eca9e37b0b22cecb6 Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 17 Oct 2024 11:11:25 -0700 Subject: [PATCH 3/6] simplify aliases --- sql/analyzer/aliases.go | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/sql/analyzer/aliases.go b/sql/analyzer/aliases.go index a3dc4ef508..dded7c2399 100644 --- a/sql/analyzer/aliases.go +++ b/sql/analyzer/aliases.go @@ -294,25 +294,6 @@ func aliasedExpressionsInNode(n sql.Node) map[string]string { return aliasesFromExpressionToName } -// aliasesDefinedInNode returns the expression aliases that are defined in the first Projector node found, starting -// the search from the specified node. All returned alias names are normalized to lower case. -func aliasesDefinedInNode(n sql.Node) []string { - projector := findFirstProjectorNode(n) - if projector == nil { - return nil - } - - var aliases []string - for _, e := range projector.ProjectedExprs() { - alias, ok := e.(*expression.Alias) - if ok { - aliases = append(aliases, strings.ToLower(alias.Name())) - } - } - - return aliases -} - // normalizeExpressions returns the expressions given after normalizing them to replace table and expression aliases // with their underlying names. This is necessary to match such expressions against those declared by implementors of // various interfaces that declare expressions to handle, such as Index.Expressions(), FilteredTable, etc. From 362f4e4b992731e113e4a6da3cb285f79e02ae5c Mon Sep 17 00:00:00 2001 From: jycor Date: Thu, 17 Oct 2024 18:13:43 +0000 Subject: [PATCH 4/6] [ga-format-pr] Run ./format_repo.sh to fix formatting --- sql/analyzer/autocommit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/analyzer/autocommit.go b/sql/analyzer/autocommit.go index 3af97ef7cb..e1ffbd1aa0 100644 --- a/sql/analyzer/autocommit.go +++ b/sql/analyzer/autocommit.go @@ -31,4 +31,4 @@ func addAutocommit(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, return n, transform.SameTree, nil } return plan.NewTransactionCommittingNode(n), transform.NewTree, nil -} \ No newline at end of file +} From e65325c14150aa5921b315edc0aad626e7f1cb1f Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 17 Oct 2024 11:23:12 -0700 Subject: [PATCH 5/6] remove more dead code --- sql/analyzer/indexed_joins.go | 21 --- sql/analyzer/inserts.go | 24 ---- sql/analyzer/optimization_rules.go | 19 --- sql/analyzer/replace_window_names.go | 208 --------------------------- sql/analyzer/resolve_ctes.go | 2 - sql/analyzer/resolve_subqueries.go | 24 ---- sql/analyzer/tables.go | 26 +--- sql/analyzer/validation_rules.go | 23 --- 8 files changed, 1 insertion(+), 346 deletions(-) delete mode 100644 sql/analyzer/replace_window_names.go diff --git a/sql/analyzer/indexed_joins.go b/sql/analyzer/indexed_joins.go index 37a0b23e38..e57cf6662a 100644 --- a/sql/analyzer/indexed_joins.go +++ b/sql/analyzer/indexed_joins.go @@ -1387,24 +1387,3 @@ func isWeaklyMonotonic(e sql.Expression) bool { } }) } - -// attrsRefSingleTableCol returns false if there are -// getFields sourced from zero or more than one table. -func attrsRefSingleTableCol(e sql.Expression) (tableCol, bool) { - var tc tableCol - var invalid bool - transform.InspectExpr(e, func(e sql.Expression) bool { - switch e := e.(type) { - case *expression.GetField: - newTc := newTableCol(e.Table(), e.Name()) - if tc.table == "" && !invalid { - tc = newTc - } else if tc != newTc { - invalid = true - } - default: - } - return invalid - }) - return tc, !invalid && tc.table != "" -} diff --git a/sql/analyzer/inserts.go b/sql/analyzer/inserts.go index c622681a94..fdc2040219 100644 --- a/sql/analyzer/inserts.go +++ b/sql/analyzer/inserts.go @@ -331,27 +331,3 @@ func isAutoUuidColumn(col *sql.Column) bool { return false } - -// validGeneratedColumnValue returns true if the column is a generated column and the source node is not a values node. -// Explicit default values (`DEFAULT`) are the only valid values to specify for a generated column -func validGeneratedColumnValue(idx int, source sql.Node) bool { - switch source := source.(type) { - case *plan.Values: - for _, tuple := range source.ExpressionTuples { - switch val := tuple[idx].(type) { - case *sql.ColumnDefaultValue: // should be wrapped, but just in case - return true - case *expression.Wrapper: - if _, ok := val.Unwrap().(*sql.ColumnDefaultValue); ok { - return true - } - return false - default: - return false - } - } - return false - default: - return false - } -} diff --git a/sql/analyzer/optimization_rules.go b/sql/analyzer/optimization_rules.go index cb20012c91..f5835f1d7d 100644 --- a/sql/analyzer/optimization_rules.go +++ b/sql/analyzer/optimization_rules.go @@ -145,25 +145,6 @@ func moveJoinConditionsToFilter(ctx *sql.Context, a *Analyzer, n sql.Node, scope }) } -// containsSources checks that all `needle` sources are contained inside `haystack`. -func containsSources(haystack, needle []sql.TableId) bool { - for _, s := range needle { - var found bool - for _, s2 := range haystack { - if s2 == s { - found = true - break - } - } - - if !found { - return false - } - } - - return true -} - // nodeSources returns the set of column sources from the schema of the node given. func nodeSources(n sql.Node) sql.FastIntSet { var tables sql.FastIntSet diff --git a/sql/analyzer/replace_window_names.go b/sql/analyzer/replace_window_names.go deleted file mode 100644 index f8f739beb8..0000000000 --- a/sql/analyzer/replace_window_names.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2022 DoltHub, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package analyzer - -import ( - "github.com/dolthub/go-mysql-server/sql" - "github.com/dolthub/go-mysql-server/sql/expression" - "github.com/dolthub/go-mysql-server/sql/plan" - "github.com/dolthub/go-mysql-server/sql/transform" -) - -// replaceNamedWindows will 1) extract window definitions from a *plan.NamedWindows node, -// 2) resolve window name references, 3) embed resolved window definitions in sql.Window clauses -// (currently in expression.UnresolvedFunction instances), and 4) replace the plan.NamedWindows -// node with its child *plan.Window. -func replaceNamedWindows(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) { - return transform.Node(n, func(n sql.Node) (sql.Node, transform.TreeIdentity, error) { - switch n.(type) { - case *plan.NamedWindows: - wn, ok := n.(*plan.NamedWindows) - if !ok { - return n, transform.SameTree, nil - } - - window, ok := wn.Child.(*plan.Window) - if !ok { - return n, transform.SameTree, nil - } - - err := checkCircularWindowDef(wn.WindowDefs) - if err != nil { - return nil, transform.SameTree, err - } - - // find and replace over expressions with new window definitions - // over sql.Windows are in unresolved aggregation functions - newExprs := make([]sql.Expression, len(window.SelectExprs)) - same := transform.SameTree - for i, expr := range window.SelectExprs { - newExprs[i], _, err = transform.Expr(expr, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) { - uf, ok := e.(*expression.UnresolvedFunction) - if !ok { - return e, transform.SameTree, nil - } - if uf.Window == nil { - return e, transform.SameTree, nil - } - newWindow, sameDef, err := resolveWindowDef(uf.Window, wn.WindowDefs) - if err != nil { - return nil, transform.SameTree, err - } - same = same && sameDef - if sameDef { - return expr, transform.SameTree, nil - } - return uf.WithWindow(newWindow), transform.NewTree, nil - }) - if err != nil { - return nil, transform.SameTree, err - } - } - if same { - return window, transform.SameTree, nil - } - return plan.NewWindow(newExprs, window.Child), transform.NewTree, nil - } - return n, transform.SameTree, nil - }) -} - -// checkCircularWindowDef verifies that window references terminate -// with concrete definitions. We use a linked-list algorithm -// because a sql.WindowDefinition can have at most one [Ref]. -func checkCircularWindowDef(windowDefs map[string]*sql.WindowDefinition) error { - var head, tail *sql.WindowDefinition - for _, def := range windowDefs { - if def.Ref == "" { - continue - } - head = def - head = windowDefs[head.Ref] - tail = def - for head != nil && tail != nil && head != tail { - tail = windowDefs[tail.Ref] - head = windowDefs[head.Ref] - if head != nil { - head = windowDefs[head.Ref] - } - } - if head != nil && head == tail { - return sql.ErrCircularWindowInheritance.New() - } - } - return nil -} - -// resolveWindowDef uses DFS to walk the [windowDefs] adjacency list, resolving and merging -// all named windows required to define the topmost window of concern. -// A WindowDefinition is considered resolved when its [Ref] is empty. Otherwise, we recurse -// to define that Ref'd window, before finally merging the resolved ref with the original window -// definition. -// A sql.WindowDef can have at most one named reference. -// We cache merged definitions in [windowDefs] to aid subsequent lookups. -func resolveWindowDef(n *sql.WindowDefinition, windowDefs map[string]*sql.WindowDefinition) (*sql.WindowDefinition, transform.TreeIdentity, error) { - // base case - if n.Ref == "" { - return n, transform.SameTree, nil - } - - var err error - ref, ok := windowDefs[n.Ref] - if !ok { - return nil, transform.SameTree, sql.ErrUnknownWindowName.New(n.Ref) - } - - // recursively resolve [n.Ref] - ref, _, err = resolveWindowDef(ref, windowDefs) - if err != nil { - return nil, transform.SameTree, err - } - - // [n] is fully defined by its attributes merging with the named reference - n, err = mergeWindowDefs(n, ref) - if err != nil { - return nil, transform.SameTree, err - } - - if n.Name != "" { - // cache lookup - windowDefs[n.Name] = n - } - return n, transform.NewTree, nil -} - -// mergeWindowDefs combines the attributes of two window definitions or returns -// an error if the two are incompatible. [def] should have a reference to -// [ref] through [def.Ref], and the return value drops the reference to indicate -// the two were properly combined. -func mergeWindowDefs(def, ref *sql.WindowDefinition) (*sql.WindowDefinition, error) { - if ref.Ref != "" { - panic("unreachable; cannot merge unresolved window definition") - } - - var orderBy sql.SortFields - switch { - case len(def.OrderBy) > 0 && len(ref.OrderBy) > 0: - return nil, sql.ErrInvalidWindowInheritance.New("", "", "both contain order by clause") - case len(def.OrderBy) > 0: - orderBy = def.OrderBy - case len(ref.OrderBy) > 0: - orderBy = ref.OrderBy - default: - } - - var partitionBy []sql.Expression - switch { - case len(def.PartitionBy) > 0 && len(ref.PartitionBy) > 0: - return nil, sql.ErrInvalidWindowInheritance.New("", "", "both contain partition by clause") - case len(def.PartitionBy) > 0: - partitionBy = def.PartitionBy - case len(ref.PartitionBy) > 0: - partitionBy = ref.PartitionBy - default: - partitionBy = []sql.Expression{} - } - - var frame sql.WindowFrame - switch { - case def.Frame != nil && ref.Frame != nil: - _, isDefDefaultFrame := def.Frame.(*plan.RowsUnboundedPrecedingToUnboundedFollowingFrame) - _, isRefDefaultFrame := ref.Frame.(*plan.RowsUnboundedPrecedingToUnboundedFollowingFrame) - - // if both frames are set and one is RowsUnboundedPrecedingToUnboundedFollowingFrame (default), - // we should use the other frame - if isDefDefaultFrame { - frame = ref.Frame - } else if isRefDefaultFrame { - frame = def.Frame - } else { - // if both frames have identical string representations, use either one - df := def.Frame.String() - rf := ref.Frame.String() - if df != rf { - return nil, sql.ErrInvalidWindowInheritance.New("", "", "both contain different frame clauses") - } - frame = def.Frame - } - case def.Frame != nil: - frame = def.Frame - case ref.Frame != nil: - frame = ref.Frame - default: - } - - return sql.NewWindowDefinition(partitionBy, orderBy, frame, "", def.Name), nil -} diff --git a/sql/analyzer/resolve_ctes.go b/sql/analyzer/resolve_ctes.go index db92d47fd9..a9a60a435d 100644 --- a/sql/analyzer/resolve_ctes.go +++ b/sql/analyzer/resolve_ctes.go @@ -20,8 +20,6 @@ import ( "github.com/dolthub/go-mysql-server/sql/transform" ) -const maxCteDepth = 5 - // schemaLength returns the length of a node's schema without actually accessing it. Useful when a node isn't yet // resolved, so Schema() could fail. func schemaLength(node sql.Node) int { diff --git a/sql/analyzer/resolve_subqueries.go b/sql/analyzer/resolve_subqueries.go index 892c04e9e3..c774ed6a8c 100644 --- a/sql/analyzer/resolve_subqueries.go +++ b/sql/analyzer/resolve_subqueries.go @@ -218,30 +218,6 @@ func resolveSubqueriesHelper(ctx *sql.Context, a *Analyzer, node sql.Node, scope }) } -// flattenTableAliases transforms TableAlias nodes that contain a SubqueryAlias or TableAlias node as the immediate -// child so that the top level TableAlias is removed and the nested SubqueryAlias or nested TableAlias is the new top -// level node, making sure to capture the alias name and transfer it to the new node. The parser doesn't directly -// create this nested structure; it occurs as the execution plan is built and altered during analysis, for -// example with CTEs that get plugged into the execution plan as the analyzer processes it. -func flattenTableAliases(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) { - span, ctx := ctx.Span("flatten_table_aliases") - defer span.End() - return transform.Node(n, func(n sql.Node) (sql.Node, transform.TreeIdentity, error) { - switch n := n.(type) { - case *plan.TableAlias: - if sa, isSA := n.Children()[0].(*plan.SubqueryAlias); isSA { - return sa.WithName(n.Name()), transform.NewTree, nil - } - if ta, isTA := n.Children()[0].(*plan.TableAlias); isTA { - return ta.WithName(n.Name()), transform.NewTree, nil - } - return n, transform.SameTree, nil - default: - return n, transform.SameTree, nil - } - }) -} - // analyzeSubqueryExpression runs analysis on the specified subquery expression, |sq|. The specified node |n| is the node // that contains the subquery expression and |finalize| indicates if this is the final run of the analyzer on the query // before execution, which means all analyzer rules are included, otherwise SubqueryExprResolveSelector is used to prevent diff --git a/sql/analyzer/tables.go b/sql/analyzer/tables.go index 4d2336901e..bac76b7526 100644 --- a/sql/analyzer/tables.go +++ b/sql/analyzer/tables.go @@ -18,8 +18,7 @@ import ( "strings" "github.com/dolthub/go-mysql-server/sql" - "github.com/dolthub/go-mysql-server/sql/expression" - "github.com/dolthub/go-mysql-server/sql/plan" + "github.com/dolthub/go-mysql-server/sql/plan" "github.com/dolthub/go-mysql-server/sql/transform" ) @@ -148,26 +147,3 @@ func getTablesByName(node sql.Node) map[string]*plan.ResolvedTable { return ret } - -// Returns the tables used in the expressions given -func findTables(exprs ...sql.Expression) []string { - tables := make(map[string]bool) - for _, e := range exprs { - sql.Inspect(e, func(e sql.Expression) bool { - switch e := e.(type) { - case *expression.GetField: - tables[e.Table()] = true - return false - default: - return true - } - }) - } - - var names []string - for table := range tables { - names = append(names, table) - } - - return names -} diff --git a/sql/analyzer/validation_rules.go b/sql/analyzer/validation_rules.go index 224cf6c89d..4325f3acd9 100644 --- a/sql/analyzer/validation_rules.go +++ b/sql/analyzer/validation_rules.go @@ -235,20 +235,6 @@ func validateDeleteFrom(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.S } } -// checkSqlMode checks if the option is set for the Session in ctx -func checkSqlMode(ctx *sql.Context, option string) (bool, error) { - // session variable overrides global - sysVal, err := ctx.Session.GetSessionVariable(ctx, "sql_mode") - if err != nil { - return false, err - } - val, ok := sysVal.(string) - if !ok { - return false, sql.ErrSystemVariableCodeFail.New("sql_mode", val) - } - return strings.Contains(val, option), nil -} - func validateGroupBy(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) { if !FlagIsSet(qFlags, sql.QFlagAggregation) { return n, transform.SameTree, nil @@ -668,15 +654,6 @@ func stringContains(strs []string, target string) bool { return false } -func tableColsContains(strs []tableCol, target tableCol) bool { - for _, s := range strs { - if s == target { - return true - } - } - return false -} - // validateReadOnlyDatabase invalidates queries that attempt to write to ReadOnlyDatabases. func validateReadOnlyDatabase(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) { valid := true From 3cbd342dc2d4ab3669b3bba9345fb6691c4a2e1e Mon Sep 17 00:00:00 2001 From: jycor Date: Thu, 17 Oct 2024 18:24:40 +0000 Subject: [PATCH 6/6] [ga-format-pr] Run ./format_repo.sh to fix formatting --- sql/analyzer/tables.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/analyzer/tables.go b/sql/analyzer/tables.go index bac76b7526..d496646485 100644 --- a/sql/analyzer/tables.go +++ b/sql/analyzer/tables.go @@ -18,7 +18,7 @@ import ( "strings" "github.com/dolthub/go-mysql-server/sql" - "github.com/dolthub/go-mysql-server/sql/plan" + "github.com/dolthub/go-mysql-server/sql/plan" "github.com/dolthub/go-mysql-server/sql/transform" )