Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ebc1e8d
fix(plan): preserve enum and set types in views
ck89119 Aug 3, 2026
1d83ee3
fix(plan): preserve special types across view binding
ck89119 Aug 3, 2026
59ae5b9
Merge branch 'main' into issue-26226-main
ck89119 Aug 3, 2026
e476ffe
fix(plan): preserve view distinct display semantics
ck89119 Aug 3, 2026
eaf3bf0
fix(plan): preserve set bitmap across view assignments
ck89119 Aug 3, 2026
e50d8e3
fix(plan): limit set passthrough to bare columns
ck89119 Aug 3, 2026
5ecd810
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 3, 2026
bb144fc
fix(plan): guard missing set projection columns
ck89119 Aug 3, 2026
037e846
fix(plan): preserve view catalog type provenance
ck89119 Aug 3, 2026
e21c569
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 3, 2026
d1c7cdf
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 3, 2026
630e72a
fix(plan): restore view types through transparent queries
ck89119 Aug 3, 2026
d46864f
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 4, 2026
88258ec
fix(plan): preserve set values across view ordering
ck89119 Aug 4, 2026
2cf1961
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 4, 2026
17a8c49
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 4, 2026
63a401c
fix(plan): generalize output column provenance
ck89119 Aug 4, 2026
2e8ec9f
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 4, 2026
6b1f393
refactor(plan): narrow output provenance metadata
ck89119 Aug 4, 2026
c7388c3
Merge remote-tracking branch 'mo/main' into issue-26226-main
ck89119 Aug 4, 2026
5e242cc
fix(plan): canonicalize semantic view values
ck89119 Aug 4, 2026
8e90d5d
fix(plan): preserve canonical view result types
ck89119 Aug 4, 2026
80108da
fix(plan): clear CTAS defaults at query boundaries
ck89119 Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pkg/sql/plan/base_binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,11 @@ func (b *baseBinder) baseBindColRef(astExpr *tree.UnresolvedName, depth int32, i
return
}

