For general information about stored routines in MySQL, see Section 27.2, “Using Stored Routines”.
The MLE component provides a number of loadable functions for working with MLE user sessions. These functions are listed and described here:
Calling this function cleans up the current MLE session state, removing any observable output from
mle_session_state()
. It also resets the session time zone, so that subsequent calls to JavaScript stored routines use the time zone set most recently in the session.Use this loadable function to obtain session information about the MLE stored program that was most recently executed.
mle_session_state()
takes one argument, a session state key (a string), and displays a session state value. A session state value is limited to a maximum size of 64K (equivalent to 16000 4-byte characters). This is a cyclic buffer; when the available space has been used up, a new entry overwrites the oldest one. Possible session state keys are listed here, with their descriptions:is_active
: Returns1
if the current MySQL user session is an MLE session, otherwise0
.stdout
: Output anything written by the stored program usingconsole.log()
.stderr
: Output anything written by the stored program usingconsole.error()
.stack_trace
: If execution of the MLE stored program is unsuccessful, this contains a stack trace which may help in pinpointing the source of the error.Syntax and similar errors encountered by an unsuccessful
CREATE FUNCTION
orCREATE PROCEDURE
statement are not written here, only runtime errors raised during execution of a stored function or stored procedure.stored_functions
: Returns the number of currently cached stored functions in the current session.stored_procedures
: Returns the number of currently cached stored procedures in the current session.stored_programs
: Returns the number of currently cached stored programs (stored functions and stored procedures) in the current session.
The session state key is a literal string value and must be quoted.
Prior to the invocation of any MLE stored programs, all three of these session state values are empty. Exiting the client and restarting the session clears all of them.
The next two examples illustrate retrieval of the session state values. We begin by creating a stored procedure
mle_states()
that displays all session state values, like this:mysql> delimiter // mysql> CREATE PROCEDURE mle_states() -> BEGIN -> SELECT -> mle_session_state("is_active") AS '-ACTIVE-', -> mle_session_state("stdout") AS '-STDOUT-', -> mle_session_state("stderr") AS '-STDERR-', -> mle_session_state("stack_trace") AS '-STACK-', -> mle_session_state("stored_functions") AS '-FUNCS-', -> mle_session_state("stored_procedures") AS '-PROCS-', -> mle_session_state("stored_programs") AS '-PROGS-'; -> END// Query OK, 0 rows affected (0.02 sec) mysql> delimiter ;
Prior to running any MLE stored programs, all of the values in the output from
mle_states()
are0
or empty, as shown here:mysql> CALL mle_states(); +----------+----------+----------+---------+---------+---------+---------+ | -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- | +----------+----------+----------+---------+---------+---------+---------+ | 0 | | | | 0 | 0 | 0 | +----------+----------+----------+---------+---------+---------+---------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
Now we create a JavaScript stored procedure
pc1()
that usesconsole.log()
andconsole.error()
in a short loop to write multiple times tostdout
and tostderr
, like this:mysql> CREATE PROCEDURE pc1() -> LANGUAGE JAVASCRIPT AS -> $$ $> let x = 0 $> $> do { $> console.log(`This is message #${++x} to stdout.`) $> console.error(`This is message #${x} to stderr.`) $> } $> while(x < 3) $> $$ -> ; Query OK, 0 rows affected (0.02 sec)
Following the execution of the
CREATE PROCEDURE
statement just shown,mle_states()
shows an active MLE session. No stored programs have yet been run, so none have been cached; this means the columns reflecting JavaSCript stored functions, procedures, and programs all show0
. The output is shown here:mysql> CALL mle_states; +----------+----------+----------+---------+---------+---------+---------+ | -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- | +----------+----------+----------+---------+---------+---------+---------+ | 1 | | | | 0 | 0 | 0 | +----------+----------+----------+---------+---------+---------+---------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
NoteQuoting strings with backtick (
`
) characters allows us to use variable interpolation in the output. If you are unfamiliar with this quoting mechanism, see Template Literals at Mozilla Developer for more information.Invoking
pc1()
followed bymle_states()
produces the result shown here:mysql> CALL pc1(); Query OK, 0 rows affected (0.00 sec) mysql> CALL mle_states()\G *************************** 1. row *************************** -ACTIVE-: 1 -STDOUT-: This is message #1 to stdout. This is message #2 to stdout. This is message #3 to stdout. -STDERR-: This is message #1 to stderr. This is message #2 to stderr. This is message #3 to stderr. -STACK-: -FUNCS-: 0 -PROCS-: 1 -PROGS-: 1 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
Executing the stored procedure starts an MLE session, so
is_active
(-ACTIVE-
) is now1
.Successive writes to
stdout
orstderr
within the same session are appended to any existing content. To see this, callpc1()
again, then check the output frommle_states()
, as shown here:mysql> CALL pc1(); Query OK, 0 rows affected (0.00 sec) mysql> CALL mle_states()\G *************************** 1. row *************************** -ACTIVE-: 1 -STDOUT-: This is message #1 to stdout. This is message #2 to stdout. This is message #3 to stdout. This is message #1 to stdout. This is message #2 to stdout. This is message #3 to stdout. -STDERR-: This is message #1 to stderr. This is message #2 to stderr. This is message #3 to stderr. This is message #1 to stderr. This is message #2 to stderr. This is message #3 to stderr. -STACK-: -FUNCS-: 0 -PROCS-: 1 -PROGS-: 1 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
Since no errors were produced by
pc1()
, the stack trace remains empty. To test the stack trace, we can create a modified copy ofpc1()
in which we change the reference toconsole.log()
to the undefined functionconsole.lob()
, like this:mysql> CREATE PROCEDURE pc2() -> LANGUAGE JAVASCRIPT AS -> $$ $> let x = 0 $> do { $> console.lob(`This is message #${++x} to stdout.`) $> console.error(`This is message #${x} to stderr.`) $> } $> while(x < 3) $> $$ -> ; Query OK, 0 rows affected (0.02 sec)
CREATE PROCEDURE pc2() LANGUAGE JAVASCRIPT AS $$ let x = 0 do { console.lob(`This is message #${++x} to stdout.`) console.error(`This is message #${x} to stderr.`) } while(x < 3) $$ ;
mysql> CREATE PROCEDURE pc2() -> LANGUAGE JAVASCRIPT AS -> $$ $> let x = 0 $> do { $> console.lob(`This is message #${++x} to stdout.`) $> console.error(`This is message #${x} to stderr.`) $> } $> while(x < 3) $> $$ -> ; Query OK, 0 rows affected (0.02 sec)
The
CREATE PROCEDURE
statement runs successfully, but when we attempt to invokepc2()
, an error results, as shown here:mysql> CALL pc2(); ERROR 6113 (HY000): JavaScript> TypeError: (intermediate value).lob is not a function
Following this, when we invoke
mle_states()
again, we see that, since we are within the same session, thestdout
andstderr
fields still contain the content written to them previously. The stack trace from the error just shown is displayed in the last column of the output:mysql> CALL mle_states()\G *************************** 1. row *************************** -ACTIVE-: 1 -STDOUT-: This is message #1 to stdout. This is message #2 to stdout. This is message #3 to stdout. This is message #1 to stdout. This is message #2 to stdout. This is message #3 to stdout. -STDERR-: This is message #1 to stderr. This is message #2 to stderr. This is message #3 to stderr. This is message #1 to stderr. This is message #2 to stderr. This is message #3 to stderr. -STACK-: <js> pc2:3:6-54 -FUNCS-: 0 -PROCS-: 2 -PROGS-: 2 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
In addition the values of the
stored_functions
,stored_procedures
, andstored_programs
keys formle_session_state()
are are0
,2
, and2
, respectively—we have created 2 stored JavaScript procedures, and no JavaScript stored functions, for a total of 2 JavaScript stored programs.The stack trace does not persist between JavaScript stored program invocations.
To clear all information from all fields in the output of
mle_states()
, callmle_session_reset()
, like this:mysql> SELECT mle_session_reset(); mysql> SELECT mle_session_reset(); +------------------------------------------+ | mle_session_reset() | +------------------------------------------+ | The session state is successfully reset. | +------------------------------------------+ 1 row in set (0.00 sec)
Invoking
mle_states()
again produces the same as the initial result, before any stored JavaScript stored programs had been used.mysql> CALL mle_states; +----------+----------+----------+---------+---------+---------+---------+ | -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- | +----------+----------+----------+---------+---------+---------+---------+ | 0 | | | | 0 | 0 | 0 | +----------+----------+----------+---------+---------+---------+---------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
Alternatively, you can clear
stdout
andstderr
from within a JavaScript routine usingconsole.clear()
.The MLE component provides this function as a means for determining the rules in effect during the current session for converting MySQL integer types (
TINYINT
,SMALLINT
,MEDIUMINT
,INT
,BIGINT
) to JavaScript values. These rules apply to input arguments to JavaScript programs as well as to values in result sets. The possible conversion rules are listed here by name:BIGINT
: Always convert to JavaScriptBigInt
.STRING
: Always convert to JavaScriptString
.UNSAFE_BIGINT
: If the value is safe, convert to JavaScriptNumber
; otherwise convert to JavaScriptBigInt
.UNSAFE_STRING
: If the value is safe, convert to JavaScriptNumber
; otherwise convert to JavaScriptString
. This is the default behavior if no rule is specified.
In the context of these conversion rules, “safe” means that the value to be converted is in the range of
-(253-1)
(-9007199254740991
) to(253-1)
(9007199254740991
), inclusive.This function can be invoked only if there are no cached stored programs in the current user session. When successful, the function returns
1
. Otherwise, attempting to invoke it raises an error, as shown here:mysql> SELECT gcd(536, 1676); // Call JS stored function +----------------+ | gcd(536, 1676) | +----------------+ | 4 | +----------------+ 1 row in set (0.00 sec) mysql> SELECT mle_set_session_state('{"integer_type":"BIGINT"}'); ERROR 1123 (HY000): Can't initialize function 'mle_set_session_state'; Cannot set options of an active session. Please reset the session first.
As the error message suggests, you must reset the session to clear the active session. To do this, use
mle_session_reset()
, like this:mysql> SELECT mle_session_reset(); +------------------------------------------+ | mle_session_reset() | +------------------------------------------+ | The session state is successfully reset. | +------------------------------------------+ 1 row in set (0.00 sec)
Now you can call
mle_set_session_state()
as shown here:mysql> SELECT mle_set_session_state('{"integer_type":"BIGINT"}'); +----------------------------------------------------+ | mle_set_session_state('{"integer_type":"BIGINT"}') | +----------------------------------------------------+ | 1 | +----------------------------------------------------+ 1 row in set (0.00 sec)
You can set the conversion type for a specific query prior to executing it using JavaScript API
Session
methods such assql()
,runSql()
, andprepare()
. See the description ofSession.sql()
for more information and examples.
You can obtain information about resource usage by the MLE
component by querying the Performance Schema
memory_summary_by_thread_by_event_name
and
memory_summary_global_by_event_name
tables using the key
memory/language_component/session
, which tracks
memory usage by each MLE user session. This key is provided by the
MLE component; it is included in the
setup_instruments
table when the MLE
component is installed, as shown here:
mysql> SELECT * FROM performance_schema.setup_instruments
> WHERE NAME LIKE '%language_component%'\G
*************************** 1. row ***************************
NAME: memory/language_component/session
ENABLED: YES
TIMED: NULL
PROPERTIES: controlled_by_default
FLAGS: controlled
VOLATILITY: 0
DOCUMENTATION: Session-specific allocations for the Language component
1 row in set (0.00 sec)
Prior to creating executing or executing any JavaScript stored programs, queries, MLE remains inactive, so that using this key returns results which are empty, or consist chiefly of zeroes, like those shown here:
mysql> SELECT * FROM performance_schema.memory_summary_by_thread_by_event_name
-> WHERE
-> EVENT_NAME = 'memory/language_component/session'
-> AND
-> COUNT_ALLOC < 0\G
Empty set (0.02 sec)
mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name
-> WHERE EVENT_NAME LIKE 'memory/language_component/%'\G
*************************** 1. row ***************************
EVENT_NAME: memory/language_component/session
COUNT_ALLOC: 0
COUNT_FREE: 0
SUM_NUMBER_OF_BYTES_ALLOC: 0
SUM_NUMBER_OF_BYTES_FREE: 0
LOW_COUNT_USED: 0
CURRENT_COUNT_USED: 0
HIGH_COUNT_USED: 0
LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 0
HIGH_NUMBER_OF_BYTES_USED: 0
1 row in set (0.01 sec)
After invoking a JavaScript stored function, the same queries now reflect the memory consumed by MLE, as shown here:
mysql> SELECT * FROM performance_schema.memory_summary_by_thread_by_event_name
-> WHERE
-> EVENT_NAME = 'memory/language_component/session'
-> AND
-> COUNT_ALLOC < 0\G
*************************** 1. row ***************************
THREAD_ID: 46
EVENT_NAME: memory/language_component/session
COUNT_ALLOC: 25
COUNT_FREE: 20
SUM_NUMBER_OF_BYTES_ALLOC: 4445
SUM_NUMBER_OF_BYTES_FREE: 2989
LOW_COUNT_USED: 0
CURRENT_COUNT_USED: 5
HIGH_COUNT_USED: 14
LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 1456
HIGH_NUMBER_OF_BYTES_USED: 3239
1 row in set (0.00 sec)
mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name
-> WHERE EVENT_NAME LIKE 'memory/language_component/%'\G
*************************** 1. row ***************************
EVENT_NAME: memory/language_component/session
COUNT_ALLOC: 25
COUNT_FREE: 20
SUM_NUMBER_OF_BYTES_ALLOC: 4445
SUM_NUMBER_OF_BYTES_FREE: 2989
LOW_COUNT_USED: 0
CURRENT_COUNT_USED: 5
HIGH_COUNT_USED: 14
LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 1456
HIGH_NUMBER_OF_BYTES_USED: 3239
1 row in set (0.00 sec)
For more information about these and related Performance Schema tables, see Section 29.12.20.10, “Memory Summary Tables”.
Memory usage by the MLE component in a given user session is
subject to the limit imposed by the
connection_memory_limit
server
system variable. See the description of this variable for more
information.