Skip to content

Commit 8999cc0

Browse files
authored
Document SQL SEQSCAN (#3645)
Resolves #3281
1 parent ea4ddce commit 8999cc0

File tree

9 files changed

+319
-184
lines changed

9 files changed

+319
-184
lines changed

doc/how-to/sql/sql_beginners_guide.rst

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Most of the matters in the Beginners' Guide will already be familiar to people w
1111

1212
.. _sql_beginners_sample_table:
1313

14-
Sample Table
14+
Sample table
1515
------------
1616

1717
In football training camp it is traditional for the trainer to begin by showing a football
@@ -270,7 +270,7 @@ NoSQL emphasizes freedom and making your own rules.
270270

271271
.. _sql_beginners_table_relationships:
272272

273-
Table Relationships
273+
Table relationships
274274
-------------------
275275

276276
Think about the two tables that have been discussed so far:
@@ -312,6 +312,20 @@ That is wrong, as will be clear in the discussion about what makes a database re
312312
Selecting with WHERE
313313
--------------------
314314

315+
.. important::
316+
317+
By default, Tarantool prohibits ``SELECT`` queries that scan table rows
318+
instead of using indexes to avoid unwanted heavy load. For the purposes of
319+
this tutorial, allow SQL scan queries in Tarantool by running the command:
320+
321+
.. code-block:: sql
322+
323+
SET SESSION "sql_seq_scan" = true;
324+
325+
Alternatively, you can allow a specific query to perform a table scan by adding
326+
the ``SEQSCAN`` keyword before the table name. Learn more about using ``SEQSCAN``
327+
in SQL scan queries in the :ref:`SQL FROM clause description <sql_from>`.
328+
315329
We gave a simple example of a SELECT statement earlier:
316330

317331
.. code-block:: sql
@@ -884,7 +898,7 @@ in format clauses. Indexes of NoSQL spaces will be used with SQL if and only if
884898

885899
.. _sql_beginners_relational_databases:
886900

887-
Relational Databases
901+
Relational databases
888902
--------------------
889903

890904
Edgar F. Codd, the person most responsible for researching and explaining relational database concepts,

doc/how-to/sql/sql_tutorial.rst

Lines changed: 84 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,55 @@ Then try to put another row:
117117
This ``INSERT`` fails because of a primary-key violation: the row with the primary
118118
key ``1, 'AB'`` already exists.
119119

120+
The SEQSCAN keyword
121+
~~~~~~~~~~~~~~~~~~~
122+
123+
In Tarantool, ``SELECT`` SQL queries that perform sequential scans (that is, go
124+
through all the table rows instead of using indexes) are prohibited by default.
125+
For example, this query leads to the error ``Scanning is not allowed for 'table2'``:
126+
127+
.. code-block:: sql
128+
129+
SELECT * FROM table2;
130+
131+
To execute a scan query, put the ``SEQSCAN`` keyword before the table name:
132+
133+
.. code-block:: sql
134+
135+
SELECT * FROM SEQSCAN table2;
136+
137+
Try to execute these queries that use indexed ``column1`` in filters:
138+
139+
.. code-block:: sql
140+
141+
SELECT * FROM table2 WHERE column1 = 1;
142+
SELECT * FROM table2 WHERE column1 + 1 = 2;
143+
144+
The result is:
145+
146+
* The first query returns rows:
147+
148+
.. code-block:: tarantoolsession
149+
150+
- [1, 'AB', 'AB', 10.5]
151+
- [1, 'CD', ' ', 10005]
152+
153+
* The second query fails with the error ``Scanning is not allowed for 'TABLE2'``.
154+
Although ``column1`` is indexed, the expression ``column1 + 1`` is not calculated
155+
from the index, which makes this ``SELECT`` a scan query.
156+
157+
.. note::
158+
159+
You can allow SQL scan queries without ``SEQSCAN`` for the current session
160+
by running the command:
161+
162+
.. code-block:: sql
163+
164+
SET SESSION "sql_seq_scan" = true;
165+
166+
167+
Learn more about using ``SEQSCAN`` in the :ref:`SQL FROM clause description <sql_from>`.
168+
120169
SELECT with ORDER BY clause
121170
~~~~~~~~~~~~~~~~~~~~~~~~~~~
122171

@@ -127,8 +176,11 @@ Retrieve the 4 rows in the table, in descending order by ``column2``, then
127176

128177
.. code-block:: sql
129178
130-
SELECT * FROM table2 ORDER BY column2 DESC, column4 ASC;
179+
SELECT * FROM SEQSCAN table2 ORDER BY column2 DESC, column4 ASC;
180+
181+
.. important::
131182

183+
Tarantool has its own
132184
The result is:
133185

134186
.. code-block:: tarantoolsession
@@ -152,9 +204,9 @@ Retrieve some of what you inserted:
152204

153205
.. code-block:: sql
154206
155-
SELECT column1, column2, column1 * column4 FROM table2 WHERE column2
207+
SELECT column1, column2, column1 * column4 FROM SEQSCAN table2 WHERE column2
156208
LIKE 'A%';
157-
SELECT column1, column2, column3, column4 FROM table2
209+
SELECT column1, column2, column3, column4 FROM SEQSCAN table2
158210
WHERE (column1 < 2 AND column4 < 10)
159211
OR column3 = X'2020';
160212
@@ -185,7 +237,7 @@ The rows which have the same values for ``column2`` are grouped and are aggregat
185237
.. code-block:: sql
186238
187239
SELECT column2, SUM(column4), COUNT(column4), AVG(column4)
188-
FROM table2
240+
FROM SEQSCAN table2
189241
GROUP BY column2;
190242
191243
The result is:
@@ -251,8 +303,8 @@ from the result table.
251303
252304
CREATE TABLE table3 (column1 INTEGER, column2 VARCHAR(100), PRIMARY KEY
253305
(column2));
254-
INSERT INTO table3 SELECT column1, column2 FROM table2 WHERE column1 <> 2;
255-
SELECT * FROM table3;
306+
INSERT INTO table3 SELECT column1, column2 FROM SEQSCAN table2 WHERE column1 <> 2;
307+
SELECT * FROM SEQSCAN table3;
256308
257309
The result is:
258310

@@ -274,8 +326,8 @@ present in ``table3``.
274326

275327
.. code-block:: sql
276328
277-
SELECT * FROM table2 WHERE (column1, column2) NOT IN (SELECT column1,
278-
column2 FROM table3);
329+
SELECT * FROM SEQSCAN table2 WHERE (column1, column2) NOT IN (SELECT column1,
330+
column2 FROM SEQSCAN table3);
279331
280332
The result is the single row that was excluded when inserting the rows with
281333
the ``INSERT ... SELECT`` statement:
@@ -295,7 +347,7 @@ column values from another table.
295347

296348
.. code-block:: sql
297349
298-
SELECT * FROM table2, table3
350+
SELECT * FROM SEQSCAN table2, table3
299351
WHERE table2.column1 = table3.column1 AND table2.column2 = table3.column2
300352
ORDER BY table2.column4;
301353
@@ -327,7 +379,7 @@ containing ``13`` in ``column2``. Then try to insert such a row.
327379
INSERT INTO table4 VALUES (12, 13);
328380
329381
Result: the insert fails, as it should, with the message
330-
``Check constraint failed ''ck_unnamed_TABLE4_1'': column2 <> 13``.
382+
``Check constraint 'ck_unnamed_TABLE4_1' failed for tuple``.
331383

332384
CREATE TABLE with a FOREIGN KEY clause
333385
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -348,7 +400,7 @@ Result:
348400
* The first ``INSERT`` statement succeeds because
349401
``table3`` contains a row with ``[2, 'AB', ' ', 12.34567]``.
350402
* The second ``INSERT`` statement, correctly, fails with the message
351-
``Failed to execute SQL statement: FOREIGN KEY constraint failed``.
403+
``Foreign key constraint ''fk_unnamed_TABLE5_1'' failed: foreign tuple was not found``.
352404

353405
UPDATE
354406
~~~~~~
@@ -361,7 +413,7 @@ Use ``SELECT`` to see what happened to ``column4``.
361413
.. code-block:: sql
362414
363415
UPDATE table2 SET column4 = column4 + 5 WHERE column4 <> 0;
364-
SELECT column4 FROM table2 ORDER BY column4;
416+
SELECT column4 FROM SEQSCAN table2 ORDER BY column4;
365417
366418
The result is: ``{NULL, NULL, 0, 10.5, 17.34567, 10005}``.
367419

@@ -385,11 +437,11 @@ Try to delete the last and first of these rows:
385437
386438
DELETE FROM table2 WHERE column1 = 2;
387439
DELETE FROM table2 WHERE column1 = -1000;
388-
SELECT COUNT(column1) FROM table2;
440+
SELECT COUNT(column1) FROM SEQSCAN table2;
389441
390442
The result is:
391443

392-
* The first ``DELETE`` statement causes an error message because
444+
* The first ``DELETE`` statement causes an error because
393445
there's a foreign-key constraint.
394446
* The second ``DELETE`` statement succeeds.
395447
* The ``SELECT`` statement shows that there are 5 rows remaining.
@@ -461,7 +513,7 @@ in many ways. For example:
461513

462514
.. code-block:: sql
463515
464-
SELECT column2, column2 || column2, SUBSTR(column2, 2, 1) FROM table2;
516+
SELECT column2, column2 || column2, SUBSTR(column2, 2, 1) FROM SEQSCAN table2;
465517
466518
The result is:
467519

@@ -479,12 +531,12 @@ Number operations
479531
You can also manipulate number data (usually defined with ``INTEGER``
480532
or ``DOUBLE`` data types) in many ways. For example:
481533

482-
* shift lleft with the ``<<`` operator
534+
* shift left with the ``<<`` operator
483535
* get modulo with the ``%`` operator
484536

485537
.. code-block:: sql
486538
487-
SELECT column1, column1 << 1, column1 << 2, column1 % 2 FROM table2;
539+
SELECT column1, column1 << 1, column1 << 2, column1 % 2 FROM SEQSCAN table2;
488540
489541
The result is:
490542

@@ -516,7 +568,7 @@ with arithmetic on a number column and ordering by a string column.
516568
INSERT INTO t6 VALUES (+1234567890, 'GD', 1e30);
517569
INSERT INTO t6 VALUES (10, 'FADEW?', 0.000001);
518570
INSERT INTO t6 VALUES (5, 'ABCDEFG', NULL);
519-
SELECT column1 + 1, column2, column4 * 2 FROM t6 ORDER BY column2;
571+
SELECT column1 + 1, column2, column4 * 2 FROM SEQSCAN t6 ORDER BY column2;
520572
521573
The result is:
522574

@@ -537,8 +589,8 @@ Create a view ``v3`` based on ``table3`` and select from it:
537589

538590
.. code-block:: sql
539591
540-
CREATE VIEW v3 AS SELECT SUBSTR(column2,1,2), column4 FROM t6 WHERE
541-
column4 >= 0;
592+
CREATE VIEW v3 AS SELECT SUBSTR(column2,1,2), column4 FROM SEQSCAN t6
593+
WHERE column4 >= 0;
542594
SELECT * FROM v3;
543595
544596
The result is:
@@ -560,8 +612,8 @@ Create such a view and select from it:
560612
.. code-block:: sql
561613
562614
WITH cte AS (
563-
SELECT SUBSTR(column2,1,2), column4 FROM t6 WHERE column4
564-
>= 0)
615+
SELECT SUBSTR(column2,1,2), column4 FROM SEQSCAN t6
616+
WHERE column4 >= 0)
565617
SELECT * FROM cte;
566618
567619
The result is the same as the ``CREATE VIEW`` result:
@@ -593,17 +645,18 @@ The result of both these statements is:
593645
Metadata
594646
~~~~~~~~
595647

