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 }