Dynamic resolution of database visitor language dependencies
By introducing a multi-language engine and a guest virtual environment into the database management system, the database system supports package management and permission control problems in multiple programming languages is solved, and the unified module import and permission management are achieved, and the system maintainability and scalability is improved.
Patent Information
- Application Number
- CN202080060989.9
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Priority Date
- 2019-08-30
- Filing Date
- 2020-08-12
- Publication Date
- 2025-08-19
- Estimated Expiration
- 2040-08-12
AI Technical Summary
The database system is difficult to support package management and import of multiple programming languages, resulting in library interference or failure. The permission model is different from the file system permission model, resulting in complex source code storage and access control.
Multilingual engine (MLE) using the guest programming language realizes transparent, modular and configurable interaction in the database management system (DBMS). It deploys guest modules into the database through the Data Definition Language (DDL) statement, uses the guest virtual environment and virtual file system to manage dependencies, and provides a unified API for module import and access control.
It realizes the unity of module import and permission management between different programming languages, improves the reusability and ease of patching of source logic, reduces the risk of library interference and failure, and supports database operations in multi-language environments.
Smart Images

Figure CN114286994B_ABST
Abstract
Description
Technical Field
[0001] The present invention relates to multi-language programming of software systems such as database management systems (DBMS).Herein are techniques for extending software systems to embed new guest programming languages that interoperate in a transparent, modular and configurable manner. Background Art
[0002] Modern programming languages like JavaScript and Python benefit from a rich and extensive ecosystem of publicly available libraries and add-ons. However, database systems offer little or no support for multiple programming languages. For example, JavaScript and Python have different approaches to package management and importing that can be difficult or impossible to reconcile.
[0003] In the JavaScript ecosystem, the use of codebase bundling tools is common. These tools resolve package dependencies imposed by require statements by inlining the source code of the dependency. The result of these bundling techniques is a monolithic source file that contains all the required source logic. These bundling tools are not available in other language ecosystems.
[0004] Package management often relies on version control. Package managers like NPM or Pip handle package versioning. NPM handles versioning by organizing different package versions in separate directories and appending version numbers to the package names. Python uses a different approach. Tools like Pip can be used to structure and manage deployments so that only a single package version is installed. However, these approaches are not easily transferable to relational databases. Database systems typically do not support different object versions.
[0005] Different projects may run with different object versions and different language settings or options, which may cause library interference or failure. Database systems have different features that are not usually encountered in the programming language ecosystem, such as:
[0006] Schema: Database objects are always created in a specific schema. If an object is created without specifying a schema, it is created in the schema of the current user account. Database objects are fully qualified when both the object name and the schema are specified. If the object is not fully qualified in a SQL query, the query optimizer will need to parse it. Consequently, the same query lacking fully qualified object references may result in different results if executed by different user accounts, such as when different versions of an object share the same name but reside in different schemas. This can present technical challenges, such as where source code should be deployed and, once deployed, how to share it.
[0007] Permissions: The database system implements a rich permissions model. Compared to the typical file system permissions model, the permissions model is much more granular. Read, create, execute, delete, and modify permissions exist at the system-wide, system-schema, user-schema, and individual database object levels. Beyond the question of where to store source code, there are also questions about whether and how to protect access to it, and what permissions it can exercise. BRIEF DESCRIPTION OF THE DRAWINGS
[0008] In the attached figure:
[0009] Figure 1 is a block diagram depicting an example computer system for processing data definition language (DDL) statements that upload an implementation of a new guest programming language into a database management system (DBMS);
[0010] Figure 2 is a flow chart describing an example computer process for executing DDL statements for uploading an implementation of a new guest programming language into a DBMS;
[0011] Figure 3 is a flow chart describing an example computer process for adding and using a new guest programming language in a DBMS;
[0012] Figure 4 is a block diagram depicting an example DBMS for processing a single DDL statement that, for a guest programming language, results in generation of a guest module containing a plurality of guest subroutines;
[0013] Figure 5 is a flow chart describing an example single DDL statement that causes a DBMS to generate a guest module containing a plurality of guest subroutines for a guest programming language;
[0014] Figure 6 is a flowchart describing some example life cycle activities of a guest module and a guest subroutine;
[0015] Figure 7 is a block diagram depicting an example DBMS for processing a request to import dependencies via a guest programming language, which causes the DBMS to provide a guest module based on a mapping;
[0016] Figure 8 is a flow chart describing processing of a request to import dependencies through a guest programming language, which causes the DBMS to provide a guest module based on a mapping;
[0017] Figure 9 is a flow diagram depicting some example activities at the boundaries of database components such as database sessions, data manipulation language (DML) statements, and visitor modules;
[0018] Figure 10 is a flowchart describing some example activities for satisfying dependencies;
[0019] Figure 11 is a block diagram depicting an example DBMS with a multi-language engine (MLE) that facilitates collaboration between different guest programming languages;
[0020] Figure 12 is a flow chart describing some example activities for accessing a guest object in a guest programming language from different guest programming languages;
[0021] Figure 13 is a block diagram depicting an example DBMS with a guest virtual environment that provides alternative bindings for identically named dependencies to different guest modules;
[0022] Figure 14 is a flow chart describing some example activities for generating, modifying, and using a guest virtual environment that symbolically binds guest dependencies to guest modules;
[0023] Figure 15 is a flow chart describing some example activities for sharing a guest virtual environment among multiple database users and multiple guest programming languages, such as in a multi-tenant environment, such as with multiple database applications that may be collaborating or isolated (i.e., not collaborating), such as in an enterprise's private cloud;
[0024] Figure 16 is a block diagram depicting an example DBMS that transparently retrieves resources from a virtual file system to generalize an alternative storage mechanism;
[0025] Figure 17 is a flow chart describing some example activities of a DBMS retrieving resources from a virtualized storage device such as a virtual file system;
[0026] Figure 18 is a block diagram illustrating a computer system upon which embodiments of the present invention may be implemented;
[0027] Figure 19 is a block diagram illustrating a basic software system that can be used to control the operation of a computing system. DETAILED DESCRIPTION
[0028] In the following description, for ease of explanation, numerous specific details are set forth to provide a thorough understanding of the present invention. However, it is apparent that the present invention can be practiced without these specific details. In other cases, well-known structures and devices are shown in block diagram form to avoid unnecessarily obscuring the present invention.
[0029] General Overview
[0030] The methods herein facilitate accessing (e.g., custom) guest objects, such as stored procedures and user-defined functions, written in modern programming languages such as JavaScript and Python, for example, from a data manipulation language (DML). In an embodiment, all programming language source code is executed by the same high-performance engine called GraalVM. For example, the guest programming language can have an implementation based on the Truffle framework. GraalVM executes these guest programming languages in the address space of the database management system (DBMS) to maximize efficiency and performance, but runs the source code sandboxed so that unauthorized memory access or system calls are impossible.
[0031] Deploying guest source code into the database is done through user-defined packages called guest modules. Each guest module is associated with a single guest programming language, and the contents and structure of a guest module are specific to that guest programming language. Guest objects, such as the logic in a guest module, can be accessed in various ways, such as:
[0032] A subroutine defined by a guest module can be called from a DML such as PL / SQL via a call specification.
[0033] Guest modules can be imported by other guest modules of the same guest programming language using the language-specific import mechanism.
[0034] • Guest modules can be imported by other guest modules of the same or different guest programming language using an application programming interface (API) implemented by the DBMS's Multi-Language Engine (MLE), which facilitates subroutines in the importing module to be called directly from the importing module.
[0035] Herein is an example MLE architecture for executing guest subroutines based on guest modules. MLE can execute stored procedures or user-defined functions (UDFs) in programming languages other than PL / SQL, such as dynamic languages like JavaScript, Ruby, Python, and / or R. MLE is not limited to the execution of dynamic languages, as it can also run more or less static languages such as Java.
[0036] An MLE can consist of several layers. The top layer can implement a guest programming language. Each guest programming language implementation running on the MLE can be based on Oracle Truffle. Truffle is a language implementation framework for building high-performance abstract syntax tree (AST) interpreters that run on virtual machines (VMs) such as the Java VM (JVM). Each node in the Truffle AST has an execute method that executes its child nodes and returns its own results, such as for partial evaluation. The main advantage of the Truffle AST interpreter is that it is self-optimizing by using profile analysis information and partial evaluation.
[0037] These profiles are collected during the execution of the guest language program. Important optimizations can include type specialization, rewriting indirect function calls, polymorphic inline caching, branch elimination, and speculative function inlining, as discussed in this paper. If the speculative assumptions prove to be wrong, the specialized AST can be restored to a more general version that provides functionality for more general cases.
[0038] When the execution count of a Truffle node reaches a predefined threshold, Truffle triggers a partial evaluation via a call to Graal. Graal is a dynamic compiler that forms another layer of the MLE. Graal can be a just-in-time compiler (JIT) for the MLE, capable of performing partial evaluations of parts of the AST, which may require the Futamura projections discussed in this paper. The output of Graal can be highly optimized machine code with deoptimization points. These points can be implemented as checkpoints that must trigger deoptimization when the speculation assumptions no longer hold. Deoptimization means that control is transferred from the compiled code back to the AST interpreter, where specialized AST nodes are then restored to more general versions.
[0039] Another layer of MLE is the VM. For example, MLE can use Oracle's Substrate VM (SVM), an embeddable VM that provides services such as code caching or garbage collection. MLE can use the same VM for all language implementations included with the MLE.
[0040] One goal could be to provide future extensibility without requiring code changes. MLE could, for example, provide a pluggable, aftermarket language approach for general-purpose languages, traditional languages, and / or domain-specific languages (DSLs). For example, a customer who has implemented their own guest programming language on top of the Truffle framework could plug that language into MLE using the MLE's API, without requiring code changes to either the MLE or the DBMS. MLE provides a unified way to deploy and manage codebase units such as packages and modules.
[0041] A guest module is a unit of (e.g., source) logic deployed into a database. Each guest module is implemented in a single, corresponding guest programming language. The content and structure of a guest module can be specific to that guest programming language. This article describes a new data definition language (DDL) statement for deploying source logic into a database as a guest module.
[0042] This article describes an MLE extension that allows all guest programming languages to share the same infrastructure for activities such as storage and lookup, such as guest modules and guest virtual environments. Additionally, database permissions can be used to control access to such components. The MLE can also include a virtual file system, through which source logic, such as guest scripts, can be distributed across several files in a nested directory structure, which can be bundled together and stored in a container format such as a zip file. Such source packages can be provided as binary large objects (BLOBs) or files and supplied to the MLE, for example, via DDL statements.
[0043] The MLE provides an architecture for intra-language and inter-language module import. The guest virtual environment can provide a mapping between module names and schema objects that hold the module contents. This mechanism can hide differences in module / package import conventions across guest programming languages. The ability to import other guest modules provides several benefits:
[0044] Ability to separate source logic into several independent modules.
[0045] Reusability of source logic. By breaking the code into modules, some modules can be reused. Libraries can be provided as separate guest modules and imported by other guest modules belonging to different projects. Thus, each guest module can have a more or less independent maintenance schedule, such as according to the software development life cycle (SDLC).
[0046] Ease of patching. Without inter-module imports, a monolithic (i.e., large) guest module would need to be redeployed even if only a small portion of the underlying source code needs to be changed. By partitioning the code into smaller guest modules, only a subset of the modules needs to be redeployed. MLE can also provide built-in modules such as Structured Query Language (SQL) drivers.
[0047] The import mechanism for guest programming languages can include logic for consulting the environment when loading modules. For example, in JavaScript, when a module is imported via a require statement, the MLE can intercept and handle the require statement specially, including resolving the dependency module name through the environment. Similar techniques are extended to other guest programming languages such as Python.
[0048] The language-agnostic mechanism for guest modules and guest virtual environments provides a unified API for managing source logic within the database. This leaves a lot of freedom for tooling deployments that can adapt to the specific needs of the programming language ecosystem. For example, version resolution can be left more or less to client-side tooling, and the resolved version can be mapped using the guest virtual environment within the database.
[0049] In an embodiment, a computer inserts an implementation of a guest programming language into a deployment of a DBMS, executes DDL statements to register the guest programming language in the DBMS, and invokes the guest programming language in the DBMS by executing DML statements.
[0050] In an embodiment, a single DDL statement is executed to define multiple subroutines for a guest programming language in a DBMS. A second DDL statement registers a specific subroutine in the DBMS as a user-defined function (UDF) or stored procedure, which can be called by a DML statement.
[0051] In an embodiment, a DML statement invokes a guest programming language, thereby causing: executing an import request native to the guest programming language to access dependencies, and resolving the dependencies based on the import request native to the guest programming language and a mapping defined in the DBMS. As described later herein, defining an object in a DBMS may require storing data and / or metadata of the object in a database schema and / or database dictionary in the DBMS or in a database of the DBMS, wherein the metadata defines properties, characteristics, or configuration of the object.
[0052] An embodiment defines a guest object implemented in a first guest programming language in a DBMS. The DBMS includes a native data manipulation language (DML), the first guest programming language, and a second guest programming language. Calling the second guest programming language from the native DML causes an access request from the second guest programming language to be executed to access the guest object implemented in the first guest programming language.
[0053] In one embodiment, a first DDL statement creates a guest virtual environment in the DBMS. A second DDL statement adds a dependency and a binding of a guest module to the guest virtual environment. The guest programming language issues a request to access the dependency. Based on the request and the binding, the guest module is accessed.
[0054] In an embodiment, the DML statement invokes a guest programming language, resulting in:
[0055] · Execute requests native to the guest programming language to access dependencies, and
[0056] • Retrieving the dependency from a virtual file system having a plurality of alternative implementation mechanisms, the plurality of alternative implementation mechanisms including: a first implementation mechanism based on an archive file or a real file system, and a second implementation mechanism based on a memory buffer or a column of a database table.
[0057] 1.0 Example Computer System
[0058] Figure 1 1 is a block diagram illustrating an example computer system 100 according to an embodiment. Data definition language (DDL) statements 181 upload the implementation of a new guest programming language to a database management system (DBMS) 110. Computer system 100 includes one or more computers, such as 190. Each computer can be a rack server such as a blade server, a personal computer, a mainframe, a virtual machine, or other computing device. When computer system 100 includes multiple computers, the computers are interconnected via a communication network.
[0059] Computer system 100 includes a DBMS 110, which can be hosted by computer 190, hosted by a different computer (not shown), or hosted by multiple computers for distributed and / or multi-instance databases. DBMS 110 supports a multi-language (i.e., multilingual) programmable database, such as a database having a multi-language engine (MLE) software layer that can embed corresponding interpreters and / or virtual machines for multiple guest programming languages, such as a Java virtual machine (JVM) and a JavaScript interpreter, either individually or in combination as in Oracle's Graal MLE. For example, the MLE can interpret text scripts, generate bytecode, interpret the bytecode, and / or compile the bytecode into native machine instructions, such as through just-in-time (JIT) compilation. For example, the MLE can include a JVM that executes bytecode generated from source logic in multiple guest programming languages.
[0060] DBMS 110 is extensible by adding guest programming languages such as 140 that are not native to DBMS 110. Guest programming language 140 can be added aftermarket for use in DBMS 110, such as a general-purpose programming (e.g., scripting) language or a domain-specific language (DSL). For example, guest programming language 140 need not be initially provided with DBMS 110, nor need it be obtained from the original equipment manufacturer (OEM) of DBMS 110 (e.g., an independent software vendor (ISV)).
[0061] The guest programming language 140 is added via data definition language (DDL) statements 181. For example, the DDL may be a proprietary language native to the DBMS 110 or a managed dialect of a database language, such as Structured Query Language (SQL). The DDL typically writes metadata to the DBMS 110, such as to a database schema and / or a database dictionary within the database of the DBMS 110, as described later herein. Native database languages, such as SQL, are initially built into the DBMS 110 and thus do not need to be separately added to the DBMS 110, as is required for the guest programming language 140. In an embodiment, the DDL statement 181 may be "CREATE MYLANGUAGE LANGUAGE MYLANGUAGE;," where MYLANGUAGE is a name that identifies the guest programming language 140.
[0062] DBMS 110 may receive DDL statements 181 from a client, such as an ad hoc database tool or other software application, such as textually via an Open Database Connectivity (ODBC) connection, which may require inter-process communication or networking, such as when computer 190 is a remote client. In another scenario, DDL statements 181 are generated internally by DBMS 110. Execution of DDL statements 181 more or less completely adds guest programming language 140 to DBMS 110.
[0063] For example, guest programming language 140 can be based on implementation files such as 150, such as class files and / or resource files, which can be loose files and / or bundled into an archive file such as a Java Archive (JAR) file. In embodiments, implementation files 150 can include: a) a grammar 162 that formally defines the syntax of guest programming language 140, such as for tokenization and / or parsing, and / or b) a parser 161, also for parsing, such as based on grammar 162, such as for constructing a parse tree (not shown). In embodiments, different guest programming languages can each have their own corresponding grammar, such as 162, but share the same parser 161. Other (e.g., shareable) language components can include a semantic analyzer, an optimizer, a (e.g., intermediate or machine) code generator, and / or a linker or loader that locates cross-referenced resources. For example, Graal provides many such components that can be shared and / or customized, such as collaborative compiler / interpreter layers, such as Truffle as a front-end and Substrate as a back-end.
[0064] In one embodiment, the implementation file of the guest programming language 140 is staged (i.e., placed) into the code base or other file system of the DBMS 110, such as by a database administrator (DBA), system administrator, or other user with access to the command shell and / or file system of the computer hosting the DBMS 110, such as manually, prior to submitting the DDL statement 181. In another embodiment, the execution of the DDL statement 181 automatically causes the implementation file to be staged into the DBMS 110, which may require copying the implementation file within the same file system, copying the implementation file between multiple file systems, (e.g., symbolic) links to the file, or uploading the implementation file from a remote client. For example, the remote client may use a Java ODBC (JDBC) driver including the Hypertext Transfer Protocol (HTTP) or the Java Remote Method Protocol (JRMP), such as by uploading the file from the remote client to a subsystem of the DBMS 110, such as the Common Gateway Interface (CGI), via an HTTP post. For example, the DDL statement 181 may include a uniform resource locator (URL) of a JAR file that contains an embeddable implementation (eg, an interpreter) of the guest programming language 140 .
[0065] Execution of the DDL statements 181 registers the guest programming language 140 (e.g., publicly) within the database dictionary 120 or other metadata repository that is part of the DBMS 110. The database dictionary 120 includes metadata that defines database objects and other configuration aspects of the DBMS 110. The database dictionary 120 may include multiple data structures that store database metadata. For example, the database dictionary 120 may include multiple files and tables. Portions of the data structures may be cached in the main memory of the database server of the DBMS 110.
[0066] The subset of metadata that defines a particular database object of DBMS 110 or a particular aspect of the configuration of DBMS 110 is referred to herein as a metadata definition or simply a definition. A definition may also include multiple data structures and tables. The definition of a particular database object may include the definitions of the constituent data objects. For example, the definition of a table may include multiple definitions of each column of the table.
[0067] The metadata in the database dictionary 120 that defines a procedure can specify the name of the procedure, the procedure's arguments, the return data type, and the data types of the arguments, and can include the source code and its compiled version. Database objects can be defined by the database dictionary 120, but the metadata in the database dictionary 120 itself can only partially specify the properties of the database object. Other properties can be defined by data structures that are not considered part of the database dictionary 120. For example, as described later in this document, a user-defined function (UDF) implemented in a Java class can be partially defined by the database dictionary 120 by specifying the name of the user's Java function and by specifying references to a file containing the source code for the Java class (i.e., a .java file) and a file containing the compiled version (i.e., byte code) of the class (i.e., a .class file).
[0068] A binding can be a definition that is directly associated with another object (such as a name) in the database dictionary 120. For example, the database dictionary 120 can contain key-value pairs, such as in a lookup table or hash table. For example, the database dictionary 120 can be an implementation of a database namespace and / or can contain database objects such as a relational schema. DDL statements can be used to write definitions and / or bindings to the database dictionary 120 or database schema.
[0069] Entries in the database dictionary 120 can be accessed using a search key, such as name 130. Objects (i.e., values) can be stored in the content memory of the database dictionary 120 directly or indirectly through a reference, such as a pointer addressing a memory location outside of the database dictionary 120 where the object is stored. Thus, components displayed within the database dictionary 120, such as the guest programming language 140, may actually reside elsewhere in the memory of the DBMS 110 and be referenced by corresponding entries (e.g., key-value pairs) of the database dictionary 120.
[0070] The name 130 can be the same language name that appears in the DDL statement 181 as described above, such as MYLANGUAGE. For example, the DDL statement 181 can immediately cause the guest programming language 140 to be generated in the memory of the DBMS 110, such as by executing initialization logic from a placed implementation file of the guest programming language 140. In an embodiment, the memory initialization for the guest programming language 140 can occur lazily, for example, upon later demand, such as when the name 130 is later used to access the guest programming language 140. Regardless of whether the initialization of the guest programming language 140 is lazy or eager, the name 130 is immediately bound to the guest programming language 140 in the database dictionary 120 by the DDL statement 181.
[0071] The DBMS 110 may then receive or generate data manipulation language (DML) statements 182, such as database queries, that cause logic to be executed within the guest programming language 140. For example, DML may be a data access dialect of a proprietary language or database language native to the DBMS 110, such as SQL. DML is designed to create, read (e.g., query), update, and delete (CRUD) ordinary data in the database of the DBMS 110. However, DDL is designed for writing (i.e., creating, updating, and deleting), but for metadata (i.e., defining) rather than database data. Query by Example (QBE) (e.g., JavaScript Object Notation, JSON) and path expressions (e.g., XPath) may be examples of all or part of DML.
[0072] DML statements 182 may contain textual references (e.g., names) to database objects defined in DBMS 110. DBMS 110 may use database dictionary 120 or the database schema to resolve these names into actual database objects, such as user-defined functions (UDFs). Some database objects may be created (i.e., defined) solely through the execution of SQL statements. Other database objects may instead be created using guest programming language 140. Thus, some database objects are also guest objects.
[0073] As described later herein, and in some cases, a guest object can be bound to a database object that is not a guest object through binding, such as facilitated by binding in a database dictionary. For example, a DML statement 182 can explicitly call a stored procedure or UDF that is a database object that, while not a guest object, is actually implemented as (i.e., bound to) a guest object, such as a subroutine 170 in the guest programming language 140.
[0074] For example, subroutine 170 can be a single Python function, or an entire imperative Python script, which is shown as a stored procedure or UDF explicitly called by DML statement 182. In an embodiment not shown, database dictionary 120 contains the declaration or definition of the stored procedure or UDF for inspection, such as by the query planner of DBMS 110. Mechanisms and techniques for manipulating the language boundary between native DML statement 182 and guest subroutine 170 are discussed below.
[0075] As described above, the guest programming language 140 can be implemented in the DBMS 110 using components and / or layers (e.g., Truffle and Substrate) dedicated to specific (e.g., compilation) activities (e.g., optimization). Thus, the execution of the guest subroutine 170 can be accelerated according to various statistical and / or incremental techniques, such as: a) Futamura projection, b) just-in-time (JIT) compilation of only a portion of the subroutine 170, and / or c) generation of speculative code with one or more deoptimization points. Speculative logic can be optimized statically or dynamically (e.g., profiling) according to the data types of inferred (e.g., observed) polymorphic variables.
[0076] Deoptimization points partition segments of the generated code that have become invalid due to unexpected data types and should be immediately replaced with less optimized (e.g., earlier) code. A partial JIT can transform hot (i.e., repeated more than a threshold number of times) segments of subroutine 170, such as compact loops, for example, by loop unrolling. As described later in this document, Futamura projections are architectural transformations that can include partial evaluation (i.e., logical specialization), memoization (i.e., a function result cache that typically has a composite key containing the name or pointer of the function and its actual argument values), and / or strength reduction (i.e., semantic refactoring; for example, a) hot spots with loop invariants and / or induction variables, or b) arithmetic operation replacement).
[0077] Substrate can apply Futamura projections such as ahead-of-time (AOT) code generation. For example, a DDL statement 181 may greedily (e.g., immediately) cause AOT code generation in the background (e.g., at a low priority) for some or all subroutines 170, even though the subroutine 170 may not be called for the first time (e.g., by a DML statement 182) until much later. Thus, engineers who anticipated complex and esoteric interpretation of a script can instead obtain machine language for direct execution that is highly optimized for a specific version of a specific central processing unit (CPU) model, such as in a production environment that is unknown or unavailable during application development.
[0078] 2.0 Sample Language Deployment Process
[0079] Figure 2 FIG. 1 is a flowchart illustrating how the computer system 100 adds a new guest programming language 140 to the DMBS 110 in an embodiment. Figure 1 discuss Figure 2 .
[0080] Depending on the embodiment, steps 202 and 204 may or may not be combined into one step. In embodiments, step 202 may be implemented entirely, partially, or not at all by DBMS 110 itself. For example, the automation required to perform step 202 may be implemented elsewhere in computer system 100 and may or may not require manual effort by a system administrator, such as a database administrator (DBA).
[0081] Step 202 inserts the implementation of the guest programming language 140 into the deployment of the DBMS 110. For example, the DBMS 110 may have a library path, such as an ordered list of file system folder paths, that identifies where the DBMS 110 can find (e.g., after-sales) extensions to its own code base, such as the code base of the implementation of the guest programming language 140, which may consist of loose files or packaged files. Automation or an administrator may place the code base files for the guest programming language 140 into the library path of the DBMS 110 (i.e., copy them into a location). Depending on the implementation of the DBMS 110, the DBMS 110 may or may not need to be restarted to prepare the DBMS 110 to load (e.g., dynamically link) the placed code base of the guest programming language 140.
[0082] At step 204, a DDL statement 181 is executed to register the guest programming language 140 in the DBMS 110. For example, a database client script or an ad hoc client may send the DDL statement 181 (e.g., via ODBC) from the computer 190 to the DBMS 110, which may be on the same or a different computer. Depending on the embodiment, the DDL statement 181 may identify any of the following: a) the name 130 of the guest programming language 140, such as for use as a named key to be inserted into the database dictionary 120, and / or b) the codebase path and / or class name of an implementation of the guest programming language 140.
[0083] Execution of the DDL statement 181 causes the multi-language engine (MLE) of the DBMS 110 to instantiate in-memory data structures that implement the guest programming language 140, which may require class loading or script execution from a placed code base of the guest programming language 140. In an embodiment, the DDL statement 181 may also perform step 202 (i.e., in conjunction with step 204).
[0084] For example, DDL statements 181 may include a uniform resource locator (URL) or cross-installation path that locates an implementation of the guest programming language 140 that does not yet need to be placed in DBMS 110. Placement may occur automatically based on a push or pull mechanism, which is suitable for deployment to a public cloud that may deny clients direct access to the file system of DBMS 110, such as through a remote shell.
[0085] In a pull embodiment, DBMS 110 may process the URL to automatically upload and place the guest programming language 140 code base into the deployment of DBMS 110. This embodiment may require a web server or file server running on the host pointed to by the URL, which may or may not be computer 190.
[0086] In a push embodiment, a client (e.g., ODBC) driver has additional logic to upload the code repository file into DBMS 110. Depending on the embodiment, this upload can be multiplexed through the driver's database connection, and DBMS 110 can save the upload to its own code repository, or the driver can use a separate network connection, such as for a Common Gateway Interface (CGI) POST to a web server, which can save the upload to the code database of DBMS 110. For example, DBMS 110 can include a web server (not shown).
[0087] After step 204, the guest programming language 140 is ready to be used in the DBMS 110. Step 206 executes the DML statement 182 that calls the guest programming language 140 in the DBMS 110. For example, as described later herein, the DBA can export subroutines of the guest programming language 140 as UDFs that can be called by the DML statements 182. Thus, the guest programming language 140 can be used indirectly for DML queries without exposing the client to the guest programming language 140. For example, a legacy query may call a complex UDF that was initially implemented as suboptimal DML and is ultimately transparently transformed (e.g., reimplemented and accelerated) by the guest programming language 140.
[0088] 3.0 Example Language Management
[0089] Figure 3 is a flowchart illustrating how the computer system 100 adds and uses a new guest programming language 140 in the DMBS 110 in an embodiment. Figure 1 discuss Figure 3 .
[0090] Steps 301-302 facilitate deploying the guest programming language 140 to a public cloud (not shown) as follows. As described above, DBMS 110 includes one or more server computers, which may or may not include client computer 190. For example, client computer 190 may be separate from DBMS 110 and host client software that acts as a remote client of DBMS 110, such as by utilizing ODBC. For example, guest computer 190 may be separate from the public cloud hosting DBMS 110. Thus, in step 301, DBMS 110 remotely receives DDL statements 181 from client computer 190.
[0091] Step 302 uploads the guest programming language's codebase file 150, which may occur automatically during processing of the DDL statements 181. Various techniques for pushing or pulling uploaded files 150 are discussed previously herein.
[0092] Steps 303-304 require configuration metadata (not shown) for the guest programming language 140 to be recorded in the database dictionary 120. Step 303 binds the name 130 of the guest programming language 140 to a (e.g., partial) linked / loaded implementation of the guest programming language 140. For example, such an implementation may be based on a codebase file 150. Linking, loading, and registration within the database dictionary 120 are discussed elsewhere herein.
[0093] Step 304 calls the guest subroutine 170 using the configuration metadata in the database dictionary 120. As described later herein, such metadata may be a calling specification that packages the subroutine 170 as a stored procedure or UDF for calling from a DML statement 182. Alternatively, another DDL statement (not shown) may generate such metadata, as described later herein.
[0094] Step 304 may result in one, some, or all of steps 305-307 of the logic being dynamically (re)optimized. As previously described herein, the guest programming language 140 may be an interpreted (e.g., scripting) language such as Python, R, JavaScript, Ruby, Pig, or (e.g., Java) intermediate byte code, all of which typically require an interpreter to execute. For example, the codebase file 150 may implement the interpreter. In embodiments such as with Truffle, the interpreter itself undergoes dynamic analysis, such as partial evaluation and other interpretations, specialization and other (e.g., speculative) optimizations, and JIT compilation.
[0095] Thus, for a particular guest subroutine 170 and / or a particular DML query 182 that calls the guest subroutine 170, the interpreter itself can be mutated / evolved towards the optimal direction. This refinement of the interpreter to suit a particular guest logic is called a Futamura projection, where there are several progressive degrees (i.e., projections) along an intensity spectrum, from optimizing the interpreter at one end of the intensity spectrum to reshaping the optimized interpreter into a compiler, or optimizing the compiler at the other end of the intensity spectrum. Step 305 performs at least a first degree of Futamura projection (i.e., interpreter optimization). The efficiency of the Futamura projection can depend on amortizing the optimization overhead (e.g., initial latency) over a large number of repeated calls to the guest subroutine 140. For example, during the execution of the same DML query 182, the guest subroutine 140 may be called for each of thousands or millions of rows in a database table.
[0096] Step 306 partially evaluates guest subroutine 170. For example, DBMS 110 may optimize all or part (e.g., a subtree) of the AST for guest subroutine 170. For example, a tight loop within guest subroutine 170 may be isolated for semantic optimization, while the remainder of guest subroutine 170 continues to be interpreted without optimization. Similarly, JIT compilation may be applied to all or part of the AST.
[0097] Step 307 generates speculation logic representing some or all of guest subroutine 170 based on more or less fragile assumptions, such as data type inferences, such as based on dynamic profiling of guest subroutine 170. The speculation logic may include guards that dynamically verify such assumptions. For example, the guards may detect failed (i.e., violated) assumptions and react by restoring the logic at the point of deoptimization, including falling back to non-optimized logic that does not require such assumptions, such as previously used and still cached logic.
[0098] 4.0 Visitor Module
[0099] Figure 4 4 is a block diagram illustrating an example DBMS 400 in an embodiment. For a guest programming language 420 , a single DDL statement 441 causes the DBMS 400 to generate a guest module 461 containing multiple guest subroutines 471 - 472 . The DBMS 400 may be an implementation of the DBMS 110 .
[0100] Language modules such as 461-463 are administrative and / or lexical (i.e., scope / visibility) units that define objects such as subroutines 471-472, which are local to the guest programming language 420 and accessible (e.g., publicly) from outside the guest module 461. Depending on the embodiment, the guest module 461 may contain other objects that are: a) also publicly accessible, but not subroutines, such as global variables, such as data structures, b) only accessible from within the guest module 461, or c) only accessible from within the guest programming language 420.
[0101] In an embodiment, DDL statement 441 may be "CREATE MLE MODULE scott.'jsmodule' LANGUAGE JAVASCRIPT AS module.exports.func=function() { ...};", as detailed below. JAVASCRIPT is the name 452 of the guest programming language 420 for which the guest module 461 is created. The name of the guest module 461 is jsmodule, as indicated by name 451.
[0102] When created, guest module 461 is registered within a database schema (not shown). If name 451 is not qualified in DDL statement 441, guest module 461 is registered within the default (e.g., current, global, and / or system) schema. If name 451 has a qualifier, such as scott, guest module 461 is registered within an existing schema named scott instead. For example, database dictionary 410 may be for a schema such as scott or default, and database dictionary 410 may contain names 451-455 as search keys. Because schemas act as namespaces, modules in different schemas may have the same unqualified name, but different qualifiers.
[0103] As appears in the example DDL statement 441 above, the new module exports (i.e., exposes) a single object named "func", which in this case happens to be: a) an anonymous (i.e., no visitor local name) JavaScript object, b) a function, and c) a function defined inline (i.e., directly in the DDL statement 441 as JavaScript). The export clause can export multiple objects, such as "AS module.exports.A = function() {} module.exports.B = function() {}", with spaces as separators.
[0104] The example DDL statement 441 above is a redundant (i.e., self-contained) form of a module creation statement because the exported object is an inline function defined. The module creation statement can have other forms that define the exported object by reference instead. The following is an example syntax of a module creation statement.
[0105] CREATE[OR REPLACE]MLE MODULE[ <module-schema> .] <name>
[0106] LANGUAGE[ <language-schema> .] <mle-language>[ENV[ <language-schema> .] <mle-env>]
[0107] [VERSION’ <version-string>']
[0108] {USING
[0109] {BFILE(<directory object name> ,<server file name> )|
[0110] {CLOB|BLOB|BFILE}<selection clause>}|
[0111] AS<module text>}
[0112] In the above syntax, the USING clause is an alternative to the AS inline clause. A BFILE item can specify a file path or resource URL, such as a JAR URL, for example, guest language material that is: remotely available, bundled in an archive file, and / or dynamic (e.g., HTTP CGI) content. A binary large object (BLOB) or character (i.e., text) large object (CLOB) item can specify a DML (e.g., SQL) select clause that retrieves content from a single column of a single row of a relational table or result set. For example, DBMS 400 can be a relational DBMS (RDBMS) that maintains tables in the database that store corresponding JavaScript objects in each row of the same column.
[0113] Depending on the embodiment, the VERSION item may be used for compatibility checking and / or for exposing multiple versions of the same module having the same name 451. The ENV item specifies a language programming environment, as described later herein.
[0114] In an embodiment, after DDL statements 441 create a guest module 461 in a guest programming language 420, guest subroutines 471-472 are immediately available for use in some, but not all, contexts, as described below. At this point, for the newly created guest module 461, the guest subroutines 471-472 may still not be declared in important components of the DBMS 400, such as the database dictionary including 410, relational algebraic mechanisms such as DML parsing and query planning, and guest programming languages other than 420. Depending on the embodiment, the guest subroutines 471-472 may not be available at all at this point, or may be visible for use only under certain combinations (e.g., all combinations) of the guest programming language 420, the guest module 461, and / or the current guest virtual environment (ENV), as described later herein.
[0115] Thus, after creating guest module 461, exposing guest subroutines 471-472 requires creating corresponding call specifications, such as 480. Call specifications 480 are metadata defined in database dictionary 410 as inter-language bindings for use with other languages, such as DML and / or (e.g., different) guest programming languages. Call specifications 480 can be used to: a) resolve (e.g., DML) calls to subroutine 472, including signature overloading; b) convert data types for input and / or output of guest subroutine 472; c) act as a placeholder or proxy for guest subroutine 472, such as in a planned or parsed query tree; and / or d) actually call (i.e., transfer control flow to) guest subroutine 472. Thus, call specifications 480 can sometimes serve as a passive description of guest subroutine 472, while at other times serving as an active intermediary (i.e., glue logic) between guest subroutine 472 and its callers.
[0116] DDL statement 442 creates call specification 480. In an embodiment, DDL statement 442 may be "CREATE ORREPLACE FUNCTION function472 RETURN VARCHAR2 AS MLE MODULE jsmoduleSIGNATURE 'subroutine472(str1 string, str2 string)';," as detailed below. The name of guest module 461 is jsmodule, as indicated by name 451. The name of guest subroutine 472 is subroutine 472. Guest subroutine 472 is exposed (e.g., renamed to account for conflicts or for backward compatibility) as function 472. Guest subroutine 472 has a signature that accepts two string parameters (i.e., string types native to guest programming language 420) and returns a string (i.e., string types native to the DML language). Execution of DDL statement 442 makes call specification 480 visible and guest subroutine 472 callable anywhere guest module 461 is available (e.g., DML and guest programming languages other than 420).
[0117] Guest modules such as 461-463 are composable and can depend on each other, as shown below. For example, guest module 462 can expose (i.e., export) objects used by guest module 461. For example, guest subroutine 471 in guest module 461 can import (and, e.g., call) a guest subroutine (not shown) provided by guest module 462.
[0118] The techniques herein seek flexibility and reuse, regardless of complexities such as backward compatibility and isolation (e.g., for multi-tenancy and / or library versioning). Thus, interdependent guest modules 461-463 are only loosely (i.e., symbolically) coupled with names 453-455, as shown below. Each guest module can rename its dependencies (i.e., other guest modules that are imported (i.e., cross-referenced)) (i.e., define its own names for the dependencies).
[0119] For example, guest module 462 is referred to within guest module 461 as name 453, which is not necessarily the original name of guest module 462. For example, guest subroutine 471 may be defined in a Python script that has an import statement that lists (i.e., cross-references) name 453, which is bound to guest module 462. However, different guest modules, such as 463, may import the same guest module 462 by different names, or may have different guest modules bound to the same name 453.
[0120] Thus, name 453 acts as an alias. In an embodiment, aliases can be cascaded. For example, within guest module 461, names 454-455 are synonymous because name 455 is bound to name 454. For example, a Python script can use name 454 or 455 to refer to guest module 463.
[0121] The guest programming language 420 can instead be Java, which can have classes instead of scripts. The activities discussed herein for script execution can instead occur during class loading and / or class execution. In an embodiment, each Java guest module is implemented as a native Java module, such as a Java-9 module, an OpenJDK Jigsaw module, or an Open Services Gateway specification (OSGi) module. Each Java module has its own descriptor class that cross-references other modules as dependencies. Except for OSGi, loading one Java module among many interdependent Java modules results in greedy loading of the transitive closure of the cross-referenced descriptor classes. Loading other implementation (e.g., helper) classes from the Java module can rely on natural class loading semantics, which are largely or completely inert.
[0122] Regardless of how lazy the native module loading is implemented, embodiments of DBMS 400 may or may not enforce greedy resolution of guest modules, even if guest module loading is more or less lazy. Module resolution requires mapping dependency names (i.e., aliases) to actual module implementations. For example, embodiments with lazy module resolution may create modules in any order by issuing DDL create statements in any order. However, greedy module resolution may require that dependency modules be created before other modules that use those dependencies, so that circular dependencies are prohibited. For example, with greedy module resolution, if any of the dependency names of a module cannot be immediately resolved to other already resolved modules, the DDL statement to create that module will fail. However, lazy module resolution may postpone resolution (e.g., if it cannot be resolved) until the dependency is actually used. In either case, whether module resolution includes module loading (e.g., script execution) depends on the embodiment.
[0123] As described above, modules 461-463 are defined within a database schema (not shown), which naturally provides potentially significant isolation, as shown below. The lifespan and visibility of guest objects may deviate from the state of existing guest language concepts, as shown below. For example, DBMS 400 may be multi-user, multi-role, multi-tenant, and access-controlled (e.g., DDL authorization statements). These complexities do not exist in traditional JavaScript environments such as web browsers. However, the database schema provides substantial isolation by enforcing visibility at various granularities.
[0124] For example, each database application or application subsystem can have its own database schema that defines its own users, their roles, and their permissions. Since applications do not typically share schemas, these applications should not share modules as follows. Multiple applications can share the same code base (e.g., scripts, libraries) of a module, and these applications can give the module the same alias. However, since these applications have separate schemas, separate instances (i.e., copies) of the module should be loaded into the RAM of the DBMS 400 at runtime. For example, the guest module 461 can be one of many defined instances of the same module deployment. The DBMS 400 treats each instance of the same module deployment as a separate (i.e., independent) module.
[0125] Each instance of the same module deployment is initialized separately, which may require repeated execution of the same code base. For example, a module creation DDL statement 441 creates only one module instance in a database schema. A module instance is distinguished from its code base as follows. A module's code base (not shown), such as a script or library, can be a unit deployed into DBMS 400. For example, multiple instances of the same module can be created by repeatedly executing the module's script.
[0126] For example, another more or less similar DDL statement (not shown) can create another module instance of the same general module, but in a different mode. Both DDL statements can result in duplicate execution of the same module code base. For example, both DDL statements can specify the same Python script or the same Java archive file (JAR) as the module code base, which will cause the script to be run twice, or the JAR to be loaded twice by two separate class loader instances. Thus, the two module instances created may have separate (i.e., independent) copies of nominally the same global variables in Python or the same static fields in Java.
[0127] 5.0 Example Module Creation Process
[0128] Figure 5 4 is a flow chart describing a single DDL statement 441 causing the DBMS 400 to generate a guest module 461 containing a plurality of guest subroutines 471-472 for the guest programming language 420. Figure 4 discuss Figure 5 .
[0129] In the illustrated embodiment, preparing a new guest subroutine 472 in the database dictionary 410 occurs in steps 502 and 504, each of which executes corresponding DDL statements 441-442, as shown below. Step 502 executes DDL statement 441 that initiates a bulk load of multiple guest subroutines 471-472 to define them in the database dictionary 410. DDL statement 441 creates a new guest module 461 for the guest programming language 420 and binds the guest module 461 in the database dictionary 410 to the name 451 contained in DDL statement 441.
[0130] DDL statements 441 directly or indirectly provide a (e.g., custom) code base that (textually) defines one or more guest subroutines 471-472. For example, DDL statements 441 may include a (e.g., quoted and character-escaped) string containing (e.g., Python) guest script statements that literally define inline guest subroutines 471-472. In another example, DDL statements 441 reference a Python script file containing these guest script statements via a URL or path.
[0131] In either case, step 502 executes these guest script statements to cause the guest programming language 420 to internally define guest objects, such as subroutines 471-472. In an embodiment, only a subset of these new guest objects 471-472 are provided directly to the DBMS 400. For example, the DDL statements 441 and / or guest script statements may declare that certain guest objects are to be exported (or, in an embodiment, not to be exported).
[0132] Exports and selective exports are discussed elsewhere in this document. For example, the multi-language engine (MLE) of the DBMS 400 can have a corresponding export implementation based on the guest programming language 420. For example, exports can be directly supported in a more or less native manner in the guest programming language 420, such as through Harmony (also known as ECMAScript 6). Unfortunately, exports intrude into the guest script processing statements, as described elsewhere in this document. Similarly, as described herein, Java's native module system requires (e.g., hand-coded) classes to implement exports. However, other implementations can appropriately separate concerns such as exports and script processing. For example, the MLE of the DBMS 400 can automatically generate boilerplate declarations for exports, dependencies (i.e., imports), and / or other aspects of modules, module boundaries, and / or module composition (i.e., aggregation arrangements).
[0133] Embodiments herein may separate the export and publication of guest objects into distinct steps 502 and 504. As described above, step 502 instantiates guest subroutines 471-472 and exports them to DBMS 400 and its MLE. However, in embodiments, exporting does not make guest subroutines 471-472 available for calling from DML statements 444, because DML statements can only call UDFs and stored procedures, not arbitrary subroutines.
[0134] Step 504 executes DDL statement 442 to generate a call specification 480 for guest subroutine 472 and registers call specification 480 in database dictionary 410 for subsequent reference by DML statements such as 444. The generation of call specification 480 is discussed previously herein. In an embodiment not shown, there is no DDL statement 442 and no step 504. Instead, call specifications are automatically (e.g., lazily) generated for all exported guest subroutines of guest module 461, such as during the previous step 502.
[0135] Step 506 executes a DML statement 444 that references a call specification 480 to call a guest subroutine 472, as previously described herein, such as during a database query. Step 506 extracts call site information from the DML statement 444, which may include the name of a UDF or stored procedure, which may be used as a lookup key to retrieve the call specification 480 from the database dictionary 410. Argument ordering and data types may be inferred from the call site, such as for signature overloading and / or warnings for semantic errors, such as the wrong number of arguments, data type mismatches for arguments or return values, or incorrect direction for OUT arguments. In embodiments, a call specification 480 may have OUT or IN / OUT arguments even when the guest programming language 420 does not natively support output arguments, such as when the MLE of the DBMS 400 can generate or otherwise provide a data structure for marshaling the arguments.
[0136] As described elsewhere herein, call specification 480 can convert return values or argument values between (e.g., somewhat similar) data types. Step 506 can repeatedly call guest subroutine 472 using call specification 480, such as for each of a plurality of database table rows and / or for each of a plurality of call sites. DML statement 444 can also call other call specifications of other guest subroutines (e.g., 471).
[0137] 6.0 Example Module Lifecycle Activities
[0138] Figure 6 is a flowchart describing some of the life cycle activities of the guest module 461 and the guest subroutines 471-472. Figure 4 discuss Figure 6 .
[0139] Steps 601-605 represent activities that may occur during the initial deployment of guest module 461. Step 606 represents maintenance (eg, patching) of guest subroutines 471-472. Step 607 represents usage of guest subroutine 472.
[0140] Initial deployment of guest module 461 may require the execution of a series of DDL statements, including guest module creation via DDL statements 441 in steps 601-603, guest module management via data control language (DCL) statements 443 in step 604, and call specification generation via DDL statements 442 in step 605. In step 601, DBMS 400 receives and begins executing DDL statements 441 to create guest module 461 and guest subroutines 471-472. Since instantiating guest subroutines 471-472 requires executing guest programming language 420, DDL statements 441 should include the name 452 of guest programming language 420. Step 601 can use name 452 as a lookup key in database dictionary 410.
[0141] Step 602 creates a new guest module 461, which may need to execute scripts or classes in the guest programming language 420. For example, the DDL statement 441 may contain an inline script or may reference a script in a file.
[0142] Step 603 binds the name 451 to the new guest module 461 in the database dictionary 410, such as according to the database object definition techniques and mechanisms described elsewhere herein. The DDL script 441 specifies the name 451. The database dictionary 410 and its association with (e.g., user or default) database schemas are discussed elsewhere herein.
[0143] Step 604 executes DCL statement 443 to grant various permissions to various users and / or roles. For example, some users may be allowed to use guest module 461 but not modify guest module 461. In addition, for example, some users may be prohibited from using guest module 461.
[0144] Step 605 executes the DDL statement 442 to generate a call specification 480 for the guest subroutine 472. For the call specification 480, step 605 may generate or reuse data type mappings between the DDL and the guest programming language 430, and may embed such mapping logic into the call specification 480. The call specification 480 may specify argument types, such as for signature resolution and / or overloading, argument direction (such as OUT), and / or indications of idempotence, cacheability, and / or thread safety (e.g., for optimization and / or parallelization).
[0145] At some later time, one, some, or all of the guest subroutines 471-472 may be modified. Step 606 executes a single DDL statement (not shown), such as an ALTER MODULE statement shown elsewhere in this document, to modify (i.e., replace) any or all of the guest subroutines 471-472. For example, the ALTER MODULE statement can specify a modified code base, such as inline or in a file. Step 606 replaces the guest subroutines 471-472 and retains any call specifications that have been generated, such as 480, although some or all such call specifications may need to be regenerated by additional DDL statements, such as for signature changes. In an embodiment, the call specification 480 is automatically regenerated during step 606.
[0146] Step 607 actually calls the guest subroutine 472 during the execution of the DML statement 444. The guest subroutine 472 may require increased privileges to access resources, or may benefit from reduced permissions for security reasons, such as to avoid accidental or malicious misuse. As described later herein, the call specification 480 can declare whether the guest subroutine 472 inherits the permissions of whichever user account calls the call specification 480, or whether the guest subroutine 472 should instead inherit the permissions of the administrative user account that defines the guest module 461.
[0147] That is, calling specification 480 specifies which of the two user accounts guest subroutine 472 should execute under. Thus, as shown, when guest subroutine 472 is called via calling specification 480, step 607 can switch to the module definer's user account. When guest subroutine 472 returns control to the executing DML statement 444, execution returns to the caller's user account, which is the user who submitted DML statement 444. User account and guest module boundaries can be related to execution contexts, as will be described later in this document.
[0148] 7.0 Module Dependencies
[0149] Figure 7 7 is a block diagram illustrating an example DBMS 700 in accordance with an embodiment. A local request 751 from a guest programming language 710 to import a dependency 790 causes the DBMS 700 to provide a guest module 721 or 722 based on a mapping 780, as shown below. The DBMS 700 may be an implementation of the DBMS 110.
[0150] Guest objects, such as exported subroutines, are defined in a guest programming language 710 of the DBMS 700, such as in a (e.g., Python) guest script 730. Although not shown, multiple guest objects may be distributed across one or more guest modules defined in the guest programming language 710. In operation, DML statements 771-773, such as SQL, may access the exported guest objects, such as in a database dictionary (not shown) of the DBMS 700.
[0151] For example, a guest module may be defined based on a (e.g., Python) guest script 730 that defines one or more guest objects, such as subroutines, that are exposed (i.e., exported). The creation of these guest objects requires the execution of the guest script 730, which occurs each time a guest module instance is defined using the same guest module deployment.
[0152] As described above, script execution creates a guest object. The lifespan of a guest object depends on various implementations as described below. A guest object's lifespan does not outlive the guest module that contains it.
[0153] The lifespan and visibility of visitor objects may deviate from the state of existing visitor language concepts, as shown below. For example, DBMS 700 can be multi-user, multi-role, multi-tenant and access-controlled (e.g., DDL authorization statements). These complexities do not exist in traditional JavaScript environments such as web browsers. DBMS 700 may have other technical issues, such as database schemas and multiple threads as namespaces, which have visibility and shared impacts that browser scripts do not have. As described elsewhere in this article, technologies such as visitor modules and environments can provide some required isolation. However, as shown below, for additional security (i.e., correctness, such as for security or compatibility), enterprises or cloud solutions may need more robust isolation.
[0154] In an embodiment, an execution context (not shown) is an additional mechanism that provides sufficient isolation. An execution context is a coarse-grained control flow mechanism with operational characteristics between lightweight threads and heavyweight processes of an operating system. Similar to threads, multiple execution contexts can share the same address space, such as the address space of DBMS 700. Like heavyweight processes, an execution context can have its own private environment namespace from which resource dependencies are resolved (i.e., looked up). Execution contexts can interoperate with database objects of DBMS 700, as shown below.
[0155] DBMS 700 can have concurrent execution contexts, each of which is dedicated to a database session and single-threaded. An execution context can live as long as its database session. An execution context can be idle at least as long as its database session is idle. Thus, only a fluctuating subset of execution contexts is actually active at any given moment. For example, a thread pool can have fewer total threads than the number of execution contexts it services.
[0156] In an embodiment, multiple execution contexts do not share guest module instances. For example, the same user may have two database sessions for the same database schema, which could create two guest module instances for the same guest module deployment. For example, for the same guest module deployment, a new guest module instance may be created for each execution context that uses the guest module deployment. Thus, guest module instance initialization may be repeated each time another execution context first uses the same guest module deployment (e.g., script execution).
[0157] For example, each execution context may have its own Java class loader. Likewise, the same (e.g., Python) guest script 730 may be repeatedly executed for separate execution contexts and for repeated instance initialization of the same guest module deployment. Thus, each execution context may have its own instance of nominally identical guest global variables.
[0158] Execution context creation may occur in the following situations. Although not shown, each exported guest subroutine has its own calling specification, as previously described. For each database session, when a call site for a guest module's calling specification is called for the first time, such as in a DML statement 771, a new execution context is created that can last as long as the session. Subsequent call sites for the same calling specification or for other calling specifications in the same guest module should reuse this execution context. In the same session, the first call of a call site for a calling specification in a different guest module causes the creation of an additional execution context.
[0159] Typically, the execution context has the same permissions as the session of the DML statement 771. However, the DDL statement (not shown) that creates the call specification can optionally specify that the execution context of the DDL statement's session should be preserved and shared (e.g., cloned) for all sessions of all users that call the call specification. Thus, user A can create a call specification bound to a guest subroutine that always executes with the permissions of user A even when the call specification is called by another user, thereby temporarily elevating permissions during the execution of the subroutine.
[0160] As described later in this document, a guest subroutine defined in one guest module can call a guest subroutine defined in another guest module. Typically, guest subroutines in different guest modules have different execution contexts even for the same session. However, when a first guest subroutine calls a second subroutine, there is only one call point in DML statement 771, and that call point is for the first subroutine. When there is only one call point, there is only one execution context for the same session, and an embodiment can reuse that execution context so that two subroutines called through the same call point (i.e., one subroutine is called directly and the other subroutine is called indirectly) should share the same execution context. Thus, a call point is the root in the entire call tree from which the same execution context can be injected into a guest subroutine, regardless of guest module boundaries. An execution context is associated with a call point or calling specification, as shown below.
[0161] In various embodiments, the guest programming language 710 can have multiple instances of the same guest module, such as one per user, one per session, one per transaction, one per (e.g., prepared, batched) DML statement, one per call specification of a DML statement, or one per call specification call site. As metadata, a call specification can be shared by some or all (e.g., asynchronous) instances of the same guest module. For example, one embodiment may require multiple instances of the same call specification, while another embodiment may instead have only a shared singleton pattern. Reinstantiating the same guest module for each DML transaction, statement, or call specification of a statement (i.e., regardless of how many call sites there are) can improve performance efficiency by balancing reinstantiation latency and lexical isolation (i.e., correctness / safety, such as security or compatibility).
[0162] In an embodiment, each call specification instantiates its own instance of the guest module it declares, regardless of how many call sites there are in the same DML statement. In this embodiment, the lifespan of any guest module does not outlive the execution of the DML statement that instantiated the guest module. Thus, each time a DML statement 771 is issued, the guest script 730 runs once for each referenced guest subroutine, i.e., not once for each repeated (e.g., per table row) call, nor once for each call site. For example, a particular guest module may export functions foo and bar, but may not export a function splat from a different guest module. If the DML statement 771 is "SELECT foo(), foo(), bar(), splat() FROM SomeTable;", then the particular guest module is instantiated twice (i.e., once for foo and once for bar). The UDF splat() can be a normal UDF implemented in SQL, or it can be implemented in different guest modules using the same or different guest programming languages.
[0163] A guest module can use (i.e., depend on) other guest modules, but an empty guest module as a dependency may be more or less useless. The resources exported by a guest module (i.e., guest objects) are what make the guest module useful. For example, a guest module may contain a guest script 730, which may initialize the guest module, including generating guest objects that may or may not be used for export, such as to other guest modules.
[0164] As shown, DML statements 771-772 interact with (e.g., call) guest objects (not shown) in the MLE's memory (e.g., RAM) that are generated by guest script 730. Each of these guest objects can be defined by corresponding lines of text in guest script 730, which itself is text.
[0165] A guest script 730 may depend on other guest modules, such as according to dependencies 790, as shown below. Regardless of whether the execution of guest script 730 is eager, lazy, interpreted, compiled, or based on intermediate code (e.g., bytecode), execution of guest script 730 occurs statement by statement (e.g., line by line), ultimately executing imperative statements 740 in guest script 730. Imperative statements 740 are import instructions that issue import requests 751 to dynamically link dependencies 790, which symbolically identify guest modules (not shown) to be resolved. Processing of import requests 751 may occur as follows.
[0166] 8.0 Example Import Processing
[0167] Figure 8 is a flow chart describing the execution of a local request 751 of an import dependency of a guest programming language 710, which causes the DMBS 700 to provide a resource 721 or 722 based on a mapping 780, as shown below. Figure 7 discuss Figure 8 .
[0168] Dynamic import of dependencies according to the techniques herein may occur in three different scenarios that share the mechanisms herein. Although not shown, one of these scenarios is caused by a DDL statement for guest module creation, as described below. As shown in the figure, the other two scenarios are caused by corresponding alternative implementations (e.g., 771-773) for the same DML statement, as described below. Figure 8 The discussion addresses all three situations in various ways as follows.
[0169] Step 802 receives and executes (eg, DDL or DML) database statements that invoke the guest programming language 710 either explicitly (ie, DDL) or implicitly (ie, a DML call site to a call specification).
[0170] For example, a DDL statement for guest module creation may call a (e.g., Python) guest script 730 to eagerly instantiate a guest object such as resource 721, which may be a guest subroutine. The guest script 730 may begin with or contain dependency import instructions elsewhere, which are typically imperative statements in the guest programming language 710, such as 740. However, as described below, some import instructions may have been statically pre-processed (i.e., inlined and removed), such as before deployment of the guest script 730, such as during the build (i.e., packaging) phase.
[0171] Such a build phase is optional for the techniques in this article. However, as with software in general, there can be both static linking (i.e., build phase) and dynamic linking (i.e., runtime), where some dependencies are fully resolved and linked (e.g., inlined) at build time. For example, JavaScript has static bundlers such as Browserify and WebPack, to which some linking can be offloaded, thus reducing the need for the dynamic import techniques in this article. Although Python does not include static inlining, tools such as Pip can move most linking responsibilities to build time, away from runtime.
[0172] In any case, it may not be possible or desirable to avoid all dynamic linking, for example for reasons discussed elsewhere herein. Thus, any time a guest script 730 executes, or any time a guest subroutine defined by a guest script 730 is later called, an import statement may be executed, thereby causing dynamic linking, as described below.
[0173] In another, though less likely, scenario, the body of the guest subroutine itself may contain import statements. Thus, calling a guest subroutine (e.g., from a DML query) may result in dynamic linking.
[0174] In another scenario that is a hybrid of the other two scenarios, the guest module is re-instantiated more or less frequently, such as for multiple execution contexts, as described later herein. For example, during the execution of DML statement 771, the initialization of an (e.g., additional) execution context may result in the instantiation of another instance of the same module deployment in the memory (e.g., RAM) of DBMS 700. Thus, in the hybrid scenario, the import statement is executed concurrently with the execution of the DML statement, as in the first scenario, but for module creation DDL statements, the import execution proceeds as described above, as in the other scenario.
[0175] Thus, whether steps 802, 804, and 806 are caused by a DDL statement or a DML statement depends on the situation. Similarly, whether this requires (re)executing all guest scripts 730 or only calling guest subroutines defined by earlier executions of guest scripts 730 also depends on the situation. Furthermore, an implementation may support only one or two of the three situations.
[0176] Step 802 leads to steps 804 and 806, as shown below. Execution of guest script 730 or one of its guest subroutines may be performed by serially executing various guest statements, including imperative statement 740, which is an import instruction that issues import request 751 in step 804 to dynamically link dependency 790, which symbolically identifies a guest module (not shown) to be resolved.
[0177] In one embodiment, the MLE of DBMS 700 has a corresponding adapter for each guest programming language implementation. During step 804, the adapter intercepts and specifically processes import request 751, as shown below. Although not shown, import request 751 includes the name of dependency 790, as required for module resolution. The MLE can use this dependency name in the next step 806, as shown below.
[0178] Step 806 resolves dependency 790. The dependency name can be used as a lookup key in dependency map 780 to select a guest module that satisfies dependency 790. Dependency map 780 can be implemented by a guest virtual environment that participates in dependency resolution, as described later herein. For example, in map 780, dependency 790 can be bound to guest module 721.
[0179] 9.0 Example Component Boundary Behavior
[0180] Figure 9 A flowchart depicting example activities at the boundaries of components such as database sessions 761-762, DML statements 771-773, and guest modules 721-722 is shown below. Figure 7 discuss Figure 9 .
[0181] Figure 9 The steps 901A-B describe multiple scenarios that may or may not occur together, as shown below. Steps 901A-B involve the same DML statement 771 invoking two call specifications in corresponding different guest modules 721-722 of the same guest programming language 710. In other words, DML statement 771 directly depends on multiple guest modules, which in embodiments implies an execution context, as shown below.
[0182] As previously described herein, an execution context typically corresponds to a combination of a database session and a guest module. That is, calls to the same guest module during the same database session can reuse a single execution context. For example, DML statement 771 occurs in database session 761. The execution of DML statement 771 spans steps 901A-B, as shown below.
[0183] During step 901A, DML statement 771 calls a first UDF whose call specification exists in guest module 721. Thus, the first UDF is called in a first execution context for the combination of database session 761 and guest module 721. If the first execution context already exists, it is reused; if not, it is created immediately.
[0184] During step 901B, the same DML statement 771 calls a second UDF whose call specification exists in a different guest module 722. Thus, even though both guest modules 721 and 722 are defined in the same guest programming language 710, the first execution context is not reused to call the second UDF. Instead, the second UDF is called in a second execution context for the combination of the same database session 761 and a different guest module 722. If the second execution context already exists, it is reused; if not, it is immediately created.
[0185] As previously described herein, each execution context that shares the deployment of guest module 721 with other execution contexts (e.g., other database sessions) may require its own guest module instance. Furthermore, as described above, each additional module instance may be initialized separately, such that guest script 730 is re-run each time an additional module instance is initialized. For example, if DML statement 771 is the first use of guest module 721 for database session 761, guest module 721 should be instantiated for database session 761 during execution of DML statement 771. Thus, DML statement 771 may cause guest script 730 to execute, which results in steps 902A-C, as shown below.
[0186] As previously described herein, the execution of the guest script 730 can proceed by interpreting the individual statements within the guest script 730 one at a time. For example, step 902 interprets the imperative statement 740, which may be an import instruction. The interpretation of the imperative statement 740 may not require steps 902B-C, may require one of steps 902B-C, or may require both steps 902B-C, as shown below.
[0187] At step 902B, the implementation of the guest programming language 710 parses the script text, such as all of the text or a single line of text of the guest script 730. For example, step 902B may generate a Truffle AST or append to an existing Truffle AST.
[0188] Depending on the guest programming language 710, the imperative statement 740 may initially be bytecode, or may be dynamically compiled into bytecode via step 902B. In either case, step 902C interprets the intermediate code, such as bytecode. Thus, although not shown, step 902B may or may not result in step 902C.
[0189] DML statement 771 can call a UDF, which in turn calls a guest subroutine via a call specification, such as through any of steps 901A-B. However, the guest subroutine can itself call other guest subroutines in other guest modules of the same guest programming language 710, as shown in steps 903A-B. For example, DML statement 771 can directly call (i.e., shown as step 903A) a guest subroutine via a UDF and call specification in guest module 721, which can then call a guest subroutine in a different guest module 722 via its own guest logic, as shown as step 903B.
[0190] Thus, just as steps 901A-B cross the boundary between two guest modules, steps 903A-B also cross the boundary between modules. However, steps 903A-B share the same execution context. Steps 901A-B do not share the same execution context. Thus, whether the boundary between guest modules causes a switch between two execution contexts depends on the situation.
[0191] An empty guest module may be more or less useless. A dependency on or import of a guest module is only required because the guest module contains the required resources (i.e., guest objects), such as guest subroutines. However, the required guest objects do not have to be subroutines, but may instead be data objects, such as arrays. For example, multiple interdependent guest modules 721-722 of the same guest programming language 710 may share the same array constructed by guest module 721. For example, in step 904, logic in guest module 722 may import guest module 721 and then reference the array.
[0192] The guest subroutine or guest script itself can issue DML statements, shown as step 905. For example, DML statement 771 can be SQL that calls a UDF, which is implemented by a guest subroutine whose guest logic issues additional SQL queries. Thus, the MLE of DBMS 700 has a fully bidirectional interface between SQL and guest programming language 710, which may require making database session 761 available to the guest subroutine as the current or default database session, which can be achieved as shown below.
[0193] In one embodiment, since each execution context can have its own independent instance of a global variable, as previously described herein, the global variable can store the database session 761 as the current session. In another embodiment, the current database session is exported, or a factory subroutine that returns the current database session is exported, and either is exported from a module that operates like a guest module, but is local to the DBMS 700 and does not have a guest programming language, or the guest programming language is a DML, such as PL / SQL or T / SQL. The guest module 721 may need to import the local module to access the current database session.
[0194] 10.0 Example Dependency Resolution Processing
[0195] Figure 10 is a flow chart describing example activities for satisfying dependencies 790 in an embodiment. Additional dependency satisfaction techniques are described later in this document. Figure 7 discuss Figure 10 .
[0196] Step 1002 loads and caches guest module 722 into memory buffer 705 of DBMS 700. For example, DML statement 771 in database session 761 causes import request 751 to access dependency 790, as previously described herein. Also as described above, DBMS 700 uses mapping 780 to determine which actual guest module should be used to satisfy dependency 790. The implementation of mapping 780 is described later herein. For example, guest module 722 may be selected to satisfy dependency 790.
[0197] Step 1004 can execute DML statement 773 in a different database session 762, which can invoke the UDF's calling convention to call a guest subroutine, which can execute import request 752 to access the same dependency 790, represented by step 1006. As described elsewhere herein, the guest module selected for dependency 790 in step 1008 depends on mapping 780, which can be based on the current database session and / or the current execution context. Thus, dependency 790 that was resolved to guest module 721 in step 702 can instead be resolved to a different guest module 722 in step 708. Additional mechanisms for such resource changes, such as guest virtual environments, are described later herein.
[0198] 11.0 Multi-language integration
[0199] Figure 11 1 is a block diagram illustrating an example software container 1100 in an embodiment. The software container 1100 has a multi-language engine (MLE) that facilitates collaboration between different guest programming languages 1112-1113, as shown below. The software container 1100 may be an implementation of the DBMS 110.
[0200] Depending on the embodiment, the software container 1100 can be any middleware capable of loading and executing custom logic, such as a platform as a service (PaaS) or infrastructure as a service (IaaS). For example, the software container 1100 can be an application server such as a web server, an inversion of control (IoC) container such as Spring, a virtual machine (VM) such as a hypervisor or Java VM (JVM), a programming language interpreter for scripts or bytecodes, an application container such as Docker or Kubernetes, or a DBMS such as an RDBMS.
[0201] As previously described herein, the MLE of software container 1100 has innovative integration mechanisms, including: a) hosting of multiple guest programming languages 1112-1113, b) loading and operation of guest modules (not shown), c) resolution of symbolic dependencies (not shown) between guest modules, and d) generation and publication of calling conventions such as 1120. Furthermore, as previously described herein, the MLE can innovatively intrude (i.e., intercept) and enhance the operations of guest programming languages 1112-1113, such as importing and exporting guest objects as shared resources.
[0202] The MLE can be implemented such that most or all of the core functionality of the MLE is available in a language-neutral manner through a small number of language-specific adapters. In an embodiment, the MLE facilitates the collaboration of multiple guest languages 1112-1113 in a transparent manner based on the collaboration of guest modules as functional units through an intermediary interface, as shown below. For example, a guest module of guest programming language 1112 can interact with a guest module of guest programming language 1113 without either guest module knowing which language the other is using. Thus, the software container 1100 achieves more or less full interface compatibility for multiple guest languages that can collaborate to, for example, facilitate the execution of statements expressed in the native programming language 1111.
[0203] Native programming language 1111 is fully integrated into software container 1100. For example, when software container 1100 is a DBMS, native programming language 1111 can be a query language such as DML (e.g., SQL). As another example, software container 1100 can be implemented using native programming language 1111. For example, when software container 1100 is a Spring IoC implemented in Java, native programming language 1111 can be Java. In an embodiment, native programming language 1111 is a domain-specific language (DSL), which may or may not be proprietary to software container 1100.
[0204] As previously described herein, for example, for a DBMS, the software container 1100 generates a calling specification, such as 1120, for a subroutine in a guest programming language 1112-1113. For example, the calling specification 1120 can export a subroutine in the guest programming language 1112 as a UDF in the native programming language 1111. The UDF calling specification 1120 includes arguments (such as 1141) and / or return values having corresponding data types native to the native programming language 1111. The calling specification 1120 also includes a data binding 1131, which converts arguments from native programming language 1111 data types to guest programming language 1112 data types, such as the data type for guest argument 1142, and vice versa for return values and / or OUT parameters. Thus, the languages 1111-1112 are more or less completely isolated from each other's type systems, such that no language 1111-1112 is exposed to the data types of the other language.
[0205] Binding 1131 is not a binding between two guest programming languages. Instead, binding 131 can be implemented as follows. As described above, as a first binding, binding 1131 can bidirectionally convert data types between languages 1111 and 1112. Similarly, native programming language 1111 can also have a second binding (not shown) that bidirectionally converts data types between languages 1111 and 1113.
[0206] In an embodiment, the binding 1132 between the guest programming languages 1112-1113 can be a coupling of both a first binding and a second binding (not shown). Thus, the data type of any one of the guest programming languages 1112-1113 is initially converted to the data type of the native programming language 1111 as an intermediate representation, and then converted to another one of the guest programming languages 1112-1113. For example, the binding 1132 can convert a Python string into an SQL string, and then into a JavaScript string, so that a Python module can pass a value to a JavaScript module.
[0207] This approach is scalable in that each guest programming language only needs to provide a two-way data binding (i.e., a binding to the native programming language 1111). In another embodiment, the binding 1132 does not use the native programming language 1111 data type as an intermediate representation, but instead directly converts between the data types of the guest programming languages 1112-1113. This approach can have higher runtime efficiency.
[0208] Regardless of how data binding 1132 is implemented, the components of software container 1100 can be arranged as shown to enable multi-language execution of queries. Integrated technologies such as calling conventions, data binding, and module dependency resolution facilitate the configuration of interdependent guest modules by transparently implementing control flow and / or data flow between modules in different guest programming languages. For example, a query in native programming language 1111 can call a subroutine in guest programming language 1112, which accesses resources such as objects 1150 in guest programming language 1113.
[0209] Thus, the execution of queries can cross the guest language boundary, engaging the guest programming languages 1112-1113 in a collaborative manner. According to such interoperability, there can be various outstanding benefits as shown below.
[0210] For example, different responsibilities for the same query can be assigned according to the natural strength of the guest programming languages 1112-1113. For example, uniform resource locator (URL) processing can be delegated to guest programming language 1112, which in turn delegates regular expressions to guest programming language 1113.
[0211] For example, application developers are not limited to any one guest programming language and thus have a wealth of third-party (e.g., open source) resources in many guest programming languages readily available for deployment as guest modules. This can shift the trade-off between buy and build toward developing functionality from scratch, thereby accelerating development and / or reducing development costs. This, in turn, can encourage larger-scale (i.e., feature-rich) database applications and / or promote integrated service topologies such as application servers with fewer (e.g., middleware) layers, which can reduce operational / management costs and skills.
[0212] 12.0 Example Guest Object Access Processing
[0213] Figure 12 is a flow chart describing example activities for accessing a guest object 1150 in a guest programming language 1113 from a different guest programming language 1113 in an embodiment. Figure 11 discuss Figure 12 .
[0214] Step 1202 is preliminary and creates a guest object 1150 in the guest programming language 1113, as previously described herein, including activities such as guest module instantiation, guest script execution, guest object export, and various database dictionary insertions. Step 1204 calls a different guest programming language 1112 from a native programming language 1111 statement, as previously described herein. For example, call specification 1120 may mediate between native programming language 1111 and guest programming language 1112, including operations such as bind 1131 for argument data type conversions as described above. Thus, step 1204 transfers control from native programming language 1111 to guest programming language 1112, which may or may not require the generation and / or switching of an execution context as described above.
[0215] Step 1206 performs a request to access a guest object 1150 in a guest programming language 1113 from a different guest programming language 1112. Again, this may or may not require the generation and / or switching of an execution context as described above. Step 1206 crosses a language boundary in a more or less similar manner as step 1204, which also crosses a language boundary. As described above herein, as with each of steps 1204 and 1206, crossing to a guest programming language requires some or all of the following: a) execution context generation and / or switching, b) guest module resolution and / or instantiation, with or without guest script execution, c) argument data type conversion and / or validation, such as by binding 1131 or 1132, d) overload signature resolution, and e) actual transfer of control to the guest programming language, such as the calling and interpretation or other execution of a guest subroutine.
[0216] As previously described, the guest script or guest subroutine can issue an instruction to import a dependency. The script or subroutine issuing the instruction does not need to know which of the same or other guest programming languages implements the guest module that can satisfy the dependency. For example, and depending on the dependency mapping, as described above and below in this document, in various scenarios presented herein, the same dependency can be satisfied by different guest modules in the same or different guest programming languages. For example, due to expected substitutions or due to unexpected name conflicts, the same dependency may resolve to a Python guest module for one client and to a JavaScript guest module for another client.
[0217] Implementations of multi-language engines may use some decoupling mechanisms, including reusable data structures and / or generated glue logic, to achieve this multi-language module pluggability. Lookup tables and hash maps provide more or less passive translation based on indirection. For example, as described elsewhere in this document, there may be a passive, greedy, or lazy adapter that translates the native modular framework of the guest programming language into the guest module mechanisms and techniques taught herein. For example, as described herein, native data types and other structures native to the software container 1100 and / or the native programming language 1111, such as various aspects of SQL, may or may not be used as a canonical representation to or from which all guest language data types are translated. In an embodiment, a namespace such as a guest virtual environment facilitates module coupling, as shown below.
[0218] 13.0 Guest Virtual Environment
[0219] Figure 13 1 is a block diagram illustrating an example computer 1300 in accordance with an embodiment. Guest virtual environments 1311-1312 of computer 1300 provide alternative bindings of identically named dependencies to different guest modules, as shown below. Computer 1300 may include an implementation of DBMS 110.
[0220] As described above, guest modules, such as 1341-1342, can rely on other guest modules to satisfy dependencies. In addition, as described above, issues such as isolation and code base versioning may limit the sharing of guest modules. For example, multiple instances of the same module deployment may be required, or different code bases (e.g., release versions) may be required for similar modules, and / or resource name conflicts may need to be avoided. Thus, computer 1300 has, for example, guest virtual environments 1311-1312 that provide isolation for multiple tenants.
[0221] The guest virtual environments 1311-1312 are namespaces that provide a mapping (i.e., bindings) (not shown) between the symbolic dependencies (i.e., names discussed herein) of some guest modules 1341-1342 and other guest modules (not shown) that act as implementations of these dependencies (i.e., definitions discussed herein). In this sense, each guest virtual environment 1311-1312 acts as a namespace through which each guest module 1341-1342 can see other required guest modules. Thus, a database application can be composed of more or less collaborating guest modules. In an embodiment, each guest virtual environment 1311-1312 is implemented as an associative data structure, such as a dictionary or hash table, that stores the bindings of guest modules for lookup, as shown below.
[0222] In one embodiment, computer 1300 includes an RDBMS or other DBMS. Other embodiments do not include a DBMS. In the illustrated embodiment, computer 1300 receives and executes DDL statements 1321-1323, such as those for a DBMS, to create or otherwise manage guest virtual environment 1312. Other embodiments may receive and execute commands that, while not DDL and / or not for a DBMS, may nonetheless create and manage guest virtual environment 1312. DDL statements 1321-1323 are examples of implementation options for computer 1300. Thus, the following discussion of techniques regarding DDL statements 1321-1323 can readily be applied to implementations that require neither a DBMS nor DDL. In one embodiment, computer 1300 includes a software container that is not a DBMS, such as those previously described herein. In one embodiment, computer 1300 requires neither a DBMS nor any of the other software containers previously described herein.
[0223] DDL statement 1323 creates a new guest virtual environment 1312 in computer 1300. DDL statement 1323 can specify a database schema in which guest virtual environment 1312 is defined, which can default to the current schema of the database session in which DDL statement 1323 is issued. DDL statement 1323 can optionally specify an existing guest virtual environment to be used as a prototype from which a clone can be generated. For example, DDL statement 1323 can specify that new guest virtual environment 1312 should be cloned from existing guest virtual environment 1311. Cloning copies all dependency bindings, and if there is no clone, new guest virtual environment 1312 initially has no dependency bindings at all.
[0224] DDL statement 1321 adds a new dependency binding to the existing guest virtual environment 1311. For example, the details of DDL statement 1321, shown as import 1360, can specify the name of the dependency and the name of the guest module to be bound to the dependency. For example, guest module 1341 in guest programming language 1350 can import a dependency by name, such as with a require() statement (not shown). The multi-language engine (MLE) (not shown) of computer 1300 can intercept and specially handle import instructions (i.e., requests), such as require(). For example, a call to require() can specify a dependency name that the MLE can use as a lookup key to select a binding in guest virtual environment 1311. The selected binding can identify other guest modules that the requesting guest module 1341 should use to obtain resources related to the require() call.
[0225] To resolve dependencies, each guest module instance has a corresponding guest virtual environment. For example, the DDL statement (not shown) for creating a guest module can specify an existing guest virtual environment. If no guest virtual environment is specified, the computer 1300 provides a default guest virtual environment for the guest module.
[0226] Multiple guest modules 1341-1342 can share the same guest virtual environment 1311. This sharing can occur regardless of whether the guest modules 1341-1342: a) have different code bases, b) are defined in different guest programming languages, c) are imported by other guest modules defined in different guest programming languages, and / or d) are loaded for different user accounts and / or database sessions.
[0227] Guest module 1341 can be initially assigned to guest virtual environment 1311 and then reassigned to guest virtual environment 1312, such as by a DDL statement (not shown). In an embodiment, this reassignment causes guest module 1341 to be (e.g., lazily) reloaded based on guest virtual environment 1312. For example, a Python script implementing guest module 1341 can be rerun.
[0228] DDL statement 1322 has details shown as reallocation 1370, which replaces the existing dependency bindings in guest virtual environment 1311 with new dependency bindings. Thus, dependencies can be remapped to different guest modules, such as newly released versions of guest modules. In embodiments, DDL statement 1322 is non-retroactive, so that guest modules already using guest virtual environment 1311 are not affected by changes to guest virtual environment 1311. For example, guest modules 1341-1342 can each use concurrently different versions of guest virtual environment 1311.
[0229] Depending on the embodiment, any of DDL statements 1321-1323 can specify: a version number of the guest programming language, configuration settings for the guest programming language, and / or a resource loading path, such as discussed later herein. Each guest virtual environment is defined in a database schema, which can contain multiple guest virtual environments. Data control language (DCL) statements 1330 can manage usage permissions for guest virtual environment 1311.
[0230] 14.0 Example Guest Virtual Environment Processing
[0231] Figure 14 is a flow chart describing example activities for generating, modifying, and using a guest virtual environment 1311 that symbolically binds guest dependencies to guest modules in an embodiment. Figure 13 discuss Figure 14 .
[0232] Step 1402 creates an initially empty (ie, unbound) guest virtual environment 1311. For example, the DDL statement 1323 may be "CREATE MLE ENV scott.'myenv';", which creates the guest virtual environment 1311 and names it myenv in the database schema scott.
[0233] Initially, the empty guest virtual environment 1311 may be somewhat unusable, as its purpose is to map dependencies to corresponding guest modules. Within the guest virtual environment 1311, step 1404 adds bindings for the dependencies. For example, DDL statement 1321 may be "ALTER MLE ENV scott.'myenv' ADD IMPORT hello MODULE scott.'hello';," which specifies that a dependency named hello should be bound to import 1360 of guest module 1341 within guest virtual environment 1311.
[0234] Guest module 1341 has been or will (now or later) be instantiated in guest programming language 1350. However, guest module 1342 is instantiated in the same or a different programming language. In either case, execution of a guest script or guest subroutine in guest module 1342 can issue a request to access a dependency named hello, such as through an import instruction, as shown in step 1406. Step 1406 resolves the dependency named hello using guest virtual environment 1311 by selecting guest module 1341. For example, guest module 1342 may be using guest virtual environment 1311, based on metadata for guest module 1342, or based on the current execution context, current database session, or current database schema.
[0235] During step 1406 , the guest virtual environment 1311 is used to resolve the dependency hello, guest module 1342 depends on guest module 1341 , which may or may not require activities such as loading, instantiating, and / or reusing the guest module 1341 .
[0236] In conjunction with the MLE described herein, the guest virtual environment 1311 can: a) contain bindings to guest modules implemented in many guest programming languages, b) be used at runtime (e.g., query time) to be resolved by guest modules defined in many guest programming languages, and c) be used to facilitate crossing the boundary between any two guest programming languages. Thus, the guest virtual environment 1311 is language neutral.
[0237] 15.0 Guest Virtual Environment Sharing
[0238] Figure 15 is a flow chart describing example activities in an embodiment for sharing a guest virtual environment 1311 between multiple database users and multiple guest programming languages, such as in a multi-tenant environment, such as with multiple database applications that may be collaborating or isolated (i.e., not collaborating), such as in an enterprise's private cloud. Figure 13 discuss Figure 15 .
[0239] Figure 15 Various scenarios are shown that may or may not be independent of each other. Step 1502 executes DCL statement 1330 to grant or revoke certain access to the existing guest virtual environment 1311 for some user accounts or roles in computer 1300. For example, security and protection may dictate that DCL statement 1330 be used to grant read-only access to guest virtual environment 1311 for most users.
[0240] In steps 1504A-B, a user account that does not have permission to modify the guest virtual environment 1311 can access such modifications as follows: Step 1504A executes DDL statements 1323 to generate the guest virtual environment 1312 as a modifiable clone of the guest virtual environment 1311. Step 1504B executes DDL statements 1322, which include reallocations 2370 to add or replace bindings between named dependencies and available guest modules 1342 in the guest virtual environment 1312.
[0241] Thus, the guest virtual environment 1312 may be customized by, for example, replacing a binding between the named dependency and a guest module 1341 with a new binding between the same named dependency and a different guest module 1342. Thus, through cloning, module replacement is possible, such as when one database application requires a patched (e.g., third-party) library, while another database application in the same DBMS of the computer 1300 must continue to use an older, more stable version of the library.
[0242] The data structures and lexical scope of dependency bindings may depend on the embodiment. For example, step 1506 may bind dependency names to guest modules within one or more data structures, such as a guest virtual environment, a database schema, and / or a database dictionary. The MLE of computer 1300 may be designed to resolve dependencies based on such relevant data structures.
[0243] These data structures, such as guest virtual environments, facilitate sharing and reuse. For example, during step 1508A, requests to import the same dependency name can be resolved to the same guest module or a similar instance of the same deployment of the guest module during step 1508B. For example, such sharing can occur even when these import requests come from different user accounts, different database sessions, or even from different guest programming languages. This is because binding structures, such as guest virtual environments, can be shared or cloned, or different guest virtual environments can be configured in other ways to contain some of the same bindings.
[0244] 16.0 Virtual File System
[0245] Figure 16 is a block diagram illustrating an example software container 1600 according to an embodiment. Software container 1600 transparently retrieves resources 1681-1682 from a virtual file system, generalizing alternative storage mechanisms 1671-1674 as described below. Software container 1600 may be an implementation of DBMS 110. Various embodiments of software containers have been discussed previously herein, including some that do not require a DBMS or DML. Thus, the techniques described herein for using a DBMS or DML with software container 1600 are presented as part of exemplary implementation options that may not exist in other embodiments. Other embodiments may utilize these described techniques without requiring a DBMS or DML.
[0246] The software container 1600 has flexible and persistent storage for data resources such as deployments of guest modules (i.e., code bases). Alternative storage mechanisms 1672-1674 provide features that actual file systems such as 1671 do not typically have. These features can be described below to support the use of code bases in a special manner that can be transparent to application developers and clients (such as client sessions 1611-1612). Similarly, the software container 1600 can enforce permissions that are orthogonal to the actual file system 1671. For example, the software container 1600 can execute as an operating system (OS) superuser, which can access all files of the actual file system 1671 and can also deny access to specific database clients, such as according to previous data control language (DCL) authorizations.
[0247] For example, a guest module (not shown) can be implemented with one or more persistent objects (e.g., resources 1681-1682) of code or data, such as executable scripts, class files, images, and / or spreadsheets. Such persistent objects can be stored as loose (i.e., individual) files, aggregated in a monolithic archive (i.e., a library), or otherwise stored in bulk, as shown below. Persistent objects can be paired with metadata objects (e.g., manifests or descriptors), which virtual file system 1650 can analyze to facilitate resource loading.
[0248] The type and nature of client sessions 1611-1612 depend on the embodiment. Client sessions 1611-1612 encapsulate separate (e.g., through enforced isolation) sequences of client use that may or may not temporarily overlap. In an embodiment, software container 1600 is an RDBMS or other DBMS, and client sessions 1611-1612 are database sessions. In an embodiment, each client session 1611-1612 is remote and has its own separate network or inter-process connection. For example, client sessions 1611-1612 can more or less correspond to a Hypertext Transfer Protocol (HTTP) session and / or the session layer (also known as layer 5) of the Open Systems Interconnection (OSI) network stack. In the illustrated embodiment, software container 1600 has client sessions 1611-1612. In other embodiments, a software container does not require client sessions. For example, a software container can receive commands from a queue or controller that can be mixed, blurred, or otherwise have no session boundaries. For example, multiple clients may submit commands to the same queue that software container 1600 relies on, regardless of the source of the commands.
[0249] The software container 1600 provides highly dynamic importing (e.g., loading) of resources. Resources are typically imported during the initialization of a guest module instance (not shown), such as when a client session 1611 first calls any call specification (not shown) of the module, which is somewhat dynamic. However, resource import (e.g., require() script statement) can occur at any time during the execution of guest logic in the guest programming language 1630. For example, require() calls can be conditional (e.g., in an if statement) and issued from within a guest subroutine (not shown), which is highly dynamic. In any case, DDL or DML statements (e.g., 1621-1622) can result in the loading of guest modules and / or guest objects. For example, DML statements 1621-1622 can issue corresponding local requests 1641-1642 to import the same dependency 1660, such as via a require() call.
[0250] Embodiments of software container 1600 that do not require a DBMS can accept commands that are neither DML nor DDL. Thus, DML statements 1621-1622 are examples of implementation options. In other embodiments, the techniques herein can enable similar use of virtual file system 1650 without a DBMS, DML, or DDL.
[0251] File system implementation backends 1671-1674 are mutually exclusive alternatives, represented by dashed arrows. Software container 1600 can have many virtual file systems, such as 1650, but each virtual file system has only one corresponding implementation backend. As shown by the solid arrow, virtual file system 1650 uses archive file 1672 as its backing store.
[0252] For example, the virtual file system 1650 can resolve the dependency 1660 by selecting a resource (not shown) from an archive file 1672 that may contain many resources. For example, the archive file 1672 can be a (compressed) zip file, a tape archive (tar) file, or a Java archive (jar) file. In an embodiment, the virtual file system 1650 extracts the resource from the archive file 1672, for example, by decompressing the archive file 1672 and following a manifest (not shown) that lists the original files contained in the archive file 1672.
[0253] In one embodiment, the virtual file system 1650 can use the extracted resources directly. In another embodiment, the virtual file system 1650 can decompose (i.e., unpack) the files within the archive file 1672 into a real file system such as 1671. For example, virtual file systems can be cascaded so that one virtual file system can delegate to another virtual file system for features such as unpacking and / or caching. For example, virtual file systems can be aggregated (e.g., daisy-chained) into a set of load paths, such as a class path or a module path.
[0254] As previously described herein, as part of the multi-language engine (MLE) of software container 1600, the parser, compiler, and / or interpreter of guest programming language 1630 can intercept and specially handle native requests 1641-1642. For example, native request 1641 can specify the qualified or unqualified name of dependency 1660, which the MLE or guest compiler can analyze to identify the symbolic name of dependency 1660. As previously described herein, a guest virtual environment (not shown) can map the symbolic dependency to an actual guest module instance. For example, dependency 1660 can be mapped to a guest module whose code base is an archive file 1672. Thus, the MLE, guest virtual environment, and virtual file system 1650 can collaborate to dynamically satisfy dependency 1660.
[0255] In an embodiment, the virtual file system can operate as a resource cache. For example, the virtual file system can be implemented using a memory buffer 1673 that can cache some or all of the guest module, including resources 1682. For example, the virtual file system 1650 can decompose archive files 1672 into the memory buffer 1673. Resources 1682 can be static resources, such as images, or can be computed (i.e., dynamically generated) guest objects, such as JavaScript Object Notation (JSON) data structures generated by the guest module's initialization script.
[0256] In an embodiment, the entire guest module or individual resources within the module can be stored as large objects (i.e., BLOBs or CLOBs) in columns 1690 of database table 1674. Thus, module resources can be managed according to database semantics rather than native file system semantics. The virtual file system can automatically issue (e.g., generate) the DML required to access database columns 1690.
[0257] 17.0 Example Virtual File System Processing
[0258] Figure 17 is a flowchart describing example activities of a software container 1600 retrieving resources such as 1681-1682 from a virtualized storage device (such as a virtual file system 1650) in an embodiment. Figure 16 discuss Figure 17 .
[0259] Step 1702 invokes a guest programming language. For example, a DML statement 1621 may be executed. At step 1704, the guest programming language executes a request 1641 to access a dependency 1660, such as an import instruction, as previously described herein.
[0260] The satisfaction of dependency 1660 can occur in two stages. In the first stage, the MLE of software container 1600 resolves dependency 1660 to a specific guest module (not shown), for example, according to a binding (such as a binding contained in a guest virtual environment (not shown)). Depending on the situation, the guest module may or may not have been loaded yet.
[0261] In the second phase, step 1706 retrieves resources 1681 that satisfy dependencies 1660. Step 1706 occurs if the resolved guest module has not yet been loaded, or may sometimes occur even if the guest module has been loaded, as described later herein.
[0262] Step 1706 detects where and how the resource 1681 is stored. Figure 17 The processing typically occurs during guest module creation / instantiation, so resource 1681 can be (one or more) guest scripts in the guest module's codebase, which can be (one or more) (e.g., text or class) files in the actual file system 1671. Alternatively, dependency 1660 can be satisfied by resources in any of data stores 1672-1674. Thus, step 1706 detects in which data store the required resource is held.
[0263] As previously described herein, the codebase of a guest module is typically identified by the DDL statements that create the guest module. Thus, the software container 1600 can maintain metadata describing the guest module, including details such as the location and type of the data store containing the guest module's codebase. Whenever the guest module is (re)instantiated, the software container 1600 can consult this metadata to detect where and how the codebase is stored.
[0264] The deployment of a guest module can be shared, such as when two database sessions each require their own instance of the guest module. For example, the two database sessions can each execute the same guest script to initialize each instance of the guest module. The virtual file system 1650 is a data store adapter that the two sessions can share to access the same resources, such as all or part of the guest module's code base. As an adapter, the virtual file system 1650 hides which data store is actually used for the guest module from the rest of the MLE of the software container 1600. Thus, the virtual file system 1650 provides a unified appearance or interface through which resources can be retrieved without exposing the retrieval mechanism.
[0265] The software container 1600 can include a virtual file system 1650 within the metadata of the guest module. Thus, step 1706 can locate and retrieve resources for the resolved dependencies by accessing the virtual file system 1650 associated with the guest module to which the dependencies are resolved. For example, a DML query may require several dependencies, and the MLE of the software container 1600 can resolve these dependencies to specific guest modules and transparently load these guest modules in a unified and storage-independent manner, even though each of these guest modules may actually reside in very different data stores.
[0266] 18.0 Example Implementation
[0267] The following is an example implementation based on a specific implementation choice. For example, the DBMS is a relational DBMS (RDBMS). Similarly, DDL, DCL, and DML are provided by SQL.
[0268] Included in this example implementation are database statements for configuring and operating the novel multi-language database components presented in this example implementation and elsewhere herein. In this example implementation, guest components may also be referred to as MLE components. For example, an MLE module is a guest module. This example implementation demonstrates support for the following languages: SQL, Java, JavaScript, and Python. The MLE used in this example implementation also supports the addition of more guest programming languages.
[0269] This example implementation highlights the integration between the MLE and corresponding modular (e.g., package) frameworks that are native and / or optimal for various guest programming languages. For example, guest modules can be arranged into a hierarchy of subdirectories by design, and package naming can reflect this hierarchy. For example, guest modules are bound and resolved by name, and such names can reflect this hierarchy. However, other embodiments of the MLE do not require imposing hierarchical semantics on names and / or subdirectories.
[0270] In an embodiment, the virtual file system, the guest virtual environment, and / or other MLE component(s) supporting guest modules may directly support hierarchical behaviors / aspects such as name tags, subfolder enumeration, parent folders, case sensitivity, and / or manifests. Additionally, as described above and shown below herein, other features of guest native modularity that the MLE may integrate include interdependencies, visibility, deferred loading, decompression, versions, and / or search order.
[0271] 18.1 Creating an MLE Language
[0272] An MLE language should be added to the RDBMS before MLE functions that execute in that language can be created and executed. A new MLE language can be added to the database using the CREATE MLE LANGUAGE DDL:
[0273] CREATE MLE LANGUAGE MYLANGUAGE;
[0274] This creates a schema object with an identifier that matches the specified language name (in this case, MYLANGUAGE). The DDL statement will register the existing MLE language implementation provided by the MLE drop-in library with the RDBMS dictionary. This DDL gives the user the ability to register his own MLE language implementation with the database, rather than relying solely on the predefined language registrations.
[0275] 18.2 Runtime State Isolation
[0276] When MLE language code, such as a dynamic MLE code segment or function exported by an MLE module, is executed in a session, the runtime state associated with the execution is encapsulated in an execution context. This runtime state includes global variables and the state of the language environment. An execution context is a separate, isolated runtime environment for one or more MLE languages. All code that shares an execution context has full access to all of its runtime state (for example, any previously defined global variables). Conversely, code executing in one execution context has no way to see or modify the runtime state of another execution context.
[0277] MLE uses execution contexts for function and procedure calls from SQL and PL / SQL. Here, execution contexts separate the runtime states of different users and different MLE modules.
[0278] 18.3 Code Management Using MLE Modules
[0279] MLE language code can be persistently stored as MLE modules. An MLE module is a schema object that contains code written in a single MLE language. MLE modules correspond to the concepts of "libraries" or "modules" in the corresponding MLE language. For example, a JavaScript MLE module is a JavaScript UMD module.
[0280] The code in the MLE module can be used in two different ways:
[0281] Functions exported by an MLE module can be published by creating a call specification. MLE call specifications can be called from SQL and PL / SQL in the same way as PL / SQL functions and procedures.
[0282] MLE modules can be imported by other MLE code written in the same language. For example, JavaScript code executed in MLE can use require() to import a JavaScript MLE module.
[0283] Once MLE supports more languages besides JavaScript, MLE modules written in one language can be imported by code written in another language.
[0284] MLE provides DDL commands to manage MLE modules in the database (e.g., create, modify, delete).
[0285] 18.4Creating an MLE Module
[0286] MLE modules are created in the database using the CREATE MLE MODULE DDL statement that specifies the name and source code of the MLE module:
[0287] CREATE MLE MODULE scott."jsmodule"
[0288] LANGUAGE JAVASCRIPT
[0289] AS module.exports.func=function(){...}
[0290] The CREATE MLE MODULE DDL statement is discussed further elsewhere in this article.
[0291] Each MLE module can only contain code written in a single MLE language. This language is specified in the DDL statement when the module is created (for example, the DDL statement above creates a JavaScript module). The specified language should be one of the MLE languages added to the database via CREATE MLELANGUAGE.
[0292] The name of the created module can be fully qualified as in the example above, that is, both the schema (scott) and the name of the created module within the schema ("jsmodule") are qualified. If the schema name is omitted, the module is created in the current user's schema.
[0293] The name of an MLE module should be unique within the schema. Like other schema object identifiers, if the module name is enclosed in double quotes, the module name is case-sensitive. If the enclosing double quotes are omitted, the name is implicitly converted to uppercase.
[0294] The source code for an MLE module can be specified inline using the AS clause, or it can be obtained from a BFILE, BLOB, or CLOB.
[0295] An MLE module can be updated by replacing it. This is done by specifying OR REPLACE in the module creation DDL, and has the advantage that previously granted object privileges remain in effect after the replacement.
[0296] CREATE OR REPLACE MLE MODULE scott."jsmodule"
[0297] LANGUAGE JAVASCRIPT
[0298] AS module.exports.bafsfunc=new function(){...}
[0299] Users should have the CREATE MLE MODULE privilege to create MLE modules in their own schema, or the CREATE ANY MLE MODULE privilege to create MLE modules in any schema.
[0300] 18.5 Structure of the MLE Module
[0301] The structure of an MLE module is language-specific. For each MLE language, an MLE module corresponds to a "unit" of code in that language (e.g., a UMD module for JavaScript, a module or package for Python). An MLE module can also optionally bundle some or all of the dependencies of the code unit it encapsulates.
[0302] The following describes how the JavaScript, Python, and Java MLE modules are constructed.
[0303] 18.6 JavaScript MLE Module
[0304] JavaScript MLE modules are UMD modules, a standard format for writing modules in JavaScript. UMD modules export functions (or, more generally, values) by assigning them to fields of the module.exports object. UMD modules can be imported using the Node.js require() function. The require() function evaluates the contents of the module and returns the module.exports object, which gives the importer access to the functions exported by the imported module.
[0305] For example, the UMD module in the following logic exports a single function squareAndAdd().
[0306] The module text also defines a function square() that is used as an implementation of squareAndAdd(). However, this function is not exported and therefore cannot itself be called directly from code that imports the module.
[0307]
[0308] module.exports.squareAndAdd=squareAndAdd;
[0309] UMD modules themselves can use require() to import other UMD modules and may require specific versions (or version ranges) of dependencies in order to work correctly. Information about all the dependencies of a JavaScript module, including their names and versions, is typically contained in a package.json file. These dependencies can be installed using npm install, which reads the package.json file and retrieves the dependencies from the package registry.
[0310] Tools such as browserify and webpack can be used to bundle a UMD module and all its dependencies into a single UMD module. The bundled module exports the same set of functions as the original module, but additionally inlines the code from all its dependencies. The require() statements on the bundled module are removed, and all calls to its functions are replaced with calls to its inlined code.
[0311] JavaScript MLE modules are UMD modules that can bundle some or all of their dependencies. Unbundled dependencies of a JavaScript MLE module (i.e., any modules loaded via a call to require() within the context of the deployed module) are satisfied via in-language module imports.
[0312] The SIGNATURE clause of a call specification can refer to one of the exported functions of a JavaScript MLE module. When such a call specification is invoked, MLE loads the module in a manner similar to the require() function: it evaluates the contents of the module, looks up the named function in the module.exports object, and calls it.
[0313] 18.7 Python MLE Module
[0314] Python MLE modules contain Python modules or packages. Modules and packages are a standard way to encapsulate code in Python and can be imported by other Python code using import statements.
[0315] A Python module is a collection of statements typically contained in a single source file. For example, the following logic represents a Python module that defines two functions:
[0316] def_square(val):
[0317] return val*val
[0318] def squareAndAdd(val1,val2):
[0319] return_square(val1)+_square(val2)
[0320] Python modules do not explicitly export functions and values. Any identifier defined in the text of a Python module is accessible to code that imports it. However, identifier names beginning with an underscore ('_') are considered private by convention. All other definitions in the module text constitute the module's public API. When a module is imported, the import statement returns a module object that encapsulates all values (including functions) declared in the module text.
[0321] Python packages are a way to further organize large code bases. Packages can be thought of as directories in the file system that contain Python modules and can contain other packages. For example, the contents of the module above could be split into two separate modules (say, exports.py and helpers.py) and placed in a directory (say, pypackage) as follows.
[0322] The logic can be in helpers.py:
[0323] def square(val):
[0324] return val*val
[0325] The logic can be in exports.py:
[0326] from.import helpers
[0327] def squareAndAdd(val1,val2):
[0328] return helpers.square(val1)+helpers.square(val2)
[0329] The components of a package can be imported individually (e.g., import pypackage.exports ), or the package itself can be imported ( import pypackage ). In the latter case, the import statement returns an object whose contents are specified by the file init.py at the top level of the package directory hierarchy. For example, to make only the function squareAndAdd() available when the package pypackage is imported, the contents of init.py would look like this.
[0330] The logic can be init.py:
[0331] from.exports import squareAndAdd
[0332] The Python ecosystem has no direct counterpart to JavaScript's browserify or webpack. Dependencies are resolved at runtime by searching and loading modules and packages from the module search path. By creating a virtualenv, better encapsulation of an application's dependencies can be achieved. The virtualenv includes all of the application's dependencies, and application execution within the virtualenv modifies the module search path so that only the versions of dependencies installed within the virtualenv are visible. The dependency versions to be installed in the virtualenv are specified via a requirements.txt file, or alternatively, a Pipfile in conjunction with the pipenv utility.
[0333] A Python MLE module is a zip file containing a Python module or package, along with all or some of its dependencies, installed in a virtualenv. The bundled dependencies are placed in a .bundleddeps directory at the top level of the deployed zip. When the MLE module is executed, the bundled dependencies are placed on the module search path. Any dependencies that are not bundled should be satisfied through in-language module imports.
[0334] The SIGNATURE clause of a call specification can refer to any function defined in the Python MLE module:
[0335] If the Python MLE module includes a Python module, this includes all functions defined in that module, and
[0336] If a Python MLE module contains Python packages, this includes functions defined by the top-level package (via its init.py file) or by any of its submodules or subpackages.
[0337] Functions in submodules or subpackages can be referenced using Python's usual dot notation (e.g., exports.squareAndAdd for the example package pypackage discussed above). When such a calling specification is invoked, MLE loads the named module or package in a manner similar to a Python import statement, looks up the named function in the returned module object, and calls it. Note that the calling specification may not refer to functions defined in any bundled dependencies.
[0338] 18.8Java MLE Module
[0339] Java MLE modules contain Java modules. Java modules are a better way to encapsulate Java code. Specifically, a Java module can contain one or more Java packages. Packages defined in a Java module are internal to that module by default. Only packages that are explicitly exported (by marking them as such in the module's module-info) are accessible from outside the module. For example, a Java module (say, jmodule) can contain two packages, com.oracle.jmodule.dependencies and com.oracle.jmodule.exports, each with a single class, as shown below.
[0340] The logic can be in Helpers.java:
[0341]
[0342] The logic can be in Exports.java:
[0343]
[0344]
[0345] The package com.oracle.jmodule.exports can be exported via the module-info.java file at the top level of the module:
[0346] This can be module-info.java:
[0347] module jmodule{
[0348] exports com.oracle.jmodule.exports;
[0349] }
[0350] Java modules may require other Java modules. For example, a Java module (say, moduleA) can require another Java module (say, moduleB) by including the appropriate requires directive in its module-info:
[0351] module moduleA{
[0352] requires moduleB;
[0353] }
[0354] Thus, when ModuleA is executed, ModuleB should be present on the module path so that ModuleA can access any packages exported by ModuleB.
[0355] A Java MLE module is a zip file containing a Java module and some or all of the modules it requires. These bundled dependencies are placed in a .bundleddeps directory at the top level of the deployed zip and are placed on the module path when the MLE module is executed. Any required modules that are not bundled should be available via in-language module imports.
[0356] The SIGNATURE clause of a call specification can reference any public static method of a class in the Java MLE module's exports package. For the example shown above, the function should be referenced by its fully qualified name (e.g., com.oracle.jmodule.exports.Exports.squareAndAdd). When such a call specification is invoked, MLE loads the named class and calls the specified static method.
[0357] 18.9 Creating a Calling Specification
[0358] By creating PL / SQL call specifications for functions exported by a deployed MLE module, the exported functions can be made available for calls from both PL / SQL and SQL. These MLE functions can then be called from anywhere a PL / SQL function or procedure can be called (e.g., in an SQL query, from within a PL / SQL program including an anonymous block, as a virtual column).
[0359] Let's look again at the example of the deployed module jsmodule described above. The MLE module jsmodule exports two functions: the doNothing() function that takes a string argument as input and does nothing, and the concat() function that takes two string arguments as input and returns the concatenated string as the result.
[0360] Since doNothing() doesn't return anything, you can't create a PL / SQL function for it. Instead, create a PL / SQL procedure:
[0361] CREATE OR REPLACE PROCEDURE
[0362] doNothing(str IN VARCHAR2)AS MLE MODULE jsmodule
[0363] SIGNATURE'doNothing(str string)';
[0364] The above call specification creates a PL / SQL procedure named doNothing() in the current user's schema. Executing this procedure will execute the exported function doNothing() in the JavaScript module jsmodule.<module name> Specifies the name of the MLE module that exports the underlying MLE language function. The SIGNATURE clause specifies the name of the exported function to be called (doNothing()), as well as its argument types. The types specified in the SIGNATURE clause are specific to the MLE language. MLE functions implemented in JavaScript use the TypeScript types in the SIGNATURE clause. In this case, the function accepts a JavaScript string; the PL / SQL VARCHAR2 string is converted to a JavaScript string before calling the underlying JavaScript implementation.
[0365] Another exported function, concat(), can be similarly used to create PL / SQL functions:
[0366] CREATE OR REPLACE FUNCTION concat
[0367] RETURN VARCHAR2
[0368] AS MLE MODULE jsmodule
[0369] SIGNATURE'concat(str1 string,str2 string)';
[0370] In this case, the calling specification additionally specifies the PL / SQL return type of the created function. The value returned by the JavaScript function concat() (of type string) is converted to the RDBMS data type (VARCHAR2). The created procedure and function can be called as usual:
[0371] SQL>CALL doNothing('unused');
[0372] SQL>SELECT concat('Hello,','World!')FROM dual; SELECT CONCAT('HELLO','World!')FROM DUAL
[0373] ------------------------------------------
[0374] Hello, World!
[0375] 18.10 Support for OUT and IN / OUT parameters
[0376] Just like regular PL / SQL functions and stored procedures, MLE functions support IN / OUT and OUT parameters in addition to IN parameters. In the PL / SQL call specification for an MLE function, these parameters are declared as IN / OUT and OUT parameters as usual. The handling of these parameters in the underlying MLE language implementation is language-specific.
[0377] Since JavaScript has no concept of output parameters, JavaScript implementations instead accept objects that wrap the parameter values. Specifically, the shape of these wrapper objects is described by the generic interfaces InOut and Out (for IN / OUT and OUT parameters, respectively), as shown below.
[0378] InOut <t>interface:
[0379] interface InOut <t>{
[0380] value:T;
[0381] }
[0382] Out <t>interface:
[0383] interface Out <t>{value:T;
[0384] }
[0385] For example, an MLE function that accepts a single VARCHAR2 IN / OUT argument, replaces all occurrences of World with Universe, and returns the number of occurrences of World in the original string:
[0386] CREATE OR REPLACE PROCEDURE
[0387] substituteWorld(str INOUT VARCHAR2)RETURN NUMBER AS MLE
[0388] MODULE inOutParamExample
[0389] SIGNATURE'substituteWorld(str InOut <string>)';
[0390] The underlying JavaScript module bar can be implemented as follows:
[0391]
[0392]
[0393] The SIGNATURE clause of the calling specification lists the parameter type of the JavaScript function as InOut <string>Thus, the input VARCHAR2 value is converted to a JavaScript string, which is then wrapped in an object and passed to the JavaScript function substituteWorld().
[0394] 18.11 JavaScript MLE module calling conventions
[0395] The SIGNATURE clause of a call specification can refer to one of the exported functions of a JavaScript MLE module. When such a call specification is invoked, MLE loads the module in a manner similar to the require() function: it evaluates the contents of the module, looks up the named function in the module.exports object, and calls it.
[0396] 18.12 Python MLE module calling convention
[0397] The SIGNATURE clause of a call specification can refer to any function defined in the Python MLE module:
[0398] If the Python MLE module includes a Python module, this includes all functions defined in that module, and
[0399] If a Python MLE module contains Python packages, this includes functions defined by the top-level package (via its init.py file) or by any of its submodules or subpackages.
[0400] Functions in submodules or subpackages can be referenced using Python's usual dot notation (e.g., exports.squareAndAdd for the example package pypackage discussed above). When such a calling specification is invoked, MLE loads the named module or package in a manner similar to a Python import statement, looks up the named function in the returned module object, and calls it. Note that the calling specification may not refer to functions defined in any bundled dependencies.
[0401] 18.13 Java MLE Module Calling Conventions
[0402] The SIGNATURE clause of a call specification can reference any public static method of a class in the Java MLE module's exports package. For the example shown above, the function should be referenced by its fully qualified name (e.g., com.oracle.jmodule.exports.Exports.squareAndAdd). When such a call specification is invoked, MLE loads the named class and calls the specified static method.
[0403] 18.14 Module Metadata
[0404] MLE modules can carry optional metadata in the form of a version string and free-form JSON value metadata. Both types of metadata are purely informational and do not affect the behavior of MLE. When creating an MLE module, you can specify a version string:
[0405] CREATE MLE MODULE scott."validator"
[0406] LANGUAGE JAVASCRIPT
[0407] VERSION'10.11.0'
[0408] AS module.exports.func=function(){...}
[0409] The JSON metadata for an MLE module can be set or replaced using the ALTER MLE MODULE DDL:
[0410] ALTER MLE MODULE mymodule SET METADATA
[0411] <json-valued-metadata>
[0412] MLE does not mandate a specific usage of JSON metadata fields.
[0413] 18.15 Runtime State Isolation for the MLE Calling Specification
[0414] PL / SQL calls to MLE functions via a calling convention execute within an execution context determined by the MLE module and the user on whose behalf the call is being made. Within a session, MLE uses a dedicated execution context for each MLE module called from SQL or PL / SQL. MLE also separates the execution contexts of MLE modules by user. For the duration of a session, all SQL or PL / SQL calls on behalf of the same user to MLE functions exported by the same module execute within the same execution context. The execution context for an MLE module is created lazily when a user first calls a function exported from SQL or PL / SQL by the module in a session.
[0415] Therefore, the runtime state of MLE modules executed on behalf of different users and with different privilege levels is completely separated. In addition, the runtime state of separate MLE modules called from SQL or PL / SQL is completely separated.
[0416] This is best illustrated by an example with two MLE modules, ModuleA and ModuleB. ModuleA exports two functions, funcl() and func2(), while ModuleB exports one function, func3() (signatures abbreviated):
[0417] CREATE MLE MODULE ModuleA LANGUAGE JAVASCRIPT AS...;
[0418] CREATE FUNCTION func1(...)RETURNS...AS MLE MODULE ModuleA SIGNATURE'func1(...)';
[0419] CREATE FUNCTION func2(...)RETURNS...AS MLE MODULE ModuleA SIGNATURE'func2(...)';
[0420] CREATE MLE MODULE ModuleB LANGUAGE JAVASCRIPT AS...;
[0421] CREATE FUNCTION func3(...)RETURNS...AS MLE MODULE ModuleB SIGNATURE'func3(...)';
[0422] All calls to func1() and func2() from SQL or PL / SQL executed on behalf of User1 use one execution context, while calls to the same functions from User2 use a separate execution context. Similarly, calls to func3() by User1 use a separate execution context from calls to func1() and func2() because func3() is exported by a different MLE module (ModuleB).
[0423] Thus, if a PL / SQL call specification for a function exported by an MLE module is declared (e.g., DDL) as a definer's right, there will be one execution context for that module in the session, since all execution occurs under the definer's right. On the other hand, for a call specification with a caller's right, each calling user will have a separate execution context.
[0424] Note that if an MLE module (say, ModuleB) is imported by another MLE module (say, ModuleA), the code from ModuleB is executed in the same execution context as ModuleA. In this case, the code of ModuleB is loaded into the execution context of ModuleA.
[0425] 18.16 Importing between MLE modules
[0426] Functions exported by an MLE module can be called from SQL and PL / SQL using calling conventions. Furthermore, functionality in an MLE module can be reused by other MLE language code outside of the MLE module itself. MLE language code in an existing execution context can import code from an MLE module in the same language using the language's native import mechanism.
[0427] Here is a JavaScript MLE module scott.hello that exports a function format:
[0428] CREATE MLE MODULE scott."hello"
[0429] LANGUAGE JAVASCRIPT AS
[0430] module.exports.format=function(person){
[0431] return'Hello,'+person+'! '
[0432] }
[0433] The MLE module scott.hello can be used directly from SQL and PL / SQL by using the calling convention:
[0434] CREATE FUNCTION scott.hello_format(name IN VARCHAR2)
[0435] RETURNS VARCHAR2 AS MLE MODULE scott."hello"SIGNATURE
[0436] 'format';
[0437] SELECT scott.hello_format('Larry')FROM dual;
[0438] This query returns the string 'Hello, Larry! '.
[0439] The MLE JavaScript runtime provides the familiar JavaScript function require() to import JavaScriptMLE modules. When the call require('hello') is executed, MLE resolves the import name 'hello' to the MLE module schema object scott.hello , loads the source attached to scott.hello as a UMD module and returns the result.
[0440] Import names are resolved to MLE module schema objects using the environment mechanism described elsewhere in this document. Similarly, functionality from the MLE module scott.hello can be used by other MLE modules. Here, the code in the MLE module scott.mymodule imports scott.hello:
[0441] CREATE MLE MODULE scott."mymodule"
[0442] LANGUAGE JAVASCRIPT
[0443] ENV scott."myenv"AS
[0444] var hello=require('hello'); module.exports.printHello=
[0445] function(person){
[0446] console.log(hello.format(person)+'(call spec)');
[0447] };
[0448] CREATE PROCEDURE scott.print_hello(name IN VARCHAR2)AS
[0449] MLE MODULE scott."mymodule"SIGNATURE'printHello';
[0450] Using the environment scott.myenv, the import name 'hello' is resolved to the MLE module schema object scott.hello. Resolution of imported names by environments is described elsewhere in this document.
[0451] The call specification scott.print_hello can then be called from PL / SQL:
[0452] BEGIN
[0453] scott.print_hello('Larry');
[0454] END;
[0455] Executing this PL / SQL block produces the following output:
[0456] Hello, Larry! (call spec)
[0457] 18.17 Module Imports and Execution Context
[0458] When the code of an MLE module is imported, it runs in the same execution context as the importing code. In the first scenario, the function form exported by the MLE module hello is called from SQL. Here, the code of the MLE module hello runs in a dedicated execution context. In the second scenario, the code of the MLE module hello is imported by the MLE module mymodule. Here, the function printHello exported by the module mymodule is called from PL / SQL. Thus, consistent with REF, mymodule executes in a dedicated execution context. On the other hand, the module hello is imported from mymodule into an existing execution context.
[0459] MLE's use of execution context can be summarized as follows:
[0460] Calls from SQL and PL / SQL to functions exported by an MLE module are executed in an execution context dedicated to the MLE module and the user on whose behalf the call is being executed.
[0461] An MLE module imported by MLE language code in an existing execution context runs in the same execution context as the importing code. Code in the imported module runs with the same permissions as the importing code.
[0462] 18.18 Context
[0463] In this example implementation, the environment or context environment can be a guest virtual environment. MLE uses an execution context to execute MLE language code. As previously described, the execution context is used both to execute dynamic MLE code segments and to call PL / SQL call specifications. MLE allows certain properties of the execution context to be configured via the environment. The execution context can be configured to use a specific environment. The execution context is then established using all properties defined in the environment. Specifically, the environment allows language options to be set to customize the MLE language runtime within the execution context, enables specific MLE modules to be imported within the execution context, and manages dependencies.
[0464] The following describes how to create an environment and how to use it to define the properties of a dynamic MLE context and the execution context of an MLE module. It also describes how to use environments to configure language options and enable MLE module import. An environment is a first-class schema object that can be managed and reused across multiple execution contexts. An environment is created using the CREATE MLE ENV DDL statement. It can be created as a fresh, empty environment:
[0465] CREATE MLE ENV scott."myenv";
[0466] Alternatively, an environment can be created as a standalone copy of an existing environment.
[0467] CREATE MLE ENV scott."myenv"CLONE <other-env>;
[0468] Note that when cloning an environment, subsequent modifications to the original environment are not propagated to the cloned environment. Cloning of environments is particularly useful for creating modified versions of the default environments provided by MLE.
[0469] You cannot modify the context properties defined in the environment for an existing execution context. Only the environment settings made when the context is created are valid for that execution context. Contexts used for MLE module calls from SQL or PL / SQL are created implicitly on demand.
[0470] 18.19 Default Environment
[0471] MLE provides a default environment object that specifies default properties for the execution context. If no environment is explicitly specified on an MLE module, the default environment is used implicitly. The default environment sets default language options. It also provides import mappings for the built-in MLE modules described elsewhere in this document.
[0472] At the database level, the default environment is defined using the initialization parameter MLE_DEFAULT_ENV. This parameter specifies the name of the schema object for the default environment. Access to the default environment must be granted to PUBLIC. The MLE_DEFAULT_ENV parameter can be modified for the duration of a session using the ALTER SESSION SET MLE_DEFAULT_ENV=<...> command. Like any initialization parameter, the current effective setting of MLE_DEFAULT_ENV can be obtained using the SHOW PARAMETERS command or the v$parameters view. Beyond the first release of MLE, future releases may configure a new default environment, for example to set new language options or to introduce new built-in MLE modules. However, this will only provide new environment objects and change the default setting of MLE_DEFAULT_ENV. The schema objects used for the previous default environment will remain unchanged. Existing MLE modules that reference specific schema objects will not be affected by the new default environment.
[0473] 18.20 Specifying Environments on MLE Modules
[0474] An MLE module called from PL / SQL via a calling specification executes in its own execution context. When called from PL / SQL, each MLE module specifies an environment that defines the properties of the execution context. However, note that when an MLE module is imported by another MLE module, the environment defined for that MLE module is not used.
[0475] When you create an MLE module using the CREATE MLE MODULE DDL statement, you define the environment for the MLE module:
[0476] CREATE MLE MODULE mymodule LANGUAGE JAVASCRIPT ENV scott."myenv"AS...;
[0477] If the ENV clause is omitted, the default environment is used. When an MLE module is created, the environment (specified explicitly or implicitly) is stored as part of the module definition. If an MLE module is created without explicitly specifying an environment, then selecting a new default environment at the instance or session level has no effect on the MLE module. This allows MLE to provide new default environments in future releases without breaking application code. Existing MLE modules will need to be modified to explicitly use the new environment. The environment of an existing MLE module object can be changed using the ALTER MLE MODULE command:
[0478] ALTER MLE MODULE mymodule ENV myenv
[0479] 18.21 Language Options
[0480] MLE allows you to customize the MLE language runtime by setting language options. For example, language options can enable or disable builtins that are not covered by the language standard. They can also be used to select a specific version of the language standard. MLE language options can be directly mapped to GraalVM language options. However, MLE only allows a whitelisted subset of GraalVM language options that are considered stable, user-facing, and supported.
[0481] Language options are configured for an execution context via language options on the environment. Each execution context created has all language options defined in its environment set. Language options are defined on an environment using the ALTER MLE ENV DDL statement. For example, an existing environment can be modified to enable JavaScript "strict" mode which configures the Graal JavaScript language options as follows:
[0482] ALTER MLE ENV scott."myenv"SET LANGUAGE OPTIONS
[0483] 'js.strict=true';
[0484] SET LANGUAGE OPTIONS replaces the existing language options configured on the environment. Multiple language options can be set as a comma-separated list of <option-name (option name)> = <option-value (option value)> pairs.
[0485] 18.22 Import parsing
[0486] Code that imports MLE modules can be imported within the existing execution context. Returning to the above example of using the JavaScript require() function to import another MLE module. In order to execute the call to require(), MLE needs to resolve the import name 'hello' to the schema object scott.hello. This requires a mapping from the import name to the schema object.
[0487] The environment maps import names to MLE module schema objects. The environment defines the MLE modules that can be imported within the execution context using that environment, and the import names with which those MLE modules can be imported. Specifically, assume the environment contains a mapping from the import name 'hello' to the MLE module scott.hello. In any execution context using that environment, JavaScript code can execute require('hello'), and the UMD module contained in scott.hello is loaded. Import mappings can be added to the environment using the ALTER MLE ENV DDL statement. For the above example, the import name 'hello' is added to the environment defined above:
[0488] ALTER MLE ENV scott."myenv"
[0489] ADD IMPORT hello MODULE scott."hello";
[0490] Import names in the environment must be unique. If an import name is added to an environment that already contains that name, an error is thrown. The environment defines the complete set of MLE modules that can be imported within a given execution context. This environment must explicitly include all transitive dependencies.
[0491] The environment decouples the import name from the actual MLE module. By updating the environment, the import name defined in the environment can be redirected to a new MLE module. This allows for the introduction of a new version of the dependency. It is the responsibility of the owner of the environment to ensure that the new version of the dependency is compatible with the code using the environment. Using the ALTER MLE ENV command, import mappings can be removed from the environment or modified to point to a different MLE module.
[0492] 18.23 JavaScript Import Names
[0493] A JavaScript MLE module is a single UMD module. In the MLE JavaScript runtime, the environment defines the search path for UMD modules: any import name defined in the environment that maps to a JavaScript MLE module (i.e., a UMD module) can be resolved with require. For example, executing require('validator') in the MLE JavaScript runtime first consults the execution context's environment to find a mapping for the import name validator. If the mapping refers to a JavaScript MLE module (e.g., scott.validator), the UMD module contained in that MLE module is retrieved, loaded by the UMD module loader, and the resulting value is returned. If the mapping for the import name validator does not exist or refers to an MLE module in a different MLE language, a PL / SQL runtime error is thrown.
[0494] 18.24 Python module import
[0495] A Python MLE module is a single Python module or Python package. When creating an execution context, the virtual environment is used as follows: for all mappings in the virtual environment that reference a Python MLE module, code units (i.e., .py modules or .zip archives) are extracted according to the import name used in the mapping and placed in a directory in the execution context's virtual file system. The Python engine's sys.path search path is then extended with all such directories. Thus, name resolution during Python imports follows normal Python rules based on sys.path.
[0496] 18.25 Built-in MLE module
[0497] MLE provides built-in modules. A prominent example is the MLE SQL driver. MLE can treat built-in modules similarly to user-defined MLE modules, using the same import mechanism. The only difference is that built-in modules are associated with the system schema.
[0498] 18.26 Creating an MLE Language
[0499] New MLE languages can be added to the database by using the CREATE MLE LANGUAGE DDL:
[0500] CREATE MLE LANGUAGE <schema>.]MYLANGUAGE;
[0501] The added language should be supported by the MLE version included in the database. MLE language objects are created in different MLE namespaces. Creating a new MLE language in its own schema requires the CREATE MLE LANGUAGE privilege, while creating a new MLE language in any schema requires the CREATE ANY MLE LANGUAGE privilege.
[0502] 18.27 Delete MLE language
[0503] The MLE language can be removed from the database by using the DROP MLE LANGUAGE DDL:
[0504] DROP MLE LANGUAGE[ <schema>.]MYLANGUAGE;
[0505] Dropping an MLE language in its own schema requires the DROP MLE LANGUAGE privilege, while dropping an MLE language in any schema requires the DROP ANY MLE LANGUAGE privilege.
[0506] 18.28 Management Environment
[0507] You create an environment using the CREATE MLE ENV DDL statement. You can create an environment as a fresh, empty environment or by cloning an existing environment. Cloning an environment creates an independent copy that is unaffected by subsequent changes to the original environment. You remove an existing environment using the DROP MLE ENV DDL statement, as shown below.
[0508] DROP MLE ENV[ <schema> .] <name>;
[0509] You can use the ALTER MLE ENV DDL statement to modify an existing environment. You can add, remove, or change mappings for imported names. Additionally, you can set language options.
[0510] The ADD IMPORT clause adds a new mapping from an import name to an MLE module schema object. If the environment already contains that import name, an error is thrown.
[0511] The DROP IMPORT clause removes an import name from the environment. If the environment does not contain the specified import name, an error is thrown.
[0512] ALTER IMPORT modifies the import mapping so that the import name refers to a different MLE module schema object. If the environment does not contain the import name, an error is thrown.
[0513] The LANGUAGE OPTIONS clause on an MLE environment specifies language options to be set for all execution contexts created using that environment. Language options are specified as a string literal consisting of comma-separated key-value pairs. Language options are only parsed at runtime when an execution context is created using the MLE environment. If the language options string turns out to be invalid (invalid format, unsupported options) at context creation time, an error is thrown.
[0514] 18.29 Creating an MLE Module
[0515] Use CREATE MLE MODULE DDL to create an MLE module:
[0516] CREATE[OR REPLACE]MLE MODULE[ <module-schema> .] <name>
[0517] LANGUAGE[ <language-schema> .] <mle-language>[ENV
[0518] [ <language-schema> .] <mle-env>]
[0519] [VERSION' <version-string>']
[0520] {USING
[0521] {BFILE(<directory object name> ,<server file name> )|
[0522] {CLOB|BLOB|BFILE}<selection clause>}|
[0523] AS<module text>}
[0524] The CREATE OR REPLACE clause specifies that a new MLE module should be created (CREATE) or an existing MLE module should be replaced (CREATE OR REPLACE).
[0525] CREATE MLE MODULE (without a REPLACE clause) throws an error if an MLE module with the given name already exists. With CREATE OR REPLACE MLE MODULE, the existing module is replaced if it exists, otherwise a new module is created. When an MLE module is replaced, there is no need to regrant permissions on that MLE module.
[0526] Users who create or replace MLE modules in their own schemas require the CREATE MLE MODULE privilege, while users who create or replace MLE modules in other users' schemas require the CREATE ANY MLE MODULE privilege.
[0527] The name of the module to be created can be fully qualified, i.e. include both the schema and the name of the module to be created within that schema. If the schema is not specified, the module is created in the current user's schema. Unless enclosed in double quotes, <module-schema> 、 <name> 、 <language-schema>and <mle-language>Similar to the MLE language, MLE modules are created in the MLE namespace.
[0528] The LANGUAGE clause specifies the MLE language of the created module. The specified language should be one of the languages created via the CREATE MLELANGUAGE DDL statement. If an unsupported MLE language is used, an error is thrown.
[0529] The optional ENV clause specifies the MLE environment for the created module. If the specified environment schema object does not exist, an error is thrown.
[0530] The optional VERSION clause specifies the version string of the MLE module.
[0531] The USING clause enables the creation of an MLE module from code contained in a CLOB, BLOB, or BFILE.
[0532] The BFILE clause specifies the directory of the file holding the contents of the MLE module to be deployed (<directory objectname> ) and the file name (<server_file_name> ). The directory object should have been created using, for example, the CREATE DIRECTORY statement.
[0533] The CLOB|BLOB|BFILE clause specifies a subquery whose result should be a single row and column of the specified type (CLOB, BLOB, or BFILE) holding the contents of the MLE module being deployed. The CLOB option is available only when the MLE module being deployed contains only text data. This is true for JavaScript, the only currently supported MLE language, but may not be true for other MLE languages added in the future. For MLE modules contained in BLOBs and BFILEs, any text data is assumed to be encoded in the database character set.
[0534] The AS clause specifies the contents of a deployed MLE module as a character sequence inlined within a DDL statement. As with CLOB, the AS clause is only applicable if the source of the MLE module contains only textual data. The character sequence should not be enclosed in quotes. Instead, the character sequence is delimited only by the end of the DDL statement.
[0535] Remove the previously deployed MLE module by using the DROP MLE MODULE DDL:
[0536] DROP MLE MODULE[ <schema> .] <name>
[0537] The DROP statement specifies the name of the module to be removed and, optionally, the schema. If no schema is specified, the current user's schema is assumed. If the module to be removed does not exist, the DROP MLE MODULE statement raises an error.
[0538] The properties of a deployed MLE module can be assigned or changed using the ALTER MLE MODULE DDL statement:
[0539] ALTER MLE MODULE[ <schema> .] <name>SET
[0540] {ENV <mle-env>|METADATA <json>}
[0541] The ALTER MLE MODULE statement specifies the name and, optionally, the schema of the module to be altered. If no schema is specified, the current user's schema is assumed. If the module does not exist, or if invalid attributes are specified, the ALTER MLE MODULE statement raises an error.
[0542] The SET ENV clause configures a new environment for the MLE module. Any execution context subsequently created for the MLE module is configured according to the new environment. An error is thrown in the following cases:
[0543] If the specified environment does not exist, an error is thrown.
[0544] If the environment does not exist in the same schema as the MLE module being changed, an error is thrown.
[0545] 18.30 Creation of MLE Calling Specification
[0546] Functions exported by deployed MLE modules can be used to create PL / SQL call specifications that can be called from anywhere that regular PL / SQL functions and procedures can be called. These call specifications are created using the familiar CREATE FUNCTION and CREATE PROCEDURE syntax, along with some MLE-specific elements:
[0547] CREATE[OR REPLACE]{FUNCTION|PROCEDURE}
[0548] [ <schema>.]<call_spec_name>[(param_declaration[,]...) ]
[0550] [RETURN datatype]
[0551] [{invoker_rights_clause|DETERMINISTIC|
[0552] parallel_enable_clause|result_cache_clause}]
[0553] {AS|IS}MLE MODULE[ <schema>.]<module_name>
[0554] SIGNATURE'<function_name_in_module> [(
[0555] mle_param_declaration)]';
[0556] Most components of the CREATE FUNCTION and CREATE PROCEDURE statements have the same semantics as their counterparts when creating a PL / SQL UDF or stored procedure:
[0557] OR REPLACE specifies that the function should be recreated if it already exists. This clause can be used to alter the definition of an existing function without dropping, recreating, and regranting object privileges previously granted on the function. Users previously granted privileges on the redefined function / procedure can still access the function without having to regrant privileges.
[0558] schema specifies the schema that the call specification will contain. If schema is omitted, the call specification is created in the current user's schema.
[0559] call_spec_name specifies the name of the calling specification to be created. Unlike MLE modules and MLE languages, which use the MLE namespace, calling specifications are created in the default namespace.
[0560] param_declaration specifies the parameters of the calling specification.
[0561] RETURN datatype is used only for UDFs and specifies the data type of the function's return value. The return value can have any data type supported by PL / SQL. Specify only the data type; length, precision, or scale information should be omitted. The invoker_rights_clause specifies whether the function is invoker's rights or definer's rights.
[0562] AUTHID CURRENT_USER creates a caller rights function, that is, the function is executed with the permissions of CURRENT_USER.
[0563] AUTHID DEFINER creates a definer rights function, that is, the function / procedure is executed with the privileges of the owner of the schema in which the function / procedure resides, and external names are resolved in that schema. This is the default.
[0564] DETERMINISTIC is used only with UDFs and indicates that the function returns the same result value each time it is called with the same values for its arguments. As with PL / SQL functions, this clause should not be used with functions that access the database in any way that might affect the function's return value. If the database chooses not to re-execute the function, the results of doing so will not be captured.
[0565] The parallel_enable_clause is used only for UDFs and is an optimization hint that indicates that the function can be executed from a parallel execution server for parallel query operations.
[0566] The MLE MODULE and SIGNATURE clauses are specific to MLE and are described below. The MLE MODULE clause specifies a deployed MLE module that exports the underlying MLE language functions for the call specification.<module_name> is the name of a deployed MLE module that exports the MLE language function specified in the SIGNATURE clause, and may or may not be fully qualified. The specified module should always be in the same schema as the calling specification being created. If the specified MLE module does not exist or is in a different schema than the calling specification being created, an error is thrown.
[0567] The SIGNATURE clause contains all the information needed to map the MLE function created by this calling specification to the specific function exported by the specified MLE module. In particular, it includes three pieces of information:
[0568] function_name_in_module specifies the name of the exported function in the MLE module
[0569] mle_param_declaration specifies the MLE language parameter types of the function (as opposed to PL / SQL parameter types) (optional)
[0570] function_name_in_module can include any alphanumeric characters as well as underscores ('_') and periods ('.').
[0571] Note that syntax parsing and analysis of the SIGNATURE clause occurs lazily, when the MLE function is first executed. Any parsing or syntax errors in the SIGNATURE clause are reported only at that time, not when the calling specification is created.
[0572] An mle_param_declaration has the following form:
[0573] mle_param_declaration::=[<argument_name>
[0574] <mle-language-type>[,]...]
[0575] MLE-language-type can be a built-in type of the MLE language (e.g., JavaScript's string or number) or a type provided by the MLE (e.g., OracleNumber or OracleDate).
[0576] mle_param_declaration can be omitted entirely from the SIGNATURE clause. In this case, the default PL / SQL-MLE language type mapping is used. The encoding used to specify the SIGNATURE clause should be the same as the database character set.
[0577] 19.0 Database Overview
[0578] Embodiments of the present invention are used in the context of a database management system (DBMS). Accordingly, a description of an example DBMS is provided.
[0579] Typically, a server, such as a database server, is a combination of integrated software components and allocations of computing resources (such as memory, nodes, and processes on those nodes) for executing the integrated software components, where the combination of software and computing resources is dedicated to providing a specific type of functionality on behalf of the server's clients. A database server manages and facilitates access to a specific database, processing client requests to access the database.
[0580] A user interacts with the database server of a DBMS by submitting commands to the database server that cause the database server to operate on the data stored in the database. A user can be one or more applications running on a client computer that interacts with the database server. In this article, multiple users may also be collectively referred to as users.
[0581] A database consists of data stored on persistent storage, such as a set of hard disks, and a database dictionary. A database is defined by its own independent database dictionary. The database dictionary contains metadata that defines the database objects contained within the database. In practice, the database dictionary defines the majority of the database. Database objects include tables, table columns, and tablespaces. A tablespace is a set of one or more files used to store data for various types of database objects, such as tables. If the data for a database object is stored in a tablespace, the database dictionary maps the database object to the tablespace or tables that hold the database object's data.
[0582] The DBMS refers to the database dictionary to determine how to execute database commands submitted to the DBMS. Database commands can access database objects defined by the dictionary.
[0583] Database commands can be in the form of database statements. In order for a database server to process database statements, the database statements must conform to the database language supported by the database server. A non-limiting example of a database language supported by many database servers is SQL, including proprietary forms of SQL supported by database servers such as Oracle (e.g., Oracle Database 11g). SQL data definition language ("DDL") instructions are sent to a database server to create or configure database objects, such as tables, views, or complex types. Data manipulation language ("DML") instructions are sent to a DBMS to manage data stored within a database structure. For example, SELECT, INSERT, UPDATE, and DELETE are common examples of DML instructions that exist in some SQL implementations. SQL / XML is a common extension of SQL used when manipulating XML data in an object-relational database.
[0584] A multi-node database management system consists of interconnected nodes that share access to the same database. Typically, the nodes are interconnected via a network and, to varying degrees, share access to shared storage, such as a set of disk drives and the data blocks stored thereon. The nodes in a multi-node database system can take the form of a group of computers (e.g., workstations, personal computers) interconnected via a network. Alternatively, the nodes can be nodes of a grid composed of nodes in the form of server blades interconnected with other server blades in a rack.
[0585] Each node in a multi-node database system hosts a database server. A server, such as a database server, is a combination of integrated software components and an allocation of computing resources (such as memory, nodes, and processes on the nodes) for executing the integrated software components on a processor. The combination of software and computing resources is dedicated to performing specific functions on behalf of one or more clients.
[0586] Resources from multiple nodes in a multi-node database system can be allocated to run the software for a particular database server. Each combination of software and allocation of resources from a node is referred to herein as a "server instance" or "instance" of the server. A database server can contain multiple database instances, some or all of which run on separate computers (including separate server blades).
[0587] 19.1 Query Processing
[0588] A query is an expression, command, or set of commands that, when executed, causes a server to perform one or more operations on a set of data. A query may specify source data object(s), such as table(s), column(s), view(s), or snapshot(s), from which result set(s) are to be determined. For example, source data object(s) may appear in the FROM clause of a Structured Query Language ("SQL") query. SQL is a well-known example language for querying database objects. As used herein, the term "query" is used to refer to any form of expressing a query, including queries in the form of database statements and any data structures used for internal query representation. The term "table" refers to any source object, such as a database table, view, or inline query block, such as an inline view or subquery, that is referenced or defined by a query and that represents a set of rows.
[0589] The query can operate on data from the source data object(s) row by row as the object(s) are loaded, or on the entire source data object(s) after the object(s) are loaded. The result set produced by one or more operations can be used by one or more other operations, and in this way, the result set can be filtered out or narrowed based on certain criteria, and / or joined or combined with other result set(s) and / or other source data object(s).
[0590] A subquery is a portion or component of a query that is distinct from the other portion(s) or component(s) of the query and can be evaluated separately from (i.e., as a separate query) the other portion(s) or component(s) of the query. The other portion(s) or component(s) of the query can form an outer query, which may or may not include other subqueries. When computing a result for the outer query, subqueries nested within the outer query can be evaluated separately, one or more times, while computing a result for the outer query.
[0591] Typically, a query analyzer receives a query statement and generates an internal query representation of the query statement. Typically, the internal query representation is a set of interconnected data structures that represent the various components and structures of the query statement.
[0592] The internal query representation can be in the form of a node graph, with each interconnected data structure corresponding to a node and corresponding to a component of the represented query statement. The internal representation is typically generated in memory for evaluation, manipulation, and transformation.
[0593] Hardware Overview
[0594] According to one embodiment, the technology described herein is implemented by one or more special-purpose computing devices. The special-purpose computing device may be hard-wired to implement the technology, or may include a digital electronic device permanently programmed to implement the technology, such as one or more application-specific integrated circuits (ASICs) or field programmable gate arrays (FPGAs), or may include one or more general-purpose hardware processors programmed to implement the technology according to program instructions in firmware, memory, other storage devices, or a combination thereof. Such a special-purpose computing device may also combine customized hard-wired logic, ASICs, or FPGAs with customized programming to implement the technology. The special-purpose computing device may be a desktop computer system, a portable computer system, a handheld device, a networking device, or any other device that contains hard-wiring and / or program logic to implement the technology.
[0595] For example, Figure 18 1 is a block diagram illustrating a computer system 1800 upon which embodiments of the present invention may be implemented. Computer system 1800 includes a bus 1802 or other communication mechanism for communicating information, and a hardware processor 1804 coupled to bus 1802 for processing information. For example, hardware processor 1804 may be a general-purpose microprocessor.
[0596] Computer system 1800 also includes a main memory 1806, such as a random access memory (RAM) or other dynamic storage device, coupled to bus 1802 for storing information and instructions to be executed by processor 1804. Main memory 1806 may also be used to store temporary variables or other intermediate information during execution of instructions by processor 1804. When stored in a non-transitory storage medium accessible to processor 1804, such instructions cause computer system 1800 to become a special-purpose machine customized to perform the operations specified in the instructions.
[0597] Computer system 1800 also includes a read-only memory (ROM) 1808 or other static storage device coupled to bus 1802 for storing static information and instructions for processor 1804. A storage device 1810, such as a magnetic disk, optical disk, or solid-state drive, is provided and coupled to bus 1802 for storing information and instructions.
[0598] The computer system 1800 may be coupled to a display 1812, such as a cathode ray tube (CRT), via bus 1802 for displaying information to a computer user. An input device 1814, including alphanumeric and other keys, is coupled to bus 1802 for communicating information and command selections to processor 1804. Another user input device is a cursor control 1816, such as a mouse, trackball, or cursor direction keys, for communicating direction information and command selections to processor 1804 and for controlling cursor movement on display 1812. Such input devices typically have two degrees of freedom, i.e., a first axis (e.g., x) and a second axis (e.g., y), that allow the device to specify a position in a plane.
[0599] Computer system 1800 can implement the techniques described herein using custom hardwired logic, one or more ASICs or FPGAs, firmware, and / or program logic that is incorporated into the computer system to make or program computer system 1800 into a special-purpose machine. According to one embodiment, computer system 1800 performs the techniques described herein in response to processor 1804 executing one or more sequences of one or more instructions contained in main memory 1806. Such instructions may be read into main memory 1806 from other storage media, such as storage device 1810. Execution of the sequences of instructions contained in main memory 1806 causes processor 1804 to perform the process steps described herein. In alternative embodiments, hardwired circuitry may be used in place of or in combination with software instructions.
[0600] As used herein, the term "storage medium" refers to any non-transitory medium that stores data and / or instructions that cause a machine to operate in a specific manner. Such storage media may include non-volatile media and / or volatile media. For example, non-volatile media include optical disks, magnetic disks, or solid-state drives, such as storage device 1810. Volatile media include dynamic memory, such as main memory 1806. For example, common forms of storage media include floppy disks, flexible disks, hard disks, solid-state drives, magnetic tape, or any other magnetic data storage medium, CD-ROMs, any other optical data storage medium, any physical medium with various aperture patterns, RAM, PROM, EPROM, FLASH-EPROM, NVRAM, any other memory chip, or cartridge memory.
[0601] Storage media are distinct from transmission media, but can be used in conjunction with them. Transmission media participate in the transfer of information between storage media. For example, transmission media include coaxial cables, copper wire, and optical fiber, including the wires that comprise bus 1802. Transmission media can also take the form of acoustic or light waves, such as those generated during radio wave and infrared data communications.
[0602] When one or more sequences of one or more instructions are transmitted to processor 1804 for execution, various forms of media may be involved. For example, the instructions may initially be carried on a disk or solid-state drive of a remote computer. The remote computer may load the instructions into its dynamic memory and send the instructions over a telephone line using a modem. A modem local to computer system 1800 may receive the data over the telephone line and convert it into an infrared signal using an infrared transmitter. An infrared detector may receive the data carried in the infrared signal, and appropriate circuitry may place the data on bus 1802. Bus 1802 carries the data to main memory 1806, from which processor 1804 retrieves and executes the instructions. The instructions received by main memory 1806 may be stored on storage device 1810, either before or after execution by processor 1804, as appropriate.
[0603] Computer system 1800 also includes a communication interface 1818 coupled to bus 1802. Communication interface 1818 provides two-way data communication coupled to network link 1820, which is connected to local network 1822. For example, communication interface 1818 can be an integrated services digital network (ISDN) card, a cable modem, a satellite modem, or a modem that provides a data communication connection with a corresponding type of telephone line. For another example, communication interface 1818 can be a local area network (LAN) card that provides a data communication connection with a compatible LAN. Wireless links can also be implemented. In any such implementation, communication interface 1818 sends and receives electrical signals, electromagnetic signals, or optical signals that carry digital data streams representing various information.
[0604] Network link 1820 generally provides data communication through one or more networks to other data devices. For example, network link 1820 can provide a connection through local network 1822 to a host computer 1824 or to data equipment operated by an Internet Service Provider (ISP) 1826. ISP 1826, in turn, provides data communication services through the global packet data communication network now commonly referred to as the "Internet" 1828. Local network 1822 and Internet 1828 both use electrical, electromagnetic, or optical signals that carry digital data streams. The signals through the various networks and the signals that carry digital data to and from computer system 1800 on network link 1820 and through communication interface 1818 are example forms of transmission media.
[0605] Computer system 1800 can send messages and receive data, including program code, through the network(s), network link 1820, and communication interface 1818. In the Internet example, server 1830 can transmit the requested application code through Internet 1828, ISP 1826, local network 1822, and communication interface 1818.
[0606] The received code may be executed by processor 1804 as it is received and / or stored in storage device 1810 or other non-volatile storage for later execution.
[0607] Software Overview
[0608] Figure 19 1 is a block diagram of a basic software system 1900 that can be used to control the operation of computing system 1800. Software system 1900 and its components (including their connections, relationships, and functions) are merely exemplary and are not intended to limit implementation of the example embodiment(s). Other software systems suitable for implementing the example embodiment(s) may have different components, including components with different connections, relationships, and functions.
[0609] Software system 1900 is provided to direct the operation of computing system 1800. Software system 1900 includes a kernel or operating system (OS) 1910, which may be stored in system memory (RAM) 1806 and on fixed storage (eg, hard disk or flash memory) 1810.
[0610] The OS 1910 manages low-level aspects of computer operation, including managing the execution of processes, memory allocation, file input and output (I / O), and device I / O. One or more application programs, represented as 1902A, 1902B, 1902C ... 1902N, can be "loaded" (e.g., transferred from fixed storage 1810 to memory 1806) for execution by the system 1900. Applications or other software intended for use on the computer system 1800 may also be stored as a set of downloadable computer-executable instructions, for example, for download and installation from an Internet location (e.g., a web server, app store, or other online service).
[0611] Software system 1900 includes a graphical user interface (GUI) 1915 for receiving user commands and data graphically (e.g., "clicks" or "touch gestures"). System 1900 can, in turn, act on these inputs according to instructions from operating system 1910 and / or application(s) 1902. GUI 1915 is also used to display the results of operations from OS 1910 and application(s) 1902, allowing the user to provide additional input on the results of the operations or terminate the session (e.g., log out).
[0612] The OS 1910 may execute directly on the bare hardware 1920 (e.g., processor(s) 1804) of the computer system 1800. Alternatively, a hypervisor or virtual machine monitor (VMM) 1930 may be placed between the bare hardware 1920 and the OS 1910. In this configuration, the VMM 1930 acts as a software "buffer" or virtualization layer between the OS 1910 and the bare hardware 1920 of the computer system 1800.
[0613] VMM 1930 instantiates and runs one or more virtual machine instances ("guest machines"). Each guest machine includes a "guest" operating system, such as OS 1910, and one or more applications designed to execute on the guest operating system, such as application(s) 1902. VMM 1930 presents a virtual operating platform to the guest operating system and manages the execution of the guest operating system.
[0614] In some cases, VMM 1930 can allow a guest operating system to run as if it were running directly on the bare hardware 1920 of computer system 1900. In these cases, the same version of the guest operating system that is configured to execute directly on the bare hardware 1920 can also execute on VMM 1930 without modification or reconfiguration. In other words, in some cases, VMM 1930 can provide full hardware and CPU virtualization to the guest operating system.
[0615] In other cases, for efficiency reasons, the guest operating system may be specifically designed or configured to execute on VMM 1930. In these cases, the guest operating system "knows" that it is executing on a virtual machine monitor. In other words, in some cases, VMM 1930 may provide paravirtualization to the guest operating system.
[0616] A computer system process includes an allocation of hardware processor time and an allocation of (physical and / or virtual) memory for storing instructions executed by the hardware processor, for storing data generated by the hardware processor in executing the instructions, and / or for storing hardware processor state (e.g., the contents of registers) between allocations of hardware processor time when the computer system process is not running. A computer system process runs under the control of an operating system and may run under the control of other programs executing on the computer system.
[0617] cloud computing
[0618] The term "cloud computing" is generally used herein to describe a computing model that enables on-demand access to a shared pool of computing resources, such as computer networks, servers, software applications, and services, and allows resources to be rapidly provisioned and released with minimal management effort or service provider interaction.
[0619] Cloud computing environments (sometimes referred to as cloud environments or just clouds) can be implemented in a variety of different ways to best suit different needs. For example, in a public cloud environment, the underlying computing infrastructure is owned by the organization that makes its cloud services available to other organizations or the public. In contrast, a private cloud environment is typically used only by or within a single organization. A community cloud is intended to be shared by several organizations within a community, while a hybrid cloud comprises two or more types of clouds (e.g., private, community, or public) bound together by data and application portability.
[0620] In general, the cloud computing model enables some of the responsibilities that might previously have been provided by an organization's own information technology department to be delivered as a service layer within the cloud environment for consumption by consumers (either internal or external to the organization, depending on the public / private nature of the cloud). The precise definition of the components or features provided by or within each cloud service layer may vary depending on the specific implementation, but common examples include: Software as a Service (SaaS), in which consumers consume software applications running on cloud infrastructure, while the SaaS provider manages or controls the underlying cloud infrastructure and applications; Platform as a Service (PaaS), in which consumers can develop, deploy, and otherwise control their own applications using software programming languages and development tools supported by the PaaS provider, while the PaaS provider manages or controls other aspects of the cloud environment (i.e., everything below the runtime execution environment); and Infrastructure as a Service (IaaS), in which consumers can deploy and run arbitrary software applications and / or be provided with processing, storage, networking, and other basic computing resources, while the IaaS provider manages or controls the underlying physical cloud infrastructure (i.e., everything below the operating system layer). Database as a Service (DBaaS), in which the consumer uses a database server or database management system running on cloud infrastructure, while the DBaaS provider manages or controls the underlying cloud infrastructure and applications.
[0621] The above basic computer hardware and software and cloud computing environment are provided to illustrate the basic underlying computer components that can be used to implement the example embodiment(s). However, the example embodiment(s) are not necessarily limited to any particular computing environment or computing device configuration. Rather, the example embodiment(s) can be implemented in any type of system architecture or processing environment that, in light of this disclosure, one skilled in the art will understand is capable of supporting the features and functions of the example embodiment(s) presented herein.
[0622] In the foregoing description, embodiments of the present invention have been described with reference to numerous specific details that may vary from implementation to implementation. Accordingly, the description and drawings should be regarded as illustrative rather than restrictive. The sole and exclusive indicator of the scope of the present invention, and what the applicants intend as the scope of the invention, is the range of literal equivalents of the set of claims issued from this application in the specific form in which such claims are issued, including any subsequent amendments. < / schema> < / schema> < / json> < / name> < / schema> < / name> < / schema> < / name> < / module-schema> < / language-schema> < / language-schema> < / name> < / module-schema> < / name> < / schema> < / schema> < / schema> < / string> < / string> < / t> < / t> < / t> < / t> < / language-schema> < / language-schema> < / name> < / module-schema>
Claims
1. A computer-implemented method comprising: A first data manipulation language (DML) statement is executed in a first database session of a database management system (DBMS), the first DML statement invoking a guest programming language such that: performing a first import request native to the guest programming language to access the dependency by name, dynamically selecting a first guest module to satisfy the dependency based on: the first import request native to the guest programming language, and a first mapping defined in the DBMS, Executing a second DML statement in a second database session of the DBMS, the second DML statement invoking the same guest programming language such that: performing a second import request native to said guest programming language to access the dependency by the same said name, and dynamically selecting a second guest module to satisfy the dependency based on: the second import request native to the guest programming language, and a second mapping defined in the DBMS; in: the guest programming language is not native to the DBMS, The first guest module and the second guest module are implemented in the guest programming language, The first mapping is based on the first database session, a first mapping binding the name to a first guest module, The second mapping is based on the second database session, and The second mapping binds the same said name to a second guest module. 2 . The method of claim 1 , wherein executing the first import request natively in the guest programming language comprises interpreting imperative statements of a script in the guest programming language.
3. The method of claim 2, wherein the interpreting the imperative statements of the script in the guest programming language comprises parsing text and / or interpreting intermediate code generated from the script.
4. The method according to claim 1, The method includes invoking a third DML statement in the guest programming language within the same first database session.
5. The method of claim 1, wherein: The executing the first DML statement that calls the guest programming language includes: calling a first user-defined function (UDF) defined in a first guest module of the guest programming language, and calling a second UDF defined in a third guest module of the same guest programming language; The first UDF and the second UDF cannot share the same instance of the guest programming language's global variable.
6. The method of claim 1, wherein: said executing the first DML statement invoking the guest programming language comprises invoking a first subroutine defined in a first guest module of the guest programming language; The method further includes accessing a second subroutine defined in a third guest module of the same guest programming language; The first subroutine and the second subroutine share the same instance of a global variable of the guest programming language.
7. One or more non-transitory computer-readable media storing instructions that, when executed by one or more processors, cause the steps of the method of any one of claims 1 to 6 to be performed.
8. A computer system comprising: one or more processors; as well as One or more non-transitory computer-readable media storing instructions that, when executed by the one or more processors, cause the steps of the method of any one of claims 1-6 to be performed.
9. A computer program product comprising instructions which, when executed by a computer, cause the computer to perform the method according to any one of claims 1 to 6.
Citation Information
Patent Citations
Deployment of javascript and typescript stored procedures and user-defined functions into database management systems
US20190065552A1