use of org.apache.ignite.internal.sql.command.SqlCommand in project ignite by apache.
the class QueryParser method parseNative.
/**
* Tries to parse sql query text using native parser. Only first (leading) sql command of the multi-statement is
* actually parsed.
*
* @param schemaName Schema name.
* @param qry which sql text to parse.
* @param remainingAllowed Whether multiple statements are allowed.
* @return Command or {@code null} if cannot parse this query.
*/
@SuppressWarnings("IfMayBeConditional")
@Nullable
private QueryParserResult parseNative(String schemaName, SqlFieldsQuery qry, boolean remainingAllowed) {
String sql = qry.getSql();
// Heuristic check for fast return.
if (!INTERNAL_CMD_RE.matcher(sql.trim()).find())
return null;
try {
SqlParser parser = new SqlParser(schemaName, sql);
SqlCommand nativeCmd = parser.nextCommand();
assert nativeCmd != null : "Empty query. Parser met end of data";
if (!(nativeCmd instanceof SqlCreateIndexCommand || nativeCmd instanceof SqlDropIndexCommand || nativeCmd instanceof SqlBeginTransactionCommand || nativeCmd instanceof SqlCommitTransactionCommand || nativeCmd instanceof SqlRollbackTransactionCommand || nativeCmd instanceof SqlBulkLoadCommand || nativeCmd instanceof SqlAlterTableCommand || nativeCmd instanceof SqlSetStreamingCommand || nativeCmd instanceof SqlCreateUserCommand || nativeCmd instanceof SqlAlterUserCommand || nativeCmd instanceof SqlDropUserCommand || nativeCmd instanceof SqlKillQueryCommand || nativeCmd instanceof SqlKillComputeTaskCommand || nativeCmd instanceof SqlKillServiceCommand || nativeCmd instanceof SqlKillTransactionCommand || nativeCmd instanceof SqlKillScanQueryCommand || nativeCmd instanceof SqlKillContinuousQueryCommand || nativeCmd instanceof SqlAnalyzeCommand || nativeCmd instanceof SqlRefreshStatitsicsCommand || nativeCmd instanceof SqlDropStatisticsCommand))
return null;
SqlFieldsQuery newQry = cloneFieldsQuery(qry).setSql(parser.lastCommandSql());
QueryDescriptor newPlanKey = queryDescriptor(schemaName, newQry);
SqlFieldsQuery remainingQry = null;
if (!F.isEmpty(parser.remainingSql())) {
checkRemainingAllowed(remainingAllowed);
remainingQry = cloneFieldsQuery(qry).setSql(parser.remainingSql()).setArgs(qry.getArgs());
}
QueryParserResultCommand cmd = new QueryParserResultCommand(nativeCmd, null, false);
return new QueryParserResult(newPlanKey, queryParameters(newQry), remainingQry, // Currently none of native statements supports parameters.
Collections.emptyList(), null, null, cmd);
} catch (SqlStrictParseException e) {
throw new IgniteSQLException(e.getMessage(), e.errorCode(), e);
} catch (Exception e) {
// Cannot parse, return.
if (log.isDebugEnabled())
log.debug("Failed to parse SQL with native parser [qry=" + sql + ", err=" + e + ']');
if (!IgniteSystemProperties.getBoolean(IgniteSystemProperties.IGNITE_SQL_PARSER_DISABLE_H2_FALLBACK))
return null;
int code = IgniteQueryErrorCode.PARSING;
if (e instanceof SqlParseException)
code = ((SqlParseException) e).code();
throw new IgniteSQLException("Failed to parse DDL statement: " + sql + ": " + e.getMessage(), code, e);
}
}
use of org.apache.ignite.internal.sql.command.SqlCommand in project ignite by apache.
the class IgniteH2Indexing method checkClusterState.
/**
* Check whether command could be executed with the given cluster state.
*
* @param parseRes Parsing result.
*/
private void checkClusterState(QueryParserResult parseRes) {
if (!ctx.state().publicApiActiveState(true)) {
if (parseRes.isCommand()) {
QueryParserResultCommand cmd = parseRes.command();
assert cmd != null;
SqlCommand cmd0 = cmd.commandNative();
if (cmd0 instanceof SqlCommitTransactionCommand || cmd0 instanceof SqlRollbackTransactionCommand)
return;
}
throw new IgniteException("Can not perform the operation because the cluster is inactive. Note, " + "that the cluster is considered inactive by default if Ignite Persistent Store is used to " + "let all the nodes join the cluster. To activate the cluster call Ignite.active(true).");
}
}
use of org.apache.ignite.internal.sql.command.SqlCommand in project ignite by apache.
the class IgniteH2Indexing method executeCommand.
/**
* Execute command.
*
* @param qryDesc Query descriptor.
* @param qryParams Query parameters.
* @param cliCtx CLient context.
* @param cmd Command (native).
* @return Result.
*/
private FieldsQueryCursor<List<?>> executeCommand(QueryDescriptor qryDesc, QueryParameters qryParams, @Nullable SqlClientContext cliCtx, QueryParserResultCommand cmd) {
if (cmd.noOp())
return zeroCursor();
SqlCommand cmdNative = cmd.commandNative();
GridSqlStatement cmdH2 = cmd.commandH2();
if (qryDesc.local()) {
throw new IgniteSQLException("DDL statements are not supported for LOCAL caches", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
long qryId = registerRunningQuery(qryDesc, qryParams, null, null);
CommandResult res = null;
Exception failReason = null;
try (TraceSurroundings ignored = MTC.support(ctx.tracing().create(SQL_CMD_QRY_EXECUTE, MTC.span()))) {
res = cmdProc.runCommand(qryDesc.sql(), cmdNative, cmdH2, qryParams, cliCtx, qryId);
return res.cursor();
} catch (IgniteException e) {
failReason = e;
throw e;
} catch (IgniteCheckedException e) {
failReason = e;
throw new IgniteSQLException("Failed to execute DDL statement [stmt=" + qryDesc.sql() + ", err=" + e.getMessage() + ']', e);
} finally {
if (res == null || res.unregisterRunningQuery())
runningQryMgr.unregister(qryId, failReason);
}
}
use of org.apache.ignite.internal.sql.command.SqlCommand in project ignite by apache.
the class SqlParserKillQuerySelfTest method assertKillQuery.
/**
* Test that given SQL is parsed as a KILL QUERY command and all parsed parameters have expected values.
*
* @param sql command.
* @param nodeIdExp Expected UUID.
* @param qryIdExp Expected query id.
*/
private static void assertKillQuery(String sql, UUID nodeIdExp, long qryIdExp, boolean async) {
SqlCommand cmd = parse(sql);
Assert.assertTrue(cmd instanceof SqlKillQueryCommand);
SqlKillQueryCommand killQryCmd = (SqlKillQueryCommand) cmd;
Assert.assertEquals(nodeIdExp, killQryCmd.nodeId());
Assert.assertEquals(qryIdExp, killQryCmd.nodeQueryId());
Assert.assertEquals(async, killQryCmd.async());
}
use of org.apache.ignite.internal.sql.command.SqlCommand in project ignite by apache.
the class JdbcThinStatement method execute0.
/**
* @param stmtType Expected statement type.
* @param sql Sql query.
* @param args Query parameters.
*
* @throws SQLException Onj error.
*/
protected void execute0(JdbcStatementType stmtType, String sql, List<Object> args) throws SQLException {
ensureNotClosed();
closeResults();
if (sql == null || sql.isEmpty())
throw new SQLException("SQL query is empty.");
checkStatementBatchEmpty();
SqlCommand nativeCmd = null;
if (stmtType != JdbcStatementType.SELECT_STATEMENT_TYPE && isEligibleForNativeParsing(sql))
nativeCmd = tryParseNative(sql);
if (nativeCmd != null) {
conn.executeNative(sql, nativeCmd, this);
resultSets = Collections.singletonList(resultSetForUpdate(0));
// as an ordinary batch citizen.
return;
}
if (conn.isStream()) {
if (stmtType == JdbcStatementType.SELECT_STATEMENT_TYPE)
throw new SQLException("executeQuery() method is not allowed in streaming mode.", SqlStateCode.INTERNAL_ERROR, IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
conn.addBatch(sql, args);
resultSets = Collections.singletonList(resultSetForUpdate(0));
return;
}
JdbcQueryExecuteRequest req = new JdbcQueryExecuteRequest(stmtType, schema, pageSize, maxRows, conn.getAutoCommit(), explicitTimeout, sql, args == null ? null : args.toArray(new Object[args.size()]));
JdbcResultWithIo resWithIo = conn.sendRequest(req, this, null);
JdbcResult res0 = resWithIo.response();
JdbcThinTcpIo stickyIo = resWithIo.cliIo();
assert res0 != null;
if (res0 instanceof JdbcBulkLoadAckResult)
res0 = sendFile((JdbcBulkLoadAckResult) res0, stickyIo);
if (res0 instanceof JdbcQueryExecuteResult) {
JdbcQueryExecuteResult res = (JdbcQueryExecuteResult) res0;
resultSets = Collections.singletonList(new JdbcThinResultSet(this, res.cursorId(), pageSize, res.last(), res.items(), res.isQuery(), conn.autoCloseServerCursor(), res.updateCount(), closeOnCompletion, stickyIo));
} else if (res0 instanceof JdbcQueryExecuteMultipleStatementsResult) {
JdbcQueryExecuteMultipleStatementsResult res = (JdbcQueryExecuteMultipleStatementsResult) res0;
List<JdbcResultInfo> resInfos = res.results();
resultSets = new ArrayList<>(resInfos.size());
boolean firstRes = true;
for (JdbcResultInfo rsInfo : resInfos) {
if (!rsInfo.isQuery())
resultSets.add(resultSetForUpdate(rsInfo.updateCount()));
else {
if (firstRes) {
firstRes = false;
resultSets.add(new JdbcThinResultSet(this, rsInfo.cursorId(), pageSize, res.isLast(), res.items(), true, conn.autoCloseServerCursor(), -1, closeOnCompletion, stickyIo));
} else {
resultSets.add(new JdbcThinResultSet(this, rsInfo.cursorId(), pageSize, false, null, true, conn.autoCloseServerCursor(), -1, closeOnCompletion, stickyIo));
}
}
}
} else
throw new SQLException("Unexpected result [res=" + res0 + ']');
assert !resultSets.isEmpty() : "At least one results set is expected";
}
Aggregations