if isEnumOrSetPlanType(typ) {
preserveSpecialValue := typ != nil && b.mysqlSpecialTargetType != nil &&
typ.Enumvalues == b.mysqlSpecialTargetType.Enumvalues &&
((isEnumPlanType(typ) && isEnumPlanType(b.mysqlSpecialTargetType)) ||
(isSetPlanType(typ) && isSetPlanType(b.mysqlSpecialTargetType)))
if isEnumOrSetPlanType(typ) && !preserveSpecialValue {
if err != nil {
errutil.ReportError(b.GetContext(), err)
return
Expand Down
16 changes: 9 additions & 7 deletions pkg/sql/plan/bind_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ import (

func NewBindContext(builder *QueryBuilder, parent *BindContext) *BindContext {
bc := &BindContext{
groupByAst: make(map[string]int32),
groupByParamAst: make(map[string]int32),
aggregateByAst: make(map[string]int32),
sampleByAst: make(map[string]int32),
projectByExpr: make(map[string]int32),
windowByAst: make(map[string]int32),
timeByAst: make(map[string]int32),
outputColumnProvenance: make(map[int32]OutputColumnProvenance),
groupByAst: make(map[string]int32),
groupByParamAst: make(map[string]int32),
aggregateByAst: make(map[string]int32),
sampleByAst: make(map[string]int32),
projectByExpr: make(map[string]int32),
windowByAst: make(map[string]int32),
timeByAst: make(map[string]int32),

projectColByAst: make(map[string]int32),

Expand Down Expand Up @@ -66,6 +67,7 @@ func NewBindContext(builder *QueryBuilder, parent *BindContext) *BindContext {
bc.viewChain = append([]string{}, parent.viewChain...)
}
bc.directView = parent.directView
bc.restoreViewMySQLSpecialTypes = parent.restoreViewMySQLSpecialTypes
}

return bc
Expand Down
19 changes: 19 additions & 0 deletions pkg/sql/plan/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ func bindAndOptimizeSelectQueryWithValidator(
isPrepareStmt bool,
skipStats bool,
validate func(*Query) error,
) (*Plan, error) {
return bindAndOptimizeSelectQueryWithValidatorAndCapture(
stmtType, ctx, stmt, isPrepareStmt, skipStats, validate, nil, false,
)
}

func bindAndOptimizeSelectQueryWithValidatorAndCapture(
stmtType plan.Query_StatementType,
ctx CompilerContext,
stmt *tree.Select,
isPrepareStmt bool,
skipStats bool,
validate func(*Query) error,
capture func(*BindContext),
restoreViewMySQLSpecialTypes bool,
) (*Plan, error) {
start := time.Now()
defer func() {
Expand All @@ -47,6 +62,7 @@ func bindAndOptimizeSelectQueryWithValidator(

builder := NewQueryBuilder(stmtType, ctx, isPrepareStmt, true)
bindCtx := NewBindContext(builder, nil)
bindCtx.restoreViewMySQLSpecialTypes = restoreViewMySQLSpecialTypes
if IsSnapshotValid(ctx.GetSnapshot()) {
bindCtx.snapshot = ctx.GetSnapshot()
}
Expand All @@ -58,6 +74,9 @@ func bindAndOptimizeSelectQueryWithValidator(
builder.skipStats = skipStats
rootId = builder.reuseMultiReferenceCTEs(rootId)
ctx.SetViews(bindCtx.views)
if capture != nil {
capture(bindCtx)
}

builder.qry.Steps = append(builder.qry.Steps, rootId)
if validate != nil {
Expand Down
53 changes: 25 additions & 28 deletions pkg/sql/plan/build_ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,24 @@ func genViewTableDef(ctx CompilerContext, stmt *tree.Select, colNames tree.Ident

// check view statement
var stmtPlan *Plan
var outputColumnProvenance []OutputColumnProvenance
captureColumnTypes := func(bindCtx *BindContext) {
outputColumnProvenance = make([]OutputColumnProvenance, len(bindCtx.headings))
for i := range outputColumnProvenance {
outputColumnProvenance[i] = bindCtx.outputColumnProvenanceForProject(int32(i))
}
}
var err error
switch s := stmt.Select.(type) {
case *tree.ParenSelect:
stmtPlan, err = bindAndOptimizeSelectQueryWithValidator(plan.Query_SELECT, ctx, s.Select, false, true, validate)
stmtPlan, err = bindAndOptimizeSelectQueryWithValidatorAndCapture(
plan.Query_SELECT, ctx, s.Select, false, true, validate, captureColumnTypes, true)
if err != nil {
return nil, err
}
default:
stmtPlan, err = bindAndOptimizeSelectQueryWithValidator(plan.Query_SELECT, ctx, stmt, false, true, validate)
stmtPlan, err = bindAndOptimizeSelectQueryWithValidatorAndCapture(
plan.Query_SELECT, ctx, stmt, false, true, validate, captureColumnTypes, true)
if err != nil {
return nil, err
}
Expand All @@ -179,11 +188,17 @@ func genViewTableDef(ctx CompilerContext, stmt *tree.Select, colNames tree.Ident
originName = string(colNames[idx])
name = originName
}
typ := &expr.Typ
if idx < len(outputColumnProvenance) {
if sourceType := mysqlSpecialTypeFromProvenance(outputColumnProvenance[idx]); sourceType != nil {
typ = sourceType
}
}
cols[idx] = &plan.ColDef{
Name: strings.ToLower(name),
OriginName: originName,
Alg: plan.CompressType_Lz4,
Typ: expr.Typ,
Typ: *typ,
Default: &plan.Default{
NullAbility: !expr.Typ.NotNullable,
Expr: nil,
Expand Down Expand Up @@ -246,16 +261,6 @@ func genAsSelectCols(ctx CompilerContext, stmt *tree.Select, isPrepareStmt bool)
builder := NewQueryBuilder(plan.Query_SELECT, ctx, isPrepareStmt, false)
bindCtx := NewBindContext(builder, nil)

getTblAndColName := func(relPos, colPos int32) (string, string) {
name := builder.nameByColRef[[2]int32{relPos, colPos}]
// name pattern: tableName.colName
splits := strings.Split(name, ".")
if len(splits) < 2 {
return "", ""
}
return splits[0], splits[1]
}

if s, ok := stmt.Select.(*tree.ParenSelect); ok {
stmt = s.Select
}
Expand All @@ -269,21 +274,13 @@ func genAsSelectCols(ctx CompilerContext, stmt *tree.Select, isPrepareStmt bool)
for i, expr := range rootNode.ProjectList {
defaultVal := ""
typ := &expr.Typ
switch e := expr.Expr.(type) {
case *plan.Expr_Col:
tblName, colName := getTblAndColName(e.Col.RelPos, e.Col.ColPos)
if binding, ok := bindCtx.bindingByTable[tblName]; ok {
defaultVal = binding.defaults[binding.colIdByName[colName]]
}
case *plan.Expr_F:
// enum
if e.F.Func.ObjName == moEnumCastIndexToValueFun || e.F.Func.ObjName == moSetCastIndexToValueFun {
// cast_index_to_value('apple,banana,orange', cast(col_name as T_uint16))
colRef := e.F.Args[1].Expr.(*plan.Expr_Col).Col
tblName, colName := getTblAndColName(colRef.RelPos, colRef.ColPos)
if binding, ok := bindCtx.bindingByTable[tblName]; ok {
typ = binding.types[binding.colIdByName[colName]]
}
provenance := bindCtx.outputColumnProvenanceForProject(int32(i))
if provenance.State == ProvenanceSingleSource && provenance.Source != nil {
if provenance.CanInheritSourceDefault && provenance.Source.Metadata.HasDefault {
defaultVal = provenance.Source.Metadata.DefaultOriginString
}
if isEnumOrSetPlanType(&provenance.Source.Metadata.Typ) {
typ = &provenance.Source.Metadata.Typ
}
}

Expand Down
Loading
Loading