scanOne is a simplified version of (*Parser).scanOneStmt() for use by HasMultipleStatements().
(lval *fakeSym)
| 1124 | // scanOne is a simplified version of (*Parser).scanOneStmt() for use |
| 1125 | // by HasMultipleStatements(). |
| 1126 | func (s *SQLScanner) scanOne(lval *fakeSym) (done, hasToks bool, err error) { |
| 1127 | // Scan the first token. |
| 1128 | for { |
| 1129 | s.Scan(lval) |
| 1130 | if lval.id == 0 { |
| 1131 | return true, false, nil |
| 1132 | } |
| 1133 | if lval.id != ';' { |
| 1134 | break |
| 1135 | } |
| 1136 | } |
| 1137 | |
| 1138 | var preValID int32 |
| 1139 | // This is used to track the degree of nested `BEGIN ATOMIC ... END` function |
| 1140 | // body context. When greater than zero, it means that we're scanning through |
| 1141 | // the function body of a `CREATE FUNCTION` statement. ';' character is only |
| 1142 | // a separator of sql statements within the body instead of a finishing line |
| 1143 | // of the `CREATE FUNCTION` statement. |
| 1144 | curFuncBodyCnt := 0 |
| 1145 | for { |
| 1146 | if lval.id == lexbase.ERROR { |
| 1147 | return true, true, fmt.Errorf("scan error: %s", lval.s) |
| 1148 | } |
| 1149 | preValID = lval.id |
| 1150 | s.Scan(lval) |
| 1151 | if preValID == lexbase.BEGIN && lval.id == lexbase.ATOMIC { |
| 1152 | curFuncBodyCnt++ |
| 1153 | } |
| 1154 | if curFuncBodyCnt > 0 && lval.id == lexbase.END { |
| 1155 | curFuncBodyCnt-- |
| 1156 | } |
| 1157 | if lval.id == 0 || (curFuncBodyCnt == 0 && lval.id == ';') { |
| 1158 | return (lval.id == 0), true, nil |
| 1159 | } |
| 1160 | } |
| 1161 | } |
| 1162 | |
| 1163 | // LastLexicalToken returns the last lexical token. If the string has no lexical |
| 1164 | // tokens, returns 0 and ok=false. |
no test coverage detected