596-
597648
To find out the internal structure of the Tarantool database with SQL,
598-
select from the Tarantool system tables:
649+
select from the Tarantool system tables ``_space``, ``_index``, and ``_trigger``:
650+
651+
.. code-block:: sql
599652
600-
* tables: ``SELECT * FROM "_space";``
601-
* indexes: ``SELECT * FROM "_index";``
602-
* triggers: ``SELECT * FROM "_trigger";``
653+
SELECT * FROM SEQSCAN "_space";
654+
SELECT * FROM SEQSCAN "_index";
655+
SELECT * FROM SEQSCAN "_trigger";
603656
604657
Actually, these statements select from NoSQL "system spaces".
605658

606-
Select from ``_space``:
659+
Select from ``_space`` by a table name:
607660

608661
.. code-block:: sql
609662
@@ -636,7 +689,7 @@ You can invoke SQL statements using the Lua function ``box.execute(string)``.
636689

637690
.. code-block:: tarantoolsession
638691
639-
tarantool> box.execute([[SELECT * FROM table3;]]);
692+
tarantool> box.execute([[SELECT * FROM SEQSCAN table3;]]);
640693
641694
The result is:
642695

@@ -684,7 +737,7 @@ a bit:
684737
start_time = os.clock();
685738
main_function();
686739
end_time = os.clock();
687-
'insert done in ' .. end_time - start_time .. ' seconds';
740+
print('insert done in ' .. end_time - start_time .. ' seconds');
688741
689742
The result is: you now have a table with a million rows, with a message saying
690743
"``insert done in 88.570578 seconds``".
@@ -701,7 +754,7 @@ Check how ``SELECT`` works on the million-row table:
701754
.. code-block:: lua
702755
703756
box.execute([[SELECT * FROM tester WHERE s1 = 73446;]]);
704-
box.execute([[SELECT * FROM tester WHERE s2 LIKE 'QFML%';]]);
757+
box.execute([[SELECT * FROM SEQSCAN tester WHERE s2 LIKE 'QFML%';]]);
705758
706759
The result is:
707760

