github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/bind_context.go (about)

     1  // Copyright 2022 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package plan
    16  
    17  import (
    18  	"context"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/catalog"
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    23  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    24  	"github.com/matrixorigin/matrixone/pkg/sql/util"
    25  )
    26  
    27  func NewBindContext(builder *QueryBuilder, parent *BindContext) *BindContext {
    28  	bc := &BindContext{
    29  		groupByAst:     make(map[string]int32),
    30  		aggregateByAst: make(map[string]int32),
    31  		sampleByAst:    make(map[string]int32),
    32  		projectByExpr:  make(map[string]int32),
    33  		windowByAst:    make(map[string]int32),
    34  		timeByAst:      make(map[string]int32),
    35  		aliasMap:       make(map[string]*aliasItem),
    36  		bindingByTag:   make(map[int32]*Binding),
    37  		bindingByTable: make(map[string]*Binding),
    38  		bindingByCol:   make(map[string]*Binding),
    39  		parent:         parent,
    40  	}
    41  	if parent != nil {
    42  		bc.defaultDatabase = parent.defaultDatabase
    43  		bc.normalCTE = parent.normalCTE
    44  		bc.cteName = parent.cteName
    45  		if parent.recSelect || parent.initSelect || parent.finalSelect {
    46  			bc.cteByName = parent.cteByName
    47  			bc.initSelect = parent.initSelect
    48  			bc.recSelect = parent.recSelect
    49  			bc.finalSelect = parent.finalSelect
    50  			bc.recRecursiveScanNodeId = parent.recRecursiveScanNodeId
    51  			bc.isTryBindingCTE = parent.isTryBindingCTE
    52  		}
    53  		bc.snapshot = parent.snapshot
    54  	}
    55  
    56  	return bc
    57  }
    58  
    59  func (bc *BindContext) rootTag() int32 {
    60  	if bc.initSelect || bc.recSelect {
    61  		return bc.sinkTag
    62  	} else if bc.resultTag > 0 {
    63  		return bc.resultTag
    64  	} else {
    65  		return bc.projectTag
    66  	}
    67  }
    68  
    69  func (bc *BindContext) topTag() int32 {
    70  	if bc.resultTag > 0 {
    71  		return bc.resultTag
    72  	} else {
    73  		return bc.projectTag
    74  	}
    75  }
    76  
    77  func (bc *BindContext) findCTE(name string) *CTERef {
    78  	if cte, ok := bc.cteByName[name]; ok {
    79  		return cte
    80  	}
    81  
    82  	parent := bc.parent
    83  	for parent != nil && name != parent.cteName {
    84  		if cte, ok := parent.cteByName[name]; ok {
    85  			if !bc.maskedCTEs[name] {
    86  				return cte
    87  			}
    88  		}
    89  
    90  		bc = parent
    91  		parent = bc.parent
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func (bc *BindContext) mergeContexts(ctx context.Context, left, right *BindContext) error {
    98  	left.parent = bc
    99  	right.parent = bc
   100  	bc.leftChild = left
   101  	bc.rightChild = right
   102  
   103  	for _, binding := range left.bindings {
   104  		bc.bindings = append(bc.bindings, binding)
   105  		bc.bindingByTag[binding.tag] = binding
   106  		bc.bindingByTable[binding.table] = binding
   107  	}
   108  
   109  	for _, binding := range right.bindings {
   110  		if _, ok := bc.bindingByTable[binding.table]; ok {
   111  			return moerr.NewInvalidInput(ctx, "table '%s' specified more than once", binding.table)
   112  		}
   113  
   114  		bc.bindings = append(bc.bindings, binding)
   115  		bc.bindingByTag[binding.tag] = binding
   116  		bc.bindingByTable[binding.table] = binding
   117  	}
   118  
   119  	for col, binding := range left.bindingByCol {
   120  		bc.bindingByCol[col] = binding
   121  	}
   122  
   123  	for col, binding := range right.bindingByCol {
   124  		if _, ok := bc.bindingByCol[col]; ok {
   125  			bc.bindingByCol[col] = nil
   126  		} else {
   127  			bc.bindingByCol[col] = binding
   128  		}
   129  	}
   130  
   131  	bc.bindingTree = &BindingTreeNode{
   132  		left:  left.bindingTree,
   133  		right: right.bindingTree,
   134  	}
   135  
   136  	return nil
   137  }
   138  
   139  func (bc *BindContext) addUsingCol(col string, typ plan.Node_JoinType, left, right *BindContext) (*plan.Expr, error) {
   140  	leftBinding, ok := left.bindingByCol[col]
   141  	if !ok {
   142  		return nil, moerr.NewInvalidInput(bc.binder.GetContext(), "column '%s' specified in USING clause does not exist in left table", col)
   143  	}
   144  	if leftBinding == nil {
   145  		return nil, moerr.NewInvalidInput(bc.binder.GetContext(), "common column '%s' appears more than once in left table", col)
   146  	}
   147  
   148  	rightBinding, ok := right.bindingByCol[col]
   149  	if !ok {
   150  		return nil, moerr.NewInvalidInput(bc.binder.GetContext(), "column '%s' specified in USING clause does not exist in right table", col)
   151  	}
   152  	if rightBinding == nil {
   153  		return nil, moerr.NewInvalidInput(bc.binder.GetContext(), "common column '%s' appears more than once in right table", col)
   154  	}
   155  
   156  	if typ != plan.Node_RIGHT {
   157  		bc.bindingByCol[col] = leftBinding
   158  		bc.bindingTree.using = append(bc.bindingTree.using, NameTuple{
   159  			table: leftBinding.table,
   160  			col:   col,
   161  		})
   162  	} else {
   163  		bc.bindingByCol[col] = rightBinding
   164  		bc.bindingTree.using = append(bc.bindingTree.using, NameTuple{
   165  			table: rightBinding.table,
   166  			col:   col,
   167  		})
   168  	}
   169  
   170  	leftPos := leftBinding.colIdByName[col]
   171  	rightPos := rightBinding.colIdByName[col]
   172  	expr, err := BindFuncExprImplByPlanExpr(bc.binder.GetContext(), "=", []*plan.Expr{
   173  		{
   174  			Typ: *leftBinding.types[leftPos],
   175  			Expr: &plan.Expr_Col{
   176  				Col: &plan.ColRef{
   177  					RelPos: leftBinding.tag,
   178  					ColPos: leftPos,
   179  				},
   180  			},
   181  		},
   182  		{
   183  			Typ: *rightBinding.types[rightPos],
   184  			Expr: &plan.Expr_Col{
   185  				Col: &plan.ColRef{
   186  					RelPos: rightBinding.tag,
   187  					ColPos: rightPos,
   188  				},
   189  			},
   190  		},
   191  	})
   192  
   193  	return expr, err
   194  }
   195  
   196  func (bc *BindContext) unfoldStar(ctx context.Context, table string, isSysAccount bool) ([]tree.SelectExpr, []string, error) {
   197  	if len(table) == 0 {
   198  		// unfold *
   199  		var exprs []tree.SelectExpr
   200  		var names []string
   201  
   202  		bc.doUnfoldStar(ctx, bc.bindingTree, make(map[string]bool), &exprs, &names, isSysAccount)
   203  
   204  		return exprs, names, nil
   205  	} else {
   206  		// unfold tbl.*
   207  		binding, ok := bc.bindingByTable[table]
   208  		if !ok {
   209  			return nil, nil, moerr.NewInvalidInput(ctx, "missing FROM-clause entry for table '%s'", table)
   210  		}
   211  
   212  		exprs := make([]tree.SelectExpr, 0)
   213  		names := make([]string, 0)
   214  
   215  		for i, col := range binding.cols {
   216  			if binding.colIsHidden[i] {
   217  				continue
   218  			}
   219  			if catalog.ContainExternalHidenCol(col) {
   220  				continue
   221  			}
   222  			//the non-sys account skips the column account_id for the cluster table
   223  			if !isSysAccount && binding.isClusterTable && util.IsClusterTableAttribute(col) {
   224  				continue
   225  			}
   226  			expr, _ := tree.NewUnresolvedName(ctx, table, col)
   227  			exprs = append(exprs, tree.SelectExpr{Expr: expr})
   228  			names = append(names, col)
   229  		}
   230  
   231  		return exprs, names, nil
   232  	}
   233  }
   234  
   235  func (bc *BindContext) doUnfoldStar(ctx context.Context, root *BindingTreeNode, visitedUsingCols map[string]bool, exprs *[]tree.SelectExpr, names *[]string, isSysAccount bool) {
   236  	if root == nil {
   237  		return
   238  	}
   239  	if root.binding != nil {
   240  		for i, col := range root.binding.cols {
   241  			if root.binding.colIsHidden[i] {
   242  				continue
   243  			}
   244  			if catalog.ContainExternalHidenCol(col) {
   245  				continue
   246  			}
   247  			//the non-sys account skips the column account_id for the cluster table
   248  			if !isSysAccount && root.binding.isClusterTable && util.IsClusterTableAttribute(col) {
   249  				continue
   250  			}
   251  			if !visitedUsingCols[col] {
   252  				expr, _ := tree.NewUnresolvedName(ctx, root.binding.table, col)
   253  				*exprs = append(*exprs, tree.SelectExpr{Expr: expr})
   254  				*names = append(*names, col)
   255  			}
   256  		}
   257  
   258  		return
   259  	}
   260  
   261  	var handledUsingCols []string
   262  
   263  	for _, using := range root.using {
   264  		if catalog.ContainExternalHidenCol(using.col) {
   265  			continue
   266  		}
   267  		//the non-sys account skips the column account_id for the cluster table
   268  		if !isSysAccount && root.binding.isClusterTable && util.IsClusterTableAttribute(using.col) {
   269  			continue
   270  		}
   271  		if !visitedUsingCols[using.col] {
   272  			handledUsingCols = append(handledUsingCols, using.col)
   273  			visitedUsingCols[using.col] = true
   274  
   275  			expr, _ := tree.NewUnresolvedName(ctx, using.table, using.col)
   276  			*exprs = append(*exprs, tree.SelectExpr{Expr: expr})
   277  			*names = append(*names, using.col)
   278  		}
   279  	}
   280  
   281  	bc.doUnfoldStar(ctx, root.left, visitedUsingCols, exprs, names, isSysAccount)
   282  	bc.doUnfoldStar(ctx, root.right, visitedUsingCols, exprs, names, isSysAccount)
   283  
   284  	for _, col := range handledUsingCols {
   285  		delete(visitedUsingCols, col)
   286  	}
   287  }
   288  
   289  func (bc *BindContext) qualifyColumnNames(astExpr tree.Expr, expandAlias ExpandAliasMode) (tree.Expr, error) {
   290  	var err error
   291  
   292  	switch exprImpl := astExpr.(type) {
   293  	case *tree.ParenExpr:
   294  		astExpr, err = bc.qualifyColumnNames(exprImpl.Expr, expandAlias)
   295  
   296  	case *tree.OrExpr:
   297  		exprImpl.Left, err = bc.qualifyColumnNames(exprImpl.Left, expandAlias)
   298  		if err != nil {
   299  			return nil, err
   300  		}
   301  
   302  		exprImpl.Right, err = bc.qualifyColumnNames(exprImpl.Right, expandAlias)
   303  
   304  	case *tree.NotExpr:
   305  		exprImpl.Expr, err = bc.qualifyColumnNames(exprImpl.Expr, expandAlias)
   306  
   307  	case *tree.AndExpr:
   308  		exprImpl.Left, err = bc.qualifyColumnNames(exprImpl.Left, expandAlias)
   309  		if err != nil {
   310  			return nil, err
   311  		}
   312  
   313  		exprImpl.Right, err = bc.qualifyColumnNames(exprImpl.Right, expandAlias)
   314  
   315  	case *tree.UnaryExpr:
   316  		exprImpl.Expr, err = bc.qualifyColumnNames(exprImpl.Expr, expandAlias)
   317  
   318  	case *tree.BinaryExpr:
   319  		exprImpl.Left, err = bc.qualifyColumnNames(exprImpl.Left, expandAlias)
   320  		if err != nil {
   321  			return nil, err
   322  		}
   323  
   324  		exprImpl.Right, err = bc.qualifyColumnNames(exprImpl.Right, expandAlias)
   325  
   326  	case *tree.ComparisonExpr:
   327  		exprImpl.Left, err = bc.qualifyColumnNames(exprImpl.Left, expandAlias)
   328  		if err != nil {
   329  			return nil, err
   330  		}
   331  
   332  		exprImpl.Right, err = bc.qualifyColumnNames(exprImpl.Right, expandAlias)
   333  
   334  	case *tree.FuncExpr:
   335  		for i := range exprImpl.Exprs {
   336  			exprImpl.Exprs[i], err = bc.qualifyColumnNames(exprImpl.Exprs[i], expandAlias)
   337  			if err != nil {
   338  				return nil, err
   339  			}
   340  		}
   341  		if exprImpl.WindowSpec != nil {
   342  			for i := range exprImpl.WindowSpec.PartitionBy {
   343  				exprImpl.WindowSpec.PartitionBy[i], err = bc.qualifyColumnNames(exprImpl.WindowSpec.PartitionBy[i], expandAlias)
   344  				if err != nil {
   345  					return nil, err
   346  				}
   347  			}
   348  			for i := range exprImpl.WindowSpec.OrderBy {
   349  				exprImpl.WindowSpec.OrderBy[i].Expr, err = bc.qualifyColumnNames(exprImpl.WindowSpec.OrderBy[i].Expr, expandAlias)
   350  				if err != nil {
   351  					return nil, err
   352  				}
   353  			}
   354  		}
   355  
   356  	case *tree.RangeCond:
   357  		exprImpl.Left, err = bc.qualifyColumnNames(exprImpl.Left, expandAlias)
   358  		if err != nil {
   359  			return nil, err
   360  		}
   361  
   362  		exprImpl.From, err = bc.qualifyColumnNames(exprImpl.From, expandAlias)
   363  		if err != nil {
   364  			return nil, err
   365  		}
   366  
   367  		exprImpl.To, err = bc.qualifyColumnNames(exprImpl.To, expandAlias)
   368  
   369  	case *tree.UnresolvedName:
   370  		if !exprImpl.Star && exprImpl.NumParts == 1 {
   371  			col := exprImpl.Parts[0]
   372  			if expandAlias == AliasBeforeColumn {
   373  				if selectItem, ok := bc.aliasMap[col]; ok {
   374  					return selectItem.astExpr, nil
   375  				}
   376  			}
   377  
   378  			if binding, ok := bc.bindingByCol[col]; ok {
   379  				if binding != nil {
   380  					exprImpl.NumParts = 2
   381  					exprImpl.Parts[1] = binding.table
   382  					return astExpr, nil
   383  				} else {
   384  					return nil, moerr.NewInvalidInput(bc.binder.GetContext(), "ambiguouse column reference to '%s'", col)
   385  				}
   386  			}
   387  
   388  			if expandAlias == AliasAfterColumn {
   389  				if selectItem, ok := bc.aliasMap[col]; ok {
   390  					return selectItem.astExpr, nil
   391  				}
   392  			}
   393  		}
   394  
   395  	case *tree.CastExpr:
   396  		exprImpl.Expr, err = bc.qualifyColumnNames(exprImpl.Expr, expandAlias)
   397  
   398  	case *tree.IsNullExpr:
   399  		exprImpl.Expr, err = bc.qualifyColumnNames(exprImpl.Expr, expandAlias)
   400  
   401  	case *tree.IsNotNullExpr:
   402  		exprImpl.Expr, err = bc.qualifyColumnNames(exprImpl.Expr, expandAlias)
   403  
   404  	case *tree.Tuple:
   405  		for i := range exprImpl.Exprs {
   406  			exprImpl.Exprs[i], err = bc.qualifyColumnNames(exprImpl.Exprs[i], expandAlias)
   407  			if err != nil {
   408  				return nil, err
   409  			}
   410  		}
   411  
   412  	case *tree.CaseExpr:
   413  		exprImpl.Expr, err = bc.qualifyColumnNames(exprImpl.Expr, expandAlias)
   414  		if err != nil {
   415  			return nil, err
   416  		}
   417  
   418  		for _, when := range exprImpl.Whens {
   419  			when.Cond, err = bc.qualifyColumnNames(when.Cond, expandAlias)
   420  			if err != nil {
   421  				return nil, err
   422  			}
   423  
   424  			when.Val, err = bc.qualifyColumnNames(when.Val, expandAlias)
   425  			if err != nil {
   426  				return nil, err
   427  			}
   428  		}
   429  
   430  		exprImpl.Else, err = bc.qualifyColumnNames(exprImpl.Else, expandAlias)
   431  
   432  	case *tree.XorExpr:
   433  		exprImpl.Left, err = bc.qualifyColumnNames(exprImpl.Left, expandAlias)
   434  		if err != nil {
   435  			return nil, err
   436  		}
   437  
   438  		exprImpl.Right, err = bc.qualifyColumnNames(exprImpl.Right, expandAlias)
   439  	}
   440  
   441  	return astExpr, err
   442  }