scanDollarQuotedString scans for so called dollar-quoted strings, which start/end with either $$ or $tag$, where tag is some arbitrary string. e.g. $$a string$$ or $escaped$a string$escaped$.
(lval *sqlSymType)
| 886 | // scanDollarQuotedString scans for so called dollar-quoted strings, which start/end with either $$ or $tag$, where |
| 887 | // tag is some arbitrary string. e.g. $$a string$$ or $escaped$a string$escaped$. |
| 888 | func (s *scanner) scanDollarQuotedString(lval *sqlSymType) bool { |
| 889 | buf := s.buffer() |
| 890 | start := s.pos |
| 891 | |
| 892 | foundStartTag := false |
| 893 | possibleEndTag := false |
| 894 | startTagIndex := -1 |
| 895 | var startTag string |
| 896 | |
| 897 | outer: |
| 898 | for { |
| 899 | ch := s.peek() |
| 900 | switch ch { |
| 901 | case '$': |
| 902 | s.pos++ |
| 903 | if foundStartTag { |
| 904 | if possibleEndTag { |
| 905 | if len(startTag) == startTagIndex { |
| 906 | // Found end tag. |
| 907 | buf = append(buf, s.in[start+len(startTag)+1:s.pos-len(startTag)-2]...) |
| 908 | break outer |
| 909 | } else { |
| 910 | // Was not the end tag but the current $ might be the start of the end tag we are looking for, so |
| 911 | // just reset the startTagIndex. |
| 912 | startTagIndex = 0 |
| 913 | } |
| 914 | } else { |
| 915 | possibleEndTag = true |
| 916 | startTagIndex = 0 |
| 917 | } |
| 918 | } else { |
| 919 | startTag = s.in[start : s.pos-1] |
| 920 | foundStartTag = true |
| 921 | } |
| 922 | |
| 923 | case eof: |
| 924 | if foundStartTag { |
| 925 | // A start tag was found, therefore we expect an end tag before the eof, otherwise it is an error. |
| 926 | lval.id = ERROR |
| 927 | lval.str = errUnterminated |
| 928 | } else { |
| 929 | // This is not a dollar-quoted string, reset the pos back to the start. |
| 930 | s.pos = start |
| 931 | } |
| 932 | return false |
| 933 | |
| 934 | default: |
| 935 | // If we haven't found a start tag yet, check whether the current characters is a valid for a tag. |
| 936 | if !foundStartTag && !lex.IsIdentStart(ch) { |
| 937 | return false |
| 938 | } |
| 939 | s.pos++ |
| 940 | if possibleEndTag { |
| 941 | // Check whether this could be the end tag. |
| 942 | if startTagIndex >= len(startTag) || ch != int(startTag[startTagIndex]) { |
| 943 | // This is not the end tag we are looking for. |
| 944 | possibleEndTag = false |
| 945 | startTagIndex = -1 |
no test coverage detected