doc/reference/reference_lua/box_space/_session_settings.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ box.space._session_settings
2626
* ``sql_reverse_unordered_selects``: return result rows in reverse order if there is no :ref:`ORDER BY clause <sql_order_by>`.
2727
Default: ``false``.
2828
* ``sql_select_debug``: show execution steps during :ref:`SELECT <sql_select>`. Default:``false``.
29+
* ``sql_seq_scan``: allow sequential scans in SQL :ref:`SELECT <sql_select>`. Default: ``true``.
2930
* ``sql_vdbe_debug``: for internal use. Default:``false``.
3031
* ``sql_defer_foreign_keys`` (removed in :doc:`2.11.0 </release/2.11.0>`): whether foreign-key checks can wait till
3132
commit. Default: ``false``.

doc/reference/reference_sql/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
The diagrams in the SQL reference are generated using [Syntrax](https://github.com/kevinpt/syntrax).
2+
3+
# Install Syntrax
4+
5+
```
6+
pip install syntrax
7+
```
8+
9+
## Troubleshooting installation issues
10+
11+
### pip: command not found
12+
13+
- Ensure that Python is installed
14+
- Try `pip3` instead of `pip`
15+
16+
### error in syntrax setup command: use_2to3 is invalid.
17+
18+
Run `pip3 install "setuptools<58.0.0"`
19+
20+
### ModuleNotFoundError: No module named 'cairo'|'gi'|'pango'
21+
22+
Search on stackoverflow %)
23+
24+
# Generate a diagram
25+
26+
Generate an SVG with the same file name:
27+
28+
```
29+
syntrax <filename>.spec -o svg
30+
```

doc/reference/reference_sql/from.spec

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ stack (
22
line(
33
choice(
44
line(
5+
choice(
6+
None,
7+
line(' SEQSCAN ')
8+
),
59
'table-name',
610
choice(
711
None,

0 commit comments

Comments
 (0)