Package dev.frostlake.executor
Class ProceduralExecutor
java.lang.Object
dev.frostlake.executor.ProceduralExecutor
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidClear cursors, exceptions, and declared variable types from a prior invocation so re-execution doesn't fail (or coerce against a stale declaration).voidvoidForget the last failure — a statement that COMPLETED means nothing is propagating any more.coerceArgument(Object value, DataType type) A CALL argument under its parameter's declared type.coerceToType(Object value, DataType type) Apply a DECLARED type to a value, exactly as the::cast would — live converts at every assignment (a TZ initialiser assigned to a baretimestampbecomes the session mapping's NTZ, assigned to adateit truncates, a scalar assigned to an OBJECT is TO_OBJECT's own refusal and to an ARRAY it wraps), and the declared WIDTH is enforced: a too-long string is refused with the truncation sentence, never silently kept.The exception names declared so far.The declared RETURNS type the block about to run judges its direct RETURNs against: only the procedure's OWN block, entered at the depth its body started from, and only for a scalar RETURNS type; null for every other block.voiddeclareVariableType(String name, DataType type) voidvoidA compound body run by another handler — an EXCEPTION handler's statements — is entered here.voidvoidvoidexecuteBlock(ProceduralBlock block) voidexecuteStatement(Statement stmt) Run one statement, remembering WHERE it stood if it fails: an error escaping the block names the failing statement's own line and position, and the INNERMOST one wins because the record is taken as the exception unwinds and a later (outer) record is ignored.voidMark that a BEGIN…END block handler has finished (nesting depth--).voidvoidintHow many BEGIN…END blocks are currently open; 1 inside the outermost.The exception currently being handled, or null if not inside an exception handler.The declared type recorded for a variable, or null when its declaration carried none.The uncaught kind live names for the recorded failure — seerecordExpressionFailure(int, int).int1-based line of the statement that is failing, or -1 when none is.int0-based column of the statement that is failing.The declared RETURNS type the executed RETURN converted its value to, or null when it kept its own.The type the executed RETURN's result column declares (live-verified): the declared RETURNS type when the value converted to it, else the static type of the expression the RETURN names (seestaticTypeOfReturn(dev.frostlake.executor.procedural.ReturnStatement, java.lang.Object)) — a text or a binary one at the column's full width either way, seeAnonymousBlockResult.columnType(dev.frostlake.types.DataType)— else null, which leaves the column to the nominal VARCHAR.getVariable(String name) booleanhasBreak()booleanbooleanhasException(String name) booleanbooleanhasVariable(String name) True when a procedural variable with this name exists in the current scope (even null-valued).inferUntypedDeclarationType(BaseExpression initialiser) The type an UNTYPED declaration takes from its initialiser (live-verified): an integer literal makes a NUMBER(38,0), a decimal literal a FLOAT, and a NAME hands over its own type when that is a whole-number NUMBER — a FOR counter's NUMBER(9,0) — or FLOAT when it carries a scale (a NUMBER(10,4) holding 1.7777 makes a FLOAT).booleanWhether a BEGIN…END block is currently executing.booleanWhether the currently-executing BEGIN…END block is nested inside another one.booleanlookupResultSet(String rawName) ForFROM TABLE(<name>)in procedural SQL: ifnameis an in-scope RESULTSET variable (raw ResultSet from:= (EXECUTE IMMEDIATE …)or aResultSetVariablefrom DEFAULT-init), return its rows (executing the DEFAULT query on first use); otherwise null.voidCalled when a variable is DECLARED (not just assigned) in the current scope.voidopenCursorOverResultSet(Cursor cursor) Open aCURSOR FOR <resultset_var>over the RESULTSET's rows (empty if it does not resolve).The parameter names in scope of the block about to run: its procedure's signature when it is the procedure's OWN block, and none for any other block.voidvoidDone handling the current exception.voidpushContinueHandler(ContinueHandler handler) Push a block's CONTINUE handler while it executes, so enclosed loops can resume on a body error.pushDeclaredReturn(DataType returnsType, Set<String> parameterNames) Start a procedure body under its declared RETURNS type (null for a table-returning body), and hand back the caller's frame to put back when the body is done.voidMarkeas the exception now being handled (so a bare RAISE; inside the handler can re-raise it).voidrecordExpressionFailure(int line, int position) Remember where a failing EXPRESSION stood.voidrecordSqlRowCount(ResultSet result) Record the DML-status globals after one executed SQL statement.voidrecordStatementFailure(int line, int position) Remember where a failing statement stood — the FIRST record of a propagation wins, so the innermost statement names itself and the enclosing constructs it unwinds through do not.voidThe DML-status effect of a completed statement whose result never surfaced as a result set.voidregisterCursor(String name, Cursor cursor) voidvoidrestoreCursors(Set<String> savedNames) voidvoidsetQueryExecutor(QueryExecutor queryExecutor) voidsetVariable(String name, Object value) Replace :varname bind-variable references in a SQL string with their current procedural-scope values, quoted as string literals.booleanOffer an exception to the innermost active CONTINUE handler; true if it handled it (caller continues).typeOfSqlInitialiser(Expression sqlInitialiser) The type an untyped declaration takes from an initialiserinferUntypedDeclarationType(dev.frostlake.executor.procedural.BaseExpression)does not type directly — seeDeclarationTypes— over the declared types in scope.
-
Constructor Details
-
ProceduralExecutor
public ProceduralExecutor()
-
-
Method Details
-
setQueryExecutor
-
getQueryExecutor
-
executeBlock
-
enterCompound
public void enterCompound()A compound body run by another handler — an EXCEPTION handler's statements — is entered here. -
exitCompound
public void exitCompound() -
pushDeclaredReturn
Start a procedure body under its declared RETURNS type (null for a table-returning body), and hand back the caller's frame to put back when the body is done. -
restoreDeclaredReturn
-
declaredReturnOfNextBlock
The declared RETURNS type the block about to run judges its direct RETURNs against: only the procedure's OWN block, entered at the depth its body started from, and only for a scalar RETURNS type; null for every other block. -
ownBlockParameterNames
The parameter names in scope of the block about to run: its procedure's signature when it is the procedure's OWN block, and none for any other block. The caller's variables are never among them. -
getReturnedDeclaredType
The declared RETURNS type the executed RETURN converted its value to, or null when it kept its own. -
getReturnedResultType
The type the executed RETURN's result column declares (live-verified): the declared RETURNS type when the value converted to it, else the static type of the expression the RETURN names (seestaticTypeOfReturn(dev.frostlake.executor.procedural.ReturnStatement, java.lang.Object)) — a text or a binary one at the column's full width either way, seeAnonymousBlockResult.columnType(dev.frostlake.types.DataType)— else null, which leaves the column to the nominal VARCHAR. -
pushContinueHandler
Push a block's CONTINUE handler while it executes, so enclosed loops can resume on a body error. -
popContinueHandler
public void popContinueHandler() -
tryContinueHandler
Offer an exception to the innermost active CONTINUE handler; true if it handled it (caller continues). -
executeStatement
Run one statement, remembering WHERE it stood if it fails: an error escaping the block names the failing statement's own line and position, and the INNERMOST one wins because the record is taken as the exception unwinds and a later (outer) record is ignored. A statement that completes clears the record, so a handled failure does not label a later, unrelated one. -
openCursorOverResultSet
Open aCURSOR FOR <resultset_var>over the RESULTSET's rows (empty if it does not resolve). -
coerceArgument
A CALL argument under its parameter's declared type. A NUMBER argument is read at the declared scale (live: 1.7777 into a NUMBER(5,2) parameter is 1.78, and SYSTEM$TYPEOF of the parameter is NUMBER(5,2)) and a text into a DATE / TIME / TIMESTAMP parameter is read as one; a VARCHAR parameter's width is NOT enforced ('abcdef' into a VARCHAR(2) parameter answers abcdef on the account), so a text — and a container — passes untouched. -
inferUntypedDeclarationType
The type an UNTYPED declaration takes from its initialiser (live-verified): an integer literal makes a NUMBER(38,0), a decimal literal a FLOAT, and a NAME hands over its own type when that is a whole-number NUMBER — a FOR counter's NUMBER(9,0) — or FLOAT when it carries a scale (a NUMBER(10,4) holding 1.7777 makes a FLOAT). Any other initialiser is typed as a SQL expression bytypeOfSqlInitialiser(dev.frostlake.executor.expressions.Expression). -
typeOfSqlInitialiser
The type an untyped declaration takes from an initialiserinferUntypedDeclarationType(dev.frostlake.executor.procedural.BaseExpression)does not type directly — seeDeclarationTypes— over the declared types in scope.- Parameters:
sqlInitialiser- the initialiser as a SQL expression, or null- Returns:
- the declared type, or null when none can be determined
-
recordSqlRowCount
Record the DML-status globals after one executed SQL statement. A DML result — one carrying "number of rows …" (inserted / updated / deleted) columns — setsSQLROWCOUNTto the affected total,SQLFOUND/SQLNOTFOUNDto whether that total is non-zero, andACTIVITY_COUNTto the same total. EVERY OTHER completed statement — a SELECT, DDL, and TRUNCATE TABLE too — resets the three DML variables to NULL and setsACTIVITY_COUNTto its own result's row count (a DDL status line counts 1, a SELECT its rows). All four start NULL. Live-verified, including the reset: a SELECT between the DML and the read answers NULL for the trio, and scripting-internal statements (LET, assignments, control flow) touch none of them. Called after each statement in a procedural block (top-level blocks execute their statements via the visitor, notexecuteSql). -
recordStatementWithoutResult
public void recordStatementWithoutResult()The DML-status effect of a completed statement whose result never surfaced as a result set. -
pushHandledException
Markeas the exception now being handled (so a bare RAISE; inside the handler can re-raise it). -
popHandledException
public void popHandledException()Done handling the current exception. -
getBlockDepth
public int getBlockDepth()How many BEGIN…END blocks are currently open; 1 inside the outermost. -
getCurrentHandledException
The exception currently being handled, or null if not inside an exception handler. -
hasException
-
evaluateExpression
-
substituteBindVariables
Replace :varname bind-variable references in a SQL string with their current procedural-scope values, quoted as string literals. -
enterScope
public void enterScope() -
exitScope
public void exitScope() -
enterIsolatedScope
public void enterIsolatedScope()- See Also:
-
markDeclaredInCurrentScope
Called when a variable is DECLARED (not just assigned) in the current scope. -
getDeclaredVariableType
The declared type recorded for a variable, or null when its declaration carried none. -
declareVariableType
-
setVariable
-
getVariable
-
hasVariable
True when a procedural variable with this name exists in the current scope (even null-valued). -
getAllVariables
-
lookupResultSet
ForFROM TABLE(<name>)in procedural SQL: ifnameis an in-scope RESULTSET variable (raw ResultSet from:= (EXECUTE IMMEDIATE …)or aResultSetVariablefrom DEFAULT-init), return its rows (executing the DEFAULT query on first use); otherwise null. Lets the query-layer TABLE() resolver surface a procedural RESULTSET as a table source. -
getReturnValue
-
hasReturned
public boolean hasReturned() -
hasBreak
public boolean hasBreak() -
hasContinue
public boolean hasContinue() -
clearReturnState
public void clearReturnState() -
recordStatementFailure
public void recordStatementFailure(int line, int position) Remember where a failing statement stood — the FIRST record of a propagation wins, so the innermost statement names itself and the enclosing constructs it unwinds through do not. -
recordExpressionFailure
public void recordExpressionFailure(int line, int position) Remember where a failing EXPRESSION stood. Live splits the uncaught kinds by WHAT was running when the fault was raised: a fault from an expression is 'EXPRESSION_ERROR' anchored on the expression's own offset — a LET initialiser, an assignment's right side, a RETURN value, an IF condition — while a failing SQL statement stays 'STATEMENT_ERROR' at the statement's. The same first-record-wins rule applies, so the expression (which fails first, innermost) beats the statement record taken as the failure unwinds. -
clearStatementFailure
public void clearStatementFailure()Forget the last failure — a statement that COMPLETED means nothing is propagating any more. -
getFailureKind
The uncaught kind live names for the recorded failure — seerecordExpressionFailure(int, int). -
getFailureLine
public int getFailureLine()1-based line of the statement that is failing, or -1 when none is. -
getFailurePosition
public int getFailurePosition()0-based column of the statement that is failing. -
enterBlock
public void enterBlock() -
exitBlock
public void exitBlock()Mark that a BEGIN…END block handler has finished (nesting depth--). -
isNestedBlock
public boolean isNestedBlock()Whether the currently-executing BEGIN…END block is nested inside another one. A nested block's RETURN must be left in the return state (not consumed) so the enclosing block sees it and propagates it up. -
isExecutingBlock
public boolean isExecutingBlock()Whether a BEGIN…END block is currently executing. Transient procedural state (cursors, user-defined exceptions, declared variable types) belongs to that running block, so it must NOT be cleared while one is live — seeclearCursorsAndExceptions(). -
clearCursorsAndExceptions
public void clearCursorsAndExceptions()Clear cursors, exceptions, and declared variable types from a prior invocation so re-execution doesn't fail (or coerce against a stale declaration). -
coerceToType
Apply a DECLARED type to a value, exactly as the::cast would — live converts at every assignment (a TZ initialiser assigned to a baretimestampbecomes the session mapping's NTZ, assigned to adateit truncates, a scalar assigned to an OBJECT is TO_OBJECT's own refusal and to an ARRAY it wraps), and the declared WIDTH is enforced: a too-long string is refused with the truncation sentence, never silently kept. -
declaredExceptionNames
The exception names declared so far. A nested block is validated as its own block when it runs, so the names an enclosing block declared have to be handed to it — and an exception is not a variable, so it would otherwise vanish from that seed. -
saveCursorNames
-
restoreCursors
-
getCursor
-
registerCursor
-
isReturnTable
public boolean isReturnTable() -
resetReturnTable
public void resetReturnTable()
-