(GenericLexer lexer, SqlParserCallback sqlParserCallback)
| 1029 | } |
| 1030 | |
| 1031 | private ExecutionModel parseCopy(GenericLexer lexer, SqlParserCallback sqlParserCallback) throws SqlException { |
| 1032 | @Nullable ExpressionNode target = null; |
| 1033 | @Nullable CharSequence selectText = null; |
| 1034 | CharSequence tok = tok(lexer, "copy source"); |
| 1035 | int startOfSelect = 0; |
| 1036 | |
| 1037 | if (tok.length() == 1 && tok.charAt(0) == '(') { |
| 1038 | startOfSelect = lexer.getPosition(); |
| 1039 | copyMode = true; |
| 1040 | try { |
| 1041 | parseDml(lexer, startOfSelect, sqlParserCallback); |
| 1042 | final int endOfSelect = lexer.getPosition() - 1; |
| 1043 | selectText = lexer.getContent().subSequence(startOfSelect, endOfSelect); |
| 1044 | expectTok(lexer, ')'); |
| 1045 | } finally { |
| 1046 | copyMode = false; |
| 1047 | } |
| 1048 | } else { |
| 1049 | lexer.unparseLast(); |
| 1050 | target = expectExpr(lexer, sqlParserCallback); |
| 1051 | } |
| 1052 | |
| 1053 | tok = tok(lexer, "'from' or 'to' or 'cancel'"); |
| 1054 | |
| 1055 | ExportModel model = copyModelPool.next(); |
| 1056 | if (isCancelKeyword(tok)) { |
| 1057 | model.setCancel(true); |
| 1058 | model.setTarget(target); |
| 1059 | |
| 1060 | tok = optTok(lexer); |
| 1061 | // no more tokens or ';' should indicate end of statement |
| 1062 | if (tok == null || Chars.equals(tok, ';')) { |
| 1063 | return model; |
| 1064 | } |
| 1065 | |
| 1066 | throw errUnexpected(lexer, tok); |
| 1067 | } |
| 1068 | |
| 1069 | if (isFromKeyword(tok) || isToKeyword(tok)) { |
| 1070 | tok = GenericLexer.immutableOf(tok); |
| 1071 | final ExpressionNode fileName = expectExpr(lexer, sqlParserCallback); |
| 1072 | if (fileName.token.length() < 3 && Chars.startsWith(fileName.token, '\'')) { |
| 1073 | throw SqlException.$(fileName.position, "file name expected"); |
| 1074 | } |
| 1075 | |
| 1076 | model.setTarget(target); |
| 1077 | model.setSelectText(selectText, startOfSelect); |
| 1078 | model.setFileName(fileName); |
| 1079 | } |
| 1080 | |
| 1081 | if (isFromKeyword(tok)) { |
| 1082 | if (Chars.isBlank(configuration.getSqlCopyInputRoot())) { |
| 1083 | throw SqlException.$(lexer.lastTokenPosition(), "COPY is disabled ['cairo.sql.copy.root' is not set?]"); |
| 1084 | } |
| 1085 | if (selectText != null) { |
| 1086 | throw SqlException.$(startOfSelect, "subqueries are not supported for `COPY-FROM`"); |
| 1087 | } |
| 1088 |
no test coverage detected