Skip to content

Commit

Permalink
Merge pull request #214 from gramian/main
Browse files Browse the repository at this point in the history
Refactor and expand SQL Section
  • Loading branch information
lvca authored Nov 10, 2023
2 parents 8fa4f12 + 9172211 commit 2821469
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 72 deletions.
107 changes: 107 additions & 0 deletions src/main/asciidoc/sql/SQL-Custom-Functions.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
[[Custom-Functions]]
=== Custom Functions

The SQL engine can be extended with custom functions written with a scripting language or via Java.

[discrete]

==== Database's function

Look at the <<Database,Database Interface>> page.


[discrete]

==== Custom Functions in SQL

Custom functions can be defined via SQL using the following command:

----
DEFINE FUNCTION <library>.<name> "<body>" [PARAMETERS [<parameter>,*]] LANGUAGE <language>
----

* `<library>` A name space to group functions.
* `<name>` The function's name.
* `<body>` The function's body encapsuled in a string in the chosen language's syntax.
* `[<parameter>,*]` A list of parameter identifiers used in the function body. For functions without parameters omit the `PARAMETERS []` block instead of supplying an empty array.
* `<language>` Either `js` (Javascript) or `sql`.

NOTE: To invoke a custom function, the function identifier (`library.function`) must be enclosed with back ticks.

NOTE: The return value in a custom SQL function is determined by the projection named `'result'`.

*Examples*

[source,sql]
----
DEFINE FUNCTION my.fma 'return a + b * c' PARAMETERS [a,b,c] LANGUAGE js;
SELECT `my.fma`(1,2,3);
----

[source,sql]
----
DEFINE FUNCTION the.answer 'SELECT "fourty-two" AS result' LANGUAGE sql;
SELECT `the.answer`();
----

'''

A custom function can be deleted via SQL using the following command:

----
DELETE FUNCTION <library>.<name>
----

* `<library>` A name space to group functions.
* `<name>` The function's name.

*Example*

[source,sql]
----
DELETE FUNCTION extra.tsum
----

[discrete]

==== Custom Functions in Java

Before to use them in your queries you need to register:

[source,java]
----
// REGISTER 'BIGGER' FUNCTION WITH FIXED 2 PARAMETERS (MIN/MAX=2)
SQLEngine.getInstance().registerFunction("bigger",
new SQLFunctionAbstract("bigger", 2, 2) {
public String getSyntax() {
return "bigger(<first>, <second>)";
}
public Object execute(Object[] iParameters) {
if (iParameters[0] == null || iParameters[1] == null)
// CHECK BOTH EXPECTED PARAMETERS
return null;
if (!(iParameters[0] instanceof Number) || !(iParameters[1] instanceof Number))
// EXCLUDE IT FROM THE RESULT SET
return null;
// USE DOUBLE TO AVOID LOSS OF PRECISION
final double v1 = ((Number) iParameters[0]).doubleValue();
final double v2 = ((Number) iParameters[1]).doubleValue();
return Math.max(v1, v2);
}
public boolean aggregateResults() {
return false;
}
});
----

Now you can execute it:

[source,java]
----
Resultset result = database.command("sql", "SELECT FROM Account WHERE bigger( salary, 10 ) > 10");
----
56 changes: 0 additions & 56 deletions src/main/asciidoc/sql/SQL-Functions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1341,59 +1341,3 @@ SELECT vectorNeighbors('Word[name,vector]','Life',10)
----

'''

[[Custom-Functions]]

==== Custom functions

The SQL engine can be extended with custom functions written with a scripting language or via Java.

[discrete]

===== Database's function

Look at the <<Database,Database Interface>> page.

[discrete]

===== Custom functions in Java

Before to use them in your queries you need to register:

[source,java]
----
// REGISTER 'BIGGER' FUNCTION WITH FIXED 2 PARAMETERS (MIN/MAX=2)
SQLEngine.getInstance().registerFunction("bigger",
new SQLFunctionAbstract("bigger", 2, 2) {
public String getSyntax() {
return "bigger(<first>, <second>)";
}
public Object execute(Object[] iParameters) {
if (iParameters[0] == null || iParameters[1] == null)
// CHECK BOTH EXPECTED PARAMETERS
return null;
if (!(iParameters[0] instanceof Number) || !(iParameters[1] instanceof Number))
// EXCLUDE IT FROM THE RESULT SET
return null;
// USE DOUBLE TO AVOID LOSS OF PRECISION
final double v1 = ((Number) iParameters[0]).doubleValue();
final double v2 = ((Number) iParameters[1]).doubleValue();
return Math.max(v1, v2);
}
public boolean aggregateResults() {
return false;
}
});
----

Now you can execute it:

[source,java]
----
Resultset result = database.command("sql", "SELECT FROM Account WHERE bigger( salary, 10 ) > 10");
----
5 changes: 4 additions & 1 deletion src/main/asciidoc/sql/SQL-Insert.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ INSERT INTO [TYPE:]<type>|BUCKET:<bucket>|INDEX:<index>
----

* *`SET`* Abbreviated syntax to set field values.
* *`CONTENT`* Defines JSON data as an option to set field values of one or multiple records.
* *`CONTENT`* Defines JSON data as an option to set field values of one (object) or multiple (in an array of objects) records.
* *`RETURN`* Defines an expression to return instead of the number of inserted records. You can use any valid SQL expression. The most common use-cases,
** `@rid` Returns the Record ID of the new record.
** `@this` Returns the entire new record.
* *`FROM`* Defines where you want to insert the result-set.

NOTE: To insert only documents, vertices, or edges with a certain *unique* property, use a <<SQL-Create-Index,unique index>>.

NOTE: If multiple documents are inserted as JSON "CONTENT", and one document causes an error,
for example due to a schema error, the remaining documents in the JSON array are not inserted.

*Examples*

* Inserts a new record with the name `Jay` and surname `Miner`.
Expand Down
2 changes: 1 addition & 1 deletion src/main/asciidoc/sql/SQL-Pagination.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[[SQL-Pagination]]
[discrete]
[[SQL-Pagination]]
=== Pagination

image:../images/edit.png[link="https://github.com/ArcadeData/arcadedb-docs/blob/main/src/main/asciidoc/sql/SQL-Pagination.adoc" float=right]
Expand Down
2 changes: 1 addition & 1 deletion src/main/asciidoc/sql/SQL-Profile.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

image:../images/edit.png[link="https://github.com/ArcadeData/arcadedb-docs/blob/main/src/main/asciidoc/sql/SQL-Profile.adoc" float=right]

PROFILE SQL command returns information about query execution planning and statistics for a specific statement.
The `PROFILE` SQL command returns information about query execution planning and statistics for a specific statement.
The statement is actually executed to provide the execution stats.

The result is the execution plan of the query (like for <<SQL-Explain,EXPLAIN>> ) with additional information about execution time spent on each step, in microseconds.
Expand Down
7 changes: 3 additions & 4 deletions src/main/asciidoc/sql/SQL-Projections.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[[SQL-Projections]]
[discrete]
[[SQL-Projections]]
=== Projections
Expand All @@ -22,7 +21,7 @@ has three projections:

[discrete]

===== Syntax
==== Syntax

*A projection* has the following syntax:

Expand All @@ -39,7 +38,7 @@ A projection block has the following syntax:

[discrete]

===== Query result
==== Query result

By default, a query returns a different result-set based on the projections it has:

Expand Down Expand Up @@ -154,7 +153,7 @@ Result: `[{"items[4]": "John Smith"}]`

[discrete]

===== Nested projections
==== Nested projections

*Syntax*:

Expand Down
6 changes: 3 additions & 3 deletions src/main/asciidoc/sql/SQL-Select-Execution.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[discrete]

=== SQL SELECT Statements Execution
==== SQL SELECT Statements Execution
image:../images/edit.png[link="https://github.com/ArcadeData/arcadedb-docs/blob/main/src/main/asciidoc/sql/SQL-Select-Execution.adoc" float=right]

The execution flow of a SELECT statement is made of many steps.
Expand All @@ -14,7 +14,7 @@ The SELECT query execution, at a very high level, is made of three steps:

[discrete]

==== Query optimization
===== Query optimization

The first step for the query executor is to run a query optimizer. This operation can change the internal structure of the SQL statement to make it more efficient, preserving the same semantics of the original query.

Expand Down Expand Up @@ -63,7 +63,7 @@ SELECT FROM Person WHERE father in (SELECT FROM Person WHERE name = 'John' and s
----
[discrete]

==== Refactoring of the WHERE conditions
===== Refactoring of the WHERE conditions

eg. consider the following:

Expand Down
14 changes: 8 additions & 6 deletions src/main/asciidoc/sql/chapter.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ include::SQL-Introduction.adoc[]

include::SQL-Projections.adoc[]

include::SQL-Functions.adoc[]

include::SQL-Methods.adoc[]
include::SQL-Pagination.adoc[]

include::SQL-Where.adoc[]

Expand Down Expand Up @@ -124,14 +122,14 @@ include::SQL-Insert.adoc[]

include::SQL-Match.adoc[]

include::SQL-Profile.adoc[]

include::SQL-Rebuild-Index.adoc[]

include::SQL-Select.adoc[]

include::SQL-Select-Execution.adoc[]

include::SQL-Pagination.adoc[]

include::SQL-Traverse.adoc[]

include::SQL-Truncate-Bucket.adoc[]
Expand All @@ -140,6 +138,10 @@ include::SQL-Truncate-Type.adoc[]

include::SQL-Update.adoc[]

include::SQL-Profile.adoc[]
include::SQL-Functions.adoc[]

include::SQL-Methods.adoc[]

include::SQL-Script.adoc[]

include::SQL-Custom-Functions.adoc[]

0 comments on commit 2821469

Please sign in to comment.