// data
Statement compileSQLProcedureStatementOrNull(Routine routine,
            StatementCompound context) {
        Statement cs    = null;
        HsqlName  label = null;
        RangeVariable[] rangeVariables = context == null
                                         ? routine.getParameterRangeVariables()
                                         : context.getRangeVariables();
        if (!routine.isTrigger() && isSimpleName() && !isReservedKey()) {
            label = readNewSchemaObjectName(SchemaObject.LABEL, false);
            // todo - improved error message
            if (token.tokenType != Tokens.COLON) {
                throw unexpectedToken(label.getNameString());
            }
            readThis(Tokens.COLON);
        }
        compileContext.reset();
        HsqlName oldSchema = session.getCurrentSchemaHsqlName();
        session.setCurrentSchemaHsqlName(routine.getSchemaName());
        try {
            switch (token.tokenType) {
                // data
                case Tokens.OPEN : {
                    if (routine.dataImpact == Routine.CONTAINS_SQL) {
                        throw Error.error(ErrorCode.X_42602,
                                          routine.getDataImpactString());
                    }
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileOpenCursorStatement(context);
                    break;
                }
                case Tokens.SELECT : {
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileSelectSingleRowStatement(rangeVariables);
                    break;
                }
                // data change
                case Tokens.INSERT :
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileInsertStatement(rangeVariables);
                    break;
                case Tokens.UPDATE :
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileUpdateStatement(rangeVariables);
                    break;
                case Tokens.DELETE :
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileDeleteStatement(rangeVariables);
                    break;
                case Tokens.TRUNCATE :
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileTruncateStatement();
                    break;
                case Tokens.MERGE :
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileMergeStatement(rangeVariables);
                    break;
                case Tokens.SET :
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    if (routine.isTrigger()) {
                        if (routine.triggerOperation
                                == StatementTypes.DELETE_WHERE) {
                            cs = compileSetStatement(rangeVariables);
                            break;
                        }
                        if (routine.triggerType != TriggerDef.BEFORE) {
                            cs = compileSetStatement(rangeVariables);
                            break;
                        }
                        int position = super.getPosition();
                        try {
                            cs = compileTriggerSetStatement(
                                routine.triggerTable, rangeVariables);
                        } catch (HsqlException e) {
                            rewind(position);
                            cs = compileSetStatement(rangeVariables);
                        }
                    } else {
                        cs = compileSetStatement(rangeVariables);
                    }
                    break;
                case Tokens.GET :
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = this.compileGetStatement(rangeVariables);
                    break;
                // control
                case Tokens.CALL : {
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileCallStatement(rangeVariables, true);
                    Routine proc = ((StatementProcedure) cs).procedure;
                    if (proc != null) {
                        switch (routine.dataImpact) {
                            case Routine.CONTAINS_SQL : {
                                if (proc.dataImpact == Routine.READS_SQL
                                        || proc.dataImpact
                                           == Routine.MODIFIES_SQL) {
                                    throw Error.error(
                                        ErrorCode.X_42602,
                                        routine.getDataImpactString());
                                }
                                break;
                            }
                            case Routine.READS_SQL : {
                                if (proc.dataImpact == Routine.MODIFIES_SQL) {
                                    throw Error.error(
                                        ErrorCode.X_42602,
                                        routine.getDataImpactString());
                                }
                                break;
                            }
                        }
                    }
                    break;
                }
                case Tokens.RETURN : {
                    if (routine.isTrigger() || label != null) {
                        throw unexpectedToken();
                    }
                    read();
                    cs = compileReturnValue(routine, context);
                    break;
                }
                case Tokens.BEGIN : {
                    cs = compileCompoundStatement(routine, context, label);
                    break;
                }
                case Tokens.WHILE : {
                    if (routine.isTrigger()) {
                        throw unexpectedToken();
                    }
                    cs = compileWhile(routine, context, label);
                    break;
                }
                case Tokens.REPEAT : {
                    cs = compileRepeat(routine, context, label);
                    break;
                }
                case Tokens.LOOP : {
                    cs = compileLoop(routine, context, label);
                    break;
                }
                case Tokens.FOR : {
                    cs = compileFor(routine, context, label);
                    break;
                }
                case Tokens.ITERATE : {
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileIterate();
                    break;
                }
                case Tokens.LEAVE : {
                    if (label != null) {
                        throw unexpectedToken();
                    }
                    cs = compileLeave(routine, context);
                    break;
                }
                case Tokens.IF : {
                    cs = compileIf(routine, context);
                    break;
                }
                case Tokens.CASE : {
                    cs = compileCase(routine, context);
                    break;
                }
                case Tokens.SIGNAL : {
                    cs = compileSignal(routine, context, label);
                    break;
                }
                case Tokens.RESIGNAL : {
                    cs = compileResignal(routine, context, label);
                    break;
                }
                default :
                    return null;
            }
            cs.setRoot(routine);
            cs.setParent(context);
            return cs;
        } finally {
            session.setCurrentSchemaHsqlName(oldSchema);
        }
    }
try {
switch (token.tokenType) {
// data
case Tokens.OPEN : {
if (routine.dataImpact == Routine.CONTAINS_SQL) {
if (token.tokenType != Tokens.COLON) {
throw unexpectedToken(label.getNameString());
}
readThis(Tokens.COLON);
}
compileContext.reset();
HsqlName oldSchema = session.getCurrentSchemaHsqlName();
session.setCurrentSchemaHsqlName(routine.getSchemaName());
try {
switch (token.tokenType) {
// data
case Tokens.OPEN : {
if (routine.dataImpact == Routine.CONTAINS_SQL) {
throw Error.error(ErrorCode.X_42602,
routine.getDataImpactString());
}
if (label != null) {
throw unexpectedToken();
}
cs = compileOpenCursorStatement(context);
break;
Statement compileSQLProcedureStatementOrNull(Routine routine,
StatementCompound context) {
Statement cs = null;
HsqlName label = null;
RangeVariable[] rangeVariables = context == null
? routine.getParameterRangeVariables()
: context.getRangeVariables();
if (!routine.isTrigger() && isSimpleName() && !isReservedKey()) {
label = readNewSchemaObjectName(SchemaObject.LABEL, false);
// todo - improved error message
if (token.tokenType != Tokens.COLON) {
throw unexpectedToken(label.getNameString());
}
readThis(Tokens.COLON);
}
compileContext.reset();
HsqlName oldSchema = session.getCurrentSchemaHsqlName();
session.setCurrentSchemaHsqlName(routine.getSchemaName());
try {
switch (token.tokenType) {
// data
case Tokens.OPEN : {
if (routine.dataImpact == Routine.CONTAINS_SQL) {
throw Error.error(ErrorCode.X_42602,
routine.getDataImpactString());
}
if (label != null) {
throw unexpectedToken();
}
cs = compileOpenCursorStatement(context);
break;
}
case Tokens.SELECT : {
if (label != null) {
throw unexpectedToken();
}
cs = compileSelectSingleRowStatement(rangeVariables);
break;
}
// data change
case Tokens.INSERT :