github.com/XiaoMi/Gaea@v1.2.5/parser/ast/util.go (about)

     1  // Copyright 2018 PingCAP, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package ast
    15  
    16  // IsReadOnly checks whether the input ast is readOnly.
    17  func IsReadOnly(node Node) bool {
    18  	switch st := node.(type) {
    19  	case *SelectStmt:
    20  		if st.LockTp == SelectLockForUpdate {
    21  			return false
    22  		}
    23  
    24  		checker := readOnlyChecker{
    25  			readOnly: true,
    26  		}
    27  
    28  		node.Accept(&checker)
    29  		return checker.readOnly
    30  	case *ExplainStmt, *DoStmt:
    31  		return true
    32  	default:
    33  		return false
    34  	}
    35  }
    36  
    37  // readOnlyChecker checks whether a query's ast is readonly, if it satisfied
    38  // 1. selectstmt;
    39  // 2. need not to set var;
    40  // it is readonly statement.
    41  type readOnlyChecker struct {
    42  	readOnly bool
    43  }
    44  
    45  // Enter implements Visitor interface.
    46  func (checker *readOnlyChecker) Enter(in Node) (out Node, skipChildren bool) {
    47  	switch node := in.(type) {
    48  	case *VariableExpr:
    49  		// like func rewriteVariable(), this stands for SetVar.
    50  		if !node.IsSystem && node.Value != nil {
    51  			checker.readOnly = false
    52  			return in, true
    53  		}
    54  	}
    55  	return in, false
    56  }
    57  
    58  // Leave implements Visitor interface.
    59  func (checker *readOnlyChecker) Leave(in Node) (out Node, ok bool) {
    60  	return in, checker.readOnly
    61  }