Search in sources :

Example 1 with OCommandExecutorSQLSelect

use of com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect in project orientdb by orientechnologies.

the class OMatchStatement method query.

private Iterator<OIdentifiable> query(final String className, final OWhereClause oWhereClause, final ORID rid, final OCommandContext ctx) {
    final ODatabaseDocument database = getDatabase();
    if (className != null) {
        OClass schemaClass = database.getMetadata().getSchema().getClass(className);
        database.checkSecurity(ORule.ResourceGeneric.CLASS, ORole.PERMISSION_READ, schemaClass.getName().toLowerCase(Locale.ENGLISH));
    // Iterable<ORecord> baseIterable = fetchFromIndex(schemaClass, oWhereClause);
    }
    // OSelectStatement stm = buildSelectStatement(className, oWhereClause);
    // return stm.execute(ctx);
    String text;
    if (oWhereClause == null) {
        if (rid != null) {
            text = "(select from " + rid + ")";
        } else {
            text = "(select from " + className + ")";
        }
    } else {
        StringBuilder builder = new StringBuilder();
        oWhereClause.toString(ctx.getInputParameters(), builder);
        synchronized (oWhereClause) {
            // this instance is shared...
            replaceIdentifier(oWhereClause, "$currentMatch", "@this");
            text = "(select from " + (rid != null ? rid : className) + " where " + builder.toString().replaceAll("\\$currentMatch", "@this") + ")";
            replaceIdentifier(oWhereClause, "@this", "$currentMatch");
        }
    }
    OSQLTarget target = new OSQLTarget(text, ctx);
    Iterable targetResult = (Iterable) target.getTargetRecords();
    if (targetResult == null) {
        return null;
    }
    if (targetResult instanceof OCommandExecutorSQLSelect) {
        ((OCommandExecutorSQLSelect) targetResult).getContext().setRecordingMetrics(ctx.isRecordingMetrics());
    } else if (targetResult instanceof OCommandExecutorSQLResultsetDelegate) {
        OCommandExecutor delegate = ((OCommandExecutorSQLResultsetDelegate) targetResult).getDelegate();
        if (delegate instanceof OCommandExecutorSQLSelect) {
            delegate.getContext().setRecordingMetrics(ctx.isRecordingMetrics());
        }
    }
    return targetResult.iterator();
}
Also used : ODatabaseDocument(com.orientechnologies.orient.core.db.document.ODatabaseDocument) OSQLTarget(com.orientechnologies.orient.core.sql.filter.OSQLTarget) OClass(com.orientechnologies.orient.core.metadata.schema.OClass) OCommandExecutorSQLSelect(com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect) OCommandExecutorSQLResultsetDelegate(com.orientechnologies.orient.core.sql.OCommandExecutorSQLResultsetDelegate)

Example 2 with OCommandExecutorSQLSelect

use of com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect in project orientdb by orientechnologies.

the class ODistributedStorage method command.

public Object command(final OCommandRequestText iCommand) {
    List<String> servers = (List<String>) iCommand.getContext().getVariable("servers");
    if (servers == null) {
        servers = new ArrayList<String>();
        iCommand.getContext().setVariable("servers", servers);
    }
    final String localNodeName = dManager.getLocalNodeName();
    servers.add(localNodeName);
    if (OScenarioThreadLocal.INSTANCE.isRunModeDistributed())
        // ALREADY DISTRIBUTED
        return wrapped.command(iCommand);
    final ODistributedConfiguration dbCfg = distributedConfiguration;
    if (!dbCfg.isReplicationActive(null, localNodeName))
        // DON'T REPLICATE
        return wrapped.command(iCommand);
    final OCommandExecutor executor = OCommandManager.instance().getExecutor(iCommand);
    executor.setProgressListener(iCommand.getProgressListener());
    executor.parse(iCommand);
    final OCommandExecutor exec = executor instanceof OCommandExecutorSQLDelegate ? ((OCommandExecutorSQLDelegate) executor).getDelegate() : executor;
    if (exec.isIdempotent() && !dManager.isNodeAvailable(dManager.getLocalNodeName(), getName())) {
        // SPECIAL CASE: NODE IS OFFLINE AND THE COMMAND IS IDEMPOTENT, EXECUTE IT LOCALLY ONLY
        ODistributedServerLog.warn(this, dManager.getLocalNodeName(), null, ODistributedServerLog.DIRECTION.NONE, "Node '%s' is %s, the command '%s' against database '%s' will be executed only on local server with the possibility to have partial result", dManager.getLocalNodeName(), dManager.getDatabaseStatus(dManager.getLocalNodeName(), getName()), iCommand, wrapped.getName());
        return wrapped.command(iCommand);
    }
    if (!exec.isIdempotent())
        checkNodeIsMaster(localNodeName, dbCfg, "Command '" + iCommand + "'");
    try {
        Object result = null;
        OCommandDistributedReplicateRequest.DISTRIBUTED_EXECUTION_MODE executionMode = OCommandDistributedReplicateRequest.DISTRIBUTED_EXECUTION_MODE.LOCAL;
        OCommandDistributedReplicateRequest.DISTRIBUTED_RESULT_MGMT resultMgmt = OCommandDistributedReplicateRequest.DISTRIBUTED_RESULT_MGMT.CHECK_FOR_EQUALS;
        boolean executeOnLocalNodeFirst = true;
        if (OScenarioThreadLocal.INSTANCE.getRunMode() != RUN_MODE.RUNNING_DISTRIBUTED) {
            if (exec instanceof OCommandDistributedReplicateRequest) {
                executionMode = ((OCommandDistributedReplicateRequest) exec).getDistributedExecutionMode();
                resultMgmt = ((OCommandDistributedReplicateRequest) exec).getDistributedResultManagement();
                executeOnLocalNodeFirst = ((OCommandDistributedReplicateRequest) exec).isDistributedExecutingOnLocalNodeFirst();
            }
        }
        switch(executionMode) {
            case LOCAL:
                // CALL IN DEFAULT MODE TO LET OWN COMMAND TO REDISTRIBUTE CHANGES (LIKE INSERT)
                return wrapped.command(iCommand);
            case REPLICATE:
                // REPLICATE IT, GET ALL THE INVOLVED NODES
                final Collection<String> involvedClusters = exec.getInvolvedClusters();
                if (resultMgmt == OCommandDistributedReplicateRequest.DISTRIBUTED_RESULT_MGMT.MERGE) {
                    if (!exec.isIdempotent() && dbCfg.isSharded())
                        throw new ODistributedException("Cannot distribute the command '" + iCommand.getText() + "' because it is not idempotent and a map-reduce has been requested");
                    final Map<String, Collection<String>> nodeClusterMap = dbCfg.getServerClusterMap(involvedClusters, localNodeName, exec.isIdempotent());
                    final Map<String, Object> results;
                    if (exec.isIdempotent() && nodeClusterMap.size() == 1 && nodeClusterMap.keySet().iterator().next().equals(localNodeName)) {
                        // LOCAL NODE, AVOID TO DISTRIBUTE IT
                        // CALL IN DEFAULT MODE TO LET OWN COMMAND TO REDISTRIBUTE CHANGES (LIKE INSERT)
                        result = wrapped.command(iCommand);
                        results = new HashMap<String, Object>(1);
                        results.put(localNodeName, result);
                    } else {
                        // SELECT: SPLIT CLASSES/CLUSTER IF ANY
                        results = executeOnServers(iCommand, exec, involvedClusters, nodeClusterMap);
                    }
                    final OCommandExecutorSQLSelect select = exec instanceof OCommandExecutorSQLSelect ? (OCommandExecutorSQLSelect) exec : null;
                    if (select != null && select.isAnyFunctionAggregates() && !select.hasGroupBy()) {
                        result = mergeResultByAggregation(select, results);
                    } else {
                        // MIX & FILTER RESULT SET AVOIDING DUPLICATES
                        // TODO: ONCE OPTIMIZED (SEE ABOVE) AVOID TO FILTER HERE
                        result = exec.mergeResults(results);
                    }
                    if (result instanceof Throwable && results.containsKey(localNodeName))
                        undoCommandOnLocalServer(iCommand);
                } else {
                    final OAbstractCommandTask task = iCommand instanceof OCommandScript ? new OScriptTask(iCommand) : new OSQLCommandTask(iCommand, new HashSet<String>());
                    task.setResultStrategy(OAbstractRemoteTask.RESULT_STRATEGY.ANY);
                    final Set<String> nodes = dbCfg.getServers(involvedClusters);
                    if (iCommand instanceof ODistributedCommand)
                        nodes.removeAll(((ODistributedCommand) iCommand).nodesToExclude());
                    if (executeOnlyLocally(localNodeName, dbCfg, exec, involvedClusters, nodes))
                        // CALL IN DEFAULT MODE TO LET OWN COMMAND TO REDISTRIBUTE CHANGES (LIKE INSERT)
                        return wrapped.command(iCommand);
                    final boolean executedLocally = executeOnLocalNodeFirst && nodes.contains(localNodeName);
                    if (exec.involveSchema())
                        // EXECUTE THE COMMAND IN LOCK
                        result = dManager.executeInDistributedDatabaseLock(getName(), 20000, dManager.getDatabaseConfiguration(getName()).modify(), new OCallable<Object, OModifiableDistributedConfiguration>() {

                            @Override
                            public Object call(OModifiableDistributedConfiguration iArgument) {
                                return executeCommand(iCommand, localNodeName, involvedClusters, task, nodes, executedLocally);
                            }
                        });
                    else
                        result = executeCommand(iCommand, localNodeName, involvedClusters, task, nodes, executedLocally);
                }
                if (exec.involveSchema())
                    // UPDATE THE SCHEMA
                    dManager.propagateSchemaChanges(ODatabaseRecordThreadLocal.INSTANCE.get());
                break;
        }
        if (result instanceof ONeedRetryException)
            throw (ONeedRetryException) result;
        else if (result instanceof RuntimeException)
            throw (RuntimeException) result;
        else if (result instanceof Exception)
            throw OException.wrapException(new ODistributedException("Error on execution distributed COMMAND"), (Exception) result);
        return result;
    } catch (OConcurrentModificationException e) {
        localDistributedDatabase.getDatabaseRepairer().enqueueRepairRecord((ORecordId) e.getRid());
        throw e;
    } catch (ONeedRetryException e) {
        // PASS THROUGH
        throw e;
    } catch (HazelcastInstanceNotActiveException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } catch (HazelcastException e) {
        throw new OOfflineNodeException("Hazelcast instance is not available");
    } catch (Exception e) {
        handleDistributedException("Cannot route COMMAND operation to the distributed node", e);
        // UNREACHABLE
        return null;
    }
}
Also used : OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) OCommandExecutorSQLDelegate(com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate) HazelcastException(com.hazelcast.core.HazelcastException) OCommandExecutorSQLSelect(com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect) HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) OException(com.orientechnologies.common.exception.OException) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException) HazelcastException(com.hazelcast.core.HazelcastException) ODistributedRedirectException(com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException) OIOException(com.orientechnologies.common.io.OIOException) OOfflineNodeException(com.orientechnologies.common.concur.OOfflineNodeException) ORecordId(com.orientechnologies.orient.core.id.ORecordId) HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException) OCommandScript(com.orientechnologies.orient.core.command.script.OCommandScript)

Example 3 with OCommandExecutorSQLSelect

use of com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect in project orientdb by orientechnologies.

the class OSQLCommandTask method execute.

public Object execute(ODistributedRequestId requestId, final OServer iServer, ODistributedServerManager iManager, final ODatabaseDocumentInternal database) throws Exception {
    if (ODistributedServerLog.isDebugEnabled())
        ODistributedServerLog.debug(this, iManager.getLocalNodeName(), getNodeSource(), DIRECTION.IN, "Execute command=%s db=%s", text.toString(), database.getName());
    Object res;
    while (true) {
        try {
            final OCommandRequest cmd = database.command(new OCommandSQL(text));
            OCommandExecutor executor = OCommandManager.instance().getExecutor((OCommandRequestInternal) cmd);
            executor.parse(cmd);
            final OCommandExecutor exec = executor instanceof OCommandExecutorSQLDelegate ? ((OCommandExecutorSQLDelegate) executor).getDelegate() : executor;
            if (exec instanceof OCommandExecutorSQLSelect && clusters.size() > 0) {
                // REWRITE THE TARGET TO USE CLUSTERS
                final StringBuilder buffer = new StringBuilder("cluster:[");
                int i = 0;
                for (String c : clusters) {
                    if (i++ > 0)
                        buffer.append(',');
                    buffer.append(c);
                }
                buffer.append("]");
                ((OCommandExecutorSQLSelect) exec).setParsedTarget(new OSQLTarget(buffer.toString(), exec.getContext()));
            }
            if (params != null)
                // EXECUTE WITH PARAMETERS
                res = executor.execute(params);
            else
                res = executor.execute(null);
            break;
        } catch (ORetryQueryException e) {
            continue;
        }
    }
    return res;
}
Also used : OCommandSQL(com.orientechnologies.orient.core.sql.OCommandSQL) OSQLTarget(com.orientechnologies.orient.core.sql.filter.OSQLTarget) OCommandExecutorSQLDelegate(com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate) OCommandExecutorSQLSelect(com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect) ORetryQueryException(com.orientechnologies.orient.core.exception.ORetryQueryException)

Aggregations

OCommandExecutorSQLSelect (com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect)3 OCommandExecutorSQLDelegate (com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate)2 OSQLTarget (com.orientechnologies.orient.core.sql.filter.OSQLTarget)2 HazelcastException (com.hazelcast.core.HazelcastException)1 HazelcastInstanceNotActiveException (com.hazelcast.core.HazelcastInstanceNotActiveException)1 ONeedRetryException (com.orientechnologies.common.concur.ONeedRetryException)1 OOfflineNodeException (com.orientechnologies.common.concur.OOfflineNodeException)1 OException (com.orientechnologies.common.exception.OException)1 OIOException (com.orientechnologies.common.io.OIOException)1 OCommandScript (com.orientechnologies.orient.core.command.script.OCommandScript)1 ODatabaseDocument (com.orientechnologies.orient.core.db.document.ODatabaseDocument)1 ORetryQueryException (com.orientechnologies.orient.core.exception.ORetryQueryException)1 ORecordId (com.orientechnologies.orient.core.id.ORecordId)1 OClass (com.orientechnologies.orient.core.metadata.schema.OClass)1 OCommandExecutorSQLResultsetDelegate (com.orientechnologies.orient.core.sql.OCommandExecutorSQLResultsetDelegate)1 OCommandSQL (com.orientechnologies.orient.core.sql.OCommandSQL)1 ODistributedRedirectException (com.orientechnologies.orient.enterprise.channel.binary.ODistributedRedirectException)1