diff --git a/ast/ast.go b/ast/ast.go index 7330196296..44e1209e07 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -72,7 +72,8 @@ type SelectQuery struct { Having Expression `json:"having,omitempty"` Qualify Expression `json:"qualify,omitempty"` Window []*WindowDefinition `json:"window,omitempty"` - OrderBy []*OrderByElement `json:"order_by,omitempty"` + OrderBy []*OrderByElement `json:"order_by,omitempty"` + Interpolate []*InterpolateElement `json:"interpolate,omitempty"` Limit Expression `json:"limit,omitempty"` LimitBy []Expression `json:"limit_by,omitempty"` LimitByLimit Expression `json:"limit_by_limit,omitempty"` // LIMIT value before BY (e.g., LIMIT 1 BY x LIMIT 3) @@ -212,6 +213,17 @@ type OrderByElement struct { func (o *OrderByElement) Pos() token.Position { return o.Position } func (o *OrderByElement) End() token.Position { return o.Position } +// InterpolateElement represents a single column interpolation in INTERPOLATE clause. +// Example: INTERPOLATE (value AS value + 1) +type InterpolateElement struct { + Position token.Position `json:"-"` + Column string `json:"column"` + Value Expression `json:"value,omitempty"` // nil if just column name +} + +func (i *InterpolateElement) Pos() token.Position { return i.Position } +func (i *InterpolateElement) End() token.Position { return i.Position } + // SettingExpr represents a setting expression. type SettingExpr struct { Position token.Position `json:"-"` @@ -284,6 +296,7 @@ type CreateQuery struct { FunctionName string `json:"function_name,omitempty"` FunctionBody Expression `json:"function_body,omitempty"` UserName string `json:"user_name,omitempty"` + Format string `json:"format,omitempty"` // For FORMAT clause } func (c *CreateQuery) Pos() token.Position { return c.Position } @@ -493,6 +506,7 @@ type DropQuery struct { OnCluster string `json:"on_cluster,omitempty"` DropDatabase bool `json:"drop_database,omitempty"` Sync bool `json:"sync,omitempty"` + Format string `json:"format,omitempty"` // For FORMAT clause } func (d *DropQuery) Pos() token.Position { return d.Position } @@ -512,6 +526,20 @@ func (u *UndropQuery) Pos() token.Position { return u.Position } func (u *UndropQuery) End() token.Position { return u.Position } func (u *UndropQuery) statementNode() {} +// UpdateQuery represents a standalone UPDATE statement. +// In ClickHouse, UPDATE is syntactic sugar for ALTER TABLE ... UPDATE +type UpdateQuery struct { + Position token.Position `json:"-"` + Database string `json:"database,omitempty"` + Table string `json:"table"` + Assignments []*Assignment `json:"assignments"` + Where Expression `json:"where,omitempty"` +} + +func (u *UpdateQuery) Pos() token.Position { return u.Position } +func (u *UpdateQuery) End() token.Position { return u.Position } +func (u *UpdateQuery) statementNode() {} + // AlterQuery represents an ALTER statement. type AlterQuery struct { Position token.Position `json:"-"` @@ -520,6 +548,7 @@ type AlterQuery struct { Commands []*AlterCommand `json:"commands"` OnCluster string `json:"on_cluster,omitempty"` Settings []*SettingExpr `json:"settings,omitempty"` + Format string `json:"format,omitempty"` // For FORMAT clause } func (a *AlterQuery) Pos() token.Position { return a.Position } @@ -624,6 +653,7 @@ const ( AlterDropStatistics AlterCommandType = "DROP_STATISTICS" AlterClearStatistics AlterCommandType = "CLEAR_STATISTICS" AlterMaterializeStatistics AlterCommandType = "MATERIALIZE_STATISTICS" + AlterModifyComment AlterCommandType = "MODIFY_COMMENT" ) // TruncateQuery represents a TRUNCATE statement. diff --git a/internal/explain/explain.go b/internal/explain/explain.go index 561fdb6329..5b37927157 100644 --- a/internal/explain/explain.go +++ b/internal/explain/explain.go @@ -12,6 +12,10 @@ import ( // This affects how negated literals with aliases are formatted var inSubqueryContext bool +// inCreateQueryContext is a package-level flag to track when we're inside a CreateQuery +// This affects whether FORMAT is output at SelectWithUnionQuery level (it shouldn't be, as CreateQuery outputs it) +var inCreateQueryContext bool + // Explain returns the EXPLAIN AST output for a statement, matching ClickHouse's format. func Explain(stmt ast.Statement) string { var sb strings.Builder @@ -57,6 +61,8 @@ func Node(sb *strings.Builder, node interface{}, depth int) { // Expressions case *ast.OrderByElement: explainOrderByElement(sb, n, indent, depth) + case *ast.InterpolateElement: + explainInterpolateElement(sb, n, indent, depth) case *ast.Identifier: explainIdentifier(sb, n, indent) case *ast.Literal: @@ -236,6 +242,8 @@ func Node(sb *strings.Builder, node interface{}, depth int) { explainCheckQuery(sb, n, indent) case *ast.CreateIndexQuery: explainCreateIndexQuery(sb, n, indent, depth) + case *ast.UpdateQuery: + explainUpdateQuery(sb, n, indent, depth) // Types case *ast.DataType: @@ -262,6 +270,8 @@ func Node(sb *strings.Builder, node interface{}, depth int) { explainDictionaryLayout(sb, n, indent, depth) case *ast.DictionaryRange: explainDictionaryRange(sb, n, indent, depth) + case *ast.Assignment: + explainAssignment(sb, n, indent, depth) default: // For unhandled types, just print the type name diff --git a/internal/explain/expressions.go b/internal/explain/expressions.go index a2717b38fc..2d37b0867d 100644 --- a/internal/explain/expressions.go +++ b/internal/explain/expressions.go @@ -235,6 +235,31 @@ func containsNonLiteralExpressions(exprs []ast.Expression) bool { return false } +// containsNonLiteralInNested checks if an array or tuple literal contains +// non-literal elements at any nesting level (identifiers, function calls, etc.) +func containsNonLiteralInNested(lit *ast.Literal) bool { + if lit.Type != ast.LiteralArray && lit.Type != ast.LiteralTuple { + return false + } + exprs, ok := lit.Value.([]ast.Expression) + if !ok { + return false + } + for _, e := range exprs { + // Check if this element is a non-literal (identifier, function call, etc.) + if _, isLit := e.(*ast.Literal); !isLit { + return true + } + // Recursively check nested arrays/tuples + if innerLit, ok := e.(*ast.Literal); ok { + if containsNonLiteralInNested(innerLit) { + return true + } + } + } + return false +} + // containsTuples checks if a slice of expressions contains any tuple literals func containsTuples(exprs []ast.Expression) bool { for _, e := range exprs { @@ -377,10 +402,23 @@ func explainUnaryExpr(sb *strings.Builder, n *ast.UnaryExpr, indent string, dept // Convert positive integer to negative switch val := lit.Value.(type) { case int64: - fmt.Fprintf(sb, "%sLiteral Int64_%d\n", indent, -val) + negVal := -val + // ClickHouse normalizes -0 to UInt64_0 + if negVal == 0 { + fmt.Fprintf(sb, "%sLiteral UInt64_0\n", indent) + } else if negVal > 0 { + fmt.Fprintf(sb, "%sLiteral UInt64_%d\n", indent, negVal) + } else { + fmt.Fprintf(sb, "%sLiteral Int64_%d\n", indent, negVal) + } return case uint64: - fmt.Fprintf(sb, "%sLiteral Int64_-%d\n", indent, val) + // ClickHouse normalizes -0 to UInt64_0 + if val == 0 { + fmt.Fprintf(sb, "%sLiteral UInt64_0\n", indent) + } else { + fmt.Fprintf(sb, "%sLiteral Int64_-%d\n", indent, val) + } return } case ast.LiteralFloat: @@ -432,11 +470,23 @@ func explainAliasedExpr(sb *strings.Builder, n *ast.AliasedExpr, depth int) { needsFunctionFormat = true break } + // Also check if nested arrays/tuples contain non-literal elements + if lit, ok := expr.(*ast.Literal); ok { + if containsNonLiteralInNested(lit) { + needsFunctionFormat = true + break + } + } } if needsFunctionFormat { // Render as Function tuple with alias fmt.Fprintf(sb, "%sFunction tuple (alias %s) (children %d)\n", indent, escapeAlias(n.Alias), 1) - fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, len(exprs)) + // For empty ExpressionList, don't include children count + if len(exprs) > 0 { + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, len(exprs)) + } else { + fmt.Fprintf(sb, "%s ExpressionList\n", indent) + } for _, expr := range exprs { Node(sb, expr, depth+2) } @@ -463,6 +513,11 @@ func explainAliasedExpr(sb *strings.Builder, n *ast.AliasedExpr, depth int) { needsFunctionFormat = true break } + // Check for function calls - use Function array + if _, ok := expr.(*ast.FunctionCall); ok { + needsFunctionFormat = true + break + } } if needsFunctionFormat { // Render as Function array with alias @@ -577,6 +632,9 @@ func explainAliasedExpr(sb *strings.Builder, n *ast.AliasedExpr, depth int) { case *ast.CaseExpr: // CASE expressions with alias explainCaseExprWithAlias(sb, e, n.Alias, indent, depth) + case *ast.ExistsExpr: + // EXISTS expressions with alias + explainExistsExprWithAlias(sb, e, n.Alias, indent, depth) default: // For other types, recursively explain and add alias info Node(sb, n.Expr, depth) diff --git a/internal/explain/format.go b/internal/explain/format.go index 751418d804..e52e8d18ba 100644 --- a/internal/explain/format.go +++ b/internal/explain/format.go @@ -74,6 +74,36 @@ func escapeStringLiteral(s string) string { return sb.String() } +// escapeStringForTypeParam escapes special characters for use in type parameters +// Uses extra escaping because type strings are embedded inside another string literal +func escapeStringForTypeParam(s string) string { + var sb strings.Builder + for i := 0; i < len(s); i++ { + b := s[i] + switch b { + case '\\': + sb.WriteString("\\\\\\\\\\\\\\\\") // backslash becomes 8 backslashes + case '\'': + sb.WriteString("\\\\\\\\\\'") // single quote becomes 5 backslashes + quote + case '\n': + sb.WriteString("\\\\\\\\n") // newline becomes \\\\n + case '\t': + sb.WriteString("\\\\\\\\t") // tab becomes \\\\t + case '\r': + sb.WriteString("\\\\\\\\r") // carriage return becomes \\\\r + case '\x00': + sb.WriteString("\\\\\\\\0") // null becomes \\\\0 + case '\b': + sb.WriteString("\\\\\\\\b") // backspace becomes \\\\b + case '\f': + sb.WriteString("\\\\\\\\f") // form feed becomes \\\\f + default: + sb.WriteByte(b) + } + } + return sb.String() +} + // FormatLiteral formats a literal value for EXPLAIN AST output func FormatLiteral(lit *ast.Literal) string { switch lit.Type { @@ -270,7 +300,9 @@ func formatBinaryExprForType(expr *ast.BinaryExpr) string { // Format left side if lit, ok := expr.Left.(*ast.Literal); ok { if lit.Type == ast.LiteralString { - left = fmt.Sprintf("\\\\\\'%s\\\\\\'", lit.Value) + // Use extra escaping for type parameters since they're embedded in another string literal + escaped := escapeStringForTypeParam(fmt.Sprintf("%v", lit.Value)) + left = fmt.Sprintf("\\\\\\'%s\\\\\\'", escaped) } else { left = fmt.Sprintf("%v", lit.Value) } @@ -285,6 +317,9 @@ func formatBinaryExprForType(expr *ast.BinaryExpr) string { right = fmt.Sprintf("%v", lit.Value) } else if ident, ok := expr.Right.(*ast.Identifier); ok { right = ident.Name() + } else if unary, ok := expr.Right.(*ast.UnaryExpr); ok { + // Handle unary expressions like -100 + right = formatUnaryExprForType(unary) } else { right = fmt.Sprintf("%v", expr.Right) } @@ -292,6 +327,14 @@ func formatBinaryExprForType(expr *ast.BinaryExpr) string { return left + " " + expr.Op + " " + right } +// formatUnaryExprForType formats a unary expression for use in type parameters (e.g., -100) +func formatUnaryExprForType(expr *ast.UnaryExpr) string { + if lit, ok := expr.Operand.(*ast.Literal); ok { + return expr.Op + fmt.Sprintf("%v", lit.Value) + } + return expr.Op + fmt.Sprintf("%v", expr.Operand) +} + // NormalizeFunctionName normalizes function names to match ClickHouse's EXPLAIN AST output func NormalizeFunctionName(name string) string { // ClickHouse normalizes certain function names in EXPLAIN AST @@ -314,9 +357,9 @@ func NormalizeFunctionName(name string) string { "least": "least", "concat_ws": "concat", "position": "position", - // SQL standard ANY/ALL subquery operators - "anymatch": "in", - "allmatch": "notIn", + // SQL standard ANY/ALL subquery operators - simple cases + "anyequals": "in", + "allnotequals": "notIn", } if n, ok := normalized[strings.ToLower(name)]; ok { return n @@ -351,6 +394,8 @@ func OperatorToFunction(op string) string { return "lessOrEquals" case ">=": return "greaterOrEquals" + case "<=>": + return "isNotDistinctFrom" case "AND": return "and" case "OR": diff --git a/internal/explain/functions.go b/internal/explain/functions.go index 2ca9ed3475..88e139f983 100644 --- a/internal/explain/functions.go +++ b/internal/explain/functions.go @@ -109,6 +109,11 @@ func windowSpecHasContent(w *ast.WindowSpec) bool { func handleSpecialFunction(sb *strings.Builder, n *ast.FunctionCall, alias string, indent string, depth int) bool { fnName := strings.ToUpper(n.Name) + // Handle quantified comparison operators (ANY/ALL with comparison operators) + if handled := handleQuantifiedComparison(sb, n, alias, indent, depth); handled { + return true + } + // POSITION('ll' IN 'Hello') -> position('Hello', 'll') if fnName == "POSITION" && len(n.Arguments) == 1 { if inExpr, ok := n.Arguments[0].(*ast.InExpr); ok { @@ -136,6 +141,140 @@ func handleSpecialFunction(sb *strings.Builder, n *ast.FunctionCall, alias strin return false } +// handleQuantifiedComparison handles ANY/ALL with comparison operators +// Returns true if the function was handled, false otherwise. +func handleQuantifiedComparison(sb *strings.Builder, n *ast.FunctionCall, alias string, indent string, depth int) bool { + fnName := strings.ToLower(n.Name) + + // Check if this is a quantified comparison function + var modifier, op string + if strings.HasPrefix(fnName, "any") { + modifier = "any" + op = fnName[3:] + } else if strings.HasPrefix(fnName, "all") { + modifier = "all" + op = fnName[3:] + } else { + return false + } + + // Must have exactly 2 arguments: left expr and subquery + if len(n.Arguments) != 2 { + return false + } + + subquery, ok := n.Arguments[1].(*ast.Subquery) + if !ok { + return false + } + + // Handle based on the operator and modifier + switch op { + case "equals": + if modifier == "any" { + // x == ANY (subquery) -> in(x, subquery) + return false // Let NormalizeFunctionName handle this + } + // x == ALL (subquery) -> complex with singleValueOrNull + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "in", "singleValueOrNull", alias, indent, depth) + return true + + case "notequals": + if modifier == "all" { + // x != ALL (subquery) -> notIn(x, subquery) + return false // Let NormalizeFunctionName handle this + } + // x != ANY (subquery) -> complex notIn with singleValueOrNull + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "notIn", "singleValueOrNull", alias, indent, depth) + return true + + case "less": + if modifier == "any" { + // x < ANY (subquery) -> x < max(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "less", "max", alias, indent, depth) + } else { + // x < ALL (subquery) -> x < min(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "less", "min", alias, indent, depth) + } + return true + + case "lessorequals": + if modifier == "any" { + // x <= ANY (subquery) -> x <= max(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "lessOrEquals", "max", alias, indent, depth) + } else { + // x <= ALL (subquery) -> x <= min(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "lessOrEquals", "min", alias, indent, depth) + } + return true + + case "greater": + if modifier == "any" { + // x > ANY (subquery) -> x > min(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "greater", "min", alias, indent, depth) + } else { + // x > ALL (subquery) -> x > max(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "greater", "max", alias, indent, depth) + } + return true + + case "greaterorequals": + if modifier == "any" { + // x >= ANY (subquery) -> x >= min(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "greaterOrEquals", "min", alias, indent, depth) + } else { + // x >= ALL (subquery) -> x >= max(subquery) + outputQuantifiedWithAggregate(sb, n.Arguments[0], subquery, "greaterOrEquals", "max", alias, indent, depth) + } + return true + } + + return false +} + +// outputQuantifiedWithAggregate outputs the ClickHouse AST format for quantified comparisons +// with an aggregate function wrapped around the subquery +func outputQuantifiedWithAggregate(sb *strings.Builder, left ast.Expression, subquery *ast.Subquery, compFunc, aggFunc string, alias string, indent string, depth int) { + if alias != "" { + fmt.Fprintf(sb, "%sFunction %s (alias %s) (children %d)\n", indent, compFunc, alias, 1) + } else { + fmt.Fprintf(sb, "%sFunction %s (children %d)\n", indent, compFunc, 1) + } + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 2) + Node(sb, left, depth+2) + + // Output the subquery wrapped with aggregate function + // Structure: Subquery -> SelectWithUnionQuery -> ExpressionList -> SelectQuery with 4 children + fmt.Fprintf(sb, "%s Subquery (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s SelectWithUnionQuery (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s SelectQuery (children %d)\n", indent, 4) + + // First ExpressionList with aggregate function + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s Function %s (children %d)\n", indent, aggFunc, 1) + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s Asterisk\n", indent) + + // First TablesInSelectQuery - wrap the original subquery + fmt.Fprintf(sb, "%s TablesInSelectQuery (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s TablesInSelectQueryElement (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s TableExpression (children %d)\n", indent, 1) + Node(sb, subquery, depth+9) + + // Second ExpressionList with aggregate function (repeated) + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s Function %s (children %d)\n", indent, aggFunc, 1) + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s Asterisk\n", indent) + + // Second TablesInSelectQuery (repeated) + fmt.Fprintf(sb, "%s TablesInSelectQuery (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s TablesInSelectQueryElement (children %d)\n", indent, 1) + fmt.Fprintf(sb, "%s TableExpression (children %d)\n", indent, 1) + Node(sb, subquery, depth+9) +} + // explainPositionWithIn outputs POSITION(needle IN haystack) as position(haystack, needle) func explainPositionWithIn(sb *strings.Builder, needle, haystack ast.Expression, alias string, indent string, depth int) { if alias != "" { @@ -1172,8 +1311,16 @@ func parseIntervalString(s string) (value string, unit string) { } func explainExistsExpr(sb *strings.Builder, n *ast.ExistsExpr, indent string, depth int) { + explainExistsExprWithAlias(sb, n, "", indent, depth) +} + +func explainExistsExprWithAlias(sb *strings.Builder, n *ast.ExistsExpr, alias string, indent string, depth int) { // EXISTS is represented as Function exists - fmt.Fprintf(sb, "%sFunction exists (children %d)\n", indent, 1) + if alias != "" { + fmt.Fprintf(sb, "%sFunction exists (alias %s) (children %d)\n", indent, alias, 1) + } else { + fmt.Fprintf(sb, "%sFunction exists (children %d)\n", indent, 1) + } fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 1) fmt.Fprintf(sb, "%s Subquery (children %d)\n", indent, 1) Node(sb, n.Query, depth+3) diff --git a/internal/explain/select.go b/internal/explain/select.go index 3c30c111aa..c9a56cd3cc 100644 --- a/internal/explain/select.go +++ b/internal/explain/select.go @@ -13,7 +13,7 @@ func explainSelectIntersectExceptQuery(sb *strings.Builder, n *ast.SelectInterse // ClickHouse wraps first operand in SelectWithUnionQuery when EXCEPT is present hasExcept := false for _, op := range n.Operators { - if op == "EXCEPT" { + if strings.HasPrefix(op, "EXCEPT") { hasExcept = true break } @@ -54,10 +54,13 @@ func explainSelectWithUnionQuery(sb *strings.Builder, n *ast.SelectWithUnionQuer } } // FORMAT clause - check if any SelectQuery has Format set - for _, sel := range n.Selects { - if sq, ok := sel.(*ast.SelectQuery); ok && sq.Format != nil { - Node(sb, sq.Format, depth+1) - break + // Skip this when inside CreateQuery context, as Format is output at CreateQuery level + if !inCreateQueryContext { + for _, sel := range n.Selects { + if sq, ok := sel.(*ast.SelectQuery); ok && sq.Format != nil { + Node(sb, sq.Format, depth+1) + break + } } } // When SETTINGS comes AFTER FORMAT, it's output at SelectWithUnionQuery level @@ -146,6 +149,13 @@ func explainSelectQuery(sb *strings.Builder, n *ast.SelectQuery, indent string, Node(sb, o, depth+2) } } + // INTERPOLATE + if len(n.Interpolate) > 0 { + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, len(n.Interpolate)) + for _, i := range n.Interpolate { + Node(sb, i, depth+2) + } + } // OFFSET (ClickHouse outputs offset before limit in EXPLAIN AST) if n.Offset != nil { Node(sb, n.Offset, depth+1) @@ -256,6 +266,22 @@ func explainOrderByElement(sb *strings.Builder, n *ast.OrderByElement, indent st } } +// explainInterpolateElement explains an INTERPOLATE element. +// Format: InterpolateElement (column colname) (children N) +func explainInterpolateElement(sb *strings.Builder, n *ast.InterpolateElement, indent string, depth int) { + children := 0 + if n.Value != nil { + children = 1 + } + + if children > 0 { + fmt.Fprintf(sb, "%sInterpolateElement (column %s) (children %d)\n", indent, n.Column, children) + Node(sb, n.Value, depth+1) + } else { + fmt.Fprintf(sb, "%sInterpolateElement (column %s)\n", indent, n.Column) + } +} + // isComplexExpr checks if an expression is complex (not a simple literal) func isComplexExpr(expr ast.Expression) bool { if expr == nil { @@ -289,10 +315,13 @@ func countSelectUnionChildren(n *ast.SelectWithUnionQuery) int { } } // Check if any SelectQuery has Format set - for _, sel := range n.Selects { - if sq, ok := sel.(*ast.SelectQuery); ok && sq.Format != nil { - count++ - break + // Skip this when inside CreateQuery context, as Format is output at CreateQuery level + if !inCreateQueryContext { + for _, sel := range n.Selects { + if sq, ok := sel.(*ast.SelectQuery); ok && sq.Format != nil { + count++ + break + } } } // When SETTINGS comes AFTER FORMAT, it's counted at SelectWithUnionQuery level @@ -342,6 +371,9 @@ func countSelectQueryChildren(n *ast.SelectQuery) int { if len(n.OrderBy) > 0 { count++ } + if len(n.Interpolate) > 0 { + count++ + } if n.LimitByLimit != nil { count++ // LIMIT n in "LIMIT n BY x LIMIT m" } diff --git a/internal/explain/statements.go b/internal/explain/statements.go index 273d7cd098..3b14cbc2ca 100644 --- a/internal/explain/statements.go +++ b/internal/explain/statements.go @@ -177,6 +177,11 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string, if n.AsTableFunction != nil { children++ } + // Count Format as a child if present + hasFormat := n.Format != "" + if hasFormat { + children++ + } // ClickHouse adds an extra space before (children N) for CREATE DATABASE if n.CreateDatabase { fmt.Fprintf(sb, "%sCreateQuery %s (children %d)\n", indent, EscapeIdentifier(name), children) @@ -252,7 +257,15 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string, } // For materialized views, output AsSelect before storage definition if n.Materialized && n.AsSelect != nil { + // Set context flag to prevent Format from being output at SelectWithUnionQuery level + // (it will be output at CreateQuery level instead) + if hasFormat { + inCreateQueryContext = true + } Node(sb, n.AsSelect, depth+1) + if hasFormat { + inCreateQueryContext = false + } } hasStorage := n.Engine != nil || len(n.OrderBy) > 0 || len(n.PrimaryKey) > 0 || n.PartitionBy != nil || n.SampleBy != nil || n.TTL != nil || len(n.Settings) > 0 if hasStorage { @@ -269,24 +282,9 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string, if len(n.PrimaryKey) > 0 { storageChildren++ } - // SAMPLE BY is only shown in EXPLAIN AST when it's a function (not a simple identifier) - // and when it's different from ORDER BY + // SAMPLE BY is always shown in EXPLAIN AST when present if n.SampleBy != nil { - if _, isIdent := n.SampleBy.(*ast.Identifier); !isIdent { - // Check if SAMPLE BY equals ORDER BY - if so, don't show it - showSampleBy := true - if len(n.OrderBy) == 1 { - var orderBySb, sampleBySb strings.Builder - Node(&orderBySb, n.OrderBy[0], 0) - Node(&sampleBySb, n.SampleBy, 0) - if orderBySb.String() == sampleBySb.String() { - showSampleBy = false - } - } - if showSampleBy { - storageChildren++ - } - } + storageChildren++ } if n.TTL != nil { storageChildren++ @@ -382,24 +380,9 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string, } } } - // SAMPLE BY is only shown in EXPLAIN AST when it's a function (not a simple identifier) - // and when it's different from ORDER BY + // SAMPLE BY is always shown in EXPLAIN AST when present if n.SampleBy != nil { - if _, isIdent := n.SampleBy.(*ast.Identifier); !isIdent { - // Check if SAMPLE BY equals ORDER BY - if so, don't show it - showSampleBy := true - if len(n.OrderBy) == 1 { - var orderBySb, sampleBySb strings.Builder - Node(&orderBySb, n.OrderBy[0], 0) - Node(&sampleBySb, n.SampleBy, 0) - if orderBySb.String() == sampleBySb.String() { - showSampleBy = false - } - } - if showSampleBy { - Node(sb, n.SampleBy, storageChildDepth) - } - } + Node(sb, n.SampleBy, storageChildDepth) } if n.TTL != nil { fmt.Fprintf(sb, "%s ExpressionList (children 1)\n", storageIndent) @@ -416,13 +399,25 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string, } // For non-materialized views, output AsSelect after storage if n.AsSelect != nil && !n.Materialized { + // Set context flag to prevent Format from being output at SelectWithUnionQuery level + // (it will be output at CreateQuery level instead) + if hasFormat { + inCreateQueryContext = true + } // AS SELECT is output directly without Subquery wrapper Node(sb, n.AsSelect, depth+1) + if hasFormat { + inCreateQueryContext = false + } } if n.AsTableFunction != nil { // AS table_function(...) is output directly Node(sb, n.AsTableFunction, depth+1) } + // Output FORMAT clause if present + if hasFormat { + fmt.Fprintf(sb, "%s Identifier %s\n", indent, n.Format) + } } func explainDropQuery(sb *strings.Builder, n *ast.DropQuery, indent string, depth int) { @@ -490,18 +485,41 @@ func explainDropQuery(sb *strings.Builder, n *ast.DropQuery, indent string, dept } // Check if we have a database-qualified name (for DROP TABLE db.table) hasDatabase := n.Database != "" && !n.DropDatabase + hasFormat := n.Format != "" + if hasDatabase { - // Database-qualified: DropQuery db table (children 2) - fmt.Fprintf(sb, "%sDropQuery %s %s (children %d)\n", indent, EscapeIdentifier(n.Database), EscapeIdentifier(name), 2) + // Database-qualified: DropQuery db table (children 2 or 3) + children := 2 + if hasFormat { + children = 3 + } + fmt.Fprintf(sb, "%sDropQuery %s %s (children %d)\n", indent, EscapeIdentifier(n.Database), EscapeIdentifier(name), children) fmt.Fprintf(sb, "%s Identifier %s\n", indent, EscapeIdentifier(n.Database)) fmt.Fprintf(sb, "%s Identifier %s\n", indent, EscapeIdentifier(name)) + if hasFormat { + fmt.Fprintf(sb, "%s Identifier %s\n", indent, n.Format) + } } else if n.DropDatabase { // DROP DATABASE uses different spacing - fmt.Fprintf(sb, "%sDropQuery %s (children %d)\n", indent, EscapeIdentifier(name), 1) + children := 1 + if hasFormat { + children = 2 + } + fmt.Fprintf(sb, "%sDropQuery %s (children %d)\n", indent, EscapeIdentifier(name), children) fmt.Fprintf(sb, "%s Identifier %s\n", indent, EscapeIdentifier(name)) + if hasFormat { + fmt.Fprintf(sb, "%s Identifier %s\n", indent, n.Format) + } } else { - fmt.Fprintf(sb, "%sDropQuery %s (children %d)\n", indent, EscapeIdentifier(name), 1) + children := 1 + if hasFormat { + children = 2 + } + fmt.Fprintf(sb, "%sDropQuery %s (children %d)\n", indent, EscapeIdentifier(name), children) fmt.Fprintf(sb, "%s Identifier %s\n", indent, EscapeIdentifier(name)) + if hasFormat { + fmt.Fprintf(sb, "%s Identifier %s\n", indent, n.Format) + } } } @@ -1075,6 +1093,10 @@ func explainAlterQuery(sb *strings.Builder, n *ast.AlterQuery, indent string, de if len(n.Settings) > 0 { children++ // Add Set child for SETTINGS } + hasFormat := n.Format != "" + if hasFormat { + children++ // Add Identifier for FORMAT + } if n.Database != "" { fmt.Fprintf(sb, "%sAlterQuery %s %s (children %d)\n", indent, n.Database, n.Table, children) } else { @@ -1092,6 +1114,9 @@ func explainAlterQuery(sb *strings.Builder, n *ast.AlterQuery, indent string, de if len(n.Settings) > 0 { fmt.Fprintf(sb, "%s Set\n", indent) } + if hasFormat { + fmt.Fprintf(sb, "%s Identifier %s\n", indent, n.Format) + } } func explainAlterCommand(sb *strings.Builder, cmd *ast.AlterCommand, indent string, depth int) { @@ -1155,6 +1180,10 @@ func explainAlterCommand(sb *strings.Builder, cmd *ast.AlterCommand, indent stri if cmd.Comment != "" { fmt.Fprintf(sb, "%s Literal \\'%s\\'\n", indent, escapeStringLiteral(cmd.Comment)) } + case ast.AlterModifyComment: + if cmd.Comment != "" { + fmt.Fprintf(sb, "%s Literal \\'%s\\'\n", indent, escapeStringLiteral(cmd.Comment)) + } case ast.AlterAddIndex, ast.AlterDropIndex, ast.AlterClearIndex, ast.AlterMaterializeIndex: if cmd.Index != "" { fmt.Fprintf(sb, "%s Identifier %s\n", indent, cmd.Index) @@ -1337,6 +1366,10 @@ func countAlterCommandChildren(cmd *ast.AlterCommand) int { if cmd.Comment != "" { children++ } + case ast.AlterModifyComment: + if cmd.Comment != "" { + children++ + } case ast.AlterRenameColumn: if cmd.ColumnName != "" { children++ @@ -1534,3 +1567,45 @@ func explainCreateIndexQuery(sb *strings.Builder, n *ast.CreateIndexQuery, inden // Child 3: Table name fmt.Fprintf(sb, "%s Identifier %s\n", indent, n.Table) } + +func explainAssignment(sb *strings.Builder, n *ast.Assignment, indent string, depth int) { + if n == nil { + return + } + // Assignment col_name (children 1) + fmt.Fprintf(sb, "%sAssignment %s (children 1)\n", indent, n.Column) + if n.Value != nil { + Node(sb, n.Value, depth+1) + } +} + +func explainUpdateQuery(sb *strings.Builder, n *ast.UpdateQuery, indent string, depth int) { + if n == nil { + fmt.Fprintf(sb, "%s*ast.UpdateQuery\n", indent) + return + } + + // Count children: always 3 (identifier, where condition, assignments) + children := 3 + + // UpdateQuery with two spaces before table name + if n.Database != "" { + fmt.Fprintf(sb, "%sUpdateQuery %s %s (children %d)\n", indent, n.Database, n.Table, children) + } else { + fmt.Fprintf(sb, "%sUpdateQuery %s (children %d)\n", indent, n.Table, children) + } + + // Child 1: Table identifier + fmt.Fprintf(sb, "%s Identifier %s\n", indent, n.Table) + + // Child 2: WHERE condition + if n.Where != nil { + Node(sb, n.Where, depth+1) + } + + // Child 3: Assignments wrapped in ExpressionList + fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, len(n.Assignments)) + for _, assign := range n.Assignments { + Node(sb, assign, depth+2) + } +} diff --git a/internal/explain/tables.go b/internal/explain/tables.go index dbae494017..9d2028fcea 100644 --- a/internal/explain/tables.go +++ b/internal/explain/tables.go @@ -2,6 +2,7 @@ package explain import ( "fmt" + "strconv" "strings" "github.com/sqlc-dev/doubleclick/ast" @@ -44,7 +45,10 @@ func explainTablesInSelectQueryElement(sb *strings.Builder, n *ast.TablesInSelec func explainTableExpression(sb *strings.Builder, n *ast.TableExpression, indent string, depth int) { children := 1 // table if n.Sample != nil { - children++ + children++ // for sample ratio + if n.Sample.Offset != nil { + children++ // for sample offset + } } fmt.Fprintf(sb, "%sTableExpression (children %d)\n", indent, children) // If there's a subquery with an alias, pass the alias to the subquery output @@ -83,6 +87,14 @@ func explainSampleClause(sb *strings.Builder, n *ast.SampleClause, indent string sb.WriteString("SampleRatio ") formatSampleRatio(sb, n.Ratio) sb.WriteString("\n") + + // Output OFFSET as a second SampleRatio line if present + if n.Offset != nil { + sb.WriteString(indent) + sb.WriteString("SampleRatio ") + formatSampleRatio(sb, n.Offset) + sb.WriteString("\n") + } } func formatSampleRatio(sb *strings.Builder, expr ast.Expression) { @@ -106,6 +118,13 @@ func formatSampleRatioOperand(sb *strings.Builder, expr ast.Expression) { case float64: // Convert decimal to fraction for EXPLAIN AST output // ClickHouse shows 0.1 as "1 / 10", 0.01 as "1 / 100", etc. + // Use Source field if available to preserve precision (0.4 vs 0.40) + if lit.Source != "" { + if frac := sourceToFraction(lit.Source); frac != "" { + sb.WriteString(frac) + return + } + } if frac := floatToFraction(v); frac != "" { sb.WriteString(frac) } else { @@ -119,6 +138,87 @@ func formatSampleRatioOperand(sb *strings.Builder, expr ast.Expression) { } } +// sourceToFraction converts a source string representation to a fraction +// This preserves the original precision (e.g., "0.4" -> "4 / 10", "0.40" -> "40 / 100") +func sourceToFraction(source string) string { + source = strings.TrimSpace(source) + + // Handle scientific notation like "2e-2" -> "2 / 100" + if strings.ContainsAny(source, "eE") { + return scientificToFraction(source) + } + + // Handle decimal notation like "0.4" or "0.40" + if strings.Contains(source, ".") { + return decimalToFraction(source) + } + + return "" +} + +// scientificToFraction handles scientific notation like "2e-2" -> "2 / 100" +func scientificToFraction(source string) string { + // Parse scientific notation: coefficient * 10^exponent + // Split by 'e' or 'E' + lower := strings.ToLower(source) + parts := strings.Split(lower, "e") + if len(parts) != 2 { + return "" + } + + coef, err := strconv.ParseFloat(parts[0], 64) + if err != nil { + return "" + } + + exp, err := strconv.Atoi(parts[1]) + if err != nil { + return "" + } + + // For negative exponents, convert to fraction + // 2e-2 = 2 * 10^-2 = 2 / 100 + if exp < 0 { + denom := int64(1) + for i := 0; i < -exp; i++ { + denom *= 10 + } + num := int64(coef) + if coef == float64(num) { + return fmt.Sprintf("%d / %d", num, denom) + } + } + return "" +} + +// decimalToFraction converts a decimal string to a fraction preserving precision +// "0.4" -> "4 / 10", "0.40" -> "40 / 100" +func decimalToFraction(source string) string { + parts := strings.Split(source, ".") + if len(parts) != 2 { + return "" + } + + decimalPart := parts[1] + // Count decimal places (including trailing zeros) + decimalPlaces := len(decimalPart) + + // Calculate denominator based on decimal places + denom := int64(1) + for i := 0; i < decimalPlaces; i++ { + denom *= 10 + } + + // Parse the decimal part as an integer (numerator) + // Handle leading zeros correctly: "0.05" -> "5 / 100" + num, err := strconv.ParseInt(decimalPart, 10, 64) + if err != nil { + return "" + } + + return fmt.Sprintf("%d / %d", num, denom) +} + // floatToFraction converts a float to a fraction string like "1 / 10" // Returns empty string if the float can't be reasonably converted to a simple fraction func floatToFraction(f float64) string { diff --git a/parser/expression.go b/parser/expression.go index 1320ebefc5..26b8007f3f 100644 --- a/parser/expression.go +++ b/parser/expression.go @@ -843,10 +843,16 @@ func (p *Parser) parseNumber() ast.Expression { lit.Source = value // Preserve original source text (e.g., "0.0" vs "0") } } else if isHexFloat { - // Parse hex float (Go doesn't support this directly, approximate) - // For now, store as string - ClickHouse will interpret it - lit.Type = ast.LiteralString - lit.Value = value + // Parse hex float (Go 1.13+ supports this via ParseFloat) + f, err := strconv.ParseFloat(value, 64) + if err != nil { + lit.Type = ast.LiteralString + lit.Value = value + } else { + lit.Type = ast.LiteralFloat + lit.Value = f + lit.Source = value // Preserve original source text + } } else { // Determine the base for parsing // - 0x/0X: hex (base 16) @@ -1727,7 +1733,7 @@ func (p *Parser) parseBinaryExpression(left ast.Expression) ast.Expression { // Check for ANY/ALL subquery comparison modifier: expr >= ANY(subquery) if p.currentIs(token.ANY) || p.currentIs(token.ALL) { - modifier := strings.ToUpper(p.current.Value) + modifier := strings.ToLower(p.current.Value) p.nextToken() if p.currentIs(token.LPAREN) { p.nextToken() @@ -1735,10 +1741,13 @@ func (p *Parser) parseBinaryExpression(left ast.Expression) ast.Expression { if p.currentIs(token.SELECT) || p.currentIs(token.WITH) { subquery := p.parseSelectWithUnion() p.expect(token.RPAREN) - // Wrap the comparison in a function call representing ANY/ALL + // Create function name that encodes both modifier and operator + // e.g., anyEquals, allLess, anyGreaterOrEquals, etc. + opName := operatorToName(expr.Op) + fnName := modifier + opName return &ast.FunctionCall{ Position: expr.Position, - Name: strings.ToLower(modifier) + "Match", + Name: fnName, Arguments: []ast.Expression{ left, &ast.Subquery{Position: expr.Position, Query: subquery}, @@ -1765,6 +1774,27 @@ func (p *Parser) parseBinaryExpression(left ast.Expression) ast.Expression { return expr } +// operatorToName converts a comparison operator to a capitalized name for use +// in ANY/ALL function names (e.g., "==" -> "Equals", "<" -> "Less") +func operatorToName(op string) string { + switch op { + case "=", "==": + return "Equals" + case "!=", "<>": + return "NotEquals" + case "<": + return "Less" + case "<=": + return "LessOrEquals" + case ">": + return "Greater" + case ">=": + return "GreaterOrEquals" + default: + return "Equals" // fallback + } +} + func (p *Parser) parseLikeExpression(left ast.Expression, not bool) ast.Expression { expr := &ast.LikeExpr{ Position: p.current.Pos, diff --git a/parser/parser.go b/parser/parser.go index 954a5381fb..9e8cda19ed 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -200,6 +200,8 @@ func (p *Parser) parseStatement() ast.Statement { return p.parseSetRole() } return p.parseSet() + case token.UPDATE: + return p.parseUpdate() case token.OPTIMIZE: return p.parseOptimize() case token.SYSTEM: @@ -284,14 +286,18 @@ func (p *Parser) parseSelectWithUnion() *ast.SelectWithUnionQuery { } p.nextToken() // skip INTERSECT/EXCEPT - // Handle DISTINCT if present (ALL case is handled in the loop condition) - if p.currentIs(token.DISTINCT) { + // Handle ALL or DISTINCT if present + if p.currentIs(token.ALL) { + op += " ALL" + p.nextToken() + } else if p.currentIs(token.DISTINCT) { op += " DISTINCT" p.nextToken() } ops = append(ops, op) - // Parse the next select + // Parse the next operand - can be a SELECT with UNION/UNION ALL + // (UNION has higher precedence than EXCEPT) var nextStmt ast.Statement if p.currentIs(token.LPAREN) { p.nextToken() // skip ( @@ -302,11 +308,11 @@ func (p *Parser) parseSelectWithUnion() *ast.SelectWithUnionQuery { p.expect(token.RPAREN) nextStmt = nested } else { - sel := p.parseSelect() - if sel == nil { + // Parse SELECT with possible UNION/UNION ALL + nextStmt = p.parseSelectWithUnionOnly() + if nextStmt == nil { break } - nextStmt = sel } stmts = append(stmts, nextStmt) } @@ -331,6 +337,13 @@ func (p *Parser) parseSelectWithUnion() *ast.SelectWithUnionQuery { // Parse UNION/INTERSECT ALL/EXCEPT ALL clauses for p.currentIs(token.UNION) || p.currentIs(token.EXCEPT) || p.currentIs(token.INTERSECT) { + // Check if we hit INTERSECT/EXCEPT that should use wrapper (not ALL) + // If so, we need to wrap the current UNION result as the first operand + if p.isIntersectExceptWithWrapper() { + // Wrap current query as first operand of INTERSECT/EXCEPT + return p.parseIntersectExceptWithFirstOperand(query) + } + var setOp string if p.currentIs(token.UNION) { setOp = "UNION" @@ -376,23 +389,131 @@ func (p *Parser) parseSelectWithUnion() *ast.SelectWithUnionQuery { return query } +// parseIntersectExceptWithFirstOperand handles the case where UNION is followed by INTERSECT/EXCEPT +// The unionQuery contains the selects that form the first operand +func (p *Parser) parseIntersectExceptWithFirstOperand(unionQuery *ast.SelectWithUnionQuery) *ast.SelectWithUnionQuery { + // Collect all operands and operators + stmts := []ast.Statement{unionQuery} + var ops []string + + // Parse all INTERSECT/EXCEPT clauses + for p.isIntersectExceptWithWrapper() { + var op string + if p.currentIs(token.EXCEPT) { + op = "EXCEPT" + } else { + op = "INTERSECT" + } + p.nextToken() // skip INTERSECT/EXCEPT + + // Handle ALL or DISTINCT if present + if p.currentIs(token.ALL) { + op += " ALL" + p.nextToken() + } else if p.currentIs(token.DISTINCT) { + op += " DISTINCT" + p.nextToken() + } + ops = append(ops, op) + + // Parse the next select + var nextStmt ast.Statement + if p.currentIs(token.LPAREN) { + p.nextToken() // skip ( + nested := p.parseSelectWithUnion() + if nested == nil { + break + } + p.expect(token.RPAREN) + nextStmt = nested + } else { + sel := p.parseSelect() + if sel == nil { + break + } + nextStmt = sel + } + stmts = append(stmts, nextStmt) + } + + // Build the tree with proper precedence + result := buildIntersectExceptTree(stmts, ops) + + // Return wrapped in SelectWithUnionQuery + return &ast.SelectWithUnionQuery{ + Position: unionQuery.Position, + Selects: []ast.Statement{result}, + } +} + +// parseSelectWithUnionOnly parses SELECT with UNION/UNION ALL but stops at INTERSECT/EXCEPT. +// This is used for parsing operands in EXCEPT expressions where UNION has higher precedence. +func (p *Parser) parseSelectWithUnionOnly() ast.Statement { + // Parse first SELECT + sel := p.parseSelect() + if sel == nil { + return nil + } + + // Check if followed by UNION (but not INTERSECT/EXCEPT which end this operand) + if !p.currentIs(token.UNION) { + return sel + } + + // Build SelectWithUnionQuery for UNION/UNION ALL chain + query := &ast.SelectWithUnionQuery{ + Position: sel.Pos(), + Selects: []ast.Statement{sel}, + } + + // Parse UNION/UNION ALL clauses + for p.currentIs(token.UNION) { + p.nextToken() // skip UNION + + var mode string + if p.currentIs(token.ALL) { + query.UnionAll = true + mode = "ALL" + p.nextToken() + } else if p.currentIs(token.DISTINCT) { + mode = "DISTINCT" + p.nextToken() + } + query.UnionModes = append(query.UnionModes, "UNION "+mode) + + // Handle parenthesized subqueries + if p.currentIs(token.LPAREN) { + p.nextToken() // skip ( + nested := p.parseSelectWithUnion() + if nested == nil { + break + } + p.expect(token.RPAREN) + for _, s := range nested.Selects { + query.Selects = append(query.Selects, s) + } + } else { + nextSel := p.parseSelect() + if nextSel == nil { + break + } + query.Selects = append(query.Selects, nextSel) + } + } + + return query +} + // isIntersectExceptWithWrapper checks if the current token is INTERSECT or EXCEPT // that should use a SelectIntersectExceptQuery wrapper. -// Only INTERSECT ALL and EXCEPT ALL are flattened (no wrapper). -// INTERSECT DISTINCT, INTERSECT, EXCEPT DISTINCT, and EXCEPT all use the wrapper. +// All INTERSECT and EXCEPT variants (including ALL and DISTINCT) use the wrapper. func (p *Parser) isIntersectExceptWithWrapper() bool { - if !p.currentIs(token.EXCEPT) && !p.currentIs(token.INTERSECT) { - return false - } - // INTERSECT ALL and EXCEPT ALL are flattened (no wrapper) - // All other cases (DISTINCT or no modifier) use the wrapper - nextTok := p.peek.Token - return nextTok != token.ALL + return p.currentIs(token.EXCEPT) || p.currentIs(token.INTERSECT) } // isIntersectOp checks if the operator is an INTERSECT variant (not EXCEPT) func isIntersectOp(op string) bool { - return op == "INTERSECT" || op == "INTERSECT DISTINCT" + return strings.HasPrefix(op, "INTERSECT") } // buildIntersectExceptTree builds the AST tree respecting operator precedence. @@ -613,6 +734,12 @@ func (p *Parser) parseSelect() *ast.SelectQuery { sel.OrderBy = p.parseOrderByList() } + // Parse INTERPOLATE clause (comes after ORDER BY ... WITH FILL) + if p.currentIs(token.INTERPOLATE) { + p.nextToken() + sel.Interpolate = p.parseInterpolateList() + } + // Parse LIMIT clause if p.currentIs(token.LIMIT) { p.nextToken() @@ -1246,6 +1373,54 @@ func (p *Parser) parseOrderByList() []*ast.OrderByElement { return elements } +// parseInterpolateList parses INTERPOLATE (col1 AS expr1, col2, col3 AS expr3) +func (p *Parser) parseInterpolateList() []*ast.InterpolateElement { + var elements []*ast.InterpolateElement + + // Expect opening parenthesis + if !p.currentIs(token.LPAREN) { + return elements + } + p.nextToken() + + for { + if p.currentIs(token.RPAREN) { + break + } + + // Column name + if !p.currentIs(token.IDENT) && !p.current.Token.IsKeyword() { + break + } + + elem := &ast.InterpolateElement{ + Position: p.current.Pos, + Column: p.current.Value, + } + p.nextToken() + + // Optional AS expression + if p.currentIs(token.AS) { + p.nextToken() + elem.Value = p.parseExpression(LOWEST) + } + + elements = append(elements, elem) + + if !p.currentIs(token.COMMA) { + break + } + p.nextToken() + } + + // Expect closing parenthesis + if p.currentIs(token.RPAREN) { + p.nextToken() + } + + return elements +} + func (p *Parser) parseSettingsList() []*ast.SettingExpr { var settings []*ast.SettingExpr @@ -1567,6 +1742,19 @@ func (p *Parser) parseCreate() ast.Statement { return nil } + // Handle FORMAT clause (for things like CREATE TABLE ... FORMAT Null) + if p.currentIs(token.FORMAT) { + p.nextToken() + // Store format name (Null, etc.) + if p.currentIs(token.NULL) { + create.Format = "Null" + p.nextToken() + } else if p.currentIs(token.IDENT) { + create.Format = p.current.Value + p.nextToken() + } + } + return create } @@ -2010,6 +2198,17 @@ func (p *Parser) parseCreateView(create *ast.CreateQuery) { p.nextToken() if p.currentIs(token.SELECT) || p.currentIs(token.WITH) || p.currentIs(token.LPAREN) { create.AsSelect = p.parseSelectWithUnion() + // Extract FORMAT from inner SelectQuery and move it to CreateQuery + // For CREATE VIEW/MATERIALIZED VIEW, FORMAT should be at CreateQuery level + if swu, ok := create.AsSelect.(*ast.SelectWithUnionQuery); ok && swu != nil { + for _, sel := range swu.Selects { + if sq, ok := sel.(*ast.SelectQuery); ok && sq != nil && sq.Format != nil { + create.Format = sq.Format.Name() + sq.Format = nil + break + } + } + } } } } @@ -3175,9 +3374,20 @@ func (p *Parser) parseColumnDeclaration() *ast.ColumnDeclaration { } // Parse column name (can be identifier or keyword like KEY) + // Also handles nested column names like n.y if p.currentIs(token.IDENT) || p.current.Token.IsKeyword() { col.Name = p.current.Value p.nextToken() + // Handle nested column names (e.g., n.y for nested columns) + for p.currentIs(token.DOT) { + p.nextToken() // skip . + if p.currentIs(token.IDENT) || p.current.Token.IsKeyword() { + col.Name += "." + p.current.Value + p.nextToken() + } else { + break + } + } } else { return nil } @@ -3463,7 +3673,7 @@ func (p *Parser) isDataTypeName(name string) bool { types := []string{ "INT", "INT8", "INT16", "INT32", "INT64", "INT128", "INT256", "UINT8", "UINT16", "UINT32", "UINT64", "UINT128", "UINT256", - "FLOAT32", "FLOAT64", "FLOAT", + "FLOAT32", "FLOAT64", "FLOAT", "BFLOAT16", "DECIMAL", "DECIMAL32", "DECIMAL64", "DECIMAL128", "DECIMAL256", "STRING", "FIXEDSTRING", "UUID", "DATE", "DATE32", "DATETIME", "DATETIME64", @@ -3917,8 +4127,12 @@ func (p *Parser) parseDrop() *ast.DropQuery { // Handle FORMAT clause (for things like DROP TABLE ... FORMAT Null) if p.currentIs(token.FORMAT) { p.nextToken() - // Skip format name (Null, etc.) - if p.currentIs(token.NULL) || p.currentIs(token.IDENT) { + // Store format name (Null, etc.) + if p.currentIs(token.NULL) { + drop.Format = "Null" + p.nextToken() + } else if p.currentIs(token.IDENT) { + drop.Format = p.current.Value p.nextToken() } } @@ -4002,6 +4216,18 @@ func (p *Parser) parseAlter() *ast.AlterQuery { alter.Settings = p.parseSettingsList() } + // Parse FORMAT clause + if p.currentIs(token.FORMAT) { + p.nextToken() + if p.currentIs(token.NULL) { + alter.Format = "Null" + p.nextToken() + } else if p.currentIs(token.IDENT) { + alter.Format = p.current.Value + p.nextToken() + } + } + return alter } @@ -4269,6 +4495,14 @@ func (p *Parser) parseAlterCommand() *ast.AlterCommand { p.nextToken() cmd.StatisticsTypes = p.parseStatisticsTypeList() } + } else if p.currentIs(token.COMMENT) { + // MODIFY COMMENT 'comment string' + cmd.Type = ast.AlterModifyComment + p.nextToken() + if p.currentIs(token.STRING) { + cmd.Comment = p.current.Value + p.nextToken() + } } case token.RENAME: p.nextToken() @@ -4492,6 +4726,61 @@ func (p *Parser) parseUndrop() *ast.UndropQuery { return undrop } +func (p *Parser) parseUpdate() *ast.UpdateQuery { + update := &ast.UpdateQuery{ + Position: p.current.Pos, + } + + p.nextToken() // skip UPDATE + + // Parse table name (can be database.table) + tableName := p.parseIdentifierName() + if tableName != "" { + if p.currentIs(token.DOT) { + p.nextToken() + update.Database = tableName + update.Table = p.parseIdentifierName() + } else { + update.Table = tableName + } + } + + // Expect SET keyword + if !p.currentIs(token.SET) { + return update + } + p.nextToken() // skip SET + + // Parse assignments: col = expr, col = expr, ... + for { + if !p.currentIs(token.IDENT) && !p.current.Token.IsKeyword() { + break + } + assign := &ast.Assignment{ + Position: p.current.Pos, + Column: p.current.Value, + } + p.nextToken() // skip column name + if p.currentIs(token.EQ) { + p.nextToken() // skip = + assign.Value = p.parseExpression(LOWEST) + } + update.Assignments = append(update.Assignments, assign) + if !p.currentIs(token.COMMA) { + break + } + p.nextToken() // skip comma + } + + // Parse WHERE clause + if p.currentIs(token.WHERE) { + p.nextToken() // skip WHERE + update.Where = p.parseExpression(LOWEST) + } + + return update +} + func (p *Parser) parseUse() *ast.UseQuery { use := &ast.UseQuery{ Position: p.current.Pos, @@ -5487,9 +5776,9 @@ func (p *Parser) parseParenthesizedSelect() *ast.SelectWithUnionQuery { pos := p.current.Pos p.nextToken() // skip ( - // Check if this is actually a SELECT statement - if !p.currentIs(token.SELECT) && !p.currentIs(token.WITH) { - // Not a SELECT, just skip until we find closing paren + // Check if this is actually a SELECT statement or nested parentheses + if !p.currentIs(token.SELECT) && !p.currentIs(token.WITH) && !p.currentIs(token.LPAREN) { + // Not a SELECT and not nested parens, just skip until we find closing paren depth := 1 for depth > 0 && !p.currentIs(token.EOF) { if p.currentIs(token.LPAREN) { diff --git a/parser/testdata/00030_alter_table/metadata.json b/parser/testdata/00030_alter_table/metadata.json index c04bc590a0..eb237b26b8 100644 --- a/parser/testdata/00030_alter_table/metadata.json +++ b/parser/testdata/00030_alter_table/metadata.json @@ -3,7 +3,6 @@ "stmt14": true, "stmt15": true, "stmt16": true, - "stmt19": true, "stmt20": true, "stmt9": true } diff --git a/parser/testdata/00061_merge_tree_alter/metadata.json b/parser/testdata/00061_merge_tree_alter/metadata.json index a8ce03a4e7..5640837dca 100644 --- a/parser/testdata/00061_merge_tree_alter/metadata.json +++ b/parser/testdata/00061_merge_tree_alter/metadata.json @@ -1,7 +1,6 @@ { "explain_todo": { "stmt33": true, - "stmt37": true, - "stmt41": true + "stmt37": true } } diff --git a/parser/testdata/00062_replicated_merge_tree_alter_zookeeper_long/metadata.json b/parser/testdata/00062_replicated_merge_tree_alter_zookeeper_long/metadata.json index 43f7a22336..a8ef33f487 100644 --- a/parser/testdata/00062_replicated_merge_tree_alter_zookeeper_long/metadata.json +++ b/parser/testdata/00062_replicated_merge_tree_alter_zookeeper_long/metadata.json @@ -1,7 +1,6 @@ { "explain_todo": { "stmt53": true, - "stmt59": true, - "stmt65": true + "stmt59": true } } diff --git a/parser/testdata/00113_shard_group_array/metadata.json b/parser/testdata/00113_shard_group_array/metadata.json index 7bfa5aa5a4..0967ef424b 100644 --- a/parser/testdata/00113_shard_group_array/metadata.json +++ b/parser/testdata/00113_shard_group_array/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt21":true,"stmt25":true}} +{} diff --git a/parser/testdata/00147_alter_nested_default/metadata.json b/parser/testdata/00147_alter_nested_default/metadata.json index 342b3ff5b4..0967ef424b 100644 --- a/parser/testdata/00147_alter_nested_default/metadata.json +++ b/parser/testdata/00147_alter_nested_default/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt8": true - } -} +{} diff --git a/parser/testdata/00255_array_concat_string/metadata.json b/parser/testdata/00255_array_concat_string/metadata.json index 4a3785ad92..0967ef424b 100644 --- a/parser/testdata/00255_array_concat_string/metadata.json +++ b/parser/testdata/00255_array_concat_string/metadata.json @@ -1,8 +1 @@ -{ - "explain_todo": { - "stmt15": true, - "stmt16": true, - "stmt17": true, - "stmt18": true - } -} +{} diff --git a/parser/testdata/00262_alter_alias/metadata.json b/parser/testdata/00262_alter_alias/metadata.json index a56c7cdb0b..0967ef424b 100644 --- a/parser/testdata/00262_alter_alias/metadata.json +++ b/parser/testdata/00262_alter_alias/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt10": true, - "stmt12": true - } -} +{} diff --git a/parser/testdata/00276_sample/metadata.json b/parser/testdata/00276_sample/metadata.json index c19358090d..0967ef424b 100644 --- a/parser/testdata/00276_sample/metadata.json +++ b/parser/testdata/00276_sample/metadata.json @@ -1,19 +1 @@ -{ - "explain_todo": { - "stmt14": true, - "stmt15": true, - "stmt16": true, - "stmt17": true, - "stmt18": true, - "stmt22": true, - "stmt27": true, - "stmt28": true, - "stmt29": true, - "stmt30": true, - "stmt31": true, - "stmt32": true, - "stmt33": true, - "stmt34": true, - "stmt39": true - } -} +{} diff --git a/parser/testdata/00298_enum_width_and_cast/metadata.json b/parser/testdata/00298_enum_width_and_cast/metadata.json index 92ffdfe8b5..0967ef424b 100644 --- a/parser/testdata/00298_enum_width_and_cast/metadata.json +++ b/parser/testdata/00298_enum_width_and_cast/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt10":true}} +{} diff --git a/parser/testdata/00348_tuples/metadata.json b/parser/testdata/00348_tuples/metadata.json index 114ee38611..c45b7602ba 100644 --- a/parser/testdata/00348_tuples/metadata.json +++ b/parser/testdata/00348_tuples/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt12": true, - "stmt7": true + "stmt12": true } } diff --git a/parser/testdata/00378_json_quote_64bit_integers/metadata.json b/parser/testdata/00378_json_quote_64bit_integers/metadata.json index 75e7fabe8b..0967ef424b 100644 --- a/parser/testdata/00378_json_quote_64bit_integers/metadata.json +++ b/parser/testdata/00378_json_quote_64bit_integers/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt10":true,"stmt11":true,"stmt12":true,"stmt6":true,"stmt7":true,"stmt8":true}} +{} diff --git a/parser/testdata/00392_enum_nested_alter/metadata.json b/parser/testdata/00392_enum_nested_alter/metadata.json index 6a047f388a..482ec8aca4 100644 --- a/parser/testdata/00392_enum_nested_alter/metadata.json +++ b/parser/testdata/00392_enum_nested_alter/metadata.json @@ -1,17 +1,9 @@ { "explain_todo": { - "stmt11": true, - "stmt13": true, - "stmt15": true, - "stmt17": true, "stmt21": true, - "stmt23": true, "stmt24": true, "stmt29": true, - "stmt31": true, "stmt4": true, - "stmt6": true, - "stmt7": true, - "stmt9": true + "stmt7": true } } diff --git a/parser/testdata/00509_extended_storage_definition_syntax_zookeeper/metadata.json b/parser/testdata/00509_extended_storage_definition_syntax_zookeeper/metadata.json index 969184549d..9be7220609 100644 --- a/parser/testdata/00509_extended_storage_definition_syntax_zookeeper/metadata.json +++ b/parser/testdata/00509_extended_storage_definition_syntax_zookeeper/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt22": true, - "stmt4": true + "stmt22": true } } diff --git a/parser/testdata/00576_nested_and_prewhere/metadata.json b/parser/testdata/00576_nested_and_prewhere/metadata.json index 943b275814..0967ef424b 100644 --- a/parser/testdata/00576_nested_and_prewhere/metadata.json +++ b/parser/testdata/00576_nested_and_prewhere/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt4": true, - "stmt6": true - } -} +{} diff --git a/parser/testdata/00578_merge_table_sampling/metadata.json b/parser/testdata/00578_merge_table_sampling/metadata.json index 92e84e943a..0967ef424b 100644 --- a/parser/testdata/00578_merge_table_sampling/metadata.json +++ b/parser/testdata/00578_merge_table_sampling/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt8": true, - "stmt9": true - } -} +{} diff --git a/parser/testdata/00622_select_in_parens/metadata.json b/parser/testdata/00622_select_in_parens/metadata.json index bc141058a4..ef58f80315 100644 --- a/parser/testdata/00622_select_in_parens/metadata.json +++ b/parser/testdata/00622_select_in_parens/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt2": true, - "stmt3": true + "stmt2": true } } diff --git a/parser/testdata/00712_prewhere_with_sampling/metadata.json b/parser/testdata/00712_prewhere_with_sampling/metadata.json index 2bca590175..0967ef424b 100644 --- a/parser/testdata/00712_prewhere_with_sampling/metadata.json +++ b/parser/testdata/00712_prewhere_with_sampling/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt2":true,"stmt7":true}} +{} diff --git a/parser/testdata/00753_system_columns_and_system_tables_long/metadata.json b/parser/testdata/00753_system_columns_and_system_tables_long/metadata.json index 6eea4ac173..0967ef424b 100644 --- a/parser/testdata/00753_system_columns_and_system_tables_long/metadata.json +++ b/parser/testdata/00753_system_columns_and_system_tables_long/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt3": true, - "stmt74": true - } -} +{} diff --git a/parser/testdata/00855_join_with_array_join/metadata.json b/parser/testdata/00855_join_with_array_join/metadata.json index 42691a609c..0967ef424b 100644 --- a/parser/testdata/00855_join_with_array_join/metadata.json +++ b/parser/testdata/00855_join_with_array_join/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt22": true, - "stmt23": true - } -} +{} diff --git a/parser/testdata/00945_bloom_filter_index/metadata.json b/parser/testdata/00945_bloom_filter_index/metadata.json index 7c0763ffaa..0967ef424b 100644 --- a/parser/testdata/00945_bloom_filter_index/metadata.json +++ b/parser/testdata/00945_bloom_filter_index/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt152": true - } -} +{} diff --git a/parser/testdata/00983_summing_merge_tree_not_an_identifier/metadata.json b/parser/testdata/00983_summing_merge_tree_not_an_identifier/metadata.json index e9d6e46171..0967ef424b 100644 --- a/parser/testdata/00983_summing_merge_tree_not_an_identifier/metadata.json +++ b/parser/testdata/00983_summing_merge_tree_not_an_identifier/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt1": true - } -} +{} diff --git a/parser/testdata/01034_prewhere_max_parallel_replicas_distributed/metadata.json b/parser/testdata/01034_prewhere_max_parallel_replicas_distributed/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/01034_prewhere_max_parallel_replicas_distributed/metadata.json +++ b/parser/testdata/01034_prewhere_max_parallel_replicas_distributed/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/01064_arrayROCAUC/metadata.json b/parser/testdata/01064_arrayROCAUC/metadata.json index a48eb63337..0967ef424b 100644 --- a/parser/testdata/01064_arrayROCAUC/metadata.json +++ b/parser/testdata/01064_arrayROCAUC/metadata.json @@ -1,8 +1 @@ -{ - "explain_todo": { - "stmt21": true, - "stmt37": true, - "stmt5": true, - "stmt53": true - } -} +{} diff --git a/parser/testdata/01068_parens/metadata.json b/parser/testdata/01068_parens/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/01068_parens/metadata.json +++ b/parser/testdata/01068_parens/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/01318_map_add_map_subtract/metadata.json b/parser/testdata/01318_map_add_map_subtract/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/01318_map_add_map_subtract/metadata.json +++ b/parser/testdata/01318_map_add_map_subtract/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/01318_map_populate_series/metadata.json b/parser/testdata/01318_map_populate_series/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/01318_map_populate_series/metadata.json +++ b/parser/testdata/01318_map_populate_series/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/01414_low_cardinality_nullable/metadata.json b/parser/testdata/01414_low_cardinality_nullable/metadata.json index 7ad5569408..0967ef424b 100644 --- a/parser/testdata/01414_low_cardinality_nullable/metadata.json +++ b/parser/testdata/01414_low_cardinality_nullable/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt9": true - } -} +{} diff --git a/parser/testdata/01421_array_nullable_element_nullable_index/metadata.json b/parser/testdata/01421_array_nullable_element_nullable_index/metadata.json index e5e4780514..0967ef424b 100644 --- a/parser/testdata/01421_array_nullable_element_nullable_index/metadata.json +++ b/parser/testdata/01421_array_nullable_element_nullable_index/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt1": true, - "stmt3": true - } -} +{} diff --git a/parser/testdata/01433_hex_float/metadata.json b/parser/testdata/01433_hex_float/metadata.json index b65b07d7a6..0967ef424b 100644 --- a/parser/testdata/01433_hex_float/metadata.json +++ b/parser/testdata/01433_hex_float/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt4": true - } -} +{} diff --git a/parser/testdata/01557_max_parallel_replicas_no_sample/metadata.json b/parser/testdata/01557_max_parallel_replicas_no_sample/metadata.json index 60f8ea1f08..0967ef424b 100644 --- a/parser/testdata/01557_max_parallel_replicas_no_sample/metadata.json +++ b/parser/testdata/01557_max_parallel_replicas_no_sample/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt11":true}} +{} diff --git a/parser/testdata/01566_negate_formatting/metadata.json b/parser/testdata/01566_negate_formatting/metadata.json index 3a06a4a1ac..0967ef424b 100644 --- a/parser/testdata/01566_negate_formatting/metadata.json +++ b/parser/testdata/01566_negate_formatting/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt5": true - } -} +{} diff --git a/parser/testdata/01576_alias_column_rewrite/metadata.json b/parser/testdata/01576_alias_column_rewrite/metadata.json index 2581609646..95cd2c2b48 100644 --- a/parser/testdata/01576_alias_column_rewrite/metadata.json +++ b/parser/testdata/01576_alias_column_rewrite/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt23": true, "stmt42": true } } diff --git a/parser/testdata/01942_create_table_with_sample/metadata.json b/parser/testdata/01942_create_table_with_sample/metadata.json index e9d6e46171..0967ef424b 100644 --- a/parser/testdata/01942_create_table_with_sample/metadata.json +++ b/parser/testdata/01942_create_table_with_sample/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt1": true - } -} +{} diff --git a/parser/testdata/02002_sampling_and_unknown_column_bug/metadata.json b/parser/testdata/02002_sampling_and_unknown_column_bug/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/02002_sampling_and_unknown_column_bug/metadata.json +++ b/parser/testdata/02002_sampling_and_unknown_column_bug/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/02004_intersect_except_const_column/metadata.json b/parser/testdata/02004_intersect_except_const_column/metadata.json index 12d7fda64a..0967ef424b 100644 --- a/parser/testdata/02004_intersect_except_const_column/metadata.json +++ b/parser/testdata/02004_intersect_except_const_column/metadata.json @@ -1,8 +1 @@ -{ - "explain_todo": { - "stmt12": true, - "stmt13": true, - "stmt14": true, - "stmt2": true - } -} +{} diff --git a/parser/testdata/02004_intersect_except_distinct_operators/metadata.json b/parser/testdata/02004_intersect_except_distinct_operators/metadata.json index c80f910d88..ed99a48b08 100644 --- a/parser/testdata/02004_intersect_except_distinct_operators/metadata.json +++ b/parser/testdata/02004_intersect_except_distinct_operators/metadata.json @@ -12,7 +12,6 @@ "stmt36": true, "stmt38": true, "stmt39": true, - "stmt42": true, - "stmt45": true + "stmt42": true } } diff --git a/parser/testdata/02004_intersect_except_operators/metadata.json b/parser/testdata/02004_intersect_except_operators/metadata.json index a064b0addd..72b95f6c78 100644 --- a/parser/testdata/02004_intersect_except_operators/metadata.json +++ b/parser/testdata/02004_intersect_except_operators/metadata.json @@ -12,7 +12,6 @@ "stmt34": true, "stmt36": true, "stmt37": true, - "stmt40": true, - "stmt43": true + "stmt40": true } } diff --git a/parser/testdata/02006_test_positional_arguments_on_cluster/metadata.json b/parser/testdata/02006_test_positional_arguments_on_cluster/metadata.json index 63647f0427..0967ef424b 100644 --- a/parser/testdata/02006_test_positional_arguments_on_cluster/metadata.json +++ b/parser/testdata/02006_test_positional_arguments_on_cluster/metadata.json @@ -1,18 +1 @@ -{ - "explain_todo": { - "stmt1": true, - "stmt11": true, - "stmt12": true, - "stmt13": true, - "stmt15": true, - "stmt16": true, - "stmt17": true, - "stmt2": true, - "stmt3": true, - "stmt4": true, - "stmt5": true, - "stmt7": true, - "stmt8": true, - "stmt9": true - } -} +{} diff --git a/parser/testdata/02007_test_any_all_operators/metadata.json b/parser/testdata/02007_test_any_all_operators/metadata.json index 4995e0b439..0967ef424b 100644 --- a/parser/testdata/02007_test_any_all_operators/metadata.json +++ b/parser/testdata/02007_test_any_all_operators/metadata.json @@ -1,19 +1 @@ -{ - "explain_todo": { - "stmt10": true, - "stmt11": true, - "stmt12": true, - "stmt13": true, - "stmt14": true, - "stmt15": true, - "stmt16": true, - "stmt17": true, - "stmt18": true, - "stmt19": true, - "stmt20": true, - "stmt5": true, - "stmt6": true, - "stmt7": true, - "stmt8": true - } -} +{} diff --git a/parser/testdata/02097_remove_sample_by/metadata.json b/parser/testdata/02097_remove_sample_by/metadata.json index 47373b0cff..9b2d5596a3 100644 --- a/parser/testdata/02097_remove_sample_by/metadata.json +++ b/parser/testdata/02097_remove_sample_by/metadata.json @@ -1,13 +1,10 @@ { "explain_todo": { "stmt13": true, - "stmt15": true, "stmt16": true, - "stmt2": true, "stmt21": true, "stmt3": true, "stmt5": true, - "stmt8": true, "stmt9": true } } diff --git a/parser/testdata/02111_modify_table_comment/metadata.json b/parser/testdata/02111_modify_table_comment/metadata.json index e0284eb884..05aa6dfc72 100644 --- a/parser/testdata/02111_modify_table_comment/metadata.json +++ b/parser/testdata/02111_modify_table_comment/metadata.json @@ -1,8 +1,6 @@ { "explain_todo": { - "stmt10": true, "stmt4": true, - "stmt6": true, "stmt8": true } } diff --git a/parser/testdata/02155_dictionary_comment/metadata.json b/parser/testdata/02155_dictionary_comment/metadata.json index 62b81668c3..0967ef424b 100644 --- a/parser/testdata/02155_dictionary_comment/metadata.json +++ b/parser/testdata/02155_dictionary_comment/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt13": true - } -} +{} diff --git a/parser/testdata/02184_default_table_engine/metadata.json b/parser/testdata/02184_default_table_engine/metadata.json index f251b24f78..482c754937 100644 --- a/parser/testdata/02184_default_table_engine/metadata.json +++ b/parser/testdata/02184_default_table_engine/metadata.json @@ -1,7 +1,6 @@ { "explain_todo": { "stmt107": true, - "stmt26": true, "stmt56": true, "stmt61": true, "stmt73": true diff --git a/parser/testdata/02354_numeric_literals_with_underscores/metadata.json b/parser/testdata/02354_numeric_literals_with_underscores/metadata.json index 0f293987f1..dbdbb76d4f 100644 --- a/parser/testdata/02354_numeric_literals_with_underscores/metadata.json +++ b/parser/testdata/02354_numeric_literals_with_underscores/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt5": true, "stmt6": true } } diff --git a/parser/testdata/02354_vector_search_queries/metadata.json b/parser/testdata/02354_vector_search_queries/metadata.json index e10d7d44e2..0967ef424b 100644 --- a/parser/testdata/02354_vector_search_queries/metadata.json +++ b/parser/testdata/02354_vector_search_queries/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt90":true}} +{} diff --git a/parser/testdata/02354_vector_search_reference_vector_types/metadata.json b/parser/testdata/02354_vector_search_reference_vector_types/metadata.json index ab9202e88e..0967ef424b 100644 --- a/parser/testdata/02354_vector_search_reference_vector_types/metadata.json +++ b/parser/testdata/02354_vector_search_reference_vector_types/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt11": true - } -} +{} diff --git a/parser/testdata/02354_vector_search_rescoring_distance_in_select_list/metadata.json b/parser/testdata/02354_vector_search_rescoring_distance_in_select_list/metadata.json index 25ecea4299..0967ef424b 100644 --- a/parser/testdata/02354_vector_search_rescoring_distance_in_select_list/metadata.json +++ b/parser/testdata/02354_vector_search_rescoring_distance_in_select_list/metadata.json @@ -1,8 +1 @@ -{ - "explain_todo": { - "stmt14": true, - "stmt16": true, - "stmt21": true, - "stmt7": true - } -} +{} diff --git a/parser/testdata/02380_analyzer_join_sample/metadata.json b/parser/testdata/02380_analyzer_join_sample/metadata.json index 08d2ef4168..342b3ff5b4 100644 --- a/parser/testdata/02380_analyzer_join_sample/metadata.json +++ b/parser/testdata/02380_analyzer_join_sample/metadata.json @@ -1,7 +1,5 @@ { "explain_todo": { - "stmt3": true, - "stmt6": true, "stmt8": true } } diff --git a/parser/testdata/02381_analyzer_join_final/metadata.json b/parser/testdata/02381_analyzer_join_final/metadata.json index 1a3f93296f..c45b7602ba 100644 --- a/parser/testdata/02381_analyzer_join_final/metadata.json +++ b/parser/testdata/02381_analyzer_join_final/metadata.json @@ -1,7 +1,5 @@ { "explain_todo": { - "stmt12": true, - "stmt3": true, - "stmt8": true + "stmt12": true } } diff --git a/parser/testdata/02481_merge_array_join_sample_by/metadata.json b/parser/testdata/02481_merge_array_join_sample_by/metadata.json index 51dfabe749..0967ef424b 100644 --- a/parser/testdata/02481_merge_array_join_sample_by/metadata.json +++ b/parser/testdata/02481_merge_array_join_sample_by/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt3":true}} +{} diff --git a/parser/testdata/02484_substitute_udf_storage_args/metadata.json b/parser/testdata/02484_substitute_udf_storage_args/metadata.json index 74d1fd2782..62b81668c3 100644 --- a/parser/testdata/02484_substitute_udf_storage_args/metadata.json +++ b/parser/testdata/02484_substitute_udf_storage_args/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt10": true, "stmt13": true } } diff --git a/parser/testdata/02559_add_parts/metadata.json b/parser/testdata/02559_add_parts/metadata.json index e9d6e46171..0967ef424b 100644 --- a/parser/testdata/02559_add_parts/metadata.json +++ b/parser/testdata/02559_add_parts/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt1": true - } -} +{} diff --git a/parser/testdata/02559_nested_multiple_levels_default/metadata.json b/parser/testdata/02559_nested_multiple_levels_default/metadata.json index c2bbb632ab..0967ef424b 100644 --- a/parser/testdata/02559_nested_multiple_levels_default/metadata.json +++ b/parser/testdata/02559_nested_multiple_levels_default/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt13": true, - "stmt7": true - } -} +{} diff --git a/parser/testdata/02681_undrop_query/metadata.json b/parser/testdata/02681_undrop_query/metadata.json index cb6306de40..3457d8d58d 100644 --- a/parser/testdata/02681_undrop_query/metadata.json +++ b/parser/testdata/02681_undrop_query/metadata.json @@ -1,12 +1,8 @@ { "explain_todo": { "stmt22": true, - "stmt23": true, - "stmt25": true, "stmt27": true, "stmt31": true, - "stmt32": true, - "stmt34": true, "stmt36": true, "stmt38": true } diff --git a/parser/testdata/02730_with_fill_by_sorting_prefix/metadata.json b/parser/testdata/02730_with_fill_by_sorting_prefix/metadata.json index 10d115b1ef..4ccbd7dd43 100644 --- a/parser/testdata/02730_with_fill_by_sorting_prefix/metadata.json +++ b/parser/testdata/02730_with_fill_by_sorting_prefix/metadata.json @@ -1,17 +1,10 @@ { "explain_todo": { - "stmt20": true, "stmt21": true, - "stmt22": true, "stmt23": true, - "stmt24": true, "stmt25": true, - "stmt26": true, "stmt27": true, - "stmt28": true, "stmt29": true, - "stmt30": true, - "stmt31": true, - "stmt32": true + "stmt31": true } } diff --git a/parser/testdata/02737_arrayJaccardIndex/metadata.json b/parser/testdata/02737_arrayJaccardIndex/metadata.json index a133290734..0967ef424b 100644 --- a/parser/testdata/02737_arrayJaccardIndex/metadata.json +++ b/parser/testdata/02737_arrayJaccardIndex/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt8":true}} +{} diff --git a/parser/testdata/02782_inconsistent_formatting_and_constant_folding/metadata.json b/parser/testdata/02782_inconsistent_formatting_and_constant_folding/metadata.json index 2837de1e13..0967ef424b 100644 --- a/parser/testdata/02782_inconsistent_formatting_and_constant_folding/metadata.json +++ b/parser/testdata/02782_inconsistent_formatting_and_constant_folding/metadata.json @@ -1,8 +1 @@ -{ - "explain_todo": { - "stmt1": true, - "stmt6": true, - "stmt7": true, - "stmt8": true - } -} +{} diff --git a/parser/testdata/02792_alter_table_modify_comment/metadata.json b/parser/testdata/02792_alter_table_modify_comment/metadata.json index 398f0169e7..1e1d731c05 100644 --- a/parser/testdata/02792_alter_table_modify_comment/metadata.json +++ b/parser/testdata/02792_alter_table_modify_comment/metadata.json @@ -1,16 +1,6 @@ { "explain_todo": { - "stmt14": true, - "stmt19": true, "stmt22": true, - "stmt24": true, - "stmt29": true, - "stmt34": true, - "stmt39": true, - "stmt4": true, - "stmt44": true, - "stmt49": true, - "stmt7": true, - "stmt9": true + "stmt7": true } } diff --git a/parser/testdata/02812_subquery_operators/metadata.json b/parser/testdata/02812_subquery_operators/metadata.json index 3a06a4a1ac..0967ef424b 100644 --- a/parser/testdata/02812_subquery_operators/metadata.json +++ b/parser/testdata/02812_subquery_operators/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt5": true - } -} +{} diff --git a/parser/testdata/02868_operator_is_not_distinct_from_priority/metadata.json b/parser/testdata/02868_operator_is_not_distinct_from_priority/metadata.json index f77f4c2ade..f8bd367cbe 100644 --- a/parser/testdata/02868_operator_is_not_distinct_from_priority/metadata.json +++ b/parser/testdata/02868_operator_is_not_distinct_from_priority/metadata.json @@ -1,8 +1,6 @@ { "explain_todo": { "stmt1": true, - "stmt10": true, - "stmt11": true, "stmt2": true, "stmt3": true, "stmt4": true, diff --git a/parser/testdata/02891_empty_tuple/metadata.json b/parser/testdata/02891_empty_tuple/metadata.json index af48d4c110..0967ef424b 100644 --- a/parser/testdata/02891_empty_tuple/metadata.json +++ b/parser/testdata/02891_empty_tuple/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt2":true}} +{} diff --git a/parser/testdata/02911_cte_invalid_query_analysis/metadata.json b/parser/testdata/02911_cte_invalid_query_analysis/metadata.json index 968942c3e9..19830977ac 100644 --- a/parser/testdata/02911_cte_invalid_query_analysis/metadata.json +++ b/parser/testdata/02911_cte_invalid_query_analysis/metadata.json @@ -2,7 +2,6 @@ "explain_todo": { "stmt4": true, "stmt5": true, - "stmt6": true, - "stmt8": true + "stmt6": true } } diff --git a/parser/testdata/02911_join_on_nullsafe_optimization/metadata.json b/parser/testdata/02911_join_on_nullsafe_optimization/metadata.json index 1bce63c700..0967ef424b 100644 --- a/parser/testdata/02911_join_on_nullsafe_optimization/metadata.json +++ b/parser/testdata/02911_join_on_nullsafe_optimization/metadata.json @@ -1,12 +1 @@ -{ - "explain_todo": { - "stmt14": true, - "stmt15": true, - "stmt17": true, - "stmt18": true, - "stmt19": true, - "stmt20": true, - "stmt32": true, - "stmt33": true - } -} +{} diff --git a/parser/testdata/02918_alter_temporary_table/metadata.json b/parser/testdata/02918_alter_temporary_table/metadata.json index 7f26f4a68c..07cb9f9814 100644 --- a/parser/testdata/02918_alter_temporary_table/metadata.json +++ b/parser/testdata/02918_alter_temporary_table/metadata.json @@ -3,7 +3,6 @@ "stmt13": true, "stmt14": true, "stmt15": true, - "stmt18": true, "stmt19": true, "stmt5": true, "stmt8": true diff --git a/parser/testdata/03002_sample_factor_where/metadata.json b/parser/testdata/03002_sample_factor_where/metadata.json index af48d4c110..0967ef424b 100644 --- a/parser/testdata/03002_sample_factor_where/metadata.json +++ b/parser/testdata/03002_sample_factor_where/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt2":true}} +{} diff --git a/parser/testdata/03033_analyzer_resolve_from_parent_scope/metadata.json b/parser/testdata/03033_analyzer_resolve_from_parent_scope/metadata.json index 9a8cc69c0b..b65b07d7a6 100644 --- a/parser/testdata/03033_analyzer_resolve_from_parent_scope/metadata.json +++ b/parser/testdata/03033_analyzer_resolve_from_parent_scope/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt2": true, "stmt4": true } } diff --git a/parser/testdata/03033_with_fill_interpolate/metadata.json b/parser/testdata/03033_with_fill_interpolate/metadata.json index b65b07d7a6..0967ef424b 100644 --- a/parser/testdata/03033_with_fill_interpolate/metadata.json +++ b/parser/testdata/03033_with_fill_interpolate/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt4": true - } -} +{} diff --git a/parser/testdata/03080_analyzer_prefer_column_name_to_alias__virtual_columns/metadata.json b/parser/testdata/03080_analyzer_prefer_column_name_to_alias__virtual_columns/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/03080_analyzer_prefer_column_name_to_alias__virtual_columns/metadata.json +++ b/parser/testdata/03080_analyzer_prefer_column_name_to_alias__virtual_columns/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/03100_lwu_01_basics/metadata.json b/parser/testdata/03100_lwu_01_basics/metadata.json index bd82208299..7b4455cd5f 100644 --- a/parser/testdata/03100_lwu_01_basics/metadata.json +++ b/parser/testdata/03100_lwu_01_basics/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt16": true, - "stmt9": true + "stmt16": true } } diff --git a/parser/testdata/03100_lwu_02_basics/metadata.json b/parser/testdata/03100_lwu_02_basics/metadata.json index afaaa4b0a6..0967ef424b 100644 --- a/parser/testdata/03100_lwu_02_basics/metadata.json +++ b/parser/testdata/03100_lwu_02_basics/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt7": true, - "stmt9": true - } -} +{} diff --git a/parser/testdata/03100_lwu_03_join/metadata.json b/parser/testdata/03100_lwu_03_join/metadata.json index f50a0f21b7..62b81668c3 100644 --- a/parser/testdata/03100_lwu_03_join/metadata.json +++ b/parser/testdata/03100_lwu_03_join/metadata.json @@ -1,7 +1,5 @@ { "explain_todo": { - "stmt10": true, - "stmt13": true, - "stmt6": true + "stmt13": true } } diff --git a/parser/testdata/03100_lwu_04_prewhere/metadata.json b/parser/testdata/03100_lwu_04_prewhere/metadata.json index 0f293987f1..0967ef424b 100644 --- a/parser/testdata/03100_lwu_04_prewhere/metadata.json +++ b/parser/testdata/03100_lwu_04_prewhere/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt5": true, - "stmt6": true - } -} +{} diff --git a/parser/testdata/03100_lwu_05_basics/metadata.json b/parser/testdata/03100_lwu_05_basics/metadata.json index dbdbb76d4f..0967ef424b 100644 --- a/parser/testdata/03100_lwu_05_basics/metadata.json +++ b/parser/testdata/03100_lwu_05_basics/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt6": true - } -} +{} diff --git a/parser/testdata/03100_lwu_06_apply_patches/metadata.json b/parser/testdata/03100_lwu_06_apply_patches/metadata.json index 7db8f80ee1..36d996a78f 100644 --- a/parser/testdata/03100_lwu_06_apply_patches/metadata.json +++ b/parser/testdata/03100_lwu_06_apply_patches/metadata.json @@ -1,8 +1,6 @@ { "explain_todo": { - "stmt10": true, "stmt18": true, - "stmt7": true, "stmt9": true } } diff --git a/parser/testdata/03100_lwu_07_merge_patches/metadata.json b/parser/testdata/03100_lwu_07_merge_patches/metadata.json index 1f8757bb32..c45b7602ba 100644 --- a/parser/testdata/03100_lwu_07_merge_patches/metadata.json +++ b/parser/testdata/03100_lwu_07_merge_patches/metadata.json @@ -1,10 +1,5 @@ { "explain_todo": { - "stmt12": true, - "stmt5": true, - "stmt6": true, - "stmt7": true, - "stmt8": true, - "stmt9": true + "stmt12": true } } diff --git a/parser/testdata/03100_lwu_08_multiple_blocks/metadata.json b/parser/testdata/03100_lwu_08_multiple_blocks/metadata.json index 3a06a4a1ac..0967ef424b 100644 --- a/parser/testdata/03100_lwu_08_multiple_blocks/metadata.json +++ b/parser/testdata/03100_lwu_08_multiple_blocks/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt5": true - } -} +{} diff --git a/parser/testdata/03100_lwu_09_different_structure/metadata.json b/parser/testdata/03100_lwu_09_different_structure/metadata.json index ebb98b5b75..b67140f418 100644 --- a/parser/testdata/03100_lwu_09_different_structure/metadata.json +++ b/parser/testdata/03100_lwu_09_different_structure/metadata.json @@ -2,9 +2,6 @@ "explain_todo": { "stmt10": true, "stmt11": true, - "stmt6": true, - "stmt7": true, - "stmt8": true, "stmt9": true } } diff --git a/parser/testdata/03100_lwu_10_apply_on_merges/metadata.json b/parser/testdata/03100_lwu_10_apply_on_merges/metadata.json index f216958458..e3311cecdb 100644 --- a/parser/testdata/03100_lwu_10_apply_on_merges/metadata.json +++ b/parser/testdata/03100_lwu_10_apply_on_merges/metadata.json @@ -1,12 +1,8 @@ { "explain_todo": { "stmt11": true, - "stmt14": true, - "stmt16": true, "stmt18": true, "stmt19": true, - "stmt5": true, - "stmt6": true, "stmt8": true } } diff --git a/parser/testdata/03100_lwu_12_sequential_consistency/metadata.json b/parser/testdata/03100_lwu_12_sequential_consistency/metadata.json index 15223e732d..ab9202e88e 100644 --- a/parser/testdata/03100_lwu_12_sequential_consistency/metadata.json +++ b/parser/testdata/03100_lwu_12_sequential_consistency/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt11": true, - "stmt9": true + "stmt11": true } } diff --git a/parser/testdata/03100_lwu_18_sequence/metadata.json b/parser/testdata/03100_lwu_18_sequence/metadata.json index 7401011030..f650e24ee6 100644 --- a/parser/testdata/03100_lwu_18_sequence/metadata.json +++ b/parser/testdata/03100_lwu_18_sequence/metadata.json @@ -1,10 +1,6 @@ { "explain_todo": { "stmt12": true, - "stmt16": true, - "stmt5": true, - "stmt6": true, - "stmt7": true, - "stmt8": true + "stmt16": true } } diff --git a/parser/testdata/03100_lwu_19_nullable/metadata.json b/parser/testdata/03100_lwu_19_nullable/metadata.json index 8555a3ee52..0967ef424b 100644 --- a/parser/testdata/03100_lwu_19_nullable/metadata.json +++ b/parser/testdata/03100_lwu_19_nullable/metadata.json @@ -1,9 +1 @@ -{ - "explain_todo": { - "stmt12": true, - "stmt16": true, - "stmt18": true, - "stmt21": true, - "stmt5": true - } -} +{} diff --git a/parser/testdata/03100_lwu_20_different_structure/metadata.json b/parser/testdata/03100_lwu_20_different_structure/metadata.json index 703138bb80..0967ef424b 100644 --- a/parser/testdata/03100_lwu_20_different_structure/metadata.json +++ b/parser/testdata/03100_lwu_20_different_structure/metadata.json @@ -1,7 +1 @@ -{ - "explain_todo": { - "stmt12": true, - "stmt16": true, - "stmt8": true - } -} +{} diff --git a/parser/testdata/03100_lwu_22_detach_attach_patches/metadata.json b/parser/testdata/03100_lwu_22_detach_attach_patches/metadata.json index 19e8872514..29a0cd7cc2 100644 --- a/parser/testdata/03100_lwu_22_detach_attach_patches/metadata.json +++ b/parser/testdata/03100_lwu_22_detach_attach_patches/metadata.json @@ -1,8 +1,5 @@ { "explain_todo": { - "stmt15": true, - "stmt16": true, - "stmt17": true, "stmt21": true, "stmt23": true, "stmt24": true, diff --git a/parser/testdata/03100_lwu_23_apply_patches/metadata.json b/parser/testdata/03100_lwu_23_apply_patches/metadata.json index 52cd57d2ce..9aa0f7414d 100644 --- a/parser/testdata/03100_lwu_23_apply_patches/metadata.json +++ b/parser/testdata/03100_lwu_23_apply_patches/metadata.json @@ -1,12 +1,6 @@ { "explain_todo": { "stmt11": true, - "stmt18": true, - "stmt19": true, - "stmt20": true, - "stmt22": true, - "stmt7": true, - "stmt8": true, - "stmt9": true + "stmt22": true } } diff --git a/parser/testdata/03100_lwu_26_subcolumns/metadata.json b/parser/testdata/03100_lwu_26_subcolumns/metadata.json index ff0eba6904..0967ef424b 100644 --- a/parser/testdata/03100_lwu_26_subcolumns/metadata.json +++ b/parser/testdata/03100_lwu_26_subcolumns/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt6": true, - "stmt7": true - } -} +{} diff --git a/parser/testdata/03100_lwu_27_update_after_on_fly_mutations/metadata.json b/parser/testdata/03100_lwu_27_update_after_on_fly_mutations/metadata.json index 2cf11720b5..0967ef424b 100644 --- a/parser/testdata/03100_lwu_27_update_after_on_fly_mutations/metadata.json +++ b/parser/testdata/03100_lwu_27_update_after_on_fly_mutations/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt10": true, - "stmt8": true - } -} +{} diff --git a/parser/testdata/03100_lwu_30_join_cache/metadata.json b/parser/testdata/03100_lwu_30_join_cache/metadata.json index 0f293987f1..dbdbb76d4f 100644 --- a/parser/testdata/03100_lwu_30_join_cache/metadata.json +++ b/parser/testdata/03100_lwu_30_join_cache/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt5": true, "stmt6": true } } diff --git a/parser/testdata/03100_lwu_31_merge_memory_usage/metadata.json b/parser/testdata/03100_lwu_31_merge_memory_usage/metadata.json index ff0eba6904..b563327205 100644 --- a/parser/testdata/03100_lwu_31_merge_memory_usage/metadata.json +++ b/parser/testdata/03100_lwu_31_merge_memory_usage/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt6": true, "stmt7": true } } diff --git a/parser/testdata/03100_lwu_32_on_fly_filter/metadata.json b/parser/testdata/03100_lwu_32_on_fly_filter/metadata.json index 92efb02376..0967ef424b 100644 --- a/parser/testdata/03100_lwu_32_on_fly_filter/metadata.json +++ b/parser/testdata/03100_lwu_32_on_fly_filter/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt6": true, - "stmt8": true - } -} +{} diff --git a/parser/testdata/03100_lwu_33_add_column/metadata.json b/parser/testdata/03100_lwu_33_add_column/metadata.json index 92efb02376..0967ef424b 100644 --- a/parser/testdata/03100_lwu_33_add_column/metadata.json +++ b/parser/testdata/03100_lwu_33_add_column/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt6": true, - "stmt8": true - } -} +{} diff --git a/parser/testdata/03100_lwu_34_multistep_prewhere/metadata.json b/parser/testdata/03100_lwu_34_multistep_prewhere/metadata.json index 661bded8e9..0967ef424b 100644 --- a/parser/testdata/03100_lwu_34_multistep_prewhere/metadata.json +++ b/parser/testdata/03100_lwu_34_multistep_prewhere/metadata.json @@ -1,7 +1 @@ -{ - "explain_todo": { - "stmt7": true, - "stmt8": true, - "stmt9": true - } -} +{} diff --git a/parser/testdata/03100_lwu_36_json_skip_indexes/metadata.json b/parser/testdata/03100_lwu_36_json_skip_indexes/metadata.json index 342b3ff5b4..0967ef424b 100644 --- a/parser/testdata/03100_lwu_36_json_skip_indexes/metadata.json +++ b/parser/testdata/03100_lwu_36_json_skip_indexes/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt8": true - } -} +{} diff --git a/parser/testdata/03100_lwu_37_update_all_columns/metadata.json b/parser/testdata/03100_lwu_37_update_all_columns/metadata.json index 3a06a4a1ac..0967ef424b 100644 --- a/parser/testdata/03100_lwu_37_update_all_columns/metadata.json +++ b/parser/testdata/03100_lwu_37_update_all_columns/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt5": true - } -} +{} diff --git a/parser/testdata/03100_lwu_39_after_replace_partition/metadata.json b/parser/testdata/03100_lwu_39_after_replace_partition/metadata.json index 58e9a6ae97..15d79beb93 100644 --- a/parser/testdata/03100_lwu_39_after_replace_partition/metadata.json +++ b/parser/testdata/03100_lwu_39_after_replace_partition/metadata.json @@ -1,8 +1,6 @@ { "explain_todo": { "stmt11": true, - "stmt12": true, - "stmt5": true, - "stmt6": true + "stmt5": true } } diff --git a/parser/testdata/03100_lwu_41_bytes_limits/metadata.json b/parser/testdata/03100_lwu_41_bytes_limits/metadata.json index 478109d1e7..0967ef424b 100644 --- a/parser/testdata/03100_lwu_41_bytes_limits/metadata.json +++ b/parser/testdata/03100_lwu_41_bytes_limits/metadata.json @@ -1,10 +1 @@ -{ - "explain_todo": { - "stmt13": true, - "stmt14": true, - "stmt15": true, - "stmt5": true, - "stmt6": true, - "stmt7": true - } -} +{} diff --git a/parser/testdata/03100_lwu_43_subquery_from_rmt/metadata.json b/parser/testdata/03100_lwu_43_subquery_from_rmt/metadata.json index 342b3ff5b4..0967ef424b 100644 --- a/parser/testdata/03100_lwu_43_subquery_from_rmt/metadata.json +++ b/parser/testdata/03100_lwu_43_subquery_from_rmt/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt8": true - } -} +{} diff --git a/parser/testdata/03100_lwu_44_missing_default/metadata.json b/parser/testdata/03100_lwu_44_missing_default/metadata.json index 8162ad6436..0967ef424b 100644 --- a/parser/testdata/03100_lwu_44_missing_default/metadata.json +++ b/parser/testdata/03100_lwu_44_missing_default/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt21": true, - "stmt9": true - } -} +{} diff --git a/parser/testdata/03100_lwu_45_query_condition_cache/metadata.json b/parser/testdata/03100_lwu_45_query_condition_cache/metadata.json index 661bded8e9..afaaa4b0a6 100644 --- a/parser/testdata/03100_lwu_45_query_condition_cache/metadata.json +++ b/parser/testdata/03100_lwu_45_query_condition_cache/metadata.json @@ -1,7 +1,6 @@ { "explain_todo": { "stmt7": true, - "stmt8": true, "stmt9": true } } diff --git a/parser/testdata/03100_lwu_deletes_1/metadata.json b/parser/testdata/03100_lwu_deletes_1/metadata.json index b470c2b73c..ccc75f74d5 100644 --- a/parser/testdata/03100_lwu_deletes_1/metadata.json +++ b/parser/testdata/03100_lwu_deletes_1/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt12": true, "stmt15": true, "stmt9": true } diff --git a/parser/testdata/03100_lwu_deletes_3/metadata.json b/parser/testdata/03100_lwu_deletes_3/metadata.json index d94c5b9752..7392d8b45e 100644 --- a/parser/testdata/03100_lwu_deletes_3/metadata.json +++ b/parser/testdata/03100_lwu_deletes_3/metadata.json @@ -1,8 +1,5 @@ { "explain_todo": { - "stmt10": true, - "stmt11": true, - "stmt12": true, "stmt13": true, "stmt14": true, "stmt15": true, diff --git a/parser/testdata/03115_alias_exists_column/metadata.json b/parser/testdata/03115_alias_exists_column/metadata.json index af48d4c110..0967ef424b 100644 --- a/parser/testdata/03115_alias_exists_column/metadata.json +++ b/parser/testdata/03115_alias_exists_column/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt2":true}} +{} diff --git a/parser/testdata/03142_alter_comment_parameterized_view/metadata.json b/parser/testdata/03142_alter_comment_parameterized_view/metadata.json index bc141058a4..ef58f80315 100644 --- a/parser/testdata/03142_alter_comment_parameterized_view/metadata.json +++ b/parser/testdata/03142_alter_comment_parameterized_view/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt2": true, - "stmt3": true + "stmt2": true } } diff --git a/parser/testdata/03155_analyzer_interpolate/metadata.json b/parser/testdata/03155_analyzer_interpolate/metadata.json index fffcb7d38b..0967ef424b 100644 --- a/parser/testdata/03155_analyzer_interpolate/metadata.json +++ b/parser/testdata/03155_analyzer_interpolate/metadata.json @@ -1,7 +1 @@ -{ - "explain_todo": { - "stmt2": true, - "stmt3": true, - "stmt4": true - } -} +{} diff --git a/parser/testdata/03222_create_timeseries_table/metadata.json b/parser/testdata/03222_create_timeseries_table/metadata.json index fffcb7d38b..0967ef424b 100644 --- a/parser/testdata/03222_create_timeseries_table/metadata.json +++ b/parser/testdata/03222_create_timeseries_table/metadata.json @@ -1,7 +1 @@ -{ - "explain_todo": { - "stmt2": true, - "stmt3": true, - "stmt4": true - } -} +{} diff --git a/parser/testdata/03224_invalid_alter/metadata.json b/parser/testdata/03224_invalid_alter/metadata.json index 57e491f07c..e6b55c3499 100644 --- a/parser/testdata/03224_invalid_alter/metadata.json +++ b/parser/testdata/03224_invalid_alter/metadata.json @@ -3,7 +3,6 @@ "stmt21": true, "stmt22": true, "stmt23": true, - "stmt30": true, "stmt31": true, "stmt32": true, "stmt33": true, diff --git a/parser/testdata/03227_test_sample_n/metadata.json b/parser/testdata/03227_test_sample_n/metadata.json index e9d6e46171..0967ef424b 100644 --- a/parser/testdata/03227_test_sample_n/metadata.json +++ b/parser/testdata/03227_test_sample_n/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt1": true - } -} +{} diff --git a/parser/testdata/03240_array_element_or_null/metadata.json b/parser/testdata/03240_array_element_or_null/metadata.json index 60e53ef924..0967ef424b 100644 --- a/parser/testdata/03240_array_element_or_null/metadata.json +++ b/parser/testdata/03240_array_element_or_null/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt45": true, - "stmt47": true - } -} +{} diff --git a/parser/testdata/03261_tuple_map_to_json_cast/metadata.json b/parser/testdata/03261_tuple_map_to_json_cast/metadata.json index f4c74e32be..0967ef424b 100644 --- a/parser/testdata/03261_tuple_map_to_json_cast/metadata.json +++ b/parser/testdata/03261_tuple_map_to_json_cast/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt10": true - } -} +{} diff --git a/parser/testdata/03272_arrayAUCPR/metadata.json b/parser/testdata/03272_arrayAUCPR/metadata.json index 3a06a4a1ac..0967ef424b 100644 --- a/parser/testdata/03272_arrayAUCPR/metadata.json +++ b/parser/testdata/03272_arrayAUCPR/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt5": true - } -} +{} diff --git a/parser/testdata/03312_analyzer_unused_projection_fix/metadata.json b/parser/testdata/03312_analyzer_unused_projection_fix/metadata.json index 682bda1cbc..0967ef424b 100644 --- a/parser/testdata/03312_analyzer_unused_projection_fix/metadata.json +++ b/parser/testdata/03312_analyzer_unused_projection_fix/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt1": true, - "stmt2": true - } -} +{} diff --git a/parser/testdata/03363_qbit_create_insert_select/metadata.json b/parser/testdata/03363_qbit_create_insert_select/metadata.json index b023fcac0e..0967ef424b 100644 --- a/parser/testdata/03363_qbit_create_insert_select/metadata.json +++ b/parser/testdata/03363_qbit_create_insert_select/metadata.json @@ -1,10 +1 @@ -{ - "explain_todo": { - "stmt32": true, - "stmt5": true, - "stmt56": true, - "stmt73": true, - "stmt79": true, - "stmt82": true - } -} +{} diff --git a/parser/testdata/03364_qbit_negative/metadata.json b/parser/testdata/03364_qbit_negative/metadata.json index 51dfabe749..0967ef424b 100644 --- a/parser/testdata/03364_qbit_negative/metadata.json +++ b/parser/testdata/03364_qbit_negative/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt3":true}} +{} diff --git a/parser/testdata/03365_qbit_casts_as_from_array/metadata.json b/parser/testdata/03365_qbit_casts_as_from_array/metadata.json index 6947807c15..9d32d2ea78 100644 --- a/parser/testdata/03365_qbit_casts_as_from_array/metadata.json +++ b/parser/testdata/03365_qbit_casts_as_from_array/metadata.json @@ -1 +1,8 @@ -{"explain_todo":{"stmt13":true,"stmt14":true,"stmt15":true,"stmt20":true,"stmt21":true,"stmt22":true,"stmt23":true}} +{ + "explain_todo": { + "stmt20": true, + "stmt21": true, + "stmt22": true, + "stmt23": true + } +} diff --git a/parser/testdata/03366_qbit_array_map_populate/metadata.json b/parser/testdata/03366_qbit_array_map_populate/metadata.json index 3cca3b6166..0967ef424b 100644 --- a/parser/testdata/03366_qbit_array_map_populate/metadata.json +++ b/parser/testdata/03366_qbit_array_map_populate/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt14":true}} +{} diff --git a/parser/testdata/03366_with_fill_dag/metadata.json b/parser/testdata/03366_with_fill_dag/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/03366_with_fill_dag/metadata.json +++ b/parser/testdata/03366_with_fill_dag/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/03367_bfloat16_tuple_final/metadata.json b/parser/testdata/03367_bfloat16_tuple_final/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/03367_bfloat16_tuple_final/metadata.json +++ b/parser/testdata/03367_bfloat16_tuple_final/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/03368_qbit_subcolumns/metadata.json b/parser/testdata/03368_qbit_subcolumns/metadata.json index 8606858586..0967ef424b 100644 --- a/parser/testdata/03368_qbit_subcolumns/metadata.json +++ b/parser/testdata/03368_qbit_subcolumns/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt16": true, - "stmt4": true - } -} +{} diff --git a/parser/testdata/03369_bfloat16_map/metadata.json b/parser/testdata/03369_bfloat16_map/metadata.json index ef58f80315..0967ef424b 100644 --- a/parser/testdata/03369_bfloat16_map/metadata.json +++ b/parser/testdata/03369_bfloat16_map/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt2": true - } -} +{} diff --git a/parser/testdata/03369_l2_distance_transposed_variadic/metadata.json b/parser/testdata/03369_l2_distance_transposed_variadic/metadata.json index c89079891b..2fc9d7d80a 100644 --- a/parser/testdata/03369_l2_distance_transposed_variadic/metadata.json +++ b/parser/testdata/03369_l2_distance_transposed_variadic/metadata.json @@ -1 +1,17 @@ -{"explain_todo":{"stmt10":true,"stmt17":true,"stmt18":true,"stmt19":true,"stmt26":true,"stmt27":true,"stmt28":true,"stmt33":true,"stmt34":true,"stmt35":true,"stmt37":true,"stmt4":true,"stmt8":true,"stmt9":true}} +{ + "explain_todo": { + "stmt10": true, + "stmt17": true, + "stmt18": true, + "stmt19": true, + "stmt26": true, + "stmt27": true, + "stmt28": true, + "stmt33": true, + "stmt34": true, + "stmt35": true, + "stmt37": true, + "stmt8": true, + "stmt9": true + } +} diff --git a/parser/testdata/03371_bfloat16_special_values/metadata.json b/parser/testdata/03371_bfloat16_special_values/metadata.json index 05f2588d5d..0967ef424b 100644 --- a/parser/testdata/03371_bfloat16_special_values/metadata.json +++ b/parser/testdata/03371_bfloat16_special_values/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt31": true - } -} +{} diff --git a/parser/testdata/03372_qbit_mergetree_1/metadata.json b/parser/testdata/03372_qbit_mergetree_1/metadata.json index 13a7459d03..0967ef424b 100644 --- a/parser/testdata/03372_qbit_mergetree_1/metadata.json +++ b/parser/testdata/03372_qbit_mergetree_1/metadata.json @@ -1,7 +1 @@ -{ - "explain_todo": { - "stmt13": true, - "stmt22": true, - "stmt4": true - } -} +{} diff --git a/parser/testdata/03372_qbit_mergetree_2/metadata.json b/parser/testdata/03372_qbit_mergetree_2/metadata.json index af3c4a9de0..0967ef424b 100644 --- a/parser/testdata/03372_qbit_mergetree_2/metadata.json +++ b/parser/testdata/03372_qbit_mergetree_2/metadata.json @@ -1,8 +1 @@ -{ - "explain_todo": { - "stmt13": true, - "stmt22": true, - "stmt31": true, - "stmt4": true - } -} +{} diff --git a/parser/testdata/03375_l2_distance_transposed_partial_reads_pass/metadata.json b/parser/testdata/03375_l2_distance_transposed_partial_reads_pass/metadata.json index 60ada59ad9..ef382ce51e 100644 --- a/parser/testdata/03375_l2_distance_transposed_partial_reads_pass/metadata.json +++ b/parser/testdata/03375_l2_distance_transposed_partial_reads_pass/metadata.json @@ -1 +1,6 @@ -{"explain_todo":{"stmt2":true,"stmt4":true,"stmt5":true}} +{ + "explain_todo": { + "stmt4": true, + "stmt5": true + } +} diff --git a/parser/testdata/03392_crash_group_by_use_nulls/metadata.json b/parser/testdata/03392_crash_group_by_use_nulls/metadata.json index e9d6e46171..0967ef424b 100644 --- a/parser/testdata/03392_crash_group_by_use_nulls/metadata.json +++ b/parser/testdata/03392_crash_group_by_use_nulls/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt1": true - } -} +{} diff --git a/parser/testdata/03393_non_constant_second_argument_for_in/metadata.json b/parser/testdata/03393_non_constant_second_argument_for_in/metadata.json index c89ada73f6..0967ef424b 100644 --- a/parser/testdata/03393_non_constant_second_argument_for_in/metadata.json +++ b/parser/testdata/03393_non_constant_second_argument_for_in/metadata.json @@ -1,7 +1 @@ -{ - "explain_todo": { - "stmt43": true, - "stmt44": true, - "stmt45": true - } -} +{} diff --git a/parser/testdata/03404_bfloat16_insert_values/metadata.json b/parser/testdata/03404_bfloat16_insert_values/metadata.json index 7614c9f5b3..24c397911d 100644 --- a/parser/testdata/03404_bfloat16_insert_values/metadata.json +++ b/parser/testdata/03404_bfloat16_insert_values/metadata.json @@ -1,8 +1,6 @@ { "explain_todo": { - "stmt10": true, "stmt14": true, - "stmt16": true, "stmt8": true } } diff --git a/parser/testdata/03447_window_functions_distinct/metadata.json b/parser/testdata/03447_window_functions_distinct/metadata.json index 342b3ff5b4..0967ef424b 100644 --- a/parser/testdata/03447_window_functions_distinct/metadata.json +++ b/parser/testdata/03447_window_functions_distinct/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt8": true - } -} +{} diff --git a/parser/testdata/03513_nullsafe_join_storage/metadata.json b/parser/testdata/03513_nullsafe_join_storage/metadata.json index ef382ce51e..0967ef424b 100644 --- a/parser/testdata/03513_nullsafe_join_storage/metadata.json +++ b/parser/testdata/03513_nullsafe_join_storage/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt4": true, - "stmt5": true - } -} +{} diff --git a/parser/testdata/03554_json_shared_data_map_serialization_compact_part_big/metadata.json b/parser/testdata/03554_json_shared_data_map_serialization_compact_part_big/metadata.json index 9be7220609..0967ef424b 100644 --- a/parser/testdata/03554_json_shared_data_map_serialization_compact_part_big/metadata.json +++ b/parser/testdata/03554_json_shared_data_map_serialization_compact_part_big/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt22": true - } -} +{} diff --git a/parser/testdata/03554_json_shared_data_map_serialization_wide_part_big/metadata.json b/parser/testdata/03554_json_shared_data_map_serialization_wide_part_big/metadata.json index 6f1e887072..0967ef424b 100644 --- a/parser/testdata/03554_json_shared_data_map_serialization_wide_part_big/metadata.json +++ b/parser/testdata/03554_json_shared_data_map_serialization_wide_part_big/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt46": true - } -} +{} diff --git a/parser/testdata/03554_json_shared_data_map_with_buckets_serialization_compact_part_big/metadata.json b/parser/testdata/03554_json_shared_data_map_with_buckets_serialization_compact_part_big/metadata.json index 7bf4b04abe..0967ef424b 100644 --- a/parser/testdata/03554_json_shared_data_map_with_buckets_serialization_compact_part_big/metadata.json +++ b/parser/testdata/03554_json_shared_data_map_with_buckets_serialization_compact_part_big/metadata.json @@ -1,5 +1 @@ -{ - "explain_todo": { - "stmt33": true - } -} +{} diff --git a/parser/testdata/03566_low_cardinality_nan_unique/metadata.json b/parser/testdata/03566_low_cardinality_nan_unique/metadata.json index 60f8ea1f08..0967ef424b 100644 --- a/parser/testdata/03566_low_cardinality_nan_unique/metadata.json +++ b/parser/testdata/03566_low_cardinality_nan_unique/metadata.json @@ -1 +1 @@ -{"explain_todo":{"stmt11":true}} +{} diff --git a/parser/testdata/03604_test_merge_tree_min_read_task_size_is_zero/metadata.json b/parser/testdata/03604_test_merge_tree_min_read_task_size_is_zero/metadata.json index ff0eba6904..dbdbb76d4f 100644 --- a/parser/testdata/03604_test_merge_tree_min_read_task_size_is_zero/metadata.json +++ b/parser/testdata/03604_test_merge_tree_min_read_task_size_is_zero/metadata.json @@ -1,6 +1,5 @@ { "explain_todo": { - "stmt6": true, - "stmt7": true + "stmt6": true } } diff --git a/parser/testdata/03611_null_safe_comparsion/metadata.json b/parser/testdata/03611_null_safe_comparsion/metadata.json index 468db56803..0967ef424b 100644 --- a/parser/testdata/03611_null_safe_comparsion/metadata.json +++ b/parser/testdata/03611_null_safe_comparsion/metadata.json @@ -1,19 +1 @@ -{ - "explain_todo": { - "stmt100": true, - "stmt101": true, - "stmt39": true, - "stmt41": true, - "stmt43": true, - "stmt47": true, - "stmt50": true, - "stmt51": true, - "stmt55": true, - "stmt57": true, - "stmt59": true, - "stmt82": true, - "stmt95": true, - "stmt96": true, - "stmt99": true - } -} +{} diff --git a/parser/testdata/03628_subcolumns_of_columns_with_dot_in_name/metadata.json b/parser/testdata/03628_subcolumns_of_columns_with_dot_in_name/metadata.json index 2712c834b2..7512c65e31 100644 --- a/parser/testdata/03628_subcolumns_of_columns_with_dot_in_name/metadata.json +++ b/parser/testdata/03628_subcolumns_of_columns_with_dot_in_name/metadata.json @@ -2,9 +2,7 @@ "explain_todo": { "stmt11": true, "stmt15": true, - "stmt20": true, "stmt24": true, - "stmt27": true, - "stmt31": true + "stmt27": true } } diff --git a/parser/testdata/03672_nested_array_nested_tuple/metadata.json b/parser/testdata/03672_nested_array_nested_tuple/metadata.json index 5fc7cc1cab..60106a3b25 100644 --- a/parser/testdata/03672_nested_array_nested_tuple/metadata.json +++ b/parser/testdata/03672_nested_array_nested_tuple/metadata.json @@ -1,8 +1,6 @@ { "explain_todo": { - "stmt10": true, "stmt3": true, - "stmt4": true, "stmt9": true } } diff --git a/parser/testdata/03715_empty_tuple_functions_conversion/metadata.json b/parser/testdata/03715_empty_tuple_functions_conversion/metadata.json index 73520390f9..0967ef424b 100644 --- a/parser/testdata/03715_empty_tuple_functions_conversion/metadata.json +++ b/parser/testdata/03715_empty_tuple_functions_conversion/metadata.json @@ -1,6 +1 @@ -{ - "explain_todo": { - "stmt12": true, - "stmt14": true - } -} +{} diff --git a/parser/testdata/03747_float_parsing_subnormal/metadata.json b/parser/testdata/03747_float_parsing_subnormal/metadata.json index e368f56fd8..0967ef424b 100644 --- a/parser/testdata/03747_float_parsing_subnormal/metadata.json +++ b/parser/testdata/03747_float_parsing_subnormal/metadata.json @@ -1,7 +1 @@ -{ - "explain_todo": { - "stmt10": true, - "stmt12": true, - "stmt9": true - } -} +{} diff --git a/token/token.go b/token/token.go index 05bf17cbe7..38ae3888d0 100644 --- a/token/token.go +++ b/token/token.go @@ -123,6 +123,7 @@ const ( INNER INSERT INTERSECT + INTERPOLATE INTERVAL INTO IS @@ -320,6 +321,7 @@ var tokens = [...]string{ INNER: "INNER", INSERT: "INSERT", INTERSECT: "INTERSECT", + INTERPOLATE: "INTERPOLATE", INTERVAL: "INTERVAL", INTO: "INTO", IS: "